Rev 3031 | Rev 3480 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3031 | Rev 3243 | ||
---|---|---|---|
Line 56... | Line 56... | ||
56 | 0x00FFFFFF, 0x00060006, |
56 | 0x00FFFFFF, 0x00060006, |
57 | 0x00D75FFF, 0x001E0000, |
57 | 0x00D75FFF, 0x001E0000, |
58 | 0x00FFFFFF, 0x00040006 /* HDMI parameters */ |
58 | 0x00FFFFFF, 0x00040006 /* HDMI parameters */ |
59 | }; |
59 | }; |
Line -... | Line 60... | ||
- | 60 | ||
- | 61 | static enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) |
|
- | 62 | { |
|
- | 63 | struct drm_encoder *encoder = &intel_encoder->base; |
|
- | 64 | int type = intel_encoder->type; |
|
- | 65 | ||
- | 66 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || |
|
- | 67 | type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) { |
|
- | 68 | struct intel_digital_port *intel_dig_port = |
|
- | 69 | enc_to_dig_port(encoder); |
|
- | 70 | return intel_dig_port->port; |
|
- | 71 | ||
- | 72 | } else if (type == INTEL_OUTPUT_ANALOG) { |
|
- | 73 | return PORT_E; |
|
- | 74 | ||
- | 75 | } else { |
|
- | 76 | DRM_ERROR("Invalid DDI encoder type %d\n", type); |
|
- | 77 | BUG(); |
|
- | 78 | } |
|
- | 79 | } |
|
60 | 80 | ||
61 | /* On Haswell, DDI port buffers must be programmed with correct values |
81 | /* On Haswell, DDI port buffers must be programmed with correct values |
62 | * 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, |
63 | * 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 |
64 | * 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 |
Line 116... | Line 136... | ||
116 | DDI_BUF_EMP_600MV_6DB_HSW, |
136 | DDI_BUF_EMP_600MV_6DB_HSW, |
117 | DDI_BUF_EMP_800MV_0DB_HSW, |
137 | DDI_BUF_EMP_800MV_0DB_HSW, |
118 | DDI_BUF_EMP_800MV_3_5DB_HSW |
138 | DDI_BUF_EMP_800MV_3_5DB_HSW |
119 | }; |
139 | }; |
Line -... | Line 140... | ||
- | 140 | ||
- | 141 | static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, |
|
- | 142 | enum port port) |
|
- | 143 | { |
|
- | 144 | uint32_t reg = DDI_BUF_CTL(port); |
|
- | 145 | int i; |
|
- | 146 | ||
- | 147 | for (i = 0; i < 8; i++) { |
|
- | 148 | udelay(1); |
|
- | 149 | if (I915_READ(reg) & DDI_BUF_IS_IDLE) |
|
- | 150 | return; |
|
- | 151 | } |
|
- | 152 | DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port)); |
|
Line 120... | Line 153... | ||
120 | 153 | } |
|
121 | 154 | ||
122 | /* Starting with Haswell, different DDI ports can work in FDI mode for |
155 | /* Starting with Haswell, different DDI ports can work in FDI mode for |
123 | * connection to the PCH-located connectors. For this, it is necessary to train |
156 | * connection to the PCH-located connectors. For this, it is necessary to train |
Line 131... | Line 164... | ||
131 | void hsw_fdi_link_train(struct drm_crtc *crtc) |
164 | void hsw_fdi_link_train(struct drm_crtc *crtc) |
132 | { |
165 | { |
133 | struct drm_device *dev = crtc->dev; |
166 | struct drm_device *dev = crtc->dev; |
134 | struct drm_i915_private *dev_priv = dev->dev_private; |
167 | struct drm_i915_private *dev_priv = dev->dev_private; |
135 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
168 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
136 | int pipe = intel_crtc->pipe; |
- | |
137 | u32 reg, temp, i; |
169 | u32 temp, i, rx_ctl_val; |
138 | - | ||
139 | /* Configure CPU PLL, wait for warmup */ |
- | |
140 | I915_WRITE(SPLL_CTL, |
- | |
141 | SPLL_PLL_ENABLE | |
- | |
142 | SPLL_PLL_FREQ_1350MHz | |
- | |
143 | SPLL_PLL_SCC); |
- | |
144 | - | ||
145 | /* Use SPLL to drive the output when in FDI mode */ |
- | |
146 | I915_WRITE(PORT_CLK_SEL(PORT_E), |
- | |
147 | PORT_CLK_SEL_SPLL); |
- | |
148 | I915_WRITE(PIPE_CLK_SEL(pipe), |
- | |
149 | PIPE_CLK_SEL_PORT(PORT_E)); |
- | |
Line -... | Line 170... | ||
- | 170 | ||
- | 171 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the |
|
- | 172 | * mode set "sequence for CRT port" document: |
|
- | 173 | * - TP1 to TP2 time with the default value |
|
- | 174 | * - FDI delay to 90h |
|
- | 175 | */ |
|
- | 176 | I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) | |
|
- | 177 | FDI_RX_PWRDN_LANE0_VAL(2) | |
|
- | 178 | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); |
|
- | 179 | ||
- | 180 | /* Enable the PCH Receiver FDI PLL */ |
|
- | 181 | rx_ctl_val = FDI_RX_PLL_ENABLE | FDI_RX_ENHANCE_FRAME_ENABLE | |
|
- | 182 | ((intel_crtc->fdi_lanes - 1) << 19); |
|
- | 183 | if (dev_priv->fdi_rx_polarity_reversed) |
|
- | 184 | rx_ctl_val |= FDI_RX_POLARITY_REVERSED_LPT; |
|
- | 185 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
|
150 | 186 | POSTING_READ(_FDI_RXA_CTL); |
|
- | 187 | udelay(220); |
|
- | 188 | ||
- | 189 | /* Switch from Rawclk to PCDclk */ |
|
- | 190 | rx_ctl_val |= FDI_PCDCLK; |
|
- | 191 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
|
- | 192 | ||
- | 193 | /* Configure Port Clock Select */ |
|
151 | udelay(20); |
194 | I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->ddi_pll_sel); |
152 | 195 | ||
- | 196 | /* Start the training iterating through available voltages and emphasis, |
|
153 | /* Start the training iterating through available voltages and emphasis */ |
197 | * testing each value twice. */ |
154 | for (i=0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values); i++) { |
198 | for (i = 0; i < ARRAY_SIZE(hsw_ddi_buf_ctl_values) * 2; i++) { |
155 | /* Configure DP_TP_CTL with auto-training */ |
199 | /* Configure DP_TP_CTL with auto-training */ |
156 | I915_WRITE(DP_TP_CTL(PORT_E), |
200 | I915_WRITE(DP_TP_CTL(PORT_E), |
157 | DP_TP_CTL_FDI_AUTOTRAIN | |
201 | DP_TP_CTL_FDI_AUTOTRAIN | |
158 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
202 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
159 | DP_TP_CTL_LINK_TRAIN_PAT1 | |
203 | DP_TP_CTL_LINK_TRAIN_PAT1 | |
Line 160... | Line 204... | ||
160 | DP_TP_CTL_ENABLE); |
204 | DP_TP_CTL_ENABLE); |
161 | - | ||
162 | /* Configure and enable DDI_BUF_CTL for DDI E with next voltage */ |
- | |
163 | temp = I915_READ(DDI_BUF_CTL(PORT_E)); |
205 | |
164 | temp = (temp & ~DDI_BUF_EMP_MASK); |
- | |
165 | I915_WRITE(DDI_BUF_CTL(PORT_E), |
206 | /* Configure and enable DDI_BUF_CTL for DDI E with next voltage */ |
166 | temp | |
207 | I915_WRITE(DDI_BUF_CTL(PORT_E), |
167 | DDI_BUF_CTL_ENABLE | |
208 | DDI_BUF_CTL_ENABLE | |
- | 209 | ((intel_crtc->fdi_lanes - 1) << 1) | |
|
Line 168... | Line 210... | ||
168 | DDI_PORT_WIDTH_X2 | |
210 | hsw_ddi_buf_ctl_values[i / 2]); |
Line 169... | Line 211... | ||
169 | hsw_ddi_buf_ctl_values[i]); |
211 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
170 | - | ||
171 | udelay(600); |
- | |
172 | - | ||
173 | /* We need to program FDI_RX_MISC with the default TP1 to TP2 |
- | |
174 | * values before enabling the receiver, and configure the delay |
- | |
175 | * for the FDI timing generator to 90h. Luckily, all the other |
212 | |
176 | * bits are supposed to be zeroed, so we can write those values |
- | |
Line 177... | Line 213... | ||
177 | * directly. |
213 | udelay(600); |
178 | */ |
214 | |
179 | I915_WRITE(FDI_RX_MISC(pipe), FDI_RX_TP1_TO_TP2_48 | |
215 | /* Program PCH FDI Receiver TU */ |
180 | FDI_RX_FDI_DELAY_90); |
216 | I915_WRITE(_FDI_RXA_TUSIZE1, TU_SIZE(64)); |
- | 217 | ||
181 | 218 | /* Enable PCH FDI Receiver with auto-training */ |
|
182 | /* Enable CPU FDI Receiver with auto-training */ |
219 | rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; |
- | 220 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
|
183 | reg = FDI_RX_CTL(pipe); |
221 | POSTING_READ(_FDI_RXA_CTL); |
184 | I915_WRITE(reg, |
222 | |
185 | I915_READ(reg) | |
223 | /* Wait for FDI receiver lane calibration */ |
186 | FDI_LINK_TRAIN_AUTO | |
224 | udelay(30); |
187 | FDI_RX_ENABLE | |
225 | |
- | 226 | /* Unset FDI_RX_MISC pwrdn lanes */ |
|
- | 227 | temp = I915_READ(_FDI_RXA_MISC); |
|
188 | FDI_LINK_TRAIN_PATTERN_1_CPT | |
228 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
Line 189... | Line 229... | ||
189 | FDI_RX_ENHANCE_FRAME_ENABLE | |
229 | I915_WRITE(_FDI_RXA_MISC, temp); |
190 | FDI_PORT_WIDTH_2X_LPT | |
230 | POSTING_READ(_FDI_RXA_MISC); |
191 | FDI_RX_PLL_ENABLE); |
231 | |
Line 192... | Line 232... | ||
192 | POSTING_READ(reg); |
232 | /* Wait for FDI auto training time */ |
193 | udelay(100); |
233 | udelay(5); |
194 | 234 | ||
195 | temp = I915_READ(DP_TP_STATUS(PORT_E)); |
235 | temp = I915_READ(DP_TP_STATUS(PORT_E)); |
196 | if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) { |
236 | if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) { |
197 | DRM_DEBUG_DRIVER("BUF_CTL training done on %d step\n", i); |
237 | DRM_DEBUG_KMS("FDI link training done on step %d\n", i); |
Line 198... | Line -... | ||
198 | - | ||
199 | /* Enable normal pixel sending for FDI */ |
- | |
200 | I915_WRITE(DP_TP_CTL(PORT_E), |
- | |
201 | DP_TP_CTL_FDI_AUTOTRAIN | |
- | |
202 | DP_TP_CTL_LINK_TRAIN_NORMAL | |
- | |
203 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
- | |
204 | DP_TP_CTL_ENABLE); |
- | |
205 | - | ||
206 | /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in FDI mode */ |
- | |
207 | temp = I915_READ(DDI_FUNC_CTL(pipe)); |
238 | |
208 | temp &= ~PIPE_DDI_PORT_MASK; |
- | |
209 | temp |= PIPE_DDI_SELECT_PORT(PORT_E) | |
- | |
210 | PIPE_DDI_MODE_SELECT_FDI | |
- | |
211 | PIPE_DDI_FUNC_ENABLE | |
- | |
212 | PIPE_DDI_PORT_WIDTH_X2; |
- | |
213 | I915_WRITE(DDI_FUNC_CTL(pipe), |
- | |
214 | temp); |
- | |
215 | break; |
- | |
216 | } else { |
- | |
217 | DRM_ERROR("Error training BUF_CTL %d\n", i); |
- | |
218 | - | ||
219 | /* Disable DP_TP_CTL and FDI_RX_CTL) and retry */ |
- | |
220 | I915_WRITE(DP_TP_CTL(PORT_E), |
- | |
221 | I915_READ(DP_TP_CTL(PORT_E)) & |
- | |
222 | ~DP_TP_CTL_ENABLE); |
- | |
223 | I915_WRITE(FDI_RX_CTL(pipe), |
239 | /* Enable normal pixel sending for FDI */ |
Line 224... | Line -... | ||
224 | I915_READ(FDI_RX_CTL(pipe)) & |
- | |
225 | ~FDI_RX_PLL_ENABLE); |
240 | I915_WRITE(DP_TP_CTL(PORT_E), |
226 | continue; |
- | |
227 | } |
- | |
228 | } |
241 | DP_TP_CTL_FDI_AUTOTRAIN | |
229 | - | ||
230 | DRM_DEBUG_KMS("FDI train done.\n"); |
242 | DP_TP_CTL_LINK_TRAIN_NORMAL | |
231 | } |
- | |
232 | - | ||
233 | /* For DDI connections, it is possible to support different outputs over the |
243 | DP_TP_CTL_ENHANCED_FRAME_ENABLE | |
Line -... | Line 244... | ||
- | 244 | DP_TP_CTL_ENABLE); |
|
234 | * same DDI port, such as HDMI or DP or even VGA via FDI. So we don't know by |
245 | |
- | 246 | return; |
|
235 | * the time the output is detected what exactly is on the other end of it. This |
247 | } |
236 | * function aims at providing support for this detection and proper output |
248 | |
237 | * configuration. |
249 | temp = I915_READ(DDI_BUF_CTL(PORT_E)); |
238 | */ |
250 | temp &= ~DDI_BUF_CTL_ENABLE; |
239 | void intel_ddi_init(struct drm_device *dev, enum port port) |
251 | I915_WRITE(DDI_BUF_CTL(PORT_E), temp); |
- | 252 | POSTING_READ(DDI_BUF_CTL(PORT_E)); |
|
240 | { |
253 | |
241 | /* For now, we don't do any proper output detection and assume that we |
254 | /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ |
242 | * handle HDMI only */ |
255 | temp = I915_READ(DP_TP_CTL(PORT_E)); |
- | 256 | temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
|
243 | 257 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; |
|
244 | switch(port){ |
258 | I915_WRITE(DP_TP_CTL(PORT_E), temp); |
245 | case PORT_A: |
- | |
- | 259 | POSTING_READ(DP_TP_CTL(PORT_E)); |
|
246 | /* We don't handle eDP and DP yet */ |
260 | |
247 | DRM_DEBUG_DRIVER("Found digital output on DDI port A\n"); |
261 | intel_wait_ddi_buf_idle(dev_priv, PORT_E); |
248 | break; |
262 | |
249 | /* Assume that the ports B, C and D are working in HDMI mode for now */ |
263 | rx_ctl_val &= ~FDI_RX_ENABLE; |
- | 264 | I915_WRITE(_FDI_RXA_CTL, rx_ctl_val); |
|
- | 265 | POSTING_READ(_FDI_RXA_CTL); |
|
250 | case PORT_B: |
266 | |
Line 251... | Line 267... | ||
251 | case PORT_C: |
267 | /* Reset FDI_RX_MISC pwrdn lanes */ |
252 | case PORT_D: |
268 | temp = I915_READ(_FDI_RXA_MISC); |
253 | intel_hdmi_init(dev, DDI_BUF_CTL(port), port); |
269 | temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
Line 643... | Line 659... | ||
643 | {296703, 2, 56, 51}, |
659 | {296703, 2, 56, 51}, |
644 | {297000, 2, 22, 20}, |
660 | {297000, 2, 22, 20}, |
645 | {298000, 2, 21, 19}, |
661 | {298000, 2, 21, 19}, |
646 | }; |
662 | }; |
Line 647... | Line 663... | ||
647 | 663 | ||
648 | void intel_ddi_mode_set(struct drm_encoder *encoder, |
664 | static void intel_ddi_mode_set(struct drm_encoder *encoder, |
649 | struct drm_display_mode *mode, |
665 | struct drm_display_mode *mode, |
650 | struct drm_display_mode *adjusted_mode) |
666 | struct drm_display_mode *adjusted_mode) |
651 | { |
- | |
652 | struct drm_device *dev = encoder->dev; |
- | |
653 | struct drm_i915_private *dev_priv = dev->dev_private; |
667 | { |
654 | struct drm_crtc *crtc = encoder->crtc; |
668 | struct drm_crtc *crtc = encoder->crtc; |
655 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
669 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
656 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
670 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
657 | int port = intel_hdmi->ddi_port; |
671 | int port = intel_ddi_get_encoder_port(intel_encoder); |
- | 672 | int pipe = intel_crtc->pipe; |
|
- | 673 | int type = intel_encoder->type; |
|
- | 674 | ||
- | 675 | DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n", |
|
- | 676 | port_name(port), pipe_name(pipe)); |
|
- | 677 | ||
- | 678 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
|
- | 679 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
|
- | 680 | ||
- | 681 | intel_dp->DP = DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
|
- | 682 | switch (intel_dp->lane_count) { |
|
- | 683 | case 1: |
|
- | 684 | intel_dp->DP |= DDI_PORT_WIDTH_X1; |
|
658 | int pipe = intel_crtc->pipe; |
685 | break; |
- | 686 | case 2: |
|
- | 687 | intel_dp->DP |= DDI_PORT_WIDTH_X2; |
|
- | 688 | break; |
|
- | 689 | case 4: |
|
- | 690 | intel_dp->DP |= DDI_PORT_WIDTH_X4; |
|
- | 691 | break; |
|
- | 692 | default: |
|
- | 693 | intel_dp->DP |= DDI_PORT_WIDTH_X4; |
|
- | 694 | WARN(1, "Unexpected DP lane count %d\n", |
|
- | 695 | intel_dp->lane_count); |
|
- | 696 | break; |
|
- | 697 | } |
|
- | 698 | ||
- | 699 | if (intel_dp->has_audio) { |
|
- | 700 | DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n", |
|
- | 701 | pipe_name(intel_crtc->pipe)); |
|
659 | int p, n2, r2; |
702 | |
- | 703 | /* write eld */ |
|
- | 704 | DRM_DEBUG_DRIVER("DP audio: write eld information\n"); |
|
- | 705 | intel_write_eld(encoder, adjusted_mode); |
|
- | 706 | } |
|
- | 707 | ||
- | 708 | intel_dp_init_link_config(intel_dp); |
|
- | 709 | ||
- | 710 | } else if (type == INTEL_OUTPUT_HDMI) { |
|
Line -... | Line 711... | ||
- | 711 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
|
- | 712 | ||
660 | u32 temp, i; |
713 | if (intel_hdmi->has_audio) { |
661 | 714 | /* Proper support for digital audio needs a new logic |
|
662 | /* On Haswell, we need to enable the clocks and prepare DDI function to |
715 | * and a new set of registers, so we leave it for future |
- | 716 | * patch bombing. |
|
- | 717 | */ |
|
- | 718 | DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", |
|
- | 719 | pipe_name(intel_crtc->pipe)); |
|
- | 720 | ||
- | 721 | /* write eld */ |
|
- | 722 | DRM_DEBUG_DRIVER("HDMI audio: write eld information\n"); |
|
- | 723 | intel_write_eld(encoder, adjusted_mode); |
|
- | 724 | } |
|
- | 725 | ||
- | 726 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
|
- | 727 | } |
|
- | 728 | } |
|
- | 729 | ||
- | 730 | static struct intel_encoder * |
|
- | 731 | intel_ddi_get_crtc_encoder(struct drm_crtc *crtc) |
|
- | 732 | { |
|
- | 733 | struct drm_device *dev = crtc->dev; |
|
- | 734 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 735 | struct intel_encoder *intel_encoder, *ret = NULL; |
|
- | 736 | int num_encoders = 0; |
|
- | 737 | ||
- | 738 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) { |
|
- | 739 | ret = intel_encoder; |
|
- | 740 | num_encoders++; |
|
- | 741 | } |
|
663 | * work in HDMI mode for this pipe. |
742 | |
- | 743 | if (num_encoders != 1) |
|
- | 744 | WARN(1, "%d encoders on crtc for pipe %d\n", num_encoders, |
|
- | 745 | intel_crtc->pipe); |
|
- | 746 | ||
- | 747 | BUG_ON(ret == NULL); |
|
- | 748 | return ret; |
|
- | 749 | } |
|
- | 750 | ||
- | 751 | void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) |
|
- | 752 | { |
|
- | 753 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
|
- | 754 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
|
- | 755 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 756 | uint32_t val; |
|
- | 757 | ||
- | 758 | switch (intel_crtc->ddi_pll_sel) { |
|
- | 759 | case PORT_CLK_SEL_SPLL: |
|
- | 760 | plls->spll_refcount--; |
|
- | 761 | if (plls->spll_refcount == 0) { |
|
- | 762 | DRM_DEBUG_KMS("Disabling SPLL\n"); |
|
- | 763 | val = I915_READ(SPLL_CTL); |
|
- | 764 | WARN_ON(!(val & SPLL_PLL_ENABLE)); |
|
- | 765 | I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); |
|
- | 766 | POSTING_READ(SPLL_CTL); |
|
- | 767 | } |
|
- | 768 | break; |
|
- | 769 | case PORT_CLK_SEL_WRPLL1: |
|
- | 770 | plls->wrpll1_refcount--; |
|
- | 771 | if (plls->wrpll1_refcount == 0) { |
|
- | 772 | DRM_DEBUG_KMS("Disabling WRPLL 1\n"); |
|
- | 773 | val = I915_READ(WRPLL_CTL1); |
|
- | 774 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
|
- | 775 | I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE); |
|
- | 776 | POSTING_READ(WRPLL_CTL1); |
|
- | 777 | } |
|
- | 778 | break; |
|
- | 779 | case PORT_CLK_SEL_WRPLL2: |
|
- | 780 | plls->wrpll2_refcount--; |
|
- | 781 | if (plls->wrpll2_refcount == 0) { |
|
- | 782 | DRM_DEBUG_KMS("Disabling WRPLL 2\n"); |
|
- | 783 | val = I915_READ(WRPLL_CTL2); |
|
- | 784 | WARN_ON(!(val & WRPLL_PLL_ENABLE)); |
|
- | 785 | I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE); |
|
- | 786 | POSTING_READ(WRPLL_CTL2); |
|
- | 787 | } |
|
- | 788 | break; |
|
- | 789 | } |
|
- | 790 | ||
- | 791 | WARN(plls->spll_refcount < 0, "Invalid SPLL refcount\n"); |
|
- | 792 | WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); |
|
- | 793 | WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n"); |
|
- | 794 | ||
- | 795 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE; |
|
- | 796 | } |
|
- | 797 | ||
- | 798 | static void intel_ddi_calculate_wrpll(int clock, int *p, int *n2, int *r2) |
|
Line 664... | Line 799... | ||
664 | */ |
799 | { |
665 | DRM_DEBUG_KMS("Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n", port_name(port), pipe_name(pipe)); |
800 | u32 i; |
666 | 801 | ||
Line 667... | Line 802... | ||
667 | for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) |
802 | for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) |
668 | if (crtc->mode.clock <= wrpll_tmds_clock_table[i].clock) |
803 | if (clock <= wrpll_tmds_clock_table[i].clock) |
Line 669... | Line 804... | ||
669 | break; |
804 | break; |
670 | 805 | ||
671 | if (i == ARRAY_SIZE(wrpll_tmds_clock_table)) |
806 | if (i == ARRAY_SIZE(wrpll_tmds_clock_table)) |
Line 672... | Line 807... | ||
672 | i--; |
807 | i--; |
673 | 808 | ||
674 | p = wrpll_tmds_clock_table[i].p; |
809 | *p = wrpll_tmds_clock_table[i].p; |
Line 675... | Line 810... | ||
675 | n2 = wrpll_tmds_clock_table[i].n2; |
810 | *n2 = wrpll_tmds_clock_table[i].n2; |
676 | r2 = wrpll_tmds_clock_table[i].r2; |
811 | *r2 = wrpll_tmds_clock_table[i].r2; |
- | 812 | ||
- | 813 | if (wrpll_tmds_clock_table[i].clock != clock) |
|
- | 814 | DRM_INFO("WRPLL: using settings for %dKHz on %dKHz mode\n", |
|
- | 815 | wrpll_tmds_clock_table[i].clock, clock); |
|
- | 816 | ||
- | 817 | DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n", |
|
- | 818 | clock, *p, *n2, *r2); |
|
- | 819 | } |
|
- | 820 | ||
- | 821 | bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock) |
|
- | 822 | { |
|
- | 823 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 824 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
|
- | 825 | struct drm_encoder *encoder = &intel_encoder->base; |
|
- | 826 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
|
- | 827 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
|
- | 828 | int type = intel_encoder->type; |
|
- | 829 | enum pipe pipe = intel_crtc->pipe; |
|
- | 830 | uint32_t reg, val; |
|
- | 831 | ||
- | 832 | /* TODO: reuse PLLs when possible (compare values) */ |
|
- | 833 | ||
- | 834 | intel_ddi_put_crtc_pll(crtc); |
|
- | 835 | ||
- | 836 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
|
- | 837 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
|
- | 838 | ||
- | 839 | switch (intel_dp->link_bw) { |
|
- | 840 | case DP_LINK_BW_1_62: |
|
- | 841 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; |
|
- | 842 | break; |
|
- | 843 | case DP_LINK_BW_2_7: |
|
- | 844 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; |
|
- | 845 | break; |
|
- | 846 | case DP_LINK_BW_5_4: |
|
Line 677... | Line -... | ||
677 | - | ||
678 | if (wrpll_tmds_clock_table[i].clock != crtc->mode.clock) |
- | |
679 | DRM_INFO("WR PLL: using settings for %dKHz on %dKHz mode\n", |
- | |
680 | wrpll_tmds_clock_table[i].clock, crtc->mode.clock); |
- | |
681 | - | ||
682 | DRM_DEBUG_KMS("WR PLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n", |
- | |
683 | crtc->mode.clock, p, n2, r2); |
- | |
684 | 847 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; |
|
685 | /* Enable LCPLL if disabled */ |
- | |
686 | temp = I915_READ(LCPLL_CTL); |
848 | break; |
687 | if (temp & LCPLL_PLL_DISABLE) |
- | |
688 | I915_WRITE(LCPLL_CTL, |
- | |
689 | temp & ~LCPLL_PLL_DISABLE); |
- | |
690 | - | ||
Line -... | Line 849... | ||
- | 849 | default: |
|
691 | /* Configure WR PLL 1, program the correct divider values for |
850 | DRM_ERROR("Link bandwidth %d unsupported\n", |
Line -... | Line 851... | ||
- | 851 | intel_dp->link_bw); |
|
692 | * the desired frequency and wait for warmup */ |
852 | return false; |
- | 853 | } |
|
693 | I915_WRITE(WRPLL_CTL1, |
854 | |
- | 855 | /* We don't need to turn any PLL on because we'll use LCPLL. */ |
|
- | 856 | return true; |
|
- | 857 | ||
- | 858 | } else if (type == INTEL_OUTPUT_HDMI) { |
|
- | 859 | int p, n2, r2; |
|
- | 860 | ||
- | 861 | if (plls->wrpll1_refcount == 0) { |
|
- | 862 | DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n", |
|
- | 863 | pipe_name(pipe)); |
|
- | 864 | plls->wrpll1_refcount++; |
|
- | 865 | reg = WRPLL_CTL1; |
|
694 | WRPLL_PLL_ENABLE | |
866 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1; |
- | 867 | } else if (plls->wrpll2_refcount == 0) { |
|
695 | WRPLL_PLL_SELECT_LCPLL_2700 | |
868 | DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n", |
- | 869 | pipe_name(pipe)); |
|
- | 870 | plls->wrpll2_refcount++; |
|
- | 871 | reg = WRPLL_CTL2; |
|
- | 872 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2; |
|
- | 873 | } else { |
|
- | 874 | DRM_ERROR("No WRPLLs available!\n"); |
|
696 | WRPLL_DIVIDER_REFERENCE(r2) | |
875 | return false; |
- | 876 | } |
|
- | 877 | ||
- | 878 | WARN(I915_READ(reg) & WRPLL_PLL_ENABLE, |
|
697 | WRPLL_DIVIDER_FEEDBACK(n2) | |
879 | "WRPLL already enabled\n"); |
698 | WRPLL_DIVIDER_POST(p)); |
880 | |
- | 881 | intel_ddi_calculate_wrpll(clock, &p, &n2, &r2); |
|
- | 882 | ||
- | 883 | val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 | |
|
- | 884 | WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | |
|
- | 885 | WRPLL_DIVIDER_POST(p); |
|
- | 886 | ||
- | 887 | } else if (type == INTEL_OUTPUT_ANALOG) { |
|
Line -... | Line 888... | ||
- | 888 | if (plls->spll_refcount == 0) { |
|
- | 889 | DRM_DEBUG_KMS("Using SPLL on pipe %c\n", |
|
- | 890 | pipe_name(pipe)); |
|
- | 891 | plls->spll_refcount++; |
|
- | 892 | reg = SPLL_CTL; |
|
- | 893 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL; |
|
- | 894 | } |
|
- | 895 | ||
699 | 896 | WARN(I915_READ(reg) & SPLL_PLL_ENABLE, |
|
Line 700... | Line 897... | ||
700 | udelay(20); |
897 | "SPLL already enabled\n"); |
701 | - | ||
702 | /* Use WRPLL1 clock to drive the output to the port, and tell the pipe to use |
- | |
703 | * this port for connection. |
898 | |
704 | */ |
- | |
705 | I915_WRITE(PORT_CLK_SEL(port), |
- | |
Line -... | Line 899... | ||
- | 899 | val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; |
|
- | 900 | ||
- | 901 | } else { |
|
- | 902 | WARN(1, "Invalid DDI encoder type %d\n", type); |
|
- | 903 | return false; |
|
- | 904 | } |
|
- | 905 | ||
706 | PORT_CLK_SEL_WRPLL1); |
906 | I915_WRITE(reg, val); |
- | 907 | udelay(20); |
|
- | 908 | ||
- | 909 | return true; |
|
- | 910 | } |
|
- | 911 | ||
- | 912 | void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) |
|
- | 913 | { |
|
- | 914 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
|
- | 915 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 916 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
|
- | 917 | enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; |
|
- | 918 | int type = intel_encoder->type; |
|
- | 919 | uint32_t temp; |
|
- | 920 | ||
- | 921 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
|
- | 922 | ||
- | 923 | temp = TRANS_MSA_SYNC_CLK; |
|
- | 924 | switch (intel_crtc->bpp) { |
|
- | 925 | case 18: |
|
707 | I915_WRITE(PIPE_CLK_SEL(pipe), |
926 | temp |= TRANS_MSA_6_BPC; |
- | 927 | break; |
|
- | 928 | case 24: |
|
708 | PIPE_CLK_SEL_PORT(port)); |
929 | temp |= TRANS_MSA_8_BPC; |
- | 930 | break; |
|
709 | 931 | case 30: |
|
Line -... | Line 932... | ||
- | 932 | temp |= TRANS_MSA_10_BPC; |
|
- | 933 | break; |
|
- | 934 | case 36: |
|
- | 935 | temp |= TRANS_MSA_12_BPC; |
|
- | 936 | break; |
|
- | 937 | default: |
|
- | 938 | temp |= TRANS_MSA_8_BPC; |
|
- | 939 | WARN(1, "%d bpp unsupported by DDI function\n", |
|
- | 940 | intel_crtc->bpp); |
|
- | 941 | } |
|
- | 942 | I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp); |
|
- | 943 | } |
|
710 | udelay(20); |
944 | } |
- | 945 | ||
711 | 946 | void intel_ddi_enable_pipe_func(struct drm_crtc *crtc) |
|
Line 712... | Line 947... | ||
712 | if (intel_hdmi->has_audio) { |
947 | { |
713 | /* Proper support for digital audio needs a new logic and a new set |
948 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
714 | * of registers, so we leave it for future patch bombing. |
949 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
715 | */ |
950 | struct drm_encoder *encoder = &intel_encoder->base; |
716 | DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n", |
951 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
717 | pipe_name(intel_crtc->pipe)); |
952 | enum pipe pipe = intel_crtc->pipe; |
718 | 953 | enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; |
|
719 | /* write eld */ |
954 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
720 | DRM_DEBUG_DRIVER("HDMI audio: write eld information\n"); |
955 | int type = intel_encoder->type; |
721 | intel_write_eld(encoder, adjusted_mode); |
956 | uint32_t temp; |
722 | } |
957 | |
723 | 958 | /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ |
|
724 | /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */ |
959 | temp = TRANS_DDI_FUNC_ENABLE; |
725 | temp = PIPE_DDI_FUNC_ENABLE | PIPE_DDI_SELECT_PORT(port); |
960 | temp |= TRANS_DDI_SELECT_PORT(port); |
726 | 961 | ||
727 | switch (intel_crtc->bpp) { |
962 | switch (intel_crtc->bpp) { |
728 | case 18: |
963 | case 18: |
Line -... | Line 964... | ||
- | 964 | temp |= TRANS_DDI_BPC_6; |
|
- | 965 | break; |
|
- | 966 | case 24: |
|
- | 967 | temp |= TRANS_DDI_BPC_8; |
|
- | 968 | break; |
|
- | 969 | case 30: |
|
- | 970 | temp |= TRANS_DDI_BPC_10; |
|
- | 971 | break; |
|
- | 972 | case 36: |
|
- | 973 | temp |= TRANS_DDI_BPC_12; |
|
- | 974 | break; |
|
- | 975 | default: |
|
- | 976 | WARN(1, "%d bpp unsupported by transcoder DDI function\n", |
|
- | 977 | intel_crtc->bpp); |
|
- | 978 | } |
|
- | 979 | ||
- | 980 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) |
|
- | 981 | temp |= TRANS_DDI_PVSYNC; |
|
- | 982 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
|
- | 983 | temp |= TRANS_DDI_PHSYNC; |
|
- | 984 | ||
- | 985 | if (cpu_transcoder == TRANSCODER_EDP) { |
|
- | 986 | switch (pipe) { |
|
- | 987 | case PIPE_A: |
|
- | 988 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
|
729 | temp |= PIPE_DDI_BPC_6; |
989 | break; |
730 | break; |
990 | case PIPE_B: |
731 | case 24: |
991 | temp |= TRANS_DDI_EDP_INPUT_B_ONOFF; |
732 | temp |= PIPE_DDI_BPC_8; |
992 | break; |
Line 733... | Line 993... | ||
733 | break; |
993 | case PIPE_C: |
734 | case 30: |
994 | temp |= TRANS_DDI_EDP_INPUT_C_ONOFF; |
735 | temp |= PIPE_DDI_BPC_10; |
- | |
736 | break; |
995 | break; |
Line -... | Line 996... | ||
- | 996 | default: |
|
737 | case 36: |
997 | BUG(); |
- | 998 | break; |
|
Line -... | Line 999... | ||
- | 999 | } |
|
- | 1000 | } |
|
- | 1001 | ||
- | 1002 | if (type == INTEL_OUTPUT_HDMI) { |
|
- | 1003 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
|
- | 1004 | ||
- | 1005 | if (intel_hdmi->has_hdmi_sink) |
|
- | 1006 | temp |= TRANS_DDI_MODE_SELECT_HDMI; |
|
- | 1007 | else |
|
- | 1008 | temp |= TRANS_DDI_MODE_SELECT_DVI; |
|
- | 1009 | ||
- | 1010 | } else if (type == INTEL_OUTPUT_ANALOG) { |
|
- | 1011 | temp |= TRANS_DDI_MODE_SELECT_FDI; |
|
- | 1012 | temp |= (intel_crtc->fdi_lanes - 1) << 1; |
|
- | 1013 | ||
- | 1014 | } else if (type == INTEL_OUTPUT_DISPLAYPORT || |
|
- | 1015 | type == INTEL_OUTPUT_EDP) { |
|
- | 1016 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
|
- | 1017 | ||
- | 1018 | temp |= TRANS_DDI_MODE_SELECT_DP_SST; |
|
- | 1019 | ||
- | 1020 | switch (intel_dp->lane_count) { |
|
- | 1021 | case 1: |
|
- | 1022 | temp |= TRANS_DDI_PORT_WIDTH_X1; |
|
- | 1023 | break; |
|
- | 1024 | case 2: |
|
- | 1025 | temp |= TRANS_DDI_PORT_WIDTH_X2; |
|
- | 1026 | break; |
|
- | 1027 | case 4: |
|
- | 1028 | temp |= TRANS_DDI_PORT_WIDTH_X4; |
|
- | 1029 | break; |
|
- | 1030 | default: |
|
- | 1031 | temp |= TRANS_DDI_PORT_WIDTH_X4; |
|
- | 1032 | WARN(1, "Unsupported lane count %d\n", |
|
- | 1033 | intel_dp->lane_count); |
|
- | 1034 | } |
|
- | 1035 | ||
- | 1036 | } else { |
|
- | 1037 | WARN(1, "Invalid encoder type %d for pipe %d\n", |
|
- | 1038 | intel_encoder->type, pipe); |
|
- | 1039 | } |
|
- | 1040 | ||
- | 1041 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); |
|
738 | temp |= PIPE_DDI_BPC_12; |
1042 | } |
- | 1043 | ||
- | 1044 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, |
|
- | 1045 | enum transcoder cpu_transcoder) |
|
- | 1046 | { |
|
- | 1047 | uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); |
|
- | 1048 | uint32_t val = I915_READ(reg); |
|
- | 1049 | ||
- | 1050 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK); |
|
- | 1051 | val |= TRANS_DDI_PORT_NONE; |
|
- | 1052 | I915_WRITE(reg, val); |
|
- | 1053 | } |
|
- | 1054 | ||
- | 1055 | bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) |
|
- | 1056 | { |
|
- | 1057 | struct drm_device *dev = intel_connector->base.dev; |
|
- | 1058 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 1059 | struct intel_encoder *intel_encoder = intel_connector->encoder; |
|
- | 1060 | int type = intel_connector->base.connector_type; |
|
- | 1061 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
|
- | 1062 | enum pipe pipe = 0; |
|
- | 1063 | enum transcoder cpu_transcoder; |
|
- | 1064 | uint32_t tmp; |
|
- | 1065 | ||
- | 1066 | if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) |
|
- | 1067 | return false; |
|
- | 1068 | ||
- | 1069 | if (port == PORT_A) |
|
- | 1070 | cpu_transcoder = TRANSCODER_EDP; |
|
- | 1071 | else |
|
- | 1072 | cpu_transcoder = pipe; |
|
- | 1073 | ||
739 | break; |
1074 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
Line 740... | Line 1075... | ||
740 | default: |
1075 | |
741 | WARN(1, "%d bpp unsupported by pipe DDI function\n", |
1076 | switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { |
742 | intel_crtc->bpp); |
1077 | case TRANS_DDI_MODE_SELECT_HDMI: |
743 | } |
1078 | case TRANS_DDI_MODE_SELECT_DVI: |
744 | 1079 | return (type == DRM_MODE_CONNECTOR_HDMIA); |
|
745 | if (intel_hdmi->has_hdmi_sink) |
1080 | |
746 | temp |= PIPE_DDI_MODE_SELECT_HDMI; |
1081 | case TRANS_DDI_MODE_SELECT_DP_SST: |
747 | else |
1082 | if (type == DRM_MODE_CONNECTOR_eDP) |
Line 748... | Line 1083... | ||
748 | temp |= PIPE_DDI_MODE_SELECT_DVI; |
1083 | return true; |
Line 749... | Line 1084... | ||
749 | 1084 | case TRANS_DDI_MODE_SELECT_DP_MST: |
|
750 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
1085 | return (type == DRM_MODE_CONNECTOR_DisplayPort); |
Line 751... | Line 1086... | ||
751 | temp |= PIPE_DDI_PVSYNC; |
1086 | |
752 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
1087 | case TRANS_DDI_MODE_SELECT_FDI: |
Line -... | Line 1088... | ||
- | 1088 | return (type == DRM_MODE_CONNECTOR_VGA); |
|
- | 1089 | ||
- | 1090 | default: |
|
- | 1091 | return false; |
|
- | 1092 | } |
|
- | 1093 | } |
|
- | 1094 | ||
- | 1095 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, |
|
- | 1096 | enum pipe *pipe) |
|
- | 1097 | { |
|
- | 1098 | struct drm_device *dev = encoder->base.dev; |
|
- | 1099 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 1100 | enum port port = intel_ddi_get_encoder_port(encoder); |
|
- | 1101 | u32 tmp; |
|
- | 1102 | int i; |
|
- | 1103 | ||
- | 1104 | tmp = I915_READ(DDI_BUF_CTL(port)); |
|
- | 1105 | ||
753 | temp |= PIPE_DDI_PHSYNC; |
1106 | if (!(tmp & DDI_BUF_CTL_ENABLE)) |
754 | 1107 | return false; |
|
755 | I915_WRITE(DDI_FUNC_CTL(pipe), temp); |
1108 | |
756 | 1109 | if (port == PORT_A) { |
|
757 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
1110 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); |
758 | } |
1111 | |
- | 1112 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { |
|
Line 759... | Line 1113... | ||
759 | 1113 | case TRANS_DDI_EDP_INPUT_A_ON: |
|
Line 760... | Line 1114... | ||
760 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, |
1114 | case TRANS_DDI_EDP_INPUT_A_ONOFF: |
761 | enum pipe *pipe) |
1115 | *pipe = PIPE_A; |
Line 762... | Line 1116... | ||
762 | { |
1116 | break; |
- | 1117 | case TRANS_DDI_EDP_INPUT_B_ONOFF: |
|
763 | struct drm_device *dev = encoder->base.dev; |
1118 | *pipe = PIPE_B; |
- | 1119 | break; |
|
- | 1120 | case TRANS_DDI_EDP_INPUT_C_ONOFF: |
|
- | 1121 | *pipe = PIPE_C; |
|
- | 1122 | break; |
|
- | 1123 | } |
|
- | 1124 | ||
- | 1125 | return true; |
|
- | 1126 | } else { |
|
- | 1127 | for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { |
|
- | 1128 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); |
|
- | 1129 | ||
- | 1130 | if ((tmp & TRANS_DDI_PORT_MASK) |
|
- | 1131 | == TRANS_DDI_SELECT_PORT(port)) { |
|
- | 1132 | *pipe = i; |
|
- | 1133 | return true; |
|
- | 1134 | } |
|
- | 1135 | } |
|
- | 1136 | } |
|
- | 1137 | ||
- | 1138 | DRM_DEBUG_KMS("No pipe for ddi port %i found\n", port); |
|
- | 1139 | ||
- | 1140 | return true; |
|
- | 1141 | } |
|
- | 1142 | ||
- | 1143 | static uint32_t intel_ddi_get_crtc_pll(struct drm_i915_private *dev_priv, |
|
- | 1144 | enum pipe pipe) |
|
- | 1145 | { |
|
- | 1146 | uint32_t temp, ret; |
|
- | 1147 | enum port port; |
|
- | 1148 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
|
- | 1149 | pipe); |
|
- | 1150 | int i; |
|
- | 1151 | ||
- | 1152 | if (cpu_transcoder == TRANSCODER_EDP) { |
|
- | 1153 | port = PORT_A; |
|
- | 1154 | } else { |
|
- | 1155 | temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); |
|
- | 1156 | temp &= TRANS_DDI_PORT_MASK; |
|
- | 1157 | ||
- | 1158 | for (i = PORT_B; i <= PORT_E; i++) |
|
- | 1159 | if (temp == TRANS_DDI_SELECT_PORT(i)) |
|
- | 1160 | port = i; |
|
- | 1161 | } |
|
- | 1162 | ||
- | 1163 | ret = I915_READ(PORT_CLK_SEL(port)); |
|
- | 1164 | ||
- | 1165 | DRM_DEBUG_KMS("Pipe %c connected to port %c using clock 0x%08x\n", |
|
- | 1166 | pipe_name(pipe), port_name(port), ret); |
|
- | 1167 | ||
- | 1168 | return ret; |
|
- | 1169 | } |
|
- | 1170 | ||
- | 1171 | void intel_ddi_setup_hw_pll_state(struct drm_device *dev) |
|
- | 1172 | { |
|
- | 1173 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 1174 | enum pipe pipe; |
|
- | 1175 | struct intel_crtc *intel_crtc; |
|
- | 1176 | ||
- | 1177 | for_each_pipe(pipe) { |
|
- | 1178 | intel_crtc = |
|
- | 1179 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
|
- | 1180 | ||
- | 1181 | if (!intel_crtc->active) |
|
- | 1182 | continue; |
|
- | 1183 | ||
- | 1184 | intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv, |
|
- | 1185 | pipe); |
|
- | 1186 | ||
- | 1187 | switch (intel_crtc->ddi_pll_sel) { |
|
- | 1188 | case PORT_CLK_SEL_SPLL: |
|
- | 1189 | dev_priv->ddi_plls.spll_refcount++; |
|
- | 1190 | break; |
|
- | 1191 | case PORT_CLK_SEL_WRPLL1: |
|
- | 1192 | dev_priv->ddi_plls.wrpll1_refcount++; |
|
- | 1193 | break; |
|
- | 1194 | case PORT_CLK_SEL_WRPLL2: |
|
- | 1195 | dev_priv->ddi_plls.wrpll2_refcount++; |
|
- | 1196 | break; |
|
- | 1197 | } |
|
- | 1198 | } |
|
- | 1199 | } |
|
- | 1200 | ||
- | 1201 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) |
|
- | 1202 | { |
|
- | 1203 | struct drm_crtc *crtc = &intel_crtc->base; |
|
- | 1204 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
|
- | 1205 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
|
- | 1206 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
|
- | 1207 | enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; |
|
- | 1208 | ||
- | 1209 | if (cpu_transcoder != TRANSCODER_EDP) |
|
- | 1210 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
|
- | 1211 | TRANS_CLK_SEL_PORT(port)); |
|
- | 1212 | } |
|
- | 1213 | ||
- | 1214 | void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) |
|
- | 1215 | { |
|
- | 1216 | struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; |
|
- | 1217 | enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; |
|
- | 1218 | ||
- | 1219 | if (cpu_transcoder != TRANSCODER_EDP) |
|
- | 1220 | I915_WRITE(TRANS_CLK_SEL(cpu_transcoder), |
|
- | 1221 | TRANS_CLK_SEL_DISABLED); |
|
- | 1222 | } |
|
- | 1223 | ||
- | 1224 | static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) |
|
- | 1225 | { |
|
- | 1226 | struct drm_encoder *encoder = &intel_encoder->base; |
|
- | 1227 | struct drm_crtc *crtc = encoder->crtc; |
|
- | 1228 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
|
- | 1229 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 1230 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
|
- | 1231 | int type = intel_encoder->type; |
|
- | 1232 | ||
- | 1233 | if (type == INTEL_OUTPUT_EDP) { |
|
- | 1234 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
|
- | 1235 | ironlake_edp_panel_vdd_on(intel_dp); |
|
- | 1236 | ironlake_edp_panel_on(intel_dp); |
|
- | 1237 | ironlake_edp_panel_vdd_off(intel_dp, true); |
|
- | 1238 | } |
|
- | 1239 | ||
- | 1240 | WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE); |
|
- | 1241 | I915_WRITE(PORT_CLK_SEL(port), intel_crtc->ddi_pll_sel); |
|
- | 1242 | ||
- | 1243 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
|
- | 1244 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
|
- | 1245 | ||
- | 1246 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
|
- | 1247 | intel_dp_start_link_train(intel_dp); |
|
- | 1248 | intel_dp_complete_link_train(intel_dp); |
|
- | 1249 | } |
|
- | 1250 | } |
|
- | 1251 | ||
- | 1252 | static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) |
|
- | 1253 | { |
|
- | 1254 | struct drm_encoder *encoder = &intel_encoder->base; |
|
- | 1255 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
|
- | 1256 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
|
- | 1257 | int type = intel_encoder->type; |
|
- | 1258 | uint32_t val; |
|
- | 1259 | bool wait = false; |
|
- | 1260 | ||
764 | struct drm_i915_private *dev_priv = dev->dev_private; |
1261 | val = I915_READ(DDI_BUF_CTL(port)); |
765 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
1262 | if (val & DDI_BUF_CTL_ENABLE) { |
766 | u32 tmp; |
1263 | val &= ~DDI_BUF_CTL_ENABLE; |
767 | int i; |
1264 | I915_WRITE(DDI_BUF_CTL(port), val); |
768 | - | ||
769 | tmp = I915_READ(DDI_BUF_CTL(intel_hdmi->ddi_port)); |
1265 | wait = true; |
770 | - | ||
771 | if (!(tmp & DDI_BUF_CTL_ENABLE)) |
1266 | } |
772 | return false; |
- | |
773 | 1267 | ||
774 | for_each_pipe(i) { |
1268 | val = I915_READ(DP_TP_CTL(port)); |
775 | tmp = I915_READ(DDI_FUNC_CTL(i)); |
1269 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
776 | 1270 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
|
777 | if ((tmp & PIPE_DDI_PORT_MASK) |
1271 | I915_WRITE(DP_TP_CTL(port), val); |
- | 1272 | ||
- | 1273 | if (wait) |
|
- | 1274 | intel_wait_ddi_buf_idle(dev_priv, port); |
|
- | 1275 | ||
- | 1276 | if (type == INTEL_OUTPUT_EDP) { |
|
778 | == PIPE_DDI_SELECT_PORT(intel_hdmi->ddi_port)) { |
1277 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
Line 779... | Line 1278... | ||
779 | *pipe = i; |
1278 | ironlake_edp_panel_vdd_on(intel_dp); |
- | 1279 | ironlake_edp_panel_off(intel_dp); |
|
- | 1280 | } |
|
- | 1281 | ||
- | 1282 | I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); |
|
- | 1283 | } |
|
- | 1284 | ||
- | 1285 | static void intel_enable_ddi(struct intel_encoder *intel_encoder) |
|
- | 1286 | { |
|
- | 1287 | struct drm_encoder *encoder = &intel_encoder->base; |
|
- | 1288 | struct drm_device *dev = encoder->dev; |
|
- | 1289 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 1290 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
|
- | 1291 | int type = intel_encoder->type; |
|
- | 1292 | ||
- | 1293 | if (type == INTEL_OUTPUT_HDMI) { |
|
- | 1294 | /* In HDMI/DVI mode, the port width, and swing/emphasis values |
|
- | 1295 | * are ignored so nothing special needs to be done besides |
|
- | 1296 | * enabling the port. |
|
- | 1297 | */ |
|
- | 1298 | I915_WRITE(DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE); |
|
- | 1299 | } else if (type == INTEL_OUTPUT_EDP) { |
|
- | 1300 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
|
- | 1301 | ||
- | 1302 | ironlake_edp_backlight_on(intel_dp); |
|
- | 1303 | } |
|
780 | return true; |
1304 | } |
781 | } |
- | |
782 | } |
1305 | |
783 | - | ||
784 | DRM_DEBUG_KMS("No pipe for ddi port %i found\n", intel_hdmi->ddi_port); |
1306 | static void intel_disable_ddi(struct intel_encoder *intel_encoder) |
785 | - | ||
Line -... | Line 1307... | ||
- | 1307 | { |
|
- | 1308 | struct drm_encoder *encoder = &intel_encoder->base; |
|
- | 1309 | int type = intel_encoder->type; |
|
- | 1310 | ||
- | 1311 | if (type == INTEL_OUTPUT_EDP) { |
|
- | 1312 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
|
- | 1313 | ||
- | 1314 | ironlake_edp_backlight_off(intel_dp); |
|
- | 1315 | } |
|
- | 1316 | } |
|
- | 1317 | ||
- | 1318 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
|
- | 1319 | { |
|
- | 1320 | if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) |
|
- | 1321 | return 450; |
|
- | 1322 | else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) == |
|
- | 1323 | LCPLL_CLK_FREQ_450) |
|
- | 1324 | return 450; |
|
- | 1325 | else if (IS_ULT(dev_priv->dev)) |
|
- | 1326 | return 338; |
|
- | 1327 | else |
|
- | 1328 | return 540; |
|
- | 1329 | } |
|
- | 1330 | ||
- | 1331 | void intel_ddi_pll_init(struct drm_device *dev) |
|
786 | return true; |
1332 | { |
- | 1333 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
787 | } |
1334 | uint32_t val = I915_READ(LCPLL_CTL); |
- | 1335 | ||
- | 1336 | /* The LCPLL register should be turned on by the BIOS. For now let's |
|
- | 1337 | * just check its state and print errors in case something is wrong. |
|
- | 1338 | * Don't even try to turn it on. |
|
- | 1339 | */ |
|
- | 1340 | ||
- | 1341 | DRM_DEBUG_KMS("CDCLK running at %dMHz\n", |
|
- | 1342 | intel_ddi_get_cdclk_freq(dev_priv)); |
|
- | 1343 | ||
- | 1344 | if (val & LCPLL_CD_SOURCE_FCLK) |
|
- | 1345 | DRM_ERROR("CDCLK source is not LCPLL\n"); |
|
- | 1346 | ||
- | 1347 | if (val & LCPLL_PLL_DISABLE) |
|
- | 1348 | DRM_ERROR("LCPLL is disabled\n"); |
|
- | 1349 | } |
|
- | 1350 | ||
- | 1351 | void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) |
|
- | 1352 | { |
|
- | 1353 | struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); |
|
- | 1354 | struct intel_dp *intel_dp = &intel_dig_port->dp; |
|
- | 1355 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
|
- | 1356 | enum port port = intel_dig_port->port; |
|
- | 1357 | bool wait; |
|
- | 1358 | uint32_t val; |
|
- | 1359 | ||
- | 1360 | if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { |
|
- | 1361 | val = I915_READ(DDI_BUF_CTL(port)); |
|
- | 1362 | if (val & DDI_BUF_CTL_ENABLE) { |
|
- | 1363 | val &= ~DDI_BUF_CTL_ENABLE; |
|
- | 1364 | I915_WRITE(DDI_BUF_CTL(port), val); |
|
- | 1365 | wait = true; |
|
- | 1366 | } |
|
- | 1367 | ||
- | 1368 | val = I915_READ(DP_TP_CTL(port)); |
|
- | 1369 | val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); |
|
- | 1370 | val |= DP_TP_CTL_LINK_TRAIN_PAT1; |
|
- | 1371 | I915_WRITE(DP_TP_CTL(port), val); |
|
- | 1372 | POSTING_READ(DP_TP_CTL(port)); |
|
- | 1373 | ||
- | 1374 | if (wait) |
|
- | 1375 | intel_wait_ddi_buf_idle(dev_priv, port); |
|
- | 1376 | } |
|
- | 1377 | ||
- | 1378 | val = DP_TP_CTL_ENABLE | DP_TP_CTL_MODE_SST | |
|
- | 1379 | DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE; |
|
- | 1380 | if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) |
|
- | 1381 | val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; |
|
- | 1382 | I915_WRITE(DP_TP_CTL(port), val); |
|
- | 1383 | POSTING_READ(DP_TP_CTL(port)); |
|
- | 1384 | ||
- | 1385 | intel_dp->DP |= DDI_BUF_CTL_ENABLE; |
|
- | 1386 | I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP); |
|
- | 1387 | POSTING_READ(DDI_BUF_CTL(port)); |
|
- | 1388 | ||
- | 1389 | udelay(600); |
|
- | 1390 | } |
|
- | 1391 | ||
- | 1392 | void intel_ddi_fdi_disable(struct drm_crtc *crtc) |
|
- | 1393 | { |
|
- | 1394 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
|
- | 1395 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
|
- | 1396 | uint32_t val; |
|
- | 1397 | ||
- | 1398 | intel_ddi_post_disable(intel_encoder); |
|
- | 1399 | ||
- | 1400 | val = I915_READ(_FDI_RXA_CTL); |
|
- | 1401 | val &= ~FDI_RX_ENABLE; |
|
- | 1402 | I915_WRITE(_FDI_RXA_CTL, val); |
|
- | 1403 | ||
- | 1404 | val = I915_READ(_FDI_RXA_MISC); |
|
- | 1405 | val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); |
|
- | 1406 | val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); |
|
- | 1407 | I915_WRITE(_FDI_RXA_MISC, val); |
|
- | 1408 | ||
- | 1409 | val = I915_READ(_FDI_RXA_CTL); |
|
- | 1410 | val &= ~FDI_PCDCLK; |
|
- | 1411 | I915_WRITE(_FDI_RXA_CTL, val); |
|
- | 1412 | ||
- | 1413 | val = I915_READ(_FDI_RXA_CTL); |
|
- | 1414 | val &= ~FDI_RX_PLL_ENABLE; |
|
- | 1415 | I915_WRITE(_FDI_RXA_CTL, val); |
|
- | 1416 | } |
|
- | 1417 | ||
- | 1418 | static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) |
|
- | 1419 | { |
|
- | 1420 | struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); |
|
- | 1421 | int type = intel_encoder->type; |
|
- | 1422 | ||
- | 1423 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) |
|
- | 1424 | intel_dp_check_link_status(intel_dp); |
|
- | 1425 | } |
|
- | 1426 | ||
- | 1427 | static void intel_ddi_destroy(struct drm_encoder *encoder) |
|
- | 1428 | { |
|
- | 1429 | /* HDMI has nothing special to destroy, so we can go with this. */ |
|
- | 1430 | intel_dp_encoder_destroy(encoder); |
|
- | 1431 | } |
|
- | 1432 | ||
- | 1433 | static bool intel_ddi_mode_fixup(struct drm_encoder *encoder, |
|
- | 1434 | const struct drm_display_mode *mode, |
|
- | 1435 | struct drm_display_mode *adjusted_mode) |
|
- | 1436 | { |
|
- | 1437 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
|
- | 1438 | int type = intel_encoder->type; |
|
- | 1439 | ||
- | 1440 | WARN(type == INTEL_OUTPUT_UNKNOWN, "mode_fixup() on unknown output!\n"); |
|
- | 1441 | ||
- | 1442 | if (type == INTEL_OUTPUT_HDMI) |
|
- | 1443 | return intel_hdmi_mode_fixup(encoder, mode, adjusted_mode); |
|
- | 1444 | else |
|
- | 1445 | return intel_dp_mode_fixup(encoder, mode, adjusted_mode); |
|
- | 1446 | } |
|
- | 1447 | ||
- | 1448 | static const struct drm_encoder_funcs intel_ddi_funcs = { |
|
- | 1449 | .destroy = intel_ddi_destroy, |
|
- | 1450 | }; |
|
- | 1451 | ||
- | 1452 | static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = { |
|
- | 1453 | .mode_fixup = intel_ddi_mode_fixup, |
|
- | 1454 | .mode_set = intel_ddi_mode_set, |
|
- | 1455 | .disable = intel_encoder_noop, |
|
- | 1456 | }; |
|
- | 1457 | ||
- | 1458 | void intel_ddi_init(struct drm_device *dev, enum port port) |
|
- | 1459 | { |
|
- | 1460 | struct intel_digital_port *intel_dig_port; |
|
- | 1461 | struct intel_encoder *intel_encoder; |
|
- | 1462 | struct drm_encoder *encoder; |
|
- | 1463 | struct intel_connector *hdmi_connector = NULL; |
|
- | 1464 | struct intel_connector *dp_connector = NULL; |
|
- | 1465 | ||
- | 1466 | intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL); |
|
- | 1467 | if (!intel_dig_port) |
|
- | 1468 | return; |
|
- | 1469 | ||
- | 1470 | dp_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
|
- | 1471 | if (!dp_connector) { |
|
- | 1472 | kfree(intel_dig_port); |
|
- | 1473 | return; |
|
- | 1474 | } |
|
- | 1475 | ||
Line -... | Line 1476... | ||
- | 1476 | if (port != PORT_A) { |
|
- | 1477 | hdmi_connector = kzalloc(sizeof(struct intel_connector), |
|
788 | 1478 | GFP_KERNEL); |
|
- | 1479 | if (!hdmi_connector) { |
|
- | 1480 | kfree(dp_connector); |
|
- | 1481 | kfree(intel_dig_port); |
|
- | 1482 | return; |
|
- | 1483 | } |
|
789 | void intel_enable_ddi(struct intel_encoder *encoder) |
1484 | } |