2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
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
9 * Software is furnished to do so, subject to the following conditions:
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
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,
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
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
24 * Eugeni Dodonov <eugeni.dodonov@intel.com>
29 #include "intel_drv.h"
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
33 * automatically adapt to HDMI connections as well
35 static const u32 hsw_ddi_translations_dp
[] = {
36 0x00FFFFFF, 0x0006000E, /* DP parameters */
37 0x00D75FFF, 0x0005000A,
38 0x00C30FFF, 0x00040006,
39 0x80AAAFFF, 0x000B0000,
40 0x00FFFFFF, 0x0005000A,
41 0x00D75FFF, 0x000C0004,
42 0x80C30FFF, 0x000B0000,
43 0x00FFFFFF, 0x00040006,
44 0x80D75FFF, 0x000B0000,
45 0x00FFFFFF, 0x00040006 /* HDMI parameters */
48 static const u32 hsw_ddi_translations_fdi
[] = {
49 0x00FFFFFF, 0x0007000E, /* FDI parameters */
50 0x00D75FFF, 0x000F000A,
51 0x00C30FFF, 0x00060006,
52 0x00AAAFFF, 0x001E0000,
53 0x00FFFFFF, 0x000F000A,
54 0x00D75FFF, 0x00160004,
55 0x00C30FFF, 0x001E0000,
56 0x00FFFFFF, 0x00060006,
57 0x00D75FFF, 0x001E0000,
58 0x00FFFFFF, 0x00040006 /* HDMI parameters */
61 /* On Haswell, DDI port buffers must be programmed with correct values
62 * 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
64 * in either FDI or DP modes only, as HDMI connections will work with both
67 void intel_prepare_ddi_buffers(struct drm_device
*dev
, enum port port
, bool use_fdi_mode
)
69 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
72 const u32
*ddi_translations
= ((use_fdi_mode
) ?
73 hsw_ddi_translations_fdi
:
74 hsw_ddi_translations_dp
);
76 DRM_DEBUG_DRIVER("Initializing DDI buffers for port %c in %s mode\n",
78 use_fdi_mode
? "FDI" : "DP");
80 WARN((use_fdi_mode
&& (port
!= PORT_E
)),
81 "Programming port %c in FDI mode, this probably will not work.\n",
84 for (i
=0, reg
=DDI_BUF_TRANS(port
); i
< ARRAY_SIZE(hsw_ddi_translations_fdi
); i
++) {
85 I915_WRITE(reg
, ddi_translations
[i
]);
90 /* Program DDI buffers translations for DP. By default, program ports A-D in DP
91 * mode and port E for FDI.
93 void intel_prepare_ddi(struct drm_device
*dev
)
97 if (IS_HASWELL(dev
)) {
98 for (port
= PORT_A
; port
< PORT_E
; port
++)
99 intel_prepare_ddi_buffers(dev
, port
, false);
101 /* DDI E is the suggested one to work in FDI mode, so program is as such by
102 * default. It will have to be re-programmed in case a digital DP output
103 * will be detected on it
105 intel_prepare_ddi_buffers(dev
, PORT_E
, true);
109 static const long hsw_ddi_buf_ctl_values
[] = {
110 DDI_BUF_EMP_400MV_0DB_HSW
,
111 DDI_BUF_EMP_400MV_3_5DB_HSW
,
112 DDI_BUF_EMP_400MV_6DB_HSW
,
113 DDI_BUF_EMP_400MV_9_5DB_HSW
,
114 DDI_BUF_EMP_600MV_0DB_HSW
,
115 DDI_BUF_EMP_600MV_3_5DB_HSW
,
116 DDI_BUF_EMP_600MV_6DB_HSW
,
117 DDI_BUF_EMP_800MV_0DB_HSW
,
118 DDI_BUF_EMP_800MV_3_5DB_HSW
122 /* 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
124 * both the DDI port and PCH receiver for the desired DDI buffer settings.
126 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
127 * please note that when FDI mode is active on DDI E, it shares 2 lines with
128 * DDI A (which is used for eDP)
131 void hsw_fdi_link_train(struct drm_crtc
*crtc
)
133 struct drm_device
*dev
= crtc
->dev
;
134 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
135 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
136 int pipe
= intel_crtc
->pipe
;
139 /* Configure CPU PLL, wait for warmup */
142 SPLL_PLL_FREQ_1350MHz
|
145 /* Use SPLL to drive the output when in FDI mode */
146 I915_WRITE(PORT_CLK_SEL(PORT_E
),
148 I915_WRITE(PIPE_CLK_SEL(pipe
),
149 PIPE_CLK_SEL_PORT(PORT_E
));
153 /* Start the training iterating through available voltages and emphasis */
154 for (i
=0; i
< ARRAY_SIZE(hsw_ddi_buf_ctl_values
); i
++) {
155 /* Configure DP_TP_CTL with auto-training */
156 I915_WRITE(DP_TP_CTL(PORT_E
),
157 DP_TP_CTL_FDI_AUTOTRAIN
|
158 DP_TP_CTL_ENHANCED_FRAME_ENABLE
|
159 DP_TP_CTL_LINK_TRAIN_PAT1
|
162 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage */
163 temp
= I915_READ(DDI_BUF_CTL(PORT_E
));
164 temp
= (temp
& ~DDI_BUF_EMP_MASK
);
165 I915_WRITE(DDI_BUF_CTL(PORT_E
),
169 hsw_ddi_buf_ctl_values
[i
]);
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
176 * bits are supposed to be zeroed, so we can write those values
179 I915_WRITE(FDI_RX_MISC(pipe
), FDI_RX_TP1_TO_TP2_48
|
180 FDI_RX_FDI_DELAY_90
);
182 /* Enable CPU FDI Receiver with auto-training */
183 reg
= FDI_RX_CTL(pipe
);
186 FDI_LINK_TRAIN_AUTO
|
188 FDI_LINK_TRAIN_PATTERN_1_CPT
|
189 FDI_RX_ENHANCE_FRAME_ENABLE
|
190 FDI_PORT_WIDTH_2X_LPT
|
195 temp
= I915_READ(DP_TP_STATUS(PORT_E
));
196 if (temp
& DP_TP_STATUS_AUTOTRAIN_DONE
) {
197 DRM_DEBUG_DRIVER("BUF_CTL training done on %d step\n", i
);
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
|
206 /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in FDI mode */
207 temp
= I915_READ(DDI_FUNC_CTL(pipe
));
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
),
217 DRM_ERROR("Error training BUF_CTL %d\n", i
);
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
)) &
223 I915_WRITE(FDI_RX_CTL(pipe
),
224 I915_READ(FDI_RX_CTL(pipe
)) &
230 DRM_DEBUG_KMS("FDI train done.\n");
233 /* For DDI connections, it is possible to support different outputs over the
234 * same DDI port, such as HDMI or DP or even VGA via FDI. So we don't know by
235 * the time the output is detected what exactly is on the other end of it. This
236 * function aims at providing support for this detection and proper output
239 void intel_ddi_init(struct drm_device
*dev
, enum port port
)
241 /* For now, we don't do any proper output detection and assume that we
242 * handle HDMI only */
246 /* We don't handle eDP and DP yet */
247 DRM_DEBUG_DRIVER("Found digital output on DDI port A\n");
249 /* Assume that the ports B, C and D are working in HDMI mode for now */
253 intel_hdmi_init(dev
, DDI_BUF_CTL(port
), port
);
256 DRM_DEBUG_DRIVER("No handlers defined for port %d, skipping DDI initialization\n",
262 /* WRPLL clock dividers */
263 struct wrpll_tmds_clock
{
265 u16 p
; /* Post divider */
266 u16 n2
; /* Feedback divider */
267 u16 r2
; /* Reference divider */
270 /* Table of matching values for WRPLL clocks programming for each frequency.
271 * The code assumes this table is sorted. */
272 static const struct wrpll_tmds_clock wrpll_tmds_clock_table
[] = {
287 {27027, 18, 100, 111},
315 {40541, 22, 147, 89},
325 {44900, 20, 108, 65},
341 {54054, 16, 173, 108},
393 {81081, 6, 100, 111},
438 {108108, 8, 173, 108},
445 {111264, 8, 150, 91},
489 {135250, 6, 167, 111},
512 {148352, 4, 100, 91},
534 {162162, 4, 131, 109},
542 {169000, 4, 104, 83},
589 {202000, 4, 112, 75},
591 {203000, 4, 146, 97},
648 void intel_ddi_mode_set(struct drm_encoder
*encoder
,
649 struct drm_display_mode
*mode
,
650 struct drm_display_mode
*adjusted_mode
)
652 struct drm_device
*dev
= encoder
->dev
;
653 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
654 struct drm_crtc
*crtc
= encoder
->crtc
;
655 struct intel_crtc
*intel_crtc
= to_intel_crtc(crtc
);
656 struct intel_hdmi
*intel_hdmi
= enc_to_intel_hdmi(encoder
);
657 int port
= intel_hdmi
->ddi_port
;
658 int pipe
= intel_crtc
->pipe
;
662 /* On Haswell, we need to enable the clocks and prepare DDI function to
663 * work in HDMI mode for this pipe.
665 DRM_DEBUG_KMS("Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n", port_name(port
), pipe_name(pipe
));
667 for (i
= 0; i
< ARRAY_SIZE(wrpll_tmds_clock_table
); i
++)
668 if (crtc
->mode
.clock
<= wrpll_tmds_clock_table
[i
].clock
)
671 if (i
== ARRAY_SIZE(wrpll_tmds_clock_table
))
674 p
= wrpll_tmds_clock_table
[i
].p
;
675 n2
= wrpll_tmds_clock_table
[i
].n2
;
676 r2
= wrpll_tmds_clock_table
[i
].r2
;
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
);
682 DRM_DEBUG_KMS("WR PLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
683 crtc
->mode
.clock
, p
, n2
, r2
);
685 /* Enable LCPLL if disabled */
686 temp
= I915_READ(LCPLL_CTL
);
687 if (temp
& LCPLL_PLL_DISABLE
)
688 I915_WRITE(LCPLL_CTL
,
689 temp
& ~LCPLL_PLL_DISABLE
);
691 /* Configure WR PLL 1, program the correct divider values for
692 * the desired frequency and wait for warmup */
693 I915_WRITE(WRPLL_CTL1
,
695 WRPLL_PLL_SELECT_LCPLL_2700
|
696 WRPLL_DIVIDER_REFERENCE(r2
) |
697 WRPLL_DIVIDER_FEEDBACK(n2
) |
698 WRPLL_DIVIDER_POST(p
));
702 /* Use WRPLL1 clock to drive the output to the port, and tell the pipe to use
703 * this port for connection.
705 I915_WRITE(PORT_CLK_SEL(port
),
706 PORT_CLK_SEL_WRPLL1
);
707 I915_WRITE(PIPE_CLK_SEL(pipe
),
708 PIPE_CLK_SEL_PORT(port
));
712 if (intel_hdmi
->has_audio
) {
713 /* Proper support for digital audio needs a new logic and a new set
714 * of registers, so we leave it for future patch bombing.
716 DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n",
717 pipe_name(intel_crtc
->pipe
));
720 DRM_DEBUG_DRIVER("HDMI audio: write eld information\n");
721 intel_write_eld(encoder
, adjusted_mode
);
724 /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */
725 temp
= PIPE_DDI_FUNC_ENABLE
| PIPE_DDI_SELECT_PORT(port
);
727 switch (intel_crtc
->bpp
) {
729 temp
|= PIPE_DDI_BPC_6
;
732 temp
|= PIPE_DDI_BPC_8
;
735 temp
|= PIPE_DDI_BPC_10
;
738 temp
|= PIPE_DDI_BPC_12
;
741 WARN(1, "%d bpp unsupported by pipe DDI function\n",
745 if (intel_hdmi
->has_hdmi_sink
)
746 temp
|= PIPE_DDI_MODE_SELECT_HDMI
;
748 temp
|= PIPE_DDI_MODE_SELECT_DVI
;
750 if (adjusted_mode
->flags
& DRM_MODE_FLAG_PVSYNC
)
751 temp
|= PIPE_DDI_PVSYNC
;
752 if (adjusted_mode
->flags
& DRM_MODE_FLAG_PHSYNC
)
753 temp
|= PIPE_DDI_PHSYNC
;
755 I915_WRITE(DDI_FUNC_CTL(pipe
), temp
);
757 intel_hdmi
->set_infoframes(encoder
, adjusted_mode
);
760 bool intel_ddi_get_hw_state(struct intel_encoder
*encoder
,
763 struct drm_device
*dev
= encoder
->base
.dev
;
764 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
765 struct intel_hdmi
*intel_hdmi
= enc_to_intel_hdmi(&encoder
->base
);
769 tmp
= I915_READ(DDI_BUF_CTL(intel_hdmi
->ddi_port
));
771 if (!(tmp
& DDI_BUF_CTL_ENABLE
))
775 tmp
= I915_READ(DDI_FUNC_CTL(i
));
777 if ((tmp
& PIPE_DDI_PORT_MASK
)
778 == PIPE_DDI_SELECT_PORT(intel_hdmi
->ddi_port
)) {
784 DRM_DEBUG_KMS("No pipe for ddi port %i found\n", intel_hdmi
->ddi_port
);
789 void intel_enable_ddi(struct intel_encoder
*encoder
)
791 struct drm_device
*dev
= encoder
->base
.dev
;
792 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
793 struct intel_hdmi
*intel_hdmi
= enc_to_intel_hdmi(&encoder
->base
);
794 int port
= intel_hdmi
->ddi_port
;
797 temp
= I915_READ(DDI_BUF_CTL(port
));
798 temp
|= DDI_BUF_CTL_ENABLE
;
800 /* Enable DDI_BUF_CTL. In HDMI/DVI mode, the port width,
801 * and swing/emphasis values are ignored so nothing special needs
802 * to be done besides enabling the port.
804 I915_WRITE(DDI_BUF_CTL(port
), temp
);
807 void intel_disable_ddi(struct intel_encoder
*encoder
)
809 struct drm_device
*dev
= encoder
->base
.dev
;
810 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
811 struct intel_hdmi
*intel_hdmi
= enc_to_intel_hdmi(&encoder
->base
);
812 int port
= intel_hdmi
->ddi_port
;
815 temp
= I915_READ(DDI_BUF_CTL(port
));
816 temp
&= ~DDI_BUF_CTL_ENABLE
;
818 I915_WRITE(DDI_BUF_CTL(port
), temp
);