1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2006 Dave Airlie <airlied@linux.ie>
3*4882a593Smuzhiyun * Copyright © 2006-2009 Intel Corporation
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
6*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
7*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
8*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
10*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the next
13*4882a593Smuzhiyun * paragraph) shall be included in all copies or substantial portions of the
14*4882a593Smuzhiyun * Software.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*4882a593Smuzhiyun * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*4882a593Smuzhiyun * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*4882a593Smuzhiyun * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE.
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun * Authors:
25*4882a593Smuzhiyun * Eric Anholt <eric@anholt.net>
26*4882a593Smuzhiyun * Jesse Barnes <jesse.barnes@intel.com>
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #include <linux/delay.h>
30*4882a593Smuzhiyun #include <linux/hdmi.h>
31*4882a593Smuzhiyun #include <linux/i2c.h>
32*4882a593Smuzhiyun #include <linux/slab.h>
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #include <drm/drm_atomic_helper.h>
35*4882a593Smuzhiyun #include <drm/drm_crtc.h>
36*4882a593Smuzhiyun #include <drm/drm_edid.h>
37*4882a593Smuzhiyun #include <drm/drm_hdcp.h>
38*4882a593Smuzhiyun #include <drm/drm_scdc_helper.h>
39*4882a593Smuzhiyun #include <drm/intel_lpe_audio.h>
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #include "i915_debugfs.h"
42*4882a593Smuzhiyun #include "i915_drv.h"
43*4882a593Smuzhiyun #include "intel_atomic.h"
44*4882a593Smuzhiyun #include "intel_audio.h"
45*4882a593Smuzhiyun #include "intel_connector.h"
46*4882a593Smuzhiyun #include "intel_ddi.h"
47*4882a593Smuzhiyun #include "intel_display_types.h"
48*4882a593Smuzhiyun #include "intel_dp.h"
49*4882a593Smuzhiyun #include "intel_dpio_phy.h"
50*4882a593Smuzhiyun #include "intel_fifo_underrun.h"
51*4882a593Smuzhiyun #include "intel_gmbus.h"
52*4882a593Smuzhiyun #include "intel_hdcp.h"
53*4882a593Smuzhiyun #include "intel_hdmi.h"
54*4882a593Smuzhiyun #include "intel_hotplug.h"
55*4882a593Smuzhiyun #include "intel_lspcon.h"
56*4882a593Smuzhiyun #include "intel_panel.h"
57*4882a593Smuzhiyun #include "intel_sdvo.h"
58*4882a593Smuzhiyun #include "intel_sideband.h"
59*4882a593Smuzhiyun
intel_hdmi_to_dev(struct intel_hdmi * intel_hdmi)60*4882a593Smuzhiyun static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun return hdmi_to_dig_port(intel_hdmi)->base.base.dev;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun static void
assert_hdmi_port_disabled(struct intel_hdmi * intel_hdmi)66*4882a593Smuzhiyun assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi);
69*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
70*4882a593Smuzhiyun u32 enabled_bits;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun enabled_bits = HAS_DDI(dev_priv) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE;
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun drm_WARN(dev,
75*4882a593Smuzhiyun intel_de_read(dev_priv, intel_hdmi->hdmi_reg) & enabled_bits,
76*4882a593Smuzhiyun "HDMI port enabled, expecting disabled\n");
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun static void
assert_hdmi_transcoder_func_disabled(struct drm_i915_private * dev_priv,enum transcoder cpu_transcoder)80*4882a593Smuzhiyun assert_hdmi_transcoder_func_disabled(struct drm_i915_private *dev_priv,
81*4882a593Smuzhiyun enum transcoder cpu_transcoder)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun drm_WARN(&dev_priv->drm,
84*4882a593Smuzhiyun intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) &
85*4882a593Smuzhiyun TRANS_DDI_FUNC_ENABLE,
86*4882a593Smuzhiyun "HDMI transcoder function enabled, expecting disabled\n");
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
enc_to_intel_hdmi(struct intel_encoder * encoder)89*4882a593Smuzhiyun struct intel_hdmi *enc_to_intel_hdmi(struct intel_encoder *encoder)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun struct intel_digital_port *dig_port =
92*4882a593Smuzhiyun container_of(&encoder->base, struct intel_digital_port,
93*4882a593Smuzhiyun base.base);
94*4882a593Smuzhiyun return &dig_port->hdmi;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun
intel_attached_hdmi(struct intel_connector * connector)97*4882a593Smuzhiyun static struct intel_hdmi *intel_attached_hdmi(struct intel_connector *connector)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun return enc_to_intel_hdmi(intel_attached_encoder(connector));
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
g4x_infoframe_index(unsigned int type)102*4882a593Smuzhiyun static u32 g4x_infoframe_index(unsigned int type)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun switch (type) {
105*4882a593Smuzhiyun case HDMI_PACKET_TYPE_GAMUT_METADATA:
106*4882a593Smuzhiyun return VIDEO_DIP_SELECT_GAMUT;
107*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_AVI:
108*4882a593Smuzhiyun return VIDEO_DIP_SELECT_AVI;
109*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_SPD:
110*4882a593Smuzhiyun return VIDEO_DIP_SELECT_SPD;
111*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_VENDOR:
112*4882a593Smuzhiyun return VIDEO_DIP_SELECT_VENDOR;
113*4882a593Smuzhiyun default:
114*4882a593Smuzhiyun MISSING_CASE(type);
115*4882a593Smuzhiyun return 0;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
g4x_infoframe_enable(unsigned int type)119*4882a593Smuzhiyun static u32 g4x_infoframe_enable(unsigned int type)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun switch (type) {
122*4882a593Smuzhiyun case HDMI_PACKET_TYPE_GENERAL_CONTROL:
123*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_GCP;
124*4882a593Smuzhiyun case HDMI_PACKET_TYPE_GAMUT_METADATA:
125*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_GAMUT;
126*4882a593Smuzhiyun case DP_SDP_VSC:
127*4882a593Smuzhiyun return 0;
128*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_AVI:
129*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_AVI;
130*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_SPD:
131*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_SPD;
132*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_VENDOR:
133*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_VENDOR;
134*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_DRM:
135*4882a593Smuzhiyun return 0;
136*4882a593Smuzhiyun default:
137*4882a593Smuzhiyun MISSING_CASE(type);
138*4882a593Smuzhiyun return 0;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
hsw_infoframe_enable(unsigned int type)142*4882a593Smuzhiyun static u32 hsw_infoframe_enable(unsigned int type)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun switch (type) {
145*4882a593Smuzhiyun case HDMI_PACKET_TYPE_GENERAL_CONTROL:
146*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_GCP_HSW;
147*4882a593Smuzhiyun case HDMI_PACKET_TYPE_GAMUT_METADATA:
148*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_GMP_HSW;
149*4882a593Smuzhiyun case DP_SDP_VSC:
150*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_VSC_HSW;
151*4882a593Smuzhiyun case DP_SDP_PPS:
152*4882a593Smuzhiyun return VDIP_ENABLE_PPS;
153*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_AVI:
154*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_AVI_HSW;
155*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_SPD:
156*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_SPD_HSW;
157*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_VENDOR:
158*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_VS_HSW;
159*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_DRM:
160*4882a593Smuzhiyun return VIDEO_DIP_ENABLE_DRM_GLK;
161*4882a593Smuzhiyun default:
162*4882a593Smuzhiyun MISSING_CASE(type);
163*4882a593Smuzhiyun return 0;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun static i915_reg_t
hsw_dip_data_reg(struct drm_i915_private * dev_priv,enum transcoder cpu_transcoder,unsigned int type,int i)168*4882a593Smuzhiyun hsw_dip_data_reg(struct drm_i915_private *dev_priv,
169*4882a593Smuzhiyun enum transcoder cpu_transcoder,
170*4882a593Smuzhiyun unsigned int type,
171*4882a593Smuzhiyun int i)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun switch (type) {
174*4882a593Smuzhiyun case HDMI_PACKET_TYPE_GAMUT_METADATA:
175*4882a593Smuzhiyun return HSW_TVIDEO_DIP_GMP_DATA(cpu_transcoder, i);
176*4882a593Smuzhiyun case DP_SDP_VSC:
177*4882a593Smuzhiyun return HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, i);
178*4882a593Smuzhiyun case DP_SDP_PPS:
179*4882a593Smuzhiyun return ICL_VIDEO_DIP_PPS_DATA(cpu_transcoder, i);
180*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_AVI:
181*4882a593Smuzhiyun return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i);
182*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_SPD:
183*4882a593Smuzhiyun return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder, i);
184*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_VENDOR:
185*4882a593Smuzhiyun return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder, i);
186*4882a593Smuzhiyun case HDMI_INFOFRAME_TYPE_DRM:
187*4882a593Smuzhiyun return GLK_TVIDEO_DIP_DRM_DATA(cpu_transcoder, i);
188*4882a593Smuzhiyun default:
189*4882a593Smuzhiyun MISSING_CASE(type);
190*4882a593Smuzhiyun return INVALID_MMIO_REG;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
hsw_dip_data_size(struct drm_i915_private * dev_priv,unsigned int type)194*4882a593Smuzhiyun static int hsw_dip_data_size(struct drm_i915_private *dev_priv,
195*4882a593Smuzhiyun unsigned int type)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun switch (type) {
198*4882a593Smuzhiyun case DP_SDP_VSC:
199*4882a593Smuzhiyun return VIDEO_DIP_VSC_DATA_SIZE;
200*4882a593Smuzhiyun case DP_SDP_PPS:
201*4882a593Smuzhiyun return VIDEO_DIP_PPS_DATA_SIZE;
202*4882a593Smuzhiyun case HDMI_PACKET_TYPE_GAMUT_METADATA:
203*4882a593Smuzhiyun if (INTEL_GEN(dev_priv) >= 11)
204*4882a593Smuzhiyun return VIDEO_DIP_GMP_DATA_SIZE;
205*4882a593Smuzhiyun else
206*4882a593Smuzhiyun return VIDEO_DIP_DATA_SIZE;
207*4882a593Smuzhiyun default:
208*4882a593Smuzhiyun return VIDEO_DIP_DATA_SIZE;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
g4x_write_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,const void * frame,ssize_t len)212*4882a593Smuzhiyun static void g4x_write_infoframe(struct intel_encoder *encoder,
213*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
214*4882a593Smuzhiyun unsigned int type,
215*4882a593Smuzhiyun const void *frame, ssize_t len)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun const u32 *data = frame;
218*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
219*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, VIDEO_DIP_CTL);
220*4882a593Smuzhiyun int i;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun drm_WARN(&dev_priv->drm, !(val & VIDEO_DIP_ENABLE),
223*4882a593Smuzhiyun "Writing DIP with CTL reg disabled\n");
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
226*4882a593Smuzhiyun val |= g4x_infoframe_index(type);
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun val &= ~g4x_infoframe_enable(type);
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun intel_de_write(dev_priv, VIDEO_DIP_CTL, val);
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun for (i = 0; i < len; i += 4) {
233*4882a593Smuzhiyun intel_de_write(dev_priv, VIDEO_DIP_DATA, *data);
234*4882a593Smuzhiyun data++;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun /* Write every possible data byte to force correct ECC calculation. */
237*4882a593Smuzhiyun for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
238*4882a593Smuzhiyun intel_de_write(dev_priv, VIDEO_DIP_DATA, 0);
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun val |= g4x_infoframe_enable(type);
241*4882a593Smuzhiyun val &= ~VIDEO_DIP_FREQ_MASK;
242*4882a593Smuzhiyun val |= VIDEO_DIP_FREQ_VSYNC;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun intel_de_write(dev_priv, VIDEO_DIP_CTL, val);
245*4882a593Smuzhiyun intel_de_posting_read(dev_priv, VIDEO_DIP_CTL);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
g4x_read_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,void * frame,ssize_t len)248*4882a593Smuzhiyun static void g4x_read_infoframe(struct intel_encoder *encoder,
249*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
250*4882a593Smuzhiyun unsigned int type,
251*4882a593Smuzhiyun void *frame, ssize_t len)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
254*4882a593Smuzhiyun u32 val, *data = frame;
255*4882a593Smuzhiyun int i;
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun val = intel_de_read(dev_priv, VIDEO_DIP_CTL);
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
260*4882a593Smuzhiyun val |= g4x_infoframe_index(type);
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun intel_de_write(dev_priv, VIDEO_DIP_CTL, val);
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun for (i = 0; i < len; i += 4)
265*4882a593Smuzhiyun *data++ = intel_de_read(dev_priv, VIDEO_DIP_DATA);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
g4x_infoframes_enabled(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)268*4882a593Smuzhiyun static u32 g4x_infoframes_enabled(struct intel_encoder *encoder,
269*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
272*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, VIDEO_DIP_CTL);
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun if ((val & VIDEO_DIP_ENABLE) == 0)
275*4882a593Smuzhiyun return 0;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(encoder->port))
278*4882a593Smuzhiyun return 0;
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun return val & (VIDEO_DIP_ENABLE_AVI |
281*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_SPD);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
ibx_write_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,const void * frame,ssize_t len)284*4882a593Smuzhiyun static void ibx_write_infoframe(struct intel_encoder *encoder,
285*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
286*4882a593Smuzhiyun unsigned int type,
287*4882a593Smuzhiyun const void *frame, ssize_t len)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun const u32 *data = frame;
290*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
291*4882a593Smuzhiyun struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
292*4882a593Smuzhiyun i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
293*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
294*4882a593Smuzhiyun int i;
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun drm_WARN(&dev_priv->drm, !(val & VIDEO_DIP_ENABLE),
297*4882a593Smuzhiyun "Writing DIP with CTL reg disabled\n");
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
300*4882a593Smuzhiyun val |= g4x_infoframe_index(type);
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun val &= ~g4x_infoframe_enable(type);
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun for (i = 0; i < len; i += 4) {
307*4882a593Smuzhiyun intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe),
308*4882a593Smuzhiyun *data);
309*4882a593Smuzhiyun data++;
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun /* Write every possible data byte to force correct ECC calculation. */
312*4882a593Smuzhiyun for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
313*4882a593Smuzhiyun intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun val |= g4x_infoframe_enable(type);
316*4882a593Smuzhiyun val &= ~VIDEO_DIP_FREQ_MASK;
317*4882a593Smuzhiyun val |= VIDEO_DIP_FREQ_VSYNC;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
320*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun
ibx_read_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,void * frame,ssize_t len)323*4882a593Smuzhiyun static void ibx_read_infoframe(struct intel_encoder *encoder,
324*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
325*4882a593Smuzhiyun unsigned int type,
326*4882a593Smuzhiyun void *frame, ssize_t len)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
329*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
330*4882a593Smuzhiyun u32 val, *data = frame;
331*4882a593Smuzhiyun int i;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun val = intel_de_read(dev_priv, TVIDEO_DIP_CTL(crtc->pipe));
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
336*4882a593Smuzhiyun val |= g4x_infoframe_index(type);
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun intel_de_write(dev_priv, TVIDEO_DIP_CTL(crtc->pipe), val);
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun for (i = 0; i < len; i += 4)
341*4882a593Smuzhiyun *data++ = intel_de_read(dev_priv, TVIDEO_DIP_DATA(crtc->pipe));
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
ibx_infoframes_enabled(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)344*4882a593Smuzhiyun static u32 ibx_infoframes_enabled(struct intel_encoder *encoder,
345*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
348*4882a593Smuzhiyun enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
349*4882a593Smuzhiyun i915_reg_t reg = TVIDEO_DIP_CTL(pipe);
350*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun if ((val & VIDEO_DIP_ENABLE) == 0)
353*4882a593Smuzhiyun return 0;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(encoder->port))
356*4882a593Smuzhiyun return 0;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun return val & (VIDEO_DIP_ENABLE_AVI |
359*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
360*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
cpt_write_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,const void * frame,ssize_t len)363*4882a593Smuzhiyun static void cpt_write_infoframe(struct intel_encoder *encoder,
364*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
365*4882a593Smuzhiyun unsigned int type,
366*4882a593Smuzhiyun const void *frame, ssize_t len)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun const u32 *data = frame;
369*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
370*4882a593Smuzhiyun struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
371*4882a593Smuzhiyun i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
372*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
373*4882a593Smuzhiyun int i;
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun drm_WARN(&dev_priv->drm, !(val & VIDEO_DIP_ENABLE),
376*4882a593Smuzhiyun "Writing DIP with CTL reg disabled\n");
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
379*4882a593Smuzhiyun val |= g4x_infoframe_index(type);
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun /* The DIP control register spec says that we need to update the AVI
382*4882a593Smuzhiyun * infoframe without clearing its enable bit */
383*4882a593Smuzhiyun if (type != HDMI_INFOFRAME_TYPE_AVI)
384*4882a593Smuzhiyun val &= ~g4x_infoframe_enable(type);
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun for (i = 0; i < len; i += 4) {
389*4882a593Smuzhiyun intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe),
390*4882a593Smuzhiyun *data);
391*4882a593Smuzhiyun data++;
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun /* Write every possible data byte to force correct ECC calculation. */
394*4882a593Smuzhiyun for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
395*4882a593Smuzhiyun intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun val |= g4x_infoframe_enable(type);
398*4882a593Smuzhiyun val &= ~VIDEO_DIP_FREQ_MASK;
399*4882a593Smuzhiyun val |= VIDEO_DIP_FREQ_VSYNC;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
402*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun
cpt_read_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,void * frame,ssize_t len)405*4882a593Smuzhiyun static void cpt_read_infoframe(struct intel_encoder *encoder,
406*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
407*4882a593Smuzhiyun unsigned int type,
408*4882a593Smuzhiyun void *frame, ssize_t len)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
411*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
412*4882a593Smuzhiyun u32 val, *data = frame;
413*4882a593Smuzhiyun int i;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun val = intel_de_read(dev_priv, TVIDEO_DIP_CTL(crtc->pipe));
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
418*4882a593Smuzhiyun val |= g4x_infoframe_index(type);
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun intel_de_write(dev_priv, TVIDEO_DIP_CTL(crtc->pipe), val);
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun for (i = 0; i < len; i += 4)
423*4882a593Smuzhiyun *data++ = intel_de_read(dev_priv, TVIDEO_DIP_DATA(crtc->pipe));
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
cpt_infoframes_enabled(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)426*4882a593Smuzhiyun static u32 cpt_infoframes_enabled(struct intel_encoder *encoder,
427*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config)
428*4882a593Smuzhiyun {
429*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
430*4882a593Smuzhiyun enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
431*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, TVIDEO_DIP_CTL(pipe));
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun if ((val & VIDEO_DIP_ENABLE) == 0)
434*4882a593Smuzhiyun return 0;
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun return val & (VIDEO_DIP_ENABLE_AVI |
437*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
438*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
vlv_write_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,const void * frame,ssize_t len)441*4882a593Smuzhiyun static void vlv_write_infoframe(struct intel_encoder *encoder,
442*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
443*4882a593Smuzhiyun unsigned int type,
444*4882a593Smuzhiyun const void *frame, ssize_t len)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun const u32 *data = frame;
447*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
448*4882a593Smuzhiyun struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
449*4882a593Smuzhiyun i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
450*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
451*4882a593Smuzhiyun int i;
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun drm_WARN(&dev_priv->drm, !(val & VIDEO_DIP_ENABLE),
454*4882a593Smuzhiyun "Writing DIP with CTL reg disabled\n");
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
457*4882a593Smuzhiyun val |= g4x_infoframe_index(type);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun val &= ~g4x_infoframe_enable(type);
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun for (i = 0; i < len; i += 4) {
464*4882a593Smuzhiyun intel_de_write(dev_priv,
465*4882a593Smuzhiyun VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
466*4882a593Smuzhiyun data++;
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun /* Write every possible data byte to force correct ECC calculation. */
469*4882a593Smuzhiyun for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
470*4882a593Smuzhiyun intel_de_write(dev_priv,
471*4882a593Smuzhiyun VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun val |= g4x_infoframe_enable(type);
474*4882a593Smuzhiyun val &= ~VIDEO_DIP_FREQ_MASK;
475*4882a593Smuzhiyun val |= VIDEO_DIP_FREQ_VSYNC;
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
478*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun
vlv_read_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,void * frame,ssize_t len)481*4882a593Smuzhiyun static void vlv_read_infoframe(struct intel_encoder *encoder,
482*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
483*4882a593Smuzhiyun unsigned int type,
484*4882a593Smuzhiyun void *frame, ssize_t len)
485*4882a593Smuzhiyun {
486*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
487*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
488*4882a593Smuzhiyun u32 val, *data = frame;
489*4882a593Smuzhiyun int i;
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun val = intel_de_read(dev_priv, VLV_TVIDEO_DIP_CTL(crtc->pipe));
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
494*4882a593Smuzhiyun val |= g4x_infoframe_index(type);
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun intel_de_write(dev_priv, VLV_TVIDEO_DIP_CTL(crtc->pipe), val);
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun for (i = 0; i < len; i += 4)
499*4882a593Smuzhiyun *data++ = intel_de_read(dev_priv,
500*4882a593Smuzhiyun VLV_TVIDEO_DIP_DATA(crtc->pipe));
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun
vlv_infoframes_enabled(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)503*4882a593Smuzhiyun static u32 vlv_infoframes_enabled(struct intel_encoder *encoder,
504*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config)
505*4882a593Smuzhiyun {
506*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
507*4882a593Smuzhiyun enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
508*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, VLV_TVIDEO_DIP_CTL(pipe));
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun if ((val & VIDEO_DIP_ENABLE) == 0)
511*4882a593Smuzhiyun return 0;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun if ((val & VIDEO_DIP_PORT_MASK) != VIDEO_DIP_PORT(encoder->port))
514*4882a593Smuzhiyun return 0;
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun return val & (VIDEO_DIP_ENABLE_AVI |
517*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
518*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun
hsw_write_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,const void * frame,ssize_t len)521*4882a593Smuzhiyun static void hsw_write_infoframe(struct intel_encoder *encoder,
522*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
523*4882a593Smuzhiyun unsigned int type,
524*4882a593Smuzhiyun const void *frame, ssize_t len)
525*4882a593Smuzhiyun {
526*4882a593Smuzhiyun const u32 *data = frame;
527*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
528*4882a593Smuzhiyun enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
529*4882a593Smuzhiyun i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
530*4882a593Smuzhiyun int data_size;
531*4882a593Smuzhiyun int i;
532*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, ctl_reg);
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun data_size = hsw_dip_data_size(dev_priv, type);
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun drm_WARN_ON(&dev_priv->drm, len > data_size);
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun val &= ~hsw_infoframe_enable(type);
539*4882a593Smuzhiyun intel_de_write(dev_priv, ctl_reg, val);
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun for (i = 0; i < len; i += 4) {
542*4882a593Smuzhiyun intel_de_write(dev_priv,
543*4882a593Smuzhiyun hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2),
544*4882a593Smuzhiyun *data);
545*4882a593Smuzhiyun data++;
546*4882a593Smuzhiyun }
547*4882a593Smuzhiyun /* Write every possible data byte to force correct ECC calculation. */
548*4882a593Smuzhiyun for (; i < data_size; i += 4)
549*4882a593Smuzhiyun intel_de_write(dev_priv,
550*4882a593Smuzhiyun hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2),
551*4882a593Smuzhiyun 0);
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun val |= hsw_infoframe_enable(type);
554*4882a593Smuzhiyun intel_de_write(dev_priv, ctl_reg, val);
555*4882a593Smuzhiyun intel_de_posting_read(dev_priv, ctl_reg);
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun
hsw_read_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,unsigned int type,void * frame,ssize_t len)558*4882a593Smuzhiyun static void hsw_read_infoframe(struct intel_encoder *encoder,
559*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
560*4882a593Smuzhiyun unsigned int type,
561*4882a593Smuzhiyun void *frame, ssize_t len)
562*4882a593Smuzhiyun {
563*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
564*4882a593Smuzhiyun enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
565*4882a593Smuzhiyun u32 val, *data = frame;
566*4882a593Smuzhiyun int i;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun val = intel_de_read(dev_priv, HSW_TVIDEO_DIP_CTL(cpu_transcoder));
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun for (i = 0; i < len; i += 4)
571*4882a593Smuzhiyun *data++ = intel_de_read(dev_priv,
572*4882a593Smuzhiyun hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2));
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun
hsw_infoframes_enabled(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config)575*4882a593Smuzhiyun static u32 hsw_infoframes_enabled(struct intel_encoder *encoder,
576*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config)
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
579*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv,
580*4882a593Smuzhiyun HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder));
581*4882a593Smuzhiyun u32 mask;
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun mask = (VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_AVI_HSW |
584*4882a593Smuzhiyun VIDEO_DIP_ENABLE_GCP_HSW | VIDEO_DIP_ENABLE_VS_HSW |
585*4882a593Smuzhiyun VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW);
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
588*4882a593Smuzhiyun mask |= VIDEO_DIP_ENABLE_DRM_GLK;
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun return val & mask;
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun static const u8 infoframe_type_to_idx[] = {
594*4882a593Smuzhiyun HDMI_PACKET_TYPE_GENERAL_CONTROL,
595*4882a593Smuzhiyun HDMI_PACKET_TYPE_GAMUT_METADATA,
596*4882a593Smuzhiyun DP_SDP_VSC,
597*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_AVI,
598*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_SPD,
599*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_VENDOR,
600*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_DRM,
601*4882a593Smuzhiyun };
602*4882a593Smuzhiyun
intel_hdmi_infoframe_enable(unsigned int type)603*4882a593Smuzhiyun u32 intel_hdmi_infoframe_enable(unsigned int type)
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun int i;
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(infoframe_type_to_idx); i++) {
608*4882a593Smuzhiyun if (infoframe_type_to_idx[i] == type)
609*4882a593Smuzhiyun return BIT(i);
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun return 0;
613*4882a593Smuzhiyun }
614*4882a593Smuzhiyun
intel_hdmi_infoframes_enabled(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)615*4882a593Smuzhiyun u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder,
616*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state)
617*4882a593Smuzhiyun {
618*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
619*4882a593Smuzhiyun struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
620*4882a593Smuzhiyun u32 val, ret = 0;
621*4882a593Smuzhiyun int i;
622*4882a593Smuzhiyun
623*4882a593Smuzhiyun val = dig_port->infoframes_enabled(encoder, crtc_state);
624*4882a593Smuzhiyun
625*4882a593Smuzhiyun /* map from hardware bits to dip idx */
626*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(infoframe_type_to_idx); i++) {
627*4882a593Smuzhiyun unsigned int type = infoframe_type_to_idx[i];
628*4882a593Smuzhiyun
629*4882a593Smuzhiyun if (HAS_DDI(dev_priv)) {
630*4882a593Smuzhiyun if (val & hsw_infoframe_enable(type))
631*4882a593Smuzhiyun ret |= BIT(i);
632*4882a593Smuzhiyun } else {
633*4882a593Smuzhiyun if (val & g4x_infoframe_enable(type))
634*4882a593Smuzhiyun ret |= BIT(i);
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun return ret;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun /*
642*4882a593Smuzhiyun * The data we write to the DIP data buffer registers is 1 byte bigger than the
643*4882a593Smuzhiyun * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting
644*4882a593Smuzhiyun * at 0). It's also a byte used by DisplayPort so the same DIP registers can be
645*4882a593Smuzhiyun * used for both technologies.
646*4882a593Smuzhiyun *
647*4882a593Smuzhiyun * DW0: Reserved/ECC/DP | HB2 | HB1 | HB0
648*4882a593Smuzhiyun * DW1: DB3 | DB2 | DB1 | DB0
649*4882a593Smuzhiyun * DW2: DB7 | DB6 | DB5 | DB4
650*4882a593Smuzhiyun * DW3: ...
651*4882a593Smuzhiyun *
652*4882a593Smuzhiyun * (HB is Header Byte, DB is Data Byte)
653*4882a593Smuzhiyun *
654*4882a593Smuzhiyun * The hdmi pack() functions don't know about that hardware specific hole so we
655*4882a593Smuzhiyun * trick them by giving an offset into the buffer and moving back the header
656*4882a593Smuzhiyun * bytes by one.
657*4882a593Smuzhiyun */
intel_write_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,enum hdmi_infoframe_type type,const union hdmi_infoframe * frame)658*4882a593Smuzhiyun static void intel_write_infoframe(struct intel_encoder *encoder,
659*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
660*4882a593Smuzhiyun enum hdmi_infoframe_type type,
661*4882a593Smuzhiyun const union hdmi_infoframe *frame)
662*4882a593Smuzhiyun {
663*4882a593Smuzhiyun struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
664*4882a593Smuzhiyun u8 buffer[VIDEO_DIP_DATA_SIZE];
665*4882a593Smuzhiyun ssize_t len;
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun if ((crtc_state->infoframes.enable &
668*4882a593Smuzhiyun intel_hdmi_infoframe_enable(type)) == 0)
669*4882a593Smuzhiyun return;
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun if (drm_WARN_ON(encoder->base.dev, frame->any.type != type))
672*4882a593Smuzhiyun return;
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun /* see comment above for the reason for this offset */
675*4882a593Smuzhiyun len = hdmi_infoframe_pack_only(frame, buffer + 1, sizeof(buffer) - 1);
676*4882a593Smuzhiyun if (drm_WARN_ON(encoder->base.dev, len < 0))
677*4882a593Smuzhiyun return;
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun /* Insert the 'hole' (see big comment above) at position 3 */
680*4882a593Smuzhiyun memmove(&buffer[0], &buffer[1], 3);
681*4882a593Smuzhiyun buffer[3] = 0;
682*4882a593Smuzhiyun len++;
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun dig_port->write_infoframe(encoder, crtc_state, type, buffer, len);
685*4882a593Smuzhiyun }
686*4882a593Smuzhiyun
intel_read_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,enum hdmi_infoframe_type type,union hdmi_infoframe * frame)687*4882a593Smuzhiyun void intel_read_infoframe(struct intel_encoder *encoder,
688*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
689*4882a593Smuzhiyun enum hdmi_infoframe_type type,
690*4882a593Smuzhiyun union hdmi_infoframe *frame)
691*4882a593Smuzhiyun {
692*4882a593Smuzhiyun struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
693*4882a593Smuzhiyun u8 buffer[VIDEO_DIP_DATA_SIZE];
694*4882a593Smuzhiyun int ret;
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun if ((crtc_state->infoframes.enable &
697*4882a593Smuzhiyun intel_hdmi_infoframe_enable(type)) == 0)
698*4882a593Smuzhiyun return;
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun dig_port->read_infoframe(encoder, crtc_state,
701*4882a593Smuzhiyun type, buffer, sizeof(buffer));
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun /* Fill the 'hole' (see big comment above) at position 3 */
704*4882a593Smuzhiyun memmove(&buffer[1], &buffer[0], 3);
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun /* see comment above for the reason for this offset */
707*4882a593Smuzhiyun ret = hdmi_infoframe_unpack(frame, buffer + 1, sizeof(buffer) - 1);
708*4882a593Smuzhiyun if (ret) {
709*4882a593Smuzhiyun drm_dbg_kms(encoder->base.dev,
710*4882a593Smuzhiyun "Failed to unpack infoframe type 0x%02x\n", type);
711*4882a593Smuzhiyun return;
712*4882a593Smuzhiyun }
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun if (frame->any.type != type)
715*4882a593Smuzhiyun drm_dbg_kms(encoder->base.dev,
716*4882a593Smuzhiyun "Found the wrong infoframe type 0x%x (expected 0x%02x)\n",
717*4882a593Smuzhiyun frame->any.type, type);
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun static bool
intel_hdmi_compute_avi_infoframe(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,struct drm_connector_state * conn_state)721*4882a593Smuzhiyun intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
722*4882a593Smuzhiyun struct intel_crtc_state *crtc_state,
723*4882a593Smuzhiyun struct drm_connector_state *conn_state)
724*4882a593Smuzhiyun {
725*4882a593Smuzhiyun struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
726*4882a593Smuzhiyun const struct drm_display_mode *adjusted_mode =
727*4882a593Smuzhiyun &crtc_state->hw.adjusted_mode;
728*4882a593Smuzhiyun struct drm_connector *connector = conn_state->connector;
729*4882a593Smuzhiyun int ret;
730*4882a593Smuzhiyun
731*4882a593Smuzhiyun if (!crtc_state->has_infoframe)
732*4882a593Smuzhiyun return true;
733*4882a593Smuzhiyun
734*4882a593Smuzhiyun crtc_state->infoframes.enable |=
735*4882a593Smuzhiyun intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI);
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector,
738*4882a593Smuzhiyun adjusted_mode);
739*4882a593Smuzhiyun if (ret)
740*4882a593Smuzhiyun return false;
741*4882a593Smuzhiyun
742*4882a593Smuzhiyun if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
743*4882a593Smuzhiyun frame->colorspace = HDMI_COLORSPACE_YUV420;
744*4882a593Smuzhiyun else if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444)
745*4882a593Smuzhiyun frame->colorspace = HDMI_COLORSPACE_YUV444;
746*4882a593Smuzhiyun else
747*4882a593Smuzhiyun frame->colorspace = HDMI_COLORSPACE_RGB;
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun drm_hdmi_avi_infoframe_colorspace(frame, conn_state);
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun /* nonsense combination */
752*4882a593Smuzhiyun drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range &&
753*4882a593Smuzhiyun crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB);
754*4882a593Smuzhiyun
755*4882a593Smuzhiyun if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) {
756*4882a593Smuzhiyun drm_hdmi_avi_infoframe_quant_range(frame, connector,
757*4882a593Smuzhiyun adjusted_mode,
758*4882a593Smuzhiyun crtc_state->limited_color_range ?
759*4882a593Smuzhiyun HDMI_QUANTIZATION_RANGE_LIMITED :
760*4882a593Smuzhiyun HDMI_QUANTIZATION_RANGE_FULL);
761*4882a593Smuzhiyun } else {
762*4882a593Smuzhiyun frame->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
763*4882a593Smuzhiyun frame->ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun drm_hdmi_avi_infoframe_content_type(frame, conn_state);
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun /* TODO: handle pixel repetition for YCBCR420 outputs */
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun ret = hdmi_avi_infoframe_check(frame);
771*4882a593Smuzhiyun if (drm_WARN_ON(encoder->base.dev, ret))
772*4882a593Smuzhiyun return false;
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun return true;
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun static bool
intel_hdmi_compute_spd_infoframe(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,struct drm_connector_state * conn_state)778*4882a593Smuzhiyun intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder,
779*4882a593Smuzhiyun struct intel_crtc_state *crtc_state,
780*4882a593Smuzhiyun struct drm_connector_state *conn_state)
781*4882a593Smuzhiyun {
782*4882a593Smuzhiyun struct hdmi_spd_infoframe *frame = &crtc_state->infoframes.spd.spd;
783*4882a593Smuzhiyun int ret;
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun if (!crtc_state->has_infoframe)
786*4882a593Smuzhiyun return true;
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun crtc_state->infoframes.enable |=
789*4882a593Smuzhiyun intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD);
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun ret = hdmi_spd_infoframe_init(frame, "Intel", "Integrated gfx");
792*4882a593Smuzhiyun if (drm_WARN_ON(encoder->base.dev, ret))
793*4882a593Smuzhiyun return false;
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun frame->sdi = HDMI_SPD_SDI_PC;
796*4882a593Smuzhiyun
797*4882a593Smuzhiyun ret = hdmi_spd_infoframe_check(frame);
798*4882a593Smuzhiyun if (drm_WARN_ON(encoder->base.dev, ret))
799*4882a593Smuzhiyun return false;
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun return true;
802*4882a593Smuzhiyun }
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun static bool
intel_hdmi_compute_hdmi_infoframe(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,struct drm_connector_state * conn_state)805*4882a593Smuzhiyun intel_hdmi_compute_hdmi_infoframe(struct intel_encoder *encoder,
806*4882a593Smuzhiyun struct intel_crtc_state *crtc_state,
807*4882a593Smuzhiyun struct drm_connector_state *conn_state)
808*4882a593Smuzhiyun {
809*4882a593Smuzhiyun struct hdmi_vendor_infoframe *frame =
810*4882a593Smuzhiyun &crtc_state->infoframes.hdmi.vendor.hdmi;
811*4882a593Smuzhiyun const struct drm_display_info *info =
812*4882a593Smuzhiyun &conn_state->connector->display_info;
813*4882a593Smuzhiyun int ret;
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun if (!crtc_state->has_infoframe || !info->has_hdmi_infoframe)
816*4882a593Smuzhiyun return true;
817*4882a593Smuzhiyun
818*4882a593Smuzhiyun crtc_state->infoframes.enable |=
819*4882a593Smuzhiyun intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_VENDOR);
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun ret = drm_hdmi_vendor_infoframe_from_display_mode(frame,
822*4882a593Smuzhiyun conn_state->connector,
823*4882a593Smuzhiyun &crtc_state->hw.adjusted_mode);
824*4882a593Smuzhiyun if (drm_WARN_ON(encoder->base.dev, ret))
825*4882a593Smuzhiyun return false;
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun ret = hdmi_vendor_infoframe_check(frame);
828*4882a593Smuzhiyun if (drm_WARN_ON(encoder->base.dev, ret))
829*4882a593Smuzhiyun return false;
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun return true;
832*4882a593Smuzhiyun }
833*4882a593Smuzhiyun
834*4882a593Smuzhiyun static bool
intel_hdmi_compute_drm_infoframe(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,struct drm_connector_state * conn_state)835*4882a593Smuzhiyun intel_hdmi_compute_drm_infoframe(struct intel_encoder *encoder,
836*4882a593Smuzhiyun struct intel_crtc_state *crtc_state,
837*4882a593Smuzhiyun struct drm_connector_state *conn_state)
838*4882a593Smuzhiyun {
839*4882a593Smuzhiyun struct hdmi_drm_infoframe *frame = &crtc_state->infoframes.drm.drm;
840*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
841*4882a593Smuzhiyun int ret;
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun if (!(INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)))
844*4882a593Smuzhiyun return true;
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun if (!crtc_state->has_infoframe)
847*4882a593Smuzhiyun return true;
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun if (!conn_state->hdr_output_metadata)
850*4882a593Smuzhiyun return true;
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun crtc_state->infoframes.enable |=
853*4882a593Smuzhiyun intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_DRM);
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun ret = drm_hdmi_infoframe_set_hdr_metadata(frame, conn_state);
856*4882a593Smuzhiyun if (ret < 0) {
857*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
858*4882a593Smuzhiyun "couldn't set HDR metadata in infoframe\n");
859*4882a593Smuzhiyun return false;
860*4882a593Smuzhiyun }
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun ret = hdmi_drm_infoframe_check(frame);
863*4882a593Smuzhiyun if (drm_WARN_ON(&dev_priv->drm, ret))
864*4882a593Smuzhiyun return false;
865*4882a593Smuzhiyun
866*4882a593Smuzhiyun return true;
867*4882a593Smuzhiyun }
868*4882a593Smuzhiyun
g4x_set_infoframes(struct intel_encoder * encoder,bool enable,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)869*4882a593Smuzhiyun static void g4x_set_infoframes(struct intel_encoder *encoder,
870*4882a593Smuzhiyun bool enable,
871*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
872*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
873*4882a593Smuzhiyun {
874*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
875*4882a593Smuzhiyun struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
876*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
877*4882a593Smuzhiyun i915_reg_t reg = VIDEO_DIP_CTL;
878*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
879*4882a593Smuzhiyun u32 port = VIDEO_DIP_PORT(encoder->port);
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun assert_hdmi_port_disabled(intel_hdmi);
882*4882a593Smuzhiyun
883*4882a593Smuzhiyun /* If the registers were not initialized yet, they might be zeroes,
884*4882a593Smuzhiyun * which means we're selecting the AVI DIP and we're setting its
885*4882a593Smuzhiyun * frequency to once. This seems to really confuse the HW and make
886*4882a593Smuzhiyun * things stop working (the register spec says the AVI always needs to
887*4882a593Smuzhiyun * be sent every VSync). So here we avoid writing to the register more
888*4882a593Smuzhiyun * than we need and also explicitly select the AVI DIP and explicitly
889*4882a593Smuzhiyun * set its frequency to every VSync. Avoiding to write it twice seems to
890*4882a593Smuzhiyun * be enough to solve the problem, but being defensive shouldn't hurt us
891*4882a593Smuzhiyun * either. */
892*4882a593Smuzhiyun val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
893*4882a593Smuzhiyun
894*4882a593Smuzhiyun if (!enable) {
895*4882a593Smuzhiyun if (!(val & VIDEO_DIP_ENABLE))
896*4882a593Smuzhiyun return;
897*4882a593Smuzhiyun if (port != (val & VIDEO_DIP_PORT_MASK)) {
898*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
899*4882a593Smuzhiyun "video DIP still enabled on port %c\n",
900*4882a593Smuzhiyun (val & VIDEO_DIP_PORT_MASK) >> 29);
901*4882a593Smuzhiyun return;
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
904*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_SPD);
905*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
906*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
907*4882a593Smuzhiyun return;
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun if (port != (val & VIDEO_DIP_PORT_MASK)) {
911*4882a593Smuzhiyun if (val & VIDEO_DIP_ENABLE) {
912*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
913*4882a593Smuzhiyun "video DIP already enabled on port %c\n",
914*4882a593Smuzhiyun (val & VIDEO_DIP_PORT_MASK) >> 29);
915*4882a593Smuzhiyun return;
916*4882a593Smuzhiyun }
917*4882a593Smuzhiyun val &= ~VIDEO_DIP_PORT_MASK;
918*4882a593Smuzhiyun val |= port;
919*4882a593Smuzhiyun }
920*4882a593Smuzhiyun
921*4882a593Smuzhiyun val |= VIDEO_DIP_ENABLE;
922*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE_AVI |
923*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_SPD);
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
926*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
927*4882a593Smuzhiyun
928*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
929*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_AVI,
930*4882a593Smuzhiyun &crtc_state->infoframes.avi);
931*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
932*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_SPD,
933*4882a593Smuzhiyun &crtc_state->infoframes.spd);
934*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
935*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_VENDOR,
936*4882a593Smuzhiyun &crtc_state->infoframes.hdmi);
937*4882a593Smuzhiyun }
938*4882a593Smuzhiyun
939*4882a593Smuzhiyun /*
940*4882a593Smuzhiyun * Determine if default_phase=1 can be indicated in the GCP infoframe.
941*4882a593Smuzhiyun *
942*4882a593Smuzhiyun * From HDMI specification 1.4a:
943*4882a593Smuzhiyun * - The first pixel of each Video Data Period shall always have a pixel packing phase of 0
944*4882a593Smuzhiyun * - The first pixel following each Video Data Period shall have a pixel packing phase of 0
945*4882a593Smuzhiyun * - The PP bits shall be constant for all GCPs and will be equal to the last packing phase
946*4882a593Smuzhiyun * - The first pixel following every transition of HSYNC or VSYNC shall have a pixel packing
947*4882a593Smuzhiyun * phase of 0
948*4882a593Smuzhiyun */
gcp_default_phase_possible(int pipe_bpp,const struct drm_display_mode * mode)949*4882a593Smuzhiyun static bool gcp_default_phase_possible(int pipe_bpp,
950*4882a593Smuzhiyun const struct drm_display_mode *mode)
951*4882a593Smuzhiyun {
952*4882a593Smuzhiyun unsigned int pixels_per_group;
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun switch (pipe_bpp) {
955*4882a593Smuzhiyun case 30:
956*4882a593Smuzhiyun /* 4 pixels in 5 clocks */
957*4882a593Smuzhiyun pixels_per_group = 4;
958*4882a593Smuzhiyun break;
959*4882a593Smuzhiyun case 36:
960*4882a593Smuzhiyun /* 2 pixels in 3 clocks */
961*4882a593Smuzhiyun pixels_per_group = 2;
962*4882a593Smuzhiyun break;
963*4882a593Smuzhiyun case 48:
964*4882a593Smuzhiyun /* 1 pixel in 2 clocks */
965*4882a593Smuzhiyun pixels_per_group = 1;
966*4882a593Smuzhiyun break;
967*4882a593Smuzhiyun default:
968*4882a593Smuzhiyun /* phase information not relevant for 8bpc */
969*4882a593Smuzhiyun return false;
970*4882a593Smuzhiyun }
971*4882a593Smuzhiyun
972*4882a593Smuzhiyun return mode->crtc_hdisplay % pixels_per_group == 0 &&
973*4882a593Smuzhiyun mode->crtc_htotal % pixels_per_group == 0 &&
974*4882a593Smuzhiyun mode->crtc_hblank_start % pixels_per_group == 0 &&
975*4882a593Smuzhiyun mode->crtc_hblank_end % pixels_per_group == 0 &&
976*4882a593Smuzhiyun mode->crtc_hsync_start % pixels_per_group == 0 &&
977*4882a593Smuzhiyun mode->crtc_hsync_end % pixels_per_group == 0 &&
978*4882a593Smuzhiyun ((mode->flags & DRM_MODE_FLAG_INTERLACE) == 0 ||
979*4882a593Smuzhiyun mode->crtc_htotal/2 % pixels_per_group == 0);
980*4882a593Smuzhiyun }
981*4882a593Smuzhiyun
intel_hdmi_set_gcp_infoframe(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)982*4882a593Smuzhiyun static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
983*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
984*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
985*4882a593Smuzhiyun {
986*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
987*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
988*4882a593Smuzhiyun i915_reg_t reg;
989*4882a593Smuzhiyun
990*4882a593Smuzhiyun if ((crtc_state->infoframes.enable &
991*4882a593Smuzhiyun intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL)) == 0)
992*4882a593Smuzhiyun return false;
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun if (HAS_DDI(dev_priv))
995*4882a593Smuzhiyun reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder);
996*4882a593Smuzhiyun else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
997*4882a593Smuzhiyun reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
998*4882a593Smuzhiyun else if (HAS_PCH_SPLIT(dev_priv))
999*4882a593Smuzhiyun reg = TVIDEO_DIP_GCP(crtc->pipe);
1000*4882a593Smuzhiyun else
1001*4882a593Smuzhiyun return false;
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun intel_de_write(dev_priv, reg, crtc_state->infoframes.gcp);
1004*4882a593Smuzhiyun
1005*4882a593Smuzhiyun return true;
1006*4882a593Smuzhiyun }
1007*4882a593Smuzhiyun
intel_hdmi_read_gcp_infoframe(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state)1008*4882a593Smuzhiyun void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
1009*4882a593Smuzhiyun struct intel_crtc_state *crtc_state)
1010*4882a593Smuzhiyun {
1011*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1012*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1013*4882a593Smuzhiyun i915_reg_t reg;
1014*4882a593Smuzhiyun
1015*4882a593Smuzhiyun if ((crtc_state->infoframes.enable &
1016*4882a593Smuzhiyun intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL)) == 0)
1017*4882a593Smuzhiyun return;
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun if (HAS_DDI(dev_priv))
1020*4882a593Smuzhiyun reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder);
1021*4882a593Smuzhiyun else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
1022*4882a593Smuzhiyun reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
1023*4882a593Smuzhiyun else if (HAS_PCH_SPLIT(dev_priv))
1024*4882a593Smuzhiyun reg = TVIDEO_DIP_GCP(crtc->pipe);
1025*4882a593Smuzhiyun else
1026*4882a593Smuzhiyun return;
1027*4882a593Smuzhiyun
1028*4882a593Smuzhiyun crtc_state->infoframes.gcp = intel_de_read(dev_priv, reg);
1029*4882a593Smuzhiyun }
1030*4882a593Smuzhiyun
intel_hdmi_compute_gcp_infoframe(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,struct drm_connector_state * conn_state)1031*4882a593Smuzhiyun static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder,
1032*4882a593Smuzhiyun struct intel_crtc_state *crtc_state,
1033*4882a593Smuzhiyun struct drm_connector_state *conn_state)
1034*4882a593Smuzhiyun {
1035*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun if (IS_G4X(dev_priv) || !crtc_state->has_infoframe)
1038*4882a593Smuzhiyun return;
1039*4882a593Smuzhiyun
1040*4882a593Smuzhiyun crtc_state->infoframes.enable |=
1041*4882a593Smuzhiyun intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GENERAL_CONTROL);
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun /* Indicate color indication for deep color mode */
1044*4882a593Smuzhiyun if (crtc_state->pipe_bpp > 24)
1045*4882a593Smuzhiyun crtc_state->infoframes.gcp |= GCP_COLOR_INDICATION;
1046*4882a593Smuzhiyun
1047*4882a593Smuzhiyun /* Enable default_phase whenever the display mode is suitably aligned */
1048*4882a593Smuzhiyun if (gcp_default_phase_possible(crtc_state->pipe_bpp,
1049*4882a593Smuzhiyun &crtc_state->hw.adjusted_mode))
1050*4882a593Smuzhiyun crtc_state->infoframes.gcp |= GCP_DEFAULT_PHASE_ENABLE;
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun
ibx_set_infoframes(struct intel_encoder * encoder,bool enable,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)1053*4882a593Smuzhiyun static void ibx_set_infoframes(struct intel_encoder *encoder,
1054*4882a593Smuzhiyun bool enable,
1055*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
1056*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
1057*4882a593Smuzhiyun {
1058*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1059*4882a593Smuzhiyun struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
1060*4882a593Smuzhiyun struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
1061*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
1062*4882a593Smuzhiyun i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
1063*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
1064*4882a593Smuzhiyun u32 port = VIDEO_DIP_PORT(encoder->port);
1065*4882a593Smuzhiyun
1066*4882a593Smuzhiyun assert_hdmi_port_disabled(intel_hdmi);
1067*4882a593Smuzhiyun
1068*4882a593Smuzhiyun /* See the big comment in g4x_set_infoframes() */
1069*4882a593Smuzhiyun val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
1070*4882a593Smuzhiyun
1071*4882a593Smuzhiyun if (!enable) {
1072*4882a593Smuzhiyun if (!(val & VIDEO_DIP_ENABLE))
1073*4882a593Smuzhiyun return;
1074*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
1075*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
1076*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
1077*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
1078*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
1079*4882a593Smuzhiyun return;
1080*4882a593Smuzhiyun }
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun if (port != (val & VIDEO_DIP_PORT_MASK)) {
1083*4882a593Smuzhiyun drm_WARN(&dev_priv->drm, val & VIDEO_DIP_ENABLE,
1084*4882a593Smuzhiyun "DIP already enabled on port %c\n",
1085*4882a593Smuzhiyun (val & VIDEO_DIP_PORT_MASK) >> 29);
1086*4882a593Smuzhiyun val &= ~VIDEO_DIP_PORT_MASK;
1087*4882a593Smuzhiyun val |= port;
1088*4882a593Smuzhiyun }
1089*4882a593Smuzhiyun
1090*4882a593Smuzhiyun val |= VIDEO_DIP_ENABLE;
1091*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE_AVI |
1092*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
1093*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
1094*4882a593Smuzhiyun
1095*4882a593Smuzhiyun if (intel_hdmi_set_gcp_infoframe(encoder, crtc_state, conn_state))
1096*4882a593Smuzhiyun val |= VIDEO_DIP_ENABLE_GCP;
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
1099*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
1100*4882a593Smuzhiyun
1101*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1102*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_AVI,
1103*4882a593Smuzhiyun &crtc_state->infoframes.avi);
1104*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1105*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_SPD,
1106*4882a593Smuzhiyun &crtc_state->infoframes.spd);
1107*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1108*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_VENDOR,
1109*4882a593Smuzhiyun &crtc_state->infoframes.hdmi);
1110*4882a593Smuzhiyun }
1111*4882a593Smuzhiyun
cpt_set_infoframes(struct intel_encoder * encoder,bool enable,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)1112*4882a593Smuzhiyun static void cpt_set_infoframes(struct intel_encoder *encoder,
1113*4882a593Smuzhiyun bool enable,
1114*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
1115*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
1116*4882a593Smuzhiyun {
1117*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1118*4882a593Smuzhiyun struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
1119*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1120*4882a593Smuzhiyun i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
1121*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
1122*4882a593Smuzhiyun
1123*4882a593Smuzhiyun assert_hdmi_port_disabled(intel_hdmi);
1124*4882a593Smuzhiyun
1125*4882a593Smuzhiyun /* See the big comment in g4x_set_infoframes() */
1126*4882a593Smuzhiyun val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
1127*4882a593Smuzhiyun
1128*4882a593Smuzhiyun if (!enable) {
1129*4882a593Smuzhiyun if (!(val & VIDEO_DIP_ENABLE))
1130*4882a593Smuzhiyun return;
1131*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
1132*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
1133*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
1134*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
1135*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
1136*4882a593Smuzhiyun return;
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun /* Set both together, unset both together: see the spec. */
1140*4882a593Smuzhiyun val |= VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI;
1141*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
1142*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
1143*4882a593Smuzhiyun
1144*4882a593Smuzhiyun if (intel_hdmi_set_gcp_infoframe(encoder, crtc_state, conn_state))
1145*4882a593Smuzhiyun val |= VIDEO_DIP_ENABLE_GCP;
1146*4882a593Smuzhiyun
1147*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
1148*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
1149*4882a593Smuzhiyun
1150*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1151*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_AVI,
1152*4882a593Smuzhiyun &crtc_state->infoframes.avi);
1153*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1154*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_SPD,
1155*4882a593Smuzhiyun &crtc_state->infoframes.spd);
1156*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1157*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_VENDOR,
1158*4882a593Smuzhiyun &crtc_state->infoframes.hdmi);
1159*4882a593Smuzhiyun }
1160*4882a593Smuzhiyun
vlv_set_infoframes(struct intel_encoder * encoder,bool enable,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)1161*4882a593Smuzhiyun static void vlv_set_infoframes(struct intel_encoder *encoder,
1162*4882a593Smuzhiyun bool enable,
1163*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
1164*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
1165*4882a593Smuzhiyun {
1166*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1167*4882a593Smuzhiyun struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
1168*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1169*4882a593Smuzhiyun i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
1170*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
1171*4882a593Smuzhiyun u32 port = VIDEO_DIP_PORT(encoder->port);
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun assert_hdmi_port_disabled(intel_hdmi);
1174*4882a593Smuzhiyun
1175*4882a593Smuzhiyun /* See the big comment in g4x_set_infoframes() */
1176*4882a593Smuzhiyun val |= VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC;
1177*4882a593Smuzhiyun
1178*4882a593Smuzhiyun if (!enable) {
1179*4882a593Smuzhiyun if (!(val & VIDEO_DIP_ENABLE))
1180*4882a593Smuzhiyun return;
1181*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE | VIDEO_DIP_ENABLE_AVI |
1182*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
1183*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
1184*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
1185*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
1186*4882a593Smuzhiyun return;
1187*4882a593Smuzhiyun }
1188*4882a593Smuzhiyun
1189*4882a593Smuzhiyun if (port != (val & VIDEO_DIP_PORT_MASK)) {
1190*4882a593Smuzhiyun drm_WARN(&dev_priv->drm, val & VIDEO_DIP_ENABLE,
1191*4882a593Smuzhiyun "DIP already enabled on port %c\n",
1192*4882a593Smuzhiyun (val & VIDEO_DIP_PORT_MASK) >> 29);
1193*4882a593Smuzhiyun val &= ~VIDEO_DIP_PORT_MASK;
1194*4882a593Smuzhiyun val |= port;
1195*4882a593Smuzhiyun }
1196*4882a593Smuzhiyun
1197*4882a593Smuzhiyun val |= VIDEO_DIP_ENABLE;
1198*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE_AVI |
1199*4882a593Smuzhiyun VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
1200*4882a593Smuzhiyun VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_ENABLE_GCP);
1201*4882a593Smuzhiyun
1202*4882a593Smuzhiyun if (intel_hdmi_set_gcp_infoframe(encoder, crtc_state, conn_state))
1203*4882a593Smuzhiyun val |= VIDEO_DIP_ENABLE_GCP;
1204*4882a593Smuzhiyun
1205*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
1206*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
1207*4882a593Smuzhiyun
1208*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1209*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_AVI,
1210*4882a593Smuzhiyun &crtc_state->infoframes.avi);
1211*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1212*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_SPD,
1213*4882a593Smuzhiyun &crtc_state->infoframes.spd);
1214*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1215*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_VENDOR,
1216*4882a593Smuzhiyun &crtc_state->infoframes.hdmi);
1217*4882a593Smuzhiyun }
1218*4882a593Smuzhiyun
hsw_set_infoframes(struct intel_encoder * encoder,bool enable,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)1219*4882a593Smuzhiyun static void hsw_set_infoframes(struct intel_encoder *encoder,
1220*4882a593Smuzhiyun bool enable,
1221*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
1222*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
1223*4882a593Smuzhiyun {
1224*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1225*4882a593Smuzhiyun i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
1226*4882a593Smuzhiyun u32 val = intel_de_read(dev_priv, reg);
1227*4882a593Smuzhiyun
1228*4882a593Smuzhiyun assert_hdmi_transcoder_func_disabled(dev_priv,
1229*4882a593Smuzhiyun crtc_state->cpu_transcoder);
1230*4882a593Smuzhiyun
1231*4882a593Smuzhiyun val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_AVI_HSW |
1232*4882a593Smuzhiyun VIDEO_DIP_ENABLE_GCP_HSW | VIDEO_DIP_ENABLE_VS_HSW |
1233*4882a593Smuzhiyun VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW |
1234*4882a593Smuzhiyun VIDEO_DIP_ENABLE_DRM_GLK);
1235*4882a593Smuzhiyun
1236*4882a593Smuzhiyun if (!enable) {
1237*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
1238*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
1239*4882a593Smuzhiyun return;
1240*4882a593Smuzhiyun }
1241*4882a593Smuzhiyun
1242*4882a593Smuzhiyun if (intel_hdmi_set_gcp_infoframe(encoder, crtc_state, conn_state))
1243*4882a593Smuzhiyun val |= VIDEO_DIP_ENABLE_GCP_HSW;
1244*4882a593Smuzhiyun
1245*4882a593Smuzhiyun intel_de_write(dev_priv, reg, val);
1246*4882a593Smuzhiyun intel_de_posting_read(dev_priv, reg);
1247*4882a593Smuzhiyun
1248*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1249*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_AVI,
1250*4882a593Smuzhiyun &crtc_state->infoframes.avi);
1251*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1252*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_SPD,
1253*4882a593Smuzhiyun &crtc_state->infoframes.spd);
1254*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1255*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_VENDOR,
1256*4882a593Smuzhiyun &crtc_state->infoframes.hdmi);
1257*4882a593Smuzhiyun intel_write_infoframe(encoder, crtc_state,
1258*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_DRM,
1259*4882a593Smuzhiyun &crtc_state->infoframes.drm);
1260*4882a593Smuzhiyun }
1261*4882a593Smuzhiyun
intel_dp_dual_mode_set_tmds_output(struct intel_hdmi * hdmi,bool enable)1262*4882a593Smuzhiyun void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
1263*4882a593Smuzhiyun {
1264*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
1265*4882a593Smuzhiyun struct i2c_adapter *adapter =
1266*4882a593Smuzhiyun intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
1267*4882a593Smuzhiyun
1268*4882a593Smuzhiyun if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
1269*4882a593Smuzhiyun return;
1270*4882a593Smuzhiyun
1271*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n",
1272*4882a593Smuzhiyun enable ? "Enabling" : "Disabling");
1273*4882a593Smuzhiyun
1274*4882a593Smuzhiyun drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
1275*4882a593Smuzhiyun adapter, enable);
1276*4882a593Smuzhiyun }
1277*4882a593Smuzhiyun
intel_hdmi_hdcp_read(struct intel_digital_port * dig_port,unsigned int offset,void * buffer,size_t size)1278*4882a593Smuzhiyun static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port,
1279*4882a593Smuzhiyun unsigned int offset, void *buffer, size_t size)
1280*4882a593Smuzhiyun {
1281*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1282*4882a593Smuzhiyun struct intel_hdmi *hdmi = &dig_port->hdmi;
1283*4882a593Smuzhiyun struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915,
1284*4882a593Smuzhiyun hdmi->ddc_bus);
1285*4882a593Smuzhiyun int ret;
1286*4882a593Smuzhiyun u8 start = offset & 0xff;
1287*4882a593Smuzhiyun struct i2c_msg msgs[] = {
1288*4882a593Smuzhiyun {
1289*4882a593Smuzhiyun .addr = DRM_HDCP_DDC_ADDR,
1290*4882a593Smuzhiyun .flags = 0,
1291*4882a593Smuzhiyun .len = 1,
1292*4882a593Smuzhiyun .buf = &start,
1293*4882a593Smuzhiyun },
1294*4882a593Smuzhiyun {
1295*4882a593Smuzhiyun .addr = DRM_HDCP_DDC_ADDR,
1296*4882a593Smuzhiyun .flags = I2C_M_RD,
1297*4882a593Smuzhiyun .len = size,
1298*4882a593Smuzhiyun .buf = buffer
1299*4882a593Smuzhiyun }
1300*4882a593Smuzhiyun };
1301*4882a593Smuzhiyun ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
1302*4882a593Smuzhiyun if (ret == ARRAY_SIZE(msgs))
1303*4882a593Smuzhiyun return 0;
1304*4882a593Smuzhiyun return ret >= 0 ? -EIO : ret;
1305*4882a593Smuzhiyun }
1306*4882a593Smuzhiyun
intel_hdmi_hdcp_write(struct intel_digital_port * dig_port,unsigned int offset,void * buffer,size_t size)1307*4882a593Smuzhiyun static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port,
1308*4882a593Smuzhiyun unsigned int offset, void *buffer, size_t size)
1309*4882a593Smuzhiyun {
1310*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1311*4882a593Smuzhiyun struct intel_hdmi *hdmi = &dig_port->hdmi;
1312*4882a593Smuzhiyun struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915,
1313*4882a593Smuzhiyun hdmi->ddc_bus);
1314*4882a593Smuzhiyun int ret;
1315*4882a593Smuzhiyun u8 *write_buf;
1316*4882a593Smuzhiyun struct i2c_msg msg;
1317*4882a593Smuzhiyun
1318*4882a593Smuzhiyun write_buf = kzalloc(size + 1, GFP_KERNEL);
1319*4882a593Smuzhiyun if (!write_buf)
1320*4882a593Smuzhiyun return -ENOMEM;
1321*4882a593Smuzhiyun
1322*4882a593Smuzhiyun write_buf[0] = offset & 0xff;
1323*4882a593Smuzhiyun memcpy(&write_buf[1], buffer, size);
1324*4882a593Smuzhiyun
1325*4882a593Smuzhiyun msg.addr = DRM_HDCP_DDC_ADDR;
1326*4882a593Smuzhiyun msg.flags = 0,
1327*4882a593Smuzhiyun msg.len = size + 1,
1328*4882a593Smuzhiyun msg.buf = write_buf;
1329*4882a593Smuzhiyun
1330*4882a593Smuzhiyun ret = i2c_transfer(adapter, &msg, 1);
1331*4882a593Smuzhiyun if (ret == 1)
1332*4882a593Smuzhiyun ret = 0;
1333*4882a593Smuzhiyun else if (ret >= 0)
1334*4882a593Smuzhiyun ret = -EIO;
1335*4882a593Smuzhiyun
1336*4882a593Smuzhiyun kfree(write_buf);
1337*4882a593Smuzhiyun return ret;
1338*4882a593Smuzhiyun }
1339*4882a593Smuzhiyun
1340*4882a593Smuzhiyun static
intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port * dig_port,u8 * an)1341*4882a593Smuzhiyun int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
1342*4882a593Smuzhiyun u8 *an)
1343*4882a593Smuzhiyun {
1344*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1345*4882a593Smuzhiyun struct intel_hdmi *hdmi = &dig_port->hdmi;
1346*4882a593Smuzhiyun struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915,
1347*4882a593Smuzhiyun hdmi->ddc_bus);
1348*4882a593Smuzhiyun int ret;
1349*4882a593Smuzhiyun
1350*4882a593Smuzhiyun ret = intel_hdmi_hdcp_write(dig_port, DRM_HDCP_DDC_AN, an,
1351*4882a593Smuzhiyun DRM_HDCP_AN_LEN);
1352*4882a593Smuzhiyun if (ret) {
1353*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Write An over DDC failed (%d)\n",
1354*4882a593Smuzhiyun ret);
1355*4882a593Smuzhiyun return ret;
1356*4882a593Smuzhiyun }
1357*4882a593Smuzhiyun
1358*4882a593Smuzhiyun ret = intel_gmbus_output_aksv(adapter);
1359*4882a593Smuzhiyun if (ret < 0) {
1360*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Failed to output aksv (%d)\n", ret);
1361*4882a593Smuzhiyun return ret;
1362*4882a593Smuzhiyun }
1363*4882a593Smuzhiyun return 0;
1364*4882a593Smuzhiyun }
1365*4882a593Smuzhiyun
intel_hdmi_hdcp_read_bksv(struct intel_digital_port * dig_port,u8 * bksv)1366*4882a593Smuzhiyun static int intel_hdmi_hdcp_read_bksv(struct intel_digital_port *dig_port,
1367*4882a593Smuzhiyun u8 *bksv)
1368*4882a593Smuzhiyun {
1369*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1370*4882a593Smuzhiyun
1371*4882a593Smuzhiyun int ret;
1372*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_BKSV, bksv,
1373*4882a593Smuzhiyun DRM_HDCP_KSV_LEN);
1374*4882a593Smuzhiyun if (ret)
1375*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Read Bksv over DDC failed (%d)\n",
1376*4882a593Smuzhiyun ret);
1377*4882a593Smuzhiyun return ret;
1378*4882a593Smuzhiyun }
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun static
intel_hdmi_hdcp_read_bstatus(struct intel_digital_port * dig_port,u8 * bstatus)1381*4882a593Smuzhiyun int intel_hdmi_hdcp_read_bstatus(struct intel_digital_port *dig_port,
1382*4882a593Smuzhiyun u8 *bstatus)
1383*4882a593Smuzhiyun {
1384*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1385*4882a593Smuzhiyun
1386*4882a593Smuzhiyun int ret;
1387*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_BSTATUS,
1388*4882a593Smuzhiyun bstatus, DRM_HDCP_BSTATUS_LEN);
1389*4882a593Smuzhiyun if (ret)
1390*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Read bstatus over DDC failed (%d)\n",
1391*4882a593Smuzhiyun ret);
1392*4882a593Smuzhiyun return ret;
1393*4882a593Smuzhiyun }
1394*4882a593Smuzhiyun
1395*4882a593Smuzhiyun static
intel_hdmi_hdcp_repeater_present(struct intel_digital_port * dig_port,bool * repeater_present)1396*4882a593Smuzhiyun int intel_hdmi_hdcp_repeater_present(struct intel_digital_port *dig_port,
1397*4882a593Smuzhiyun bool *repeater_present)
1398*4882a593Smuzhiyun {
1399*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1400*4882a593Smuzhiyun int ret;
1401*4882a593Smuzhiyun u8 val;
1402*4882a593Smuzhiyun
1403*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_BCAPS, &val, 1);
1404*4882a593Smuzhiyun if (ret) {
1405*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Read bcaps over DDC failed (%d)\n",
1406*4882a593Smuzhiyun ret);
1407*4882a593Smuzhiyun return ret;
1408*4882a593Smuzhiyun }
1409*4882a593Smuzhiyun *repeater_present = val & DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT;
1410*4882a593Smuzhiyun return 0;
1411*4882a593Smuzhiyun }
1412*4882a593Smuzhiyun
1413*4882a593Smuzhiyun static
intel_hdmi_hdcp_read_ri_prime(struct intel_digital_port * dig_port,u8 * ri_prime)1414*4882a593Smuzhiyun int intel_hdmi_hdcp_read_ri_prime(struct intel_digital_port *dig_port,
1415*4882a593Smuzhiyun u8 *ri_prime)
1416*4882a593Smuzhiyun {
1417*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1418*4882a593Smuzhiyun
1419*4882a593Smuzhiyun int ret;
1420*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_RI_PRIME,
1421*4882a593Smuzhiyun ri_prime, DRM_HDCP_RI_LEN);
1422*4882a593Smuzhiyun if (ret)
1423*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Read Ri' over DDC failed (%d)\n",
1424*4882a593Smuzhiyun ret);
1425*4882a593Smuzhiyun return ret;
1426*4882a593Smuzhiyun }
1427*4882a593Smuzhiyun
1428*4882a593Smuzhiyun static
intel_hdmi_hdcp_read_ksv_ready(struct intel_digital_port * dig_port,bool * ksv_ready)1429*4882a593Smuzhiyun int intel_hdmi_hdcp_read_ksv_ready(struct intel_digital_port *dig_port,
1430*4882a593Smuzhiyun bool *ksv_ready)
1431*4882a593Smuzhiyun {
1432*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1433*4882a593Smuzhiyun int ret;
1434*4882a593Smuzhiyun u8 val;
1435*4882a593Smuzhiyun
1436*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_BCAPS, &val, 1);
1437*4882a593Smuzhiyun if (ret) {
1438*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Read bcaps over DDC failed (%d)\n",
1439*4882a593Smuzhiyun ret);
1440*4882a593Smuzhiyun return ret;
1441*4882a593Smuzhiyun }
1442*4882a593Smuzhiyun *ksv_ready = val & DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY;
1443*4882a593Smuzhiyun return 0;
1444*4882a593Smuzhiyun }
1445*4882a593Smuzhiyun
1446*4882a593Smuzhiyun static
intel_hdmi_hdcp_read_ksv_fifo(struct intel_digital_port * dig_port,int num_downstream,u8 * ksv_fifo)1447*4882a593Smuzhiyun int intel_hdmi_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port,
1448*4882a593Smuzhiyun int num_downstream, u8 *ksv_fifo)
1449*4882a593Smuzhiyun {
1450*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1451*4882a593Smuzhiyun int ret;
1452*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_KSV_FIFO,
1453*4882a593Smuzhiyun ksv_fifo, num_downstream * DRM_HDCP_KSV_LEN);
1454*4882a593Smuzhiyun if (ret) {
1455*4882a593Smuzhiyun drm_dbg_kms(&i915->drm,
1456*4882a593Smuzhiyun "Read ksv fifo over DDC failed (%d)\n", ret);
1457*4882a593Smuzhiyun return ret;
1458*4882a593Smuzhiyun }
1459*4882a593Smuzhiyun return 0;
1460*4882a593Smuzhiyun }
1461*4882a593Smuzhiyun
1462*4882a593Smuzhiyun static
intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port * dig_port,int i,u32 * part)1463*4882a593Smuzhiyun int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *dig_port,
1464*4882a593Smuzhiyun int i, u32 *part)
1465*4882a593Smuzhiyun {
1466*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1467*4882a593Smuzhiyun int ret;
1468*4882a593Smuzhiyun
1469*4882a593Smuzhiyun if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
1470*4882a593Smuzhiyun return -EINVAL;
1471*4882a593Smuzhiyun
1472*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, DRM_HDCP_DDC_V_PRIME(i),
1473*4882a593Smuzhiyun part, DRM_HDCP_V_PRIME_PART_LEN);
1474*4882a593Smuzhiyun if (ret)
1475*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Read V'[%d] over DDC failed (%d)\n",
1476*4882a593Smuzhiyun i, ret);
1477*4882a593Smuzhiyun return ret;
1478*4882a593Smuzhiyun }
1479*4882a593Smuzhiyun
kbl_repositioning_enc_en_signal(struct intel_connector * connector,enum transcoder cpu_transcoder)1480*4882a593Smuzhiyun static int kbl_repositioning_enc_en_signal(struct intel_connector *connector,
1481*4882a593Smuzhiyun enum transcoder cpu_transcoder)
1482*4882a593Smuzhiyun {
1483*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1484*4882a593Smuzhiyun struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
1485*4882a593Smuzhiyun struct drm_crtc *crtc = connector->base.state->crtc;
1486*4882a593Smuzhiyun struct intel_crtc *intel_crtc = container_of(crtc,
1487*4882a593Smuzhiyun struct intel_crtc, base);
1488*4882a593Smuzhiyun u32 scanline;
1489*4882a593Smuzhiyun int ret;
1490*4882a593Smuzhiyun
1491*4882a593Smuzhiyun for (;;) {
1492*4882a593Smuzhiyun scanline = intel_de_read(dev_priv, PIPEDSL(intel_crtc->pipe));
1493*4882a593Smuzhiyun if (scanline > 100 && scanline < 200)
1494*4882a593Smuzhiyun break;
1495*4882a593Smuzhiyun usleep_range(25, 50);
1496*4882a593Smuzhiyun }
1497*4882a593Smuzhiyun
1498*4882a593Smuzhiyun ret = intel_ddi_toggle_hdcp_signalling(&dig_port->base, cpu_transcoder,
1499*4882a593Smuzhiyun false);
1500*4882a593Smuzhiyun if (ret) {
1501*4882a593Smuzhiyun drm_err(&dev_priv->drm,
1502*4882a593Smuzhiyun "Disable HDCP signalling failed (%d)\n", ret);
1503*4882a593Smuzhiyun return ret;
1504*4882a593Smuzhiyun }
1505*4882a593Smuzhiyun ret = intel_ddi_toggle_hdcp_signalling(&dig_port->base, cpu_transcoder,
1506*4882a593Smuzhiyun true);
1507*4882a593Smuzhiyun if (ret) {
1508*4882a593Smuzhiyun drm_err(&dev_priv->drm,
1509*4882a593Smuzhiyun "Enable HDCP signalling failed (%d)\n", ret);
1510*4882a593Smuzhiyun return ret;
1511*4882a593Smuzhiyun }
1512*4882a593Smuzhiyun
1513*4882a593Smuzhiyun return 0;
1514*4882a593Smuzhiyun }
1515*4882a593Smuzhiyun
1516*4882a593Smuzhiyun static
intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port * dig_port,enum transcoder cpu_transcoder,bool enable)1517*4882a593Smuzhiyun int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *dig_port,
1518*4882a593Smuzhiyun enum transcoder cpu_transcoder,
1519*4882a593Smuzhiyun bool enable)
1520*4882a593Smuzhiyun {
1521*4882a593Smuzhiyun struct intel_hdmi *hdmi = &dig_port->hdmi;
1522*4882a593Smuzhiyun struct intel_connector *connector = hdmi->attached_connector;
1523*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1524*4882a593Smuzhiyun int ret;
1525*4882a593Smuzhiyun
1526*4882a593Smuzhiyun if (!enable)
1527*4882a593Smuzhiyun usleep_range(6, 60); /* Bspec says >= 6us */
1528*4882a593Smuzhiyun
1529*4882a593Smuzhiyun ret = intel_ddi_toggle_hdcp_signalling(&dig_port->base, cpu_transcoder,
1530*4882a593Smuzhiyun enable);
1531*4882a593Smuzhiyun if (ret) {
1532*4882a593Smuzhiyun drm_err(&dev_priv->drm, "%s HDCP signalling failed (%d)\n",
1533*4882a593Smuzhiyun enable ? "Enable" : "Disable", ret);
1534*4882a593Smuzhiyun return ret;
1535*4882a593Smuzhiyun }
1536*4882a593Smuzhiyun
1537*4882a593Smuzhiyun /*
1538*4882a593Smuzhiyun * WA: To fix incorrect positioning of the window of
1539*4882a593Smuzhiyun * opportunity and enc_en signalling in KABYLAKE.
1540*4882a593Smuzhiyun */
1541*4882a593Smuzhiyun if (IS_KABYLAKE(dev_priv) && enable)
1542*4882a593Smuzhiyun return kbl_repositioning_enc_en_signal(connector,
1543*4882a593Smuzhiyun cpu_transcoder);
1544*4882a593Smuzhiyun
1545*4882a593Smuzhiyun return 0;
1546*4882a593Smuzhiyun }
1547*4882a593Smuzhiyun
1548*4882a593Smuzhiyun static
intel_hdmi_hdcp_check_link_once(struct intel_digital_port * dig_port,struct intel_connector * connector)1549*4882a593Smuzhiyun bool intel_hdmi_hdcp_check_link_once(struct intel_digital_port *dig_port,
1550*4882a593Smuzhiyun struct intel_connector *connector)
1551*4882a593Smuzhiyun {
1552*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1553*4882a593Smuzhiyun enum port port = dig_port->base.port;
1554*4882a593Smuzhiyun enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
1555*4882a593Smuzhiyun int ret;
1556*4882a593Smuzhiyun union {
1557*4882a593Smuzhiyun u32 reg;
1558*4882a593Smuzhiyun u8 shim[DRM_HDCP_RI_LEN];
1559*4882a593Smuzhiyun } ri;
1560*4882a593Smuzhiyun
1561*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read_ri_prime(dig_port, ri.shim);
1562*4882a593Smuzhiyun if (ret)
1563*4882a593Smuzhiyun return false;
1564*4882a593Smuzhiyun
1565*4882a593Smuzhiyun intel_de_write(i915, HDCP_RPRIME(i915, cpu_transcoder, port), ri.reg);
1566*4882a593Smuzhiyun
1567*4882a593Smuzhiyun /* Wait for Ri prime match */
1568*4882a593Smuzhiyun if (wait_for((intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
1569*4882a593Smuzhiyun (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC)) ==
1570*4882a593Smuzhiyun (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
1571*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Ri' mismatch detected (%x)\n",
1572*4882a593Smuzhiyun intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder,
1573*4882a593Smuzhiyun port)));
1574*4882a593Smuzhiyun return false;
1575*4882a593Smuzhiyun }
1576*4882a593Smuzhiyun return true;
1577*4882a593Smuzhiyun }
1578*4882a593Smuzhiyun
1579*4882a593Smuzhiyun static
intel_hdmi_hdcp_check_link(struct intel_digital_port * dig_port,struct intel_connector * connector)1580*4882a593Smuzhiyun bool intel_hdmi_hdcp_check_link(struct intel_digital_port *dig_port,
1581*4882a593Smuzhiyun struct intel_connector *connector)
1582*4882a593Smuzhiyun {
1583*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1584*4882a593Smuzhiyun int retry;
1585*4882a593Smuzhiyun
1586*4882a593Smuzhiyun for (retry = 0; retry < 3; retry++)
1587*4882a593Smuzhiyun if (intel_hdmi_hdcp_check_link_once(dig_port, connector))
1588*4882a593Smuzhiyun return true;
1589*4882a593Smuzhiyun
1590*4882a593Smuzhiyun drm_err(&i915->drm, "Link check failed\n");
1591*4882a593Smuzhiyun return false;
1592*4882a593Smuzhiyun }
1593*4882a593Smuzhiyun
1594*4882a593Smuzhiyun struct hdcp2_hdmi_msg_timeout {
1595*4882a593Smuzhiyun u8 msg_id;
1596*4882a593Smuzhiyun u16 timeout;
1597*4882a593Smuzhiyun };
1598*4882a593Smuzhiyun
1599*4882a593Smuzhiyun static const struct hdcp2_hdmi_msg_timeout hdcp2_msg_timeout[] = {
1600*4882a593Smuzhiyun { HDCP_2_2_AKE_SEND_CERT, HDCP_2_2_CERT_TIMEOUT_MS, },
1601*4882a593Smuzhiyun { HDCP_2_2_AKE_SEND_PAIRING_INFO, HDCP_2_2_PAIRING_TIMEOUT_MS, },
1602*4882a593Smuzhiyun { HDCP_2_2_LC_SEND_LPRIME, HDCP_2_2_HDMI_LPRIME_TIMEOUT_MS, },
1603*4882a593Smuzhiyun { HDCP_2_2_REP_SEND_RECVID_LIST, HDCP_2_2_RECVID_LIST_TIMEOUT_MS, },
1604*4882a593Smuzhiyun { HDCP_2_2_REP_STREAM_READY, HDCP_2_2_STREAM_READY_TIMEOUT_MS, },
1605*4882a593Smuzhiyun };
1606*4882a593Smuzhiyun
1607*4882a593Smuzhiyun static
intel_hdmi_hdcp2_read_rx_status(struct intel_digital_port * dig_port,u8 * rx_status)1608*4882a593Smuzhiyun int intel_hdmi_hdcp2_read_rx_status(struct intel_digital_port *dig_port,
1609*4882a593Smuzhiyun u8 *rx_status)
1610*4882a593Smuzhiyun {
1611*4882a593Smuzhiyun return intel_hdmi_hdcp_read(dig_port,
1612*4882a593Smuzhiyun HDCP_2_2_HDMI_REG_RXSTATUS_OFFSET,
1613*4882a593Smuzhiyun rx_status,
1614*4882a593Smuzhiyun HDCP_2_2_HDMI_RXSTATUS_LEN);
1615*4882a593Smuzhiyun }
1616*4882a593Smuzhiyun
get_hdcp2_msg_timeout(u8 msg_id,bool is_paired)1617*4882a593Smuzhiyun static int get_hdcp2_msg_timeout(u8 msg_id, bool is_paired)
1618*4882a593Smuzhiyun {
1619*4882a593Smuzhiyun int i;
1620*4882a593Smuzhiyun
1621*4882a593Smuzhiyun if (msg_id == HDCP_2_2_AKE_SEND_HPRIME) {
1622*4882a593Smuzhiyun if (is_paired)
1623*4882a593Smuzhiyun return HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS;
1624*4882a593Smuzhiyun else
1625*4882a593Smuzhiyun return HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS;
1626*4882a593Smuzhiyun }
1627*4882a593Smuzhiyun
1628*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(hdcp2_msg_timeout); i++) {
1629*4882a593Smuzhiyun if (hdcp2_msg_timeout[i].msg_id == msg_id)
1630*4882a593Smuzhiyun return hdcp2_msg_timeout[i].timeout;
1631*4882a593Smuzhiyun }
1632*4882a593Smuzhiyun
1633*4882a593Smuzhiyun return -EINVAL;
1634*4882a593Smuzhiyun }
1635*4882a593Smuzhiyun
1636*4882a593Smuzhiyun static int
hdcp2_detect_msg_availability(struct intel_digital_port * dig_port,u8 msg_id,bool * msg_ready,ssize_t * msg_sz)1637*4882a593Smuzhiyun hdcp2_detect_msg_availability(struct intel_digital_port *dig_port,
1638*4882a593Smuzhiyun u8 msg_id, bool *msg_ready,
1639*4882a593Smuzhiyun ssize_t *msg_sz)
1640*4882a593Smuzhiyun {
1641*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1642*4882a593Smuzhiyun u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN];
1643*4882a593Smuzhiyun int ret;
1644*4882a593Smuzhiyun
1645*4882a593Smuzhiyun ret = intel_hdmi_hdcp2_read_rx_status(dig_port, rx_status);
1646*4882a593Smuzhiyun if (ret < 0) {
1647*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "rx_status read failed. Err %d\n",
1648*4882a593Smuzhiyun ret);
1649*4882a593Smuzhiyun return ret;
1650*4882a593Smuzhiyun }
1651*4882a593Smuzhiyun
1652*4882a593Smuzhiyun *msg_sz = ((HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(rx_status[1]) << 8) |
1653*4882a593Smuzhiyun rx_status[0]);
1654*4882a593Smuzhiyun
1655*4882a593Smuzhiyun if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST)
1656*4882a593Smuzhiyun *msg_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(rx_status[1]) &&
1657*4882a593Smuzhiyun *msg_sz);
1658*4882a593Smuzhiyun else
1659*4882a593Smuzhiyun *msg_ready = *msg_sz;
1660*4882a593Smuzhiyun
1661*4882a593Smuzhiyun return 0;
1662*4882a593Smuzhiyun }
1663*4882a593Smuzhiyun
1664*4882a593Smuzhiyun static ssize_t
intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port * dig_port,u8 msg_id,bool paired)1665*4882a593Smuzhiyun intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *dig_port,
1666*4882a593Smuzhiyun u8 msg_id, bool paired)
1667*4882a593Smuzhiyun {
1668*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1669*4882a593Smuzhiyun bool msg_ready = false;
1670*4882a593Smuzhiyun int timeout, ret;
1671*4882a593Smuzhiyun ssize_t msg_sz = 0;
1672*4882a593Smuzhiyun
1673*4882a593Smuzhiyun timeout = get_hdcp2_msg_timeout(msg_id, paired);
1674*4882a593Smuzhiyun if (timeout < 0)
1675*4882a593Smuzhiyun return timeout;
1676*4882a593Smuzhiyun
1677*4882a593Smuzhiyun ret = __wait_for(ret = hdcp2_detect_msg_availability(dig_port,
1678*4882a593Smuzhiyun msg_id, &msg_ready,
1679*4882a593Smuzhiyun &msg_sz),
1680*4882a593Smuzhiyun !ret && msg_ready && msg_sz, timeout * 1000,
1681*4882a593Smuzhiyun 1000, 5 * 1000);
1682*4882a593Smuzhiyun if (ret)
1683*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "msg_id: %d, ret: %d, timeout: %d\n",
1684*4882a593Smuzhiyun msg_id, ret, timeout);
1685*4882a593Smuzhiyun
1686*4882a593Smuzhiyun return ret ? ret : msg_sz;
1687*4882a593Smuzhiyun }
1688*4882a593Smuzhiyun
1689*4882a593Smuzhiyun static
intel_hdmi_hdcp2_write_msg(struct intel_digital_port * dig_port,void * buf,size_t size)1690*4882a593Smuzhiyun int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *dig_port,
1691*4882a593Smuzhiyun void *buf, size_t size)
1692*4882a593Smuzhiyun {
1693*4882a593Smuzhiyun unsigned int offset;
1694*4882a593Smuzhiyun
1695*4882a593Smuzhiyun offset = HDCP_2_2_HDMI_REG_WR_MSG_OFFSET;
1696*4882a593Smuzhiyun return intel_hdmi_hdcp_write(dig_port, offset, buf, size);
1697*4882a593Smuzhiyun }
1698*4882a593Smuzhiyun
1699*4882a593Smuzhiyun static
intel_hdmi_hdcp2_read_msg(struct intel_digital_port * dig_port,u8 msg_id,void * buf,size_t size)1700*4882a593Smuzhiyun int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *dig_port,
1701*4882a593Smuzhiyun u8 msg_id, void *buf, size_t size)
1702*4882a593Smuzhiyun {
1703*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1704*4882a593Smuzhiyun struct intel_hdmi *hdmi = &dig_port->hdmi;
1705*4882a593Smuzhiyun struct intel_hdcp *hdcp = &hdmi->attached_connector->hdcp;
1706*4882a593Smuzhiyun unsigned int offset;
1707*4882a593Smuzhiyun ssize_t ret;
1708*4882a593Smuzhiyun
1709*4882a593Smuzhiyun ret = intel_hdmi_hdcp2_wait_for_msg(dig_port, msg_id,
1710*4882a593Smuzhiyun hdcp->is_paired);
1711*4882a593Smuzhiyun if (ret < 0)
1712*4882a593Smuzhiyun return ret;
1713*4882a593Smuzhiyun
1714*4882a593Smuzhiyun /*
1715*4882a593Smuzhiyun * Available msg size should be equal to or lesser than the
1716*4882a593Smuzhiyun * available buffer.
1717*4882a593Smuzhiyun */
1718*4882a593Smuzhiyun if (ret > size) {
1719*4882a593Smuzhiyun drm_dbg_kms(&i915->drm,
1720*4882a593Smuzhiyun "msg_sz(%zd) is more than exp size(%zu)\n",
1721*4882a593Smuzhiyun ret, size);
1722*4882a593Smuzhiyun return -1;
1723*4882a593Smuzhiyun }
1724*4882a593Smuzhiyun
1725*4882a593Smuzhiyun offset = HDCP_2_2_HDMI_REG_RD_MSG_OFFSET;
1726*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, offset, buf, ret);
1727*4882a593Smuzhiyun if (ret)
1728*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Failed to read msg_id: %d(%zd)\n",
1729*4882a593Smuzhiyun msg_id, ret);
1730*4882a593Smuzhiyun
1731*4882a593Smuzhiyun return ret;
1732*4882a593Smuzhiyun }
1733*4882a593Smuzhiyun
1734*4882a593Smuzhiyun static
intel_hdmi_hdcp2_check_link(struct intel_digital_port * dig_port)1735*4882a593Smuzhiyun int intel_hdmi_hdcp2_check_link(struct intel_digital_port *dig_port)
1736*4882a593Smuzhiyun {
1737*4882a593Smuzhiyun u8 rx_status[HDCP_2_2_HDMI_RXSTATUS_LEN];
1738*4882a593Smuzhiyun int ret;
1739*4882a593Smuzhiyun
1740*4882a593Smuzhiyun ret = intel_hdmi_hdcp2_read_rx_status(dig_port, rx_status);
1741*4882a593Smuzhiyun if (ret)
1742*4882a593Smuzhiyun return ret;
1743*4882a593Smuzhiyun
1744*4882a593Smuzhiyun /*
1745*4882a593Smuzhiyun * Re-auth request and Link Integrity Failures are represented by
1746*4882a593Smuzhiyun * same bit. i.e reauth_req.
1747*4882a593Smuzhiyun */
1748*4882a593Smuzhiyun if (HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(rx_status[1]))
1749*4882a593Smuzhiyun ret = HDCP_REAUTH_REQUEST;
1750*4882a593Smuzhiyun else if (HDCP_2_2_HDMI_RXSTATUS_READY(rx_status[1]))
1751*4882a593Smuzhiyun ret = HDCP_TOPOLOGY_CHANGE;
1752*4882a593Smuzhiyun
1753*4882a593Smuzhiyun return ret;
1754*4882a593Smuzhiyun }
1755*4882a593Smuzhiyun
1756*4882a593Smuzhiyun static
intel_hdmi_hdcp2_capable(struct intel_digital_port * dig_port,bool * capable)1757*4882a593Smuzhiyun int intel_hdmi_hdcp2_capable(struct intel_digital_port *dig_port,
1758*4882a593Smuzhiyun bool *capable)
1759*4882a593Smuzhiyun {
1760*4882a593Smuzhiyun u8 hdcp2_version;
1761*4882a593Smuzhiyun int ret;
1762*4882a593Smuzhiyun
1763*4882a593Smuzhiyun *capable = false;
1764*4882a593Smuzhiyun ret = intel_hdmi_hdcp_read(dig_port, HDCP_2_2_HDMI_REG_VER_OFFSET,
1765*4882a593Smuzhiyun &hdcp2_version, sizeof(hdcp2_version));
1766*4882a593Smuzhiyun if (!ret && hdcp2_version & HDCP_2_2_HDMI_SUPPORT_MASK)
1767*4882a593Smuzhiyun *capable = true;
1768*4882a593Smuzhiyun
1769*4882a593Smuzhiyun return ret;
1770*4882a593Smuzhiyun }
1771*4882a593Smuzhiyun
1772*4882a593Smuzhiyun static const struct intel_hdcp_shim intel_hdmi_hdcp_shim = {
1773*4882a593Smuzhiyun .write_an_aksv = intel_hdmi_hdcp_write_an_aksv,
1774*4882a593Smuzhiyun .read_bksv = intel_hdmi_hdcp_read_bksv,
1775*4882a593Smuzhiyun .read_bstatus = intel_hdmi_hdcp_read_bstatus,
1776*4882a593Smuzhiyun .repeater_present = intel_hdmi_hdcp_repeater_present,
1777*4882a593Smuzhiyun .read_ri_prime = intel_hdmi_hdcp_read_ri_prime,
1778*4882a593Smuzhiyun .read_ksv_ready = intel_hdmi_hdcp_read_ksv_ready,
1779*4882a593Smuzhiyun .read_ksv_fifo = intel_hdmi_hdcp_read_ksv_fifo,
1780*4882a593Smuzhiyun .read_v_prime_part = intel_hdmi_hdcp_read_v_prime_part,
1781*4882a593Smuzhiyun .toggle_signalling = intel_hdmi_hdcp_toggle_signalling,
1782*4882a593Smuzhiyun .check_link = intel_hdmi_hdcp_check_link,
1783*4882a593Smuzhiyun .write_2_2_msg = intel_hdmi_hdcp2_write_msg,
1784*4882a593Smuzhiyun .read_2_2_msg = intel_hdmi_hdcp2_read_msg,
1785*4882a593Smuzhiyun .check_2_2_link = intel_hdmi_hdcp2_check_link,
1786*4882a593Smuzhiyun .hdcp_2_2_capable = intel_hdmi_hdcp2_capable,
1787*4882a593Smuzhiyun .protocol = HDCP_PROTOCOL_HDMI,
1788*4882a593Smuzhiyun };
1789*4882a593Smuzhiyun
intel_hdmi_prepare(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)1790*4882a593Smuzhiyun static void intel_hdmi_prepare(struct intel_encoder *encoder,
1791*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state)
1792*4882a593Smuzhiyun {
1793*4882a593Smuzhiyun struct drm_device *dev = encoder->base.dev;
1794*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
1795*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1796*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1797*4882a593Smuzhiyun const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
1798*4882a593Smuzhiyun u32 hdmi_val;
1799*4882a593Smuzhiyun
1800*4882a593Smuzhiyun intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
1801*4882a593Smuzhiyun
1802*4882a593Smuzhiyun hdmi_val = SDVO_ENCODING_HDMI;
1803*4882a593Smuzhiyun if (!HAS_PCH_SPLIT(dev_priv) && crtc_state->limited_color_range)
1804*4882a593Smuzhiyun hdmi_val |= HDMI_COLOR_RANGE_16_235;
1805*4882a593Smuzhiyun if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
1806*4882a593Smuzhiyun hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH;
1807*4882a593Smuzhiyun if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
1808*4882a593Smuzhiyun hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
1809*4882a593Smuzhiyun
1810*4882a593Smuzhiyun if (crtc_state->pipe_bpp > 24)
1811*4882a593Smuzhiyun hdmi_val |= HDMI_COLOR_FORMAT_12bpc;
1812*4882a593Smuzhiyun else
1813*4882a593Smuzhiyun hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
1814*4882a593Smuzhiyun
1815*4882a593Smuzhiyun if (crtc_state->has_hdmi_sink)
1816*4882a593Smuzhiyun hdmi_val |= HDMI_MODE_SELECT_HDMI;
1817*4882a593Smuzhiyun
1818*4882a593Smuzhiyun if (HAS_PCH_CPT(dev_priv))
1819*4882a593Smuzhiyun hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);
1820*4882a593Smuzhiyun else if (IS_CHERRYVIEW(dev_priv))
1821*4882a593Smuzhiyun hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe);
1822*4882a593Smuzhiyun else
1823*4882a593Smuzhiyun hdmi_val |= SDVO_PIPE_SEL(crtc->pipe);
1824*4882a593Smuzhiyun
1825*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, hdmi_val);
1826*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
1827*4882a593Smuzhiyun }
1828*4882a593Smuzhiyun
intel_hdmi_get_hw_state(struct intel_encoder * encoder,enum pipe * pipe)1829*4882a593Smuzhiyun static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
1830*4882a593Smuzhiyun enum pipe *pipe)
1831*4882a593Smuzhiyun {
1832*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
1833*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1834*4882a593Smuzhiyun intel_wakeref_t wakeref;
1835*4882a593Smuzhiyun bool ret;
1836*4882a593Smuzhiyun
1837*4882a593Smuzhiyun wakeref = intel_display_power_get_if_enabled(dev_priv,
1838*4882a593Smuzhiyun encoder->power_domain);
1839*4882a593Smuzhiyun if (!wakeref)
1840*4882a593Smuzhiyun return false;
1841*4882a593Smuzhiyun
1842*4882a593Smuzhiyun ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe);
1843*4882a593Smuzhiyun
1844*4882a593Smuzhiyun intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
1845*4882a593Smuzhiyun
1846*4882a593Smuzhiyun return ret;
1847*4882a593Smuzhiyun }
1848*4882a593Smuzhiyun
intel_hdmi_get_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config)1849*4882a593Smuzhiyun static void intel_hdmi_get_config(struct intel_encoder *encoder,
1850*4882a593Smuzhiyun struct intel_crtc_state *pipe_config)
1851*4882a593Smuzhiyun {
1852*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1853*4882a593Smuzhiyun struct drm_device *dev = encoder->base.dev;
1854*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
1855*4882a593Smuzhiyun u32 tmp, flags = 0;
1856*4882a593Smuzhiyun int dotclock;
1857*4882a593Smuzhiyun
1858*4882a593Smuzhiyun pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
1859*4882a593Smuzhiyun
1860*4882a593Smuzhiyun tmp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
1861*4882a593Smuzhiyun
1862*4882a593Smuzhiyun if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
1863*4882a593Smuzhiyun flags |= DRM_MODE_FLAG_PHSYNC;
1864*4882a593Smuzhiyun else
1865*4882a593Smuzhiyun flags |= DRM_MODE_FLAG_NHSYNC;
1866*4882a593Smuzhiyun
1867*4882a593Smuzhiyun if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
1868*4882a593Smuzhiyun flags |= DRM_MODE_FLAG_PVSYNC;
1869*4882a593Smuzhiyun else
1870*4882a593Smuzhiyun flags |= DRM_MODE_FLAG_NVSYNC;
1871*4882a593Smuzhiyun
1872*4882a593Smuzhiyun if (tmp & HDMI_MODE_SELECT_HDMI)
1873*4882a593Smuzhiyun pipe_config->has_hdmi_sink = true;
1874*4882a593Smuzhiyun
1875*4882a593Smuzhiyun pipe_config->infoframes.enable |=
1876*4882a593Smuzhiyun intel_hdmi_infoframes_enabled(encoder, pipe_config);
1877*4882a593Smuzhiyun
1878*4882a593Smuzhiyun if (pipe_config->infoframes.enable)
1879*4882a593Smuzhiyun pipe_config->has_infoframe = true;
1880*4882a593Smuzhiyun
1881*4882a593Smuzhiyun if (tmp & HDMI_AUDIO_ENABLE)
1882*4882a593Smuzhiyun pipe_config->has_audio = true;
1883*4882a593Smuzhiyun
1884*4882a593Smuzhiyun if (!HAS_PCH_SPLIT(dev_priv) &&
1885*4882a593Smuzhiyun tmp & HDMI_COLOR_RANGE_16_235)
1886*4882a593Smuzhiyun pipe_config->limited_color_range = true;
1887*4882a593Smuzhiyun
1888*4882a593Smuzhiyun pipe_config->hw.adjusted_mode.flags |= flags;
1889*4882a593Smuzhiyun
1890*4882a593Smuzhiyun if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
1891*4882a593Smuzhiyun dotclock = pipe_config->port_clock * 2 / 3;
1892*4882a593Smuzhiyun else
1893*4882a593Smuzhiyun dotclock = pipe_config->port_clock;
1894*4882a593Smuzhiyun
1895*4882a593Smuzhiyun if (pipe_config->pixel_multiplier)
1896*4882a593Smuzhiyun dotclock /= pipe_config->pixel_multiplier;
1897*4882a593Smuzhiyun
1898*4882a593Smuzhiyun pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
1899*4882a593Smuzhiyun
1900*4882a593Smuzhiyun pipe_config->lane_count = 4;
1901*4882a593Smuzhiyun
1902*4882a593Smuzhiyun intel_hdmi_read_gcp_infoframe(encoder, pipe_config);
1903*4882a593Smuzhiyun
1904*4882a593Smuzhiyun intel_read_infoframe(encoder, pipe_config,
1905*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_AVI,
1906*4882a593Smuzhiyun &pipe_config->infoframes.avi);
1907*4882a593Smuzhiyun intel_read_infoframe(encoder, pipe_config,
1908*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_SPD,
1909*4882a593Smuzhiyun &pipe_config->infoframes.spd);
1910*4882a593Smuzhiyun intel_read_infoframe(encoder, pipe_config,
1911*4882a593Smuzhiyun HDMI_INFOFRAME_TYPE_VENDOR,
1912*4882a593Smuzhiyun &pipe_config->infoframes.hdmi);
1913*4882a593Smuzhiyun }
1914*4882a593Smuzhiyun
intel_enable_hdmi_audio(struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)1915*4882a593Smuzhiyun static void intel_enable_hdmi_audio(struct intel_encoder *encoder,
1916*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
1917*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
1918*4882a593Smuzhiyun {
1919*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1920*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
1921*4882a593Smuzhiyun
1922*4882a593Smuzhiyun drm_WARN_ON(&i915->drm, !pipe_config->has_hdmi_sink);
1923*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "Enabling HDMI audio on pipe %c\n",
1924*4882a593Smuzhiyun pipe_name(crtc->pipe));
1925*4882a593Smuzhiyun intel_audio_codec_enable(encoder, pipe_config, conn_state);
1926*4882a593Smuzhiyun }
1927*4882a593Smuzhiyun
g4x_enable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)1928*4882a593Smuzhiyun static void g4x_enable_hdmi(struct intel_atomic_state *state,
1929*4882a593Smuzhiyun struct intel_encoder *encoder,
1930*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
1931*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
1932*4882a593Smuzhiyun {
1933*4882a593Smuzhiyun struct drm_device *dev = encoder->base.dev;
1934*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
1935*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1936*4882a593Smuzhiyun u32 temp;
1937*4882a593Smuzhiyun
1938*4882a593Smuzhiyun temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
1939*4882a593Smuzhiyun
1940*4882a593Smuzhiyun temp |= SDVO_ENABLE;
1941*4882a593Smuzhiyun if (pipe_config->has_audio)
1942*4882a593Smuzhiyun temp |= HDMI_AUDIO_ENABLE;
1943*4882a593Smuzhiyun
1944*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
1945*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
1946*4882a593Smuzhiyun
1947*4882a593Smuzhiyun if (pipe_config->has_audio)
1948*4882a593Smuzhiyun intel_enable_hdmi_audio(encoder, pipe_config, conn_state);
1949*4882a593Smuzhiyun }
1950*4882a593Smuzhiyun
ibx_enable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)1951*4882a593Smuzhiyun static void ibx_enable_hdmi(struct intel_atomic_state *state,
1952*4882a593Smuzhiyun struct intel_encoder *encoder,
1953*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
1954*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
1955*4882a593Smuzhiyun {
1956*4882a593Smuzhiyun struct drm_device *dev = encoder->base.dev;
1957*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
1958*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
1959*4882a593Smuzhiyun u32 temp;
1960*4882a593Smuzhiyun
1961*4882a593Smuzhiyun temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
1962*4882a593Smuzhiyun
1963*4882a593Smuzhiyun temp |= SDVO_ENABLE;
1964*4882a593Smuzhiyun if (pipe_config->has_audio)
1965*4882a593Smuzhiyun temp |= HDMI_AUDIO_ENABLE;
1966*4882a593Smuzhiyun
1967*4882a593Smuzhiyun /*
1968*4882a593Smuzhiyun * HW workaround, need to write this twice for issue
1969*4882a593Smuzhiyun * that may result in first write getting masked.
1970*4882a593Smuzhiyun */
1971*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
1972*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
1973*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
1974*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
1975*4882a593Smuzhiyun
1976*4882a593Smuzhiyun /*
1977*4882a593Smuzhiyun * HW workaround, need to toggle enable bit off and on
1978*4882a593Smuzhiyun * for 12bpc with pixel repeat.
1979*4882a593Smuzhiyun *
1980*4882a593Smuzhiyun * FIXME: BSpec says this should be done at the end of
1981*4882a593Smuzhiyun * of the modeset sequence, so not sure if this isn't too soon.
1982*4882a593Smuzhiyun */
1983*4882a593Smuzhiyun if (pipe_config->pipe_bpp > 24 &&
1984*4882a593Smuzhiyun pipe_config->pixel_multiplier > 1) {
1985*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg,
1986*4882a593Smuzhiyun temp & ~SDVO_ENABLE);
1987*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
1988*4882a593Smuzhiyun
1989*4882a593Smuzhiyun /*
1990*4882a593Smuzhiyun * HW workaround, need to write this twice for issue
1991*4882a593Smuzhiyun * that may result in first write getting masked.
1992*4882a593Smuzhiyun */
1993*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
1994*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
1995*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
1996*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
1997*4882a593Smuzhiyun }
1998*4882a593Smuzhiyun
1999*4882a593Smuzhiyun if (pipe_config->has_audio)
2000*4882a593Smuzhiyun intel_enable_hdmi_audio(encoder, pipe_config, conn_state);
2001*4882a593Smuzhiyun }
2002*4882a593Smuzhiyun
cpt_enable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)2003*4882a593Smuzhiyun static void cpt_enable_hdmi(struct intel_atomic_state *state,
2004*4882a593Smuzhiyun struct intel_encoder *encoder,
2005*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
2006*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2007*4882a593Smuzhiyun {
2008*4882a593Smuzhiyun struct drm_device *dev = encoder->base.dev;
2009*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
2010*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
2011*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2012*4882a593Smuzhiyun enum pipe pipe = crtc->pipe;
2013*4882a593Smuzhiyun u32 temp;
2014*4882a593Smuzhiyun
2015*4882a593Smuzhiyun temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
2016*4882a593Smuzhiyun
2017*4882a593Smuzhiyun temp |= SDVO_ENABLE;
2018*4882a593Smuzhiyun if (pipe_config->has_audio)
2019*4882a593Smuzhiyun temp |= HDMI_AUDIO_ENABLE;
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun /*
2022*4882a593Smuzhiyun * WaEnableHDMI8bpcBefore12bpc:snb,ivb
2023*4882a593Smuzhiyun *
2024*4882a593Smuzhiyun * The procedure for 12bpc is as follows:
2025*4882a593Smuzhiyun * 1. disable HDMI clock gating
2026*4882a593Smuzhiyun * 2. enable HDMI with 8bpc
2027*4882a593Smuzhiyun * 3. enable HDMI with 12bpc
2028*4882a593Smuzhiyun * 4. enable HDMI clock gating
2029*4882a593Smuzhiyun */
2030*4882a593Smuzhiyun
2031*4882a593Smuzhiyun if (pipe_config->pipe_bpp > 24) {
2032*4882a593Smuzhiyun intel_de_write(dev_priv, TRANS_CHICKEN1(pipe),
2033*4882a593Smuzhiyun intel_de_read(dev_priv, TRANS_CHICKEN1(pipe)) | TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE);
2034*4882a593Smuzhiyun
2035*4882a593Smuzhiyun temp &= ~SDVO_COLOR_FORMAT_MASK;
2036*4882a593Smuzhiyun temp |= SDVO_COLOR_FORMAT_8bpc;
2037*4882a593Smuzhiyun }
2038*4882a593Smuzhiyun
2039*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2040*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2041*4882a593Smuzhiyun
2042*4882a593Smuzhiyun if (pipe_config->pipe_bpp > 24) {
2043*4882a593Smuzhiyun temp &= ~SDVO_COLOR_FORMAT_MASK;
2044*4882a593Smuzhiyun temp |= HDMI_COLOR_FORMAT_12bpc;
2045*4882a593Smuzhiyun
2046*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2047*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2048*4882a593Smuzhiyun
2049*4882a593Smuzhiyun intel_de_write(dev_priv, TRANS_CHICKEN1(pipe),
2050*4882a593Smuzhiyun intel_de_read(dev_priv, TRANS_CHICKEN1(pipe)) & ~TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE);
2051*4882a593Smuzhiyun }
2052*4882a593Smuzhiyun
2053*4882a593Smuzhiyun if (pipe_config->has_audio)
2054*4882a593Smuzhiyun intel_enable_hdmi_audio(encoder, pipe_config, conn_state);
2055*4882a593Smuzhiyun }
2056*4882a593Smuzhiyun
vlv_enable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)2057*4882a593Smuzhiyun static void vlv_enable_hdmi(struct intel_atomic_state *state,
2058*4882a593Smuzhiyun struct intel_encoder *encoder,
2059*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
2060*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2061*4882a593Smuzhiyun {
2062*4882a593Smuzhiyun }
2063*4882a593Smuzhiyun
intel_disable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)2064*4882a593Smuzhiyun static void intel_disable_hdmi(struct intel_atomic_state *state,
2065*4882a593Smuzhiyun struct intel_encoder *encoder,
2066*4882a593Smuzhiyun const struct intel_crtc_state *old_crtc_state,
2067*4882a593Smuzhiyun const struct drm_connector_state *old_conn_state)
2068*4882a593Smuzhiyun {
2069*4882a593Smuzhiyun struct drm_device *dev = encoder->base.dev;
2070*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
2071*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2072*4882a593Smuzhiyun struct intel_digital_port *dig_port =
2073*4882a593Smuzhiyun hdmi_to_dig_port(intel_hdmi);
2074*4882a593Smuzhiyun struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
2075*4882a593Smuzhiyun u32 temp;
2076*4882a593Smuzhiyun
2077*4882a593Smuzhiyun temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
2078*4882a593Smuzhiyun
2079*4882a593Smuzhiyun temp &= ~(SDVO_ENABLE | HDMI_AUDIO_ENABLE);
2080*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2081*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2082*4882a593Smuzhiyun
2083*4882a593Smuzhiyun /*
2084*4882a593Smuzhiyun * HW workaround for IBX, we need to move the port
2085*4882a593Smuzhiyun * to transcoder A after disabling it to allow the
2086*4882a593Smuzhiyun * matching DP port to be enabled on transcoder A.
2087*4882a593Smuzhiyun */
2088*4882a593Smuzhiyun if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {
2089*4882a593Smuzhiyun /*
2090*4882a593Smuzhiyun * We get CPU/PCH FIFO underruns on the other pipe when
2091*4882a593Smuzhiyun * doing the workaround. Sweep them under the rug.
2092*4882a593Smuzhiyun */
2093*4882a593Smuzhiyun intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
2094*4882a593Smuzhiyun intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
2095*4882a593Smuzhiyun
2096*4882a593Smuzhiyun temp &= ~SDVO_PIPE_SEL_MASK;
2097*4882a593Smuzhiyun temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A);
2098*4882a593Smuzhiyun /*
2099*4882a593Smuzhiyun * HW workaround, need to write this twice for issue
2100*4882a593Smuzhiyun * that may result in first write getting masked.
2101*4882a593Smuzhiyun */
2102*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2103*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2104*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2105*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2106*4882a593Smuzhiyun
2107*4882a593Smuzhiyun temp &= ~SDVO_ENABLE;
2108*4882a593Smuzhiyun intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
2109*4882a593Smuzhiyun intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
2110*4882a593Smuzhiyun
2111*4882a593Smuzhiyun intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
2112*4882a593Smuzhiyun intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
2113*4882a593Smuzhiyun intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
2114*4882a593Smuzhiyun }
2115*4882a593Smuzhiyun
2116*4882a593Smuzhiyun dig_port->set_infoframes(encoder,
2117*4882a593Smuzhiyun false,
2118*4882a593Smuzhiyun old_crtc_state, old_conn_state);
2119*4882a593Smuzhiyun
2120*4882a593Smuzhiyun intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
2121*4882a593Smuzhiyun }
2122*4882a593Smuzhiyun
g4x_disable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)2123*4882a593Smuzhiyun static void g4x_disable_hdmi(struct intel_atomic_state *state,
2124*4882a593Smuzhiyun struct intel_encoder *encoder,
2125*4882a593Smuzhiyun const struct intel_crtc_state *old_crtc_state,
2126*4882a593Smuzhiyun const struct drm_connector_state *old_conn_state)
2127*4882a593Smuzhiyun {
2128*4882a593Smuzhiyun if (old_crtc_state->has_audio)
2129*4882a593Smuzhiyun intel_audio_codec_disable(encoder,
2130*4882a593Smuzhiyun old_crtc_state, old_conn_state);
2131*4882a593Smuzhiyun
2132*4882a593Smuzhiyun intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);
2133*4882a593Smuzhiyun }
2134*4882a593Smuzhiyun
pch_disable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)2135*4882a593Smuzhiyun static void pch_disable_hdmi(struct intel_atomic_state *state,
2136*4882a593Smuzhiyun struct intel_encoder *encoder,
2137*4882a593Smuzhiyun const struct intel_crtc_state *old_crtc_state,
2138*4882a593Smuzhiyun const struct drm_connector_state *old_conn_state)
2139*4882a593Smuzhiyun {
2140*4882a593Smuzhiyun if (old_crtc_state->has_audio)
2141*4882a593Smuzhiyun intel_audio_codec_disable(encoder,
2142*4882a593Smuzhiyun old_crtc_state, old_conn_state);
2143*4882a593Smuzhiyun }
2144*4882a593Smuzhiyun
pch_post_disable_hdmi(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)2145*4882a593Smuzhiyun static void pch_post_disable_hdmi(struct intel_atomic_state *state,
2146*4882a593Smuzhiyun struct intel_encoder *encoder,
2147*4882a593Smuzhiyun const struct intel_crtc_state *old_crtc_state,
2148*4882a593Smuzhiyun const struct drm_connector_state *old_conn_state)
2149*4882a593Smuzhiyun {
2150*4882a593Smuzhiyun intel_disable_hdmi(state, encoder, old_crtc_state, old_conn_state);
2151*4882a593Smuzhiyun }
2152*4882a593Smuzhiyun
intel_hdmi_source_max_tmds_clock(struct intel_encoder * encoder)2153*4882a593Smuzhiyun static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder)
2154*4882a593Smuzhiyun {
2155*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2156*4882a593Smuzhiyun int max_tmds_clock, vbt_max_tmds_clock;
2157*4882a593Smuzhiyun
2158*4882a593Smuzhiyun if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
2159*4882a593Smuzhiyun max_tmds_clock = 594000;
2160*4882a593Smuzhiyun else if (INTEL_GEN(dev_priv) >= 8 || IS_HASWELL(dev_priv))
2161*4882a593Smuzhiyun max_tmds_clock = 300000;
2162*4882a593Smuzhiyun else if (INTEL_GEN(dev_priv) >= 5)
2163*4882a593Smuzhiyun max_tmds_clock = 225000;
2164*4882a593Smuzhiyun else
2165*4882a593Smuzhiyun max_tmds_clock = 165000;
2166*4882a593Smuzhiyun
2167*4882a593Smuzhiyun vbt_max_tmds_clock = intel_bios_max_tmds_clock(encoder);
2168*4882a593Smuzhiyun if (vbt_max_tmds_clock)
2169*4882a593Smuzhiyun max_tmds_clock = min(max_tmds_clock, vbt_max_tmds_clock);
2170*4882a593Smuzhiyun
2171*4882a593Smuzhiyun return max_tmds_clock;
2172*4882a593Smuzhiyun }
2173*4882a593Smuzhiyun
intel_has_hdmi_sink(struct intel_hdmi * hdmi,const struct drm_connector_state * conn_state)2174*4882a593Smuzhiyun static bool intel_has_hdmi_sink(struct intel_hdmi *hdmi,
2175*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2176*4882a593Smuzhiyun {
2177*4882a593Smuzhiyun return hdmi->has_hdmi_sink &&
2178*4882a593Smuzhiyun READ_ONCE(to_intel_digital_connector_state(conn_state)->force_audio) != HDMI_AUDIO_OFF_DVI;
2179*4882a593Smuzhiyun }
2180*4882a593Smuzhiyun
hdmi_port_clock_limit(struct intel_hdmi * hdmi,bool respect_downstream_limits,bool has_hdmi_sink)2181*4882a593Smuzhiyun static int hdmi_port_clock_limit(struct intel_hdmi *hdmi,
2182*4882a593Smuzhiyun bool respect_downstream_limits,
2183*4882a593Smuzhiyun bool has_hdmi_sink)
2184*4882a593Smuzhiyun {
2185*4882a593Smuzhiyun struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base;
2186*4882a593Smuzhiyun int max_tmds_clock = intel_hdmi_source_max_tmds_clock(encoder);
2187*4882a593Smuzhiyun
2188*4882a593Smuzhiyun if (respect_downstream_limits) {
2189*4882a593Smuzhiyun struct intel_connector *connector = hdmi->attached_connector;
2190*4882a593Smuzhiyun const struct drm_display_info *info = &connector->base.display_info;
2191*4882a593Smuzhiyun
2192*4882a593Smuzhiyun if (hdmi->dp_dual_mode.max_tmds_clock)
2193*4882a593Smuzhiyun max_tmds_clock = min(max_tmds_clock,
2194*4882a593Smuzhiyun hdmi->dp_dual_mode.max_tmds_clock);
2195*4882a593Smuzhiyun
2196*4882a593Smuzhiyun if (info->max_tmds_clock)
2197*4882a593Smuzhiyun max_tmds_clock = min(max_tmds_clock,
2198*4882a593Smuzhiyun info->max_tmds_clock);
2199*4882a593Smuzhiyun else if (!has_hdmi_sink)
2200*4882a593Smuzhiyun max_tmds_clock = min(max_tmds_clock, 165000);
2201*4882a593Smuzhiyun }
2202*4882a593Smuzhiyun
2203*4882a593Smuzhiyun return max_tmds_clock;
2204*4882a593Smuzhiyun }
2205*4882a593Smuzhiyun
2206*4882a593Smuzhiyun static enum drm_mode_status
hdmi_port_clock_valid(struct intel_hdmi * hdmi,int clock,bool respect_downstream_limits,bool has_hdmi_sink)2207*4882a593Smuzhiyun hdmi_port_clock_valid(struct intel_hdmi *hdmi,
2208*4882a593Smuzhiyun int clock, bool respect_downstream_limits,
2209*4882a593Smuzhiyun bool has_hdmi_sink)
2210*4882a593Smuzhiyun {
2211*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
2212*4882a593Smuzhiyun
2213*4882a593Smuzhiyun if (clock < 25000)
2214*4882a593Smuzhiyun return MODE_CLOCK_LOW;
2215*4882a593Smuzhiyun if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits,
2216*4882a593Smuzhiyun has_hdmi_sink))
2217*4882a593Smuzhiyun return MODE_CLOCK_HIGH;
2218*4882a593Smuzhiyun
2219*4882a593Smuzhiyun /* GLK DPLL can't generate 446-480 MHz */
2220*4882a593Smuzhiyun if (IS_GEMINILAKE(dev_priv) && clock > 446666 && clock < 480000)
2221*4882a593Smuzhiyun return MODE_CLOCK_RANGE;
2222*4882a593Smuzhiyun
2223*4882a593Smuzhiyun /* BXT/GLK DPLL can't generate 223-240 MHz */
2224*4882a593Smuzhiyun if (IS_GEN9_LP(dev_priv) && clock > 223333 && clock < 240000)
2225*4882a593Smuzhiyun return MODE_CLOCK_RANGE;
2226*4882a593Smuzhiyun
2227*4882a593Smuzhiyun /* CHV DPLL can't generate 216-240 MHz */
2228*4882a593Smuzhiyun if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000)
2229*4882a593Smuzhiyun return MODE_CLOCK_RANGE;
2230*4882a593Smuzhiyun
2231*4882a593Smuzhiyun return MODE_OK;
2232*4882a593Smuzhiyun }
2233*4882a593Smuzhiyun
2234*4882a593Smuzhiyun static enum drm_mode_status
intel_hdmi_mode_valid(struct drm_connector * connector,struct drm_display_mode * mode)2235*4882a593Smuzhiyun intel_hdmi_mode_valid(struct drm_connector *connector,
2236*4882a593Smuzhiyun struct drm_display_mode *mode)
2237*4882a593Smuzhiyun {
2238*4882a593Smuzhiyun struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
2239*4882a593Smuzhiyun struct drm_device *dev = intel_hdmi_to_dev(hdmi);
2240*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
2241*4882a593Smuzhiyun enum drm_mode_status status;
2242*4882a593Smuzhiyun int clock = mode->clock;
2243*4882a593Smuzhiyun int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
2244*4882a593Smuzhiyun bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state);
2245*4882a593Smuzhiyun
2246*4882a593Smuzhiyun if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
2247*4882a593Smuzhiyun return MODE_NO_DBLESCAN;
2248*4882a593Smuzhiyun
2249*4882a593Smuzhiyun if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
2250*4882a593Smuzhiyun clock *= 2;
2251*4882a593Smuzhiyun
2252*4882a593Smuzhiyun if (clock > max_dotclk)
2253*4882a593Smuzhiyun return MODE_CLOCK_HIGH;
2254*4882a593Smuzhiyun
2255*4882a593Smuzhiyun if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
2256*4882a593Smuzhiyun if (!has_hdmi_sink)
2257*4882a593Smuzhiyun return MODE_CLOCK_LOW;
2258*4882a593Smuzhiyun clock *= 2;
2259*4882a593Smuzhiyun }
2260*4882a593Smuzhiyun
2261*4882a593Smuzhiyun if (drm_mode_is_420_only(&connector->display_info, mode))
2262*4882a593Smuzhiyun clock /= 2;
2263*4882a593Smuzhiyun
2264*4882a593Smuzhiyun /* check if we can do 8bpc */
2265*4882a593Smuzhiyun status = hdmi_port_clock_valid(hdmi, clock, true, has_hdmi_sink);
2266*4882a593Smuzhiyun
2267*4882a593Smuzhiyun if (has_hdmi_sink) {
2268*4882a593Smuzhiyun /* if we can't do 8bpc we may still be able to do 12bpc */
2269*4882a593Smuzhiyun if (status != MODE_OK && !HAS_GMCH(dev_priv))
2270*4882a593Smuzhiyun status = hdmi_port_clock_valid(hdmi, clock * 3 / 2,
2271*4882a593Smuzhiyun true, has_hdmi_sink);
2272*4882a593Smuzhiyun
2273*4882a593Smuzhiyun /* if we can't do 8,12bpc we may still be able to do 10bpc */
2274*4882a593Smuzhiyun if (status != MODE_OK && INTEL_GEN(dev_priv) >= 11)
2275*4882a593Smuzhiyun status = hdmi_port_clock_valid(hdmi, clock * 5 / 4,
2276*4882a593Smuzhiyun true, has_hdmi_sink);
2277*4882a593Smuzhiyun }
2278*4882a593Smuzhiyun if (status != MODE_OK)
2279*4882a593Smuzhiyun return status;
2280*4882a593Smuzhiyun
2281*4882a593Smuzhiyun return intel_mode_valid_max_plane_size(dev_priv, mode);
2282*4882a593Smuzhiyun }
2283*4882a593Smuzhiyun
intel_hdmi_deep_color_possible(const struct intel_crtc_state * crtc_state,int bpc,bool has_hdmi_sink,bool ycbcr420_output)2284*4882a593Smuzhiyun bool intel_hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
2285*4882a593Smuzhiyun int bpc, bool has_hdmi_sink, bool ycbcr420_output)
2286*4882a593Smuzhiyun {
2287*4882a593Smuzhiyun struct drm_atomic_state *state = crtc_state->uapi.state;
2288*4882a593Smuzhiyun struct drm_connector_state *connector_state;
2289*4882a593Smuzhiyun struct drm_connector *connector;
2290*4882a593Smuzhiyun int i;
2291*4882a593Smuzhiyun
2292*4882a593Smuzhiyun if (crtc_state->pipe_bpp < bpc * 3)
2293*4882a593Smuzhiyun return false;
2294*4882a593Smuzhiyun
2295*4882a593Smuzhiyun if (!has_hdmi_sink)
2296*4882a593Smuzhiyun return false;
2297*4882a593Smuzhiyun
2298*4882a593Smuzhiyun for_each_new_connector_in_state(state, connector, connector_state, i) {
2299*4882a593Smuzhiyun const struct drm_display_info *info = &connector->display_info;
2300*4882a593Smuzhiyun
2301*4882a593Smuzhiyun if (connector_state->crtc != crtc_state->uapi.crtc)
2302*4882a593Smuzhiyun continue;
2303*4882a593Smuzhiyun
2304*4882a593Smuzhiyun if (ycbcr420_output) {
2305*4882a593Smuzhiyun const struct drm_hdmi_info *hdmi = &info->hdmi;
2306*4882a593Smuzhiyun
2307*4882a593Smuzhiyun if (bpc == 12 && !(hdmi->y420_dc_modes &
2308*4882a593Smuzhiyun DRM_EDID_YCBCR420_DC_36))
2309*4882a593Smuzhiyun return false;
2310*4882a593Smuzhiyun else if (bpc == 10 && !(hdmi->y420_dc_modes &
2311*4882a593Smuzhiyun DRM_EDID_YCBCR420_DC_30))
2312*4882a593Smuzhiyun return false;
2313*4882a593Smuzhiyun } else {
2314*4882a593Smuzhiyun if (bpc == 12 && !(info->edid_hdmi_dc_modes &
2315*4882a593Smuzhiyun DRM_EDID_HDMI_DC_36))
2316*4882a593Smuzhiyun return false;
2317*4882a593Smuzhiyun else if (bpc == 10 && !(info->edid_hdmi_dc_modes &
2318*4882a593Smuzhiyun DRM_EDID_HDMI_DC_30))
2319*4882a593Smuzhiyun return false;
2320*4882a593Smuzhiyun }
2321*4882a593Smuzhiyun }
2322*4882a593Smuzhiyun
2323*4882a593Smuzhiyun return true;
2324*4882a593Smuzhiyun }
2325*4882a593Smuzhiyun
hdmi_deep_color_possible(const struct intel_crtc_state * crtc_state,int bpc)2326*4882a593Smuzhiyun static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
2327*4882a593Smuzhiyun int bpc)
2328*4882a593Smuzhiyun {
2329*4882a593Smuzhiyun struct drm_i915_private *dev_priv =
2330*4882a593Smuzhiyun to_i915(crtc_state->uapi.crtc->dev);
2331*4882a593Smuzhiyun const struct drm_display_mode *adjusted_mode =
2332*4882a593Smuzhiyun &crtc_state->hw.adjusted_mode;
2333*4882a593Smuzhiyun
2334*4882a593Smuzhiyun if (HAS_GMCH(dev_priv))
2335*4882a593Smuzhiyun return false;
2336*4882a593Smuzhiyun
2337*4882a593Smuzhiyun if (bpc == 10 && INTEL_GEN(dev_priv) < 11)
2338*4882a593Smuzhiyun return false;
2339*4882a593Smuzhiyun
2340*4882a593Smuzhiyun /*
2341*4882a593Smuzhiyun * HDMI deep color affects the clocks, so it's only possible
2342*4882a593Smuzhiyun * when not cloning with other encoder types.
2343*4882a593Smuzhiyun */
2344*4882a593Smuzhiyun if (crtc_state->output_types != BIT(INTEL_OUTPUT_HDMI))
2345*4882a593Smuzhiyun return false;
2346*4882a593Smuzhiyun
2347*4882a593Smuzhiyun /* Display Wa_1405510057:icl,ehl */
2348*4882a593Smuzhiyun if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
2349*4882a593Smuzhiyun bpc == 10 && IS_GEN(dev_priv, 11) &&
2350*4882a593Smuzhiyun (adjusted_mode->crtc_hblank_end -
2351*4882a593Smuzhiyun adjusted_mode->crtc_hblank_start) % 8 == 2)
2352*4882a593Smuzhiyun return false;
2353*4882a593Smuzhiyun
2354*4882a593Smuzhiyun return intel_hdmi_deep_color_possible(crtc_state, bpc,
2355*4882a593Smuzhiyun crtc_state->has_hdmi_sink,
2356*4882a593Smuzhiyun crtc_state->output_format ==
2357*4882a593Smuzhiyun INTEL_OUTPUT_FORMAT_YCBCR420);
2358*4882a593Smuzhiyun }
2359*4882a593Smuzhiyun
2360*4882a593Smuzhiyun static int
intel_hdmi_ycbcr420_config(struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)2361*4882a593Smuzhiyun intel_hdmi_ycbcr420_config(struct intel_crtc_state *crtc_state,
2362*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2363*4882a593Smuzhiyun {
2364*4882a593Smuzhiyun struct drm_connector *connector = conn_state->connector;
2365*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(connector->dev);
2366*4882a593Smuzhiyun const struct drm_display_mode *adjusted_mode =
2367*4882a593Smuzhiyun &crtc_state->hw.adjusted_mode;
2368*4882a593Smuzhiyun
2369*4882a593Smuzhiyun if (!drm_mode_is_420_only(&connector->display_info, adjusted_mode))
2370*4882a593Smuzhiyun return 0;
2371*4882a593Smuzhiyun
2372*4882a593Smuzhiyun if (!connector->ycbcr_420_allowed) {
2373*4882a593Smuzhiyun drm_err(&i915->drm,
2374*4882a593Smuzhiyun "Platform doesn't support YCBCR420 output\n");
2375*4882a593Smuzhiyun return -EINVAL;
2376*4882a593Smuzhiyun }
2377*4882a593Smuzhiyun
2378*4882a593Smuzhiyun crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420;
2379*4882a593Smuzhiyun
2380*4882a593Smuzhiyun return intel_pch_panel_fitting(crtc_state, conn_state);
2381*4882a593Smuzhiyun }
2382*4882a593Smuzhiyun
intel_hdmi_port_clock(int clock,int bpc)2383*4882a593Smuzhiyun static int intel_hdmi_port_clock(int clock, int bpc)
2384*4882a593Smuzhiyun {
2385*4882a593Smuzhiyun /*
2386*4882a593Smuzhiyun * Need to adjust the port link by:
2387*4882a593Smuzhiyun * 1.5x for 12bpc
2388*4882a593Smuzhiyun * 1.25x for 10bpc
2389*4882a593Smuzhiyun */
2390*4882a593Smuzhiyun return clock * bpc / 8;
2391*4882a593Smuzhiyun }
2392*4882a593Smuzhiyun
intel_hdmi_compute_bpc(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state,int clock)2393*4882a593Smuzhiyun static int intel_hdmi_compute_bpc(struct intel_encoder *encoder,
2394*4882a593Smuzhiyun struct intel_crtc_state *crtc_state,
2395*4882a593Smuzhiyun int clock)
2396*4882a593Smuzhiyun {
2397*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2398*4882a593Smuzhiyun int bpc;
2399*4882a593Smuzhiyun
2400*4882a593Smuzhiyun for (bpc = 12; bpc >= 10; bpc -= 2) {
2401*4882a593Smuzhiyun if (hdmi_deep_color_possible(crtc_state, bpc) &&
2402*4882a593Smuzhiyun hdmi_port_clock_valid(intel_hdmi,
2403*4882a593Smuzhiyun intel_hdmi_port_clock(clock, bpc),
2404*4882a593Smuzhiyun true, crtc_state->has_hdmi_sink) == MODE_OK)
2405*4882a593Smuzhiyun return bpc;
2406*4882a593Smuzhiyun }
2407*4882a593Smuzhiyun
2408*4882a593Smuzhiyun return 8;
2409*4882a593Smuzhiyun }
2410*4882a593Smuzhiyun
intel_hdmi_compute_clock(struct intel_encoder * encoder,struct intel_crtc_state * crtc_state)2411*4882a593Smuzhiyun static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
2412*4882a593Smuzhiyun struct intel_crtc_state *crtc_state)
2413*4882a593Smuzhiyun {
2414*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(encoder->base.dev);
2415*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2416*4882a593Smuzhiyun const struct drm_display_mode *adjusted_mode =
2417*4882a593Smuzhiyun &crtc_state->hw.adjusted_mode;
2418*4882a593Smuzhiyun int bpc, clock = adjusted_mode->crtc_clock;
2419*4882a593Smuzhiyun
2420*4882a593Smuzhiyun if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
2421*4882a593Smuzhiyun clock *= 2;
2422*4882a593Smuzhiyun
2423*4882a593Smuzhiyun /* YCBCR420 TMDS rate requirement is half the pixel clock */
2424*4882a593Smuzhiyun if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
2425*4882a593Smuzhiyun clock /= 2;
2426*4882a593Smuzhiyun
2427*4882a593Smuzhiyun bpc = intel_hdmi_compute_bpc(encoder, crtc_state, clock);
2428*4882a593Smuzhiyun
2429*4882a593Smuzhiyun crtc_state->port_clock = intel_hdmi_port_clock(clock, bpc);
2430*4882a593Smuzhiyun
2431*4882a593Smuzhiyun /*
2432*4882a593Smuzhiyun * pipe_bpp could already be below 8bpc due to
2433*4882a593Smuzhiyun * FDI bandwidth constraints. We shouldn't bump it
2434*4882a593Smuzhiyun * back up to 8bpc in that case.
2435*4882a593Smuzhiyun */
2436*4882a593Smuzhiyun if (crtc_state->pipe_bpp > bpc * 3)
2437*4882a593Smuzhiyun crtc_state->pipe_bpp = bpc * 3;
2438*4882a593Smuzhiyun
2439*4882a593Smuzhiyun drm_dbg_kms(&i915->drm,
2440*4882a593Smuzhiyun "picking %d bpc for HDMI output (pipe bpp: %d)\n",
2441*4882a593Smuzhiyun bpc, crtc_state->pipe_bpp);
2442*4882a593Smuzhiyun
2443*4882a593Smuzhiyun if (hdmi_port_clock_valid(intel_hdmi, crtc_state->port_clock,
2444*4882a593Smuzhiyun false, crtc_state->has_hdmi_sink) != MODE_OK) {
2445*4882a593Smuzhiyun drm_dbg_kms(&i915->drm,
2446*4882a593Smuzhiyun "unsupported HDMI clock (%d kHz), rejecting mode\n",
2447*4882a593Smuzhiyun crtc_state->port_clock);
2448*4882a593Smuzhiyun return -EINVAL;
2449*4882a593Smuzhiyun }
2450*4882a593Smuzhiyun
2451*4882a593Smuzhiyun return 0;
2452*4882a593Smuzhiyun }
2453*4882a593Smuzhiyun
intel_hdmi_limited_color_range(const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)2454*4882a593Smuzhiyun bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_state,
2455*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2456*4882a593Smuzhiyun {
2457*4882a593Smuzhiyun const struct intel_digital_connector_state *intel_conn_state =
2458*4882a593Smuzhiyun to_intel_digital_connector_state(conn_state);
2459*4882a593Smuzhiyun const struct drm_display_mode *adjusted_mode =
2460*4882a593Smuzhiyun &crtc_state->hw.adjusted_mode;
2461*4882a593Smuzhiyun
2462*4882a593Smuzhiyun /*
2463*4882a593Smuzhiyun * Our YCbCr output is always limited range.
2464*4882a593Smuzhiyun * crtc_state->limited_color_range only applies to RGB,
2465*4882a593Smuzhiyun * and it must never be set for YCbCr or we risk setting
2466*4882a593Smuzhiyun * some conflicting bits in PIPECONF which will mess up
2467*4882a593Smuzhiyun * the colors on the monitor.
2468*4882a593Smuzhiyun */
2469*4882a593Smuzhiyun if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
2470*4882a593Smuzhiyun return false;
2471*4882a593Smuzhiyun
2472*4882a593Smuzhiyun if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) {
2473*4882a593Smuzhiyun /* See CEA-861-E - 5.1 Default Encoding Parameters */
2474*4882a593Smuzhiyun return crtc_state->has_hdmi_sink &&
2475*4882a593Smuzhiyun drm_default_rgb_quant_range(adjusted_mode) ==
2476*4882a593Smuzhiyun HDMI_QUANTIZATION_RANGE_LIMITED;
2477*4882a593Smuzhiyun } else {
2478*4882a593Smuzhiyun return intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_LIMITED;
2479*4882a593Smuzhiyun }
2480*4882a593Smuzhiyun }
2481*4882a593Smuzhiyun
intel_hdmi_has_audio(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state,const struct drm_connector_state * conn_state)2482*4882a593Smuzhiyun static bool intel_hdmi_has_audio(struct intel_encoder *encoder,
2483*4882a593Smuzhiyun const struct intel_crtc_state *crtc_state,
2484*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2485*4882a593Smuzhiyun {
2486*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2487*4882a593Smuzhiyun const struct intel_digital_connector_state *intel_conn_state =
2488*4882a593Smuzhiyun to_intel_digital_connector_state(conn_state);
2489*4882a593Smuzhiyun
2490*4882a593Smuzhiyun if (!crtc_state->has_hdmi_sink)
2491*4882a593Smuzhiyun return false;
2492*4882a593Smuzhiyun
2493*4882a593Smuzhiyun if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
2494*4882a593Smuzhiyun return intel_hdmi->has_audio;
2495*4882a593Smuzhiyun else
2496*4882a593Smuzhiyun return intel_conn_state->force_audio == HDMI_AUDIO_ON;
2497*4882a593Smuzhiyun }
2498*4882a593Smuzhiyun
intel_hdmi_compute_config(struct intel_encoder * encoder,struct intel_crtc_state * pipe_config,struct drm_connector_state * conn_state)2499*4882a593Smuzhiyun int intel_hdmi_compute_config(struct intel_encoder *encoder,
2500*4882a593Smuzhiyun struct intel_crtc_state *pipe_config,
2501*4882a593Smuzhiyun struct drm_connector_state *conn_state)
2502*4882a593Smuzhiyun {
2503*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2504*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2505*4882a593Smuzhiyun struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
2506*4882a593Smuzhiyun struct drm_connector *connector = conn_state->connector;
2507*4882a593Smuzhiyun struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
2508*4882a593Smuzhiyun int ret;
2509*4882a593Smuzhiyun
2510*4882a593Smuzhiyun if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
2511*4882a593Smuzhiyun return -EINVAL;
2512*4882a593Smuzhiyun
2513*4882a593Smuzhiyun pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
2514*4882a593Smuzhiyun pipe_config->has_hdmi_sink = intel_has_hdmi_sink(intel_hdmi,
2515*4882a593Smuzhiyun conn_state);
2516*4882a593Smuzhiyun
2517*4882a593Smuzhiyun if (pipe_config->has_hdmi_sink)
2518*4882a593Smuzhiyun pipe_config->has_infoframe = true;
2519*4882a593Smuzhiyun
2520*4882a593Smuzhiyun if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
2521*4882a593Smuzhiyun pipe_config->pixel_multiplier = 2;
2522*4882a593Smuzhiyun
2523*4882a593Smuzhiyun ret = intel_hdmi_ycbcr420_config(pipe_config, conn_state);
2524*4882a593Smuzhiyun if (ret)
2525*4882a593Smuzhiyun return ret;
2526*4882a593Smuzhiyun
2527*4882a593Smuzhiyun pipe_config->limited_color_range =
2528*4882a593Smuzhiyun intel_hdmi_limited_color_range(pipe_config, conn_state);
2529*4882a593Smuzhiyun
2530*4882a593Smuzhiyun if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv))
2531*4882a593Smuzhiyun pipe_config->has_pch_encoder = true;
2532*4882a593Smuzhiyun
2533*4882a593Smuzhiyun pipe_config->has_audio =
2534*4882a593Smuzhiyun intel_hdmi_has_audio(encoder, pipe_config, conn_state);
2535*4882a593Smuzhiyun
2536*4882a593Smuzhiyun ret = intel_hdmi_compute_clock(encoder, pipe_config);
2537*4882a593Smuzhiyun if (ret)
2538*4882a593Smuzhiyun return ret;
2539*4882a593Smuzhiyun
2540*4882a593Smuzhiyun if (conn_state->picture_aspect_ratio)
2541*4882a593Smuzhiyun adjusted_mode->picture_aspect_ratio =
2542*4882a593Smuzhiyun conn_state->picture_aspect_ratio;
2543*4882a593Smuzhiyun
2544*4882a593Smuzhiyun pipe_config->lane_count = 4;
2545*4882a593Smuzhiyun
2546*4882a593Smuzhiyun if (scdc->scrambling.supported && (INTEL_GEN(dev_priv) >= 10 ||
2547*4882a593Smuzhiyun IS_GEMINILAKE(dev_priv))) {
2548*4882a593Smuzhiyun if (scdc->scrambling.low_rates)
2549*4882a593Smuzhiyun pipe_config->hdmi_scrambling = true;
2550*4882a593Smuzhiyun
2551*4882a593Smuzhiyun if (pipe_config->port_clock > 340000) {
2552*4882a593Smuzhiyun pipe_config->hdmi_scrambling = true;
2553*4882a593Smuzhiyun pipe_config->hdmi_high_tmds_clock_ratio = true;
2554*4882a593Smuzhiyun }
2555*4882a593Smuzhiyun }
2556*4882a593Smuzhiyun
2557*4882a593Smuzhiyun intel_hdmi_compute_gcp_infoframe(encoder, pipe_config,
2558*4882a593Smuzhiyun conn_state);
2559*4882a593Smuzhiyun
2560*4882a593Smuzhiyun if (!intel_hdmi_compute_avi_infoframe(encoder, pipe_config, conn_state)) {
2561*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm, "bad AVI infoframe\n");
2562*4882a593Smuzhiyun return -EINVAL;
2563*4882a593Smuzhiyun }
2564*4882a593Smuzhiyun
2565*4882a593Smuzhiyun if (!intel_hdmi_compute_spd_infoframe(encoder, pipe_config, conn_state)) {
2566*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm, "bad SPD infoframe\n");
2567*4882a593Smuzhiyun return -EINVAL;
2568*4882a593Smuzhiyun }
2569*4882a593Smuzhiyun
2570*4882a593Smuzhiyun if (!intel_hdmi_compute_hdmi_infoframe(encoder, pipe_config, conn_state)) {
2571*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm, "bad HDMI infoframe\n");
2572*4882a593Smuzhiyun return -EINVAL;
2573*4882a593Smuzhiyun }
2574*4882a593Smuzhiyun
2575*4882a593Smuzhiyun if (!intel_hdmi_compute_drm_infoframe(encoder, pipe_config, conn_state)) {
2576*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm, "bad DRM infoframe\n");
2577*4882a593Smuzhiyun return -EINVAL;
2578*4882a593Smuzhiyun }
2579*4882a593Smuzhiyun
2580*4882a593Smuzhiyun return 0;
2581*4882a593Smuzhiyun }
2582*4882a593Smuzhiyun
2583*4882a593Smuzhiyun static void
intel_hdmi_unset_edid(struct drm_connector * connector)2584*4882a593Smuzhiyun intel_hdmi_unset_edid(struct drm_connector *connector)
2585*4882a593Smuzhiyun {
2586*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
2587*4882a593Smuzhiyun
2588*4882a593Smuzhiyun intel_hdmi->has_hdmi_sink = false;
2589*4882a593Smuzhiyun intel_hdmi->has_audio = false;
2590*4882a593Smuzhiyun
2591*4882a593Smuzhiyun intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
2592*4882a593Smuzhiyun intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
2593*4882a593Smuzhiyun
2594*4882a593Smuzhiyun kfree(to_intel_connector(connector)->detect_edid);
2595*4882a593Smuzhiyun to_intel_connector(connector)->detect_edid = NULL;
2596*4882a593Smuzhiyun }
2597*4882a593Smuzhiyun
2598*4882a593Smuzhiyun static void
intel_hdmi_dp_dual_mode_detect(struct drm_connector * connector,bool has_edid)2599*4882a593Smuzhiyun intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
2600*4882a593Smuzhiyun {
2601*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(connector->dev);
2602*4882a593Smuzhiyun struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
2603*4882a593Smuzhiyun enum port port = hdmi_to_dig_port(hdmi)->base.port;
2604*4882a593Smuzhiyun struct i2c_adapter *adapter =
2605*4882a593Smuzhiyun intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
2606*4882a593Smuzhiyun enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter);
2607*4882a593Smuzhiyun
2608*4882a593Smuzhiyun /*
2609*4882a593Smuzhiyun * Type 1 DVI adaptors are not required to implement any
2610*4882a593Smuzhiyun * registers, so we can't always detect their presence.
2611*4882a593Smuzhiyun * Ideally we should be able to check the state of the
2612*4882a593Smuzhiyun * CONFIG1 pin, but no such luck on our hardware.
2613*4882a593Smuzhiyun *
2614*4882a593Smuzhiyun * The only method left to us is to check the VBT to see
2615*4882a593Smuzhiyun * if the port is a dual mode capable DP port. But let's
2616*4882a593Smuzhiyun * only do that when we sucesfully read the EDID, to avoid
2617*4882a593Smuzhiyun * confusing log messages about DP dual mode adaptors when
2618*4882a593Smuzhiyun * there's nothing connected to the port.
2619*4882a593Smuzhiyun */
2620*4882a593Smuzhiyun if (type == DRM_DP_DUAL_MODE_UNKNOWN) {
2621*4882a593Smuzhiyun /* An overridden EDID imply that we want this port for testing.
2622*4882a593Smuzhiyun * Make sure not to set limits for that port.
2623*4882a593Smuzhiyun */
2624*4882a593Smuzhiyun if (has_edid && !connector->override_edid &&
2625*4882a593Smuzhiyun intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
2626*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
2627*4882a593Smuzhiyun "Assuming DP dual mode adaptor presence based on VBT\n");
2628*4882a593Smuzhiyun type = DRM_DP_DUAL_MODE_TYPE1_DVI;
2629*4882a593Smuzhiyun } else {
2630*4882a593Smuzhiyun type = DRM_DP_DUAL_MODE_NONE;
2631*4882a593Smuzhiyun }
2632*4882a593Smuzhiyun }
2633*4882a593Smuzhiyun
2634*4882a593Smuzhiyun if (type == DRM_DP_DUAL_MODE_NONE)
2635*4882a593Smuzhiyun return;
2636*4882a593Smuzhiyun
2637*4882a593Smuzhiyun hdmi->dp_dual_mode.type = type;
2638*4882a593Smuzhiyun hdmi->dp_dual_mode.max_tmds_clock =
2639*4882a593Smuzhiyun drm_dp_dual_mode_max_tmds_clock(type, adapter);
2640*4882a593Smuzhiyun
2641*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
2642*4882a593Smuzhiyun "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
2643*4882a593Smuzhiyun drm_dp_get_dual_mode_type_name(type),
2644*4882a593Smuzhiyun hdmi->dp_dual_mode.max_tmds_clock);
2645*4882a593Smuzhiyun }
2646*4882a593Smuzhiyun
2647*4882a593Smuzhiyun static bool
intel_hdmi_set_edid(struct drm_connector * connector)2648*4882a593Smuzhiyun intel_hdmi_set_edid(struct drm_connector *connector)
2649*4882a593Smuzhiyun {
2650*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(connector->dev);
2651*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
2652*4882a593Smuzhiyun intel_wakeref_t wakeref;
2653*4882a593Smuzhiyun struct edid *edid;
2654*4882a593Smuzhiyun bool connected = false;
2655*4882a593Smuzhiyun struct i2c_adapter *i2c;
2656*4882a593Smuzhiyun
2657*4882a593Smuzhiyun wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
2658*4882a593Smuzhiyun
2659*4882a593Smuzhiyun i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
2660*4882a593Smuzhiyun
2661*4882a593Smuzhiyun edid = drm_get_edid(connector, i2c);
2662*4882a593Smuzhiyun
2663*4882a593Smuzhiyun if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
2664*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
2665*4882a593Smuzhiyun "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
2666*4882a593Smuzhiyun intel_gmbus_force_bit(i2c, true);
2667*4882a593Smuzhiyun edid = drm_get_edid(connector, i2c);
2668*4882a593Smuzhiyun intel_gmbus_force_bit(i2c, false);
2669*4882a593Smuzhiyun }
2670*4882a593Smuzhiyun
2671*4882a593Smuzhiyun intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
2672*4882a593Smuzhiyun
2673*4882a593Smuzhiyun intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
2674*4882a593Smuzhiyun
2675*4882a593Smuzhiyun to_intel_connector(connector)->detect_edid = edid;
2676*4882a593Smuzhiyun if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
2677*4882a593Smuzhiyun intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
2678*4882a593Smuzhiyun intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
2679*4882a593Smuzhiyun
2680*4882a593Smuzhiyun connected = true;
2681*4882a593Smuzhiyun }
2682*4882a593Smuzhiyun
2683*4882a593Smuzhiyun cec_notifier_set_phys_addr_from_edid(intel_hdmi->cec_notifier, edid);
2684*4882a593Smuzhiyun
2685*4882a593Smuzhiyun return connected;
2686*4882a593Smuzhiyun }
2687*4882a593Smuzhiyun
2688*4882a593Smuzhiyun static enum drm_connector_status
intel_hdmi_detect(struct drm_connector * connector,bool force)2689*4882a593Smuzhiyun intel_hdmi_detect(struct drm_connector *connector, bool force)
2690*4882a593Smuzhiyun {
2691*4882a593Smuzhiyun enum drm_connector_status status = connector_status_disconnected;
2692*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(connector->dev);
2693*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
2694*4882a593Smuzhiyun struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
2695*4882a593Smuzhiyun intel_wakeref_t wakeref;
2696*4882a593Smuzhiyun
2697*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
2698*4882a593Smuzhiyun connector->base.id, connector->name);
2699*4882a593Smuzhiyun
2700*4882a593Smuzhiyun if (!INTEL_DISPLAY_ENABLED(dev_priv))
2701*4882a593Smuzhiyun return connector_status_disconnected;
2702*4882a593Smuzhiyun
2703*4882a593Smuzhiyun wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
2704*4882a593Smuzhiyun
2705*4882a593Smuzhiyun if (INTEL_GEN(dev_priv) >= 11 &&
2706*4882a593Smuzhiyun !intel_digital_port_connected(encoder))
2707*4882a593Smuzhiyun goto out;
2708*4882a593Smuzhiyun
2709*4882a593Smuzhiyun intel_hdmi_unset_edid(connector);
2710*4882a593Smuzhiyun
2711*4882a593Smuzhiyun if (intel_hdmi_set_edid(connector))
2712*4882a593Smuzhiyun status = connector_status_connected;
2713*4882a593Smuzhiyun
2714*4882a593Smuzhiyun out:
2715*4882a593Smuzhiyun intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
2716*4882a593Smuzhiyun
2717*4882a593Smuzhiyun if (status != connector_status_connected)
2718*4882a593Smuzhiyun cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);
2719*4882a593Smuzhiyun
2720*4882a593Smuzhiyun /*
2721*4882a593Smuzhiyun * Make sure the refs for power wells enabled during detect are
2722*4882a593Smuzhiyun * dropped to avoid a new detect cycle triggered by HPD polling.
2723*4882a593Smuzhiyun */
2724*4882a593Smuzhiyun intel_display_power_flush_work(dev_priv);
2725*4882a593Smuzhiyun
2726*4882a593Smuzhiyun return status;
2727*4882a593Smuzhiyun }
2728*4882a593Smuzhiyun
2729*4882a593Smuzhiyun static void
intel_hdmi_force(struct drm_connector * connector)2730*4882a593Smuzhiyun intel_hdmi_force(struct drm_connector *connector)
2731*4882a593Smuzhiyun {
2732*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(connector->dev);
2733*4882a593Smuzhiyun
2734*4882a593Smuzhiyun drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n",
2735*4882a593Smuzhiyun connector->base.id, connector->name);
2736*4882a593Smuzhiyun
2737*4882a593Smuzhiyun intel_hdmi_unset_edid(connector);
2738*4882a593Smuzhiyun
2739*4882a593Smuzhiyun if (connector->status != connector_status_connected)
2740*4882a593Smuzhiyun return;
2741*4882a593Smuzhiyun
2742*4882a593Smuzhiyun intel_hdmi_set_edid(connector);
2743*4882a593Smuzhiyun }
2744*4882a593Smuzhiyun
intel_hdmi_get_modes(struct drm_connector * connector)2745*4882a593Smuzhiyun static int intel_hdmi_get_modes(struct drm_connector *connector)
2746*4882a593Smuzhiyun {
2747*4882a593Smuzhiyun struct edid *edid;
2748*4882a593Smuzhiyun
2749*4882a593Smuzhiyun edid = to_intel_connector(connector)->detect_edid;
2750*4882a593Smuzhiyun if (edid == NULL)
2751*4882a593Smuzhiyun return 0;
2752*4882a593Smuzhiyun
2753*4882a593Smuzhiyun return intel_connector_update_modes(connector, edid);
2754*4882a593Smuzhiyun }
2755*4882a593Smuzhiyun
intel_hdmi_pre_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)2756*4882a593Smuzhiyun static void intel_hdmi_pre_enable(struct intel_atomic_state *state,
2757*4882a593Smuzhiyun struct intel_encoder *encoder,
2758*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
2759*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2760*4882a593Smuzhiyun {
2761*4882a593Smuzhiyun struct intel_digital_port *dig_port =
2762*4882a593Smuzhiyun enc_to_dig_port(encoder);
2763*4882a593Smuzhiyun
2764*4882a593Smuzhiyun intel_hdmi_prepare(encoder, pipe_config);
2765*4882a593Smuzhiyun
2766*4882a593Smuzhiyun dig_port->set_infoframes(encoder,
2767*4882a593Smuzhiyun pipe_config->has_infoframe,
2768*4882a593Smuzhiyun pipe_config, conn_state);
2769*4882a593Smuzhiyun }
2770*4882a593Smuzhiyun
vlv_hdmi_pre_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)2771*4882a593Smuzhiyun static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
2772*4882a593Smuzhiyun struct intel_encoder *encoder,
2773*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
2774*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2775*4882a593Smuzhiyun {
2776*4882a593Smuzhiyun struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
2777*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2778*4882a593Smuzhiyun
2779*4882a593Smuzhiyun vlv_phy_pre_encoder_enable(encoder, pipe_config);
2780*4882a593Smuzhiyun
2781*4882a593Smuzhiyun /* HDMI 1.0V-2dB */
2782*4882a593Smuzhiyun vlv_set_phy_signal_level(encoder, 0x2b245f5f, 0x00002000, 0x5578b83a,
2783*4882a593Smuzhiyun 0x2b247878);
2784*4882a593Smuzhiyun
2785*4882a593Smuzhiyun dig_port->set_infoframes(encoder,
2786*4882a593Smuzhiyun pipe_config->has_infoframe,
2787*4882a593Smuzhiyun pipe_config, conn_state);
2788*4882a593Smuzhiyun
2789*4882a593Smuzhiyun g4x_enable_hdmi(state, encoder, pipe_config, conn_state);
2790*4882a593Smuzhiyun
2791*4882a593Smuzhiyun vlv_wait_port_ready(dev_priv, dig_port, 0x0);
2792*4882a593Smuzhiyun }
2793*4882a593Smuzhiyun
vlv_hdmi_pre_pll_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)2794*4882a593Smuzhiyun static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
2795*4882a593Smuzhiyun struct intel_encoder *encoder,
2796*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
2797*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2798*4882a593Smuzhiyun {
2799*4882a593Smuzhiyun intel_hdmi_prepare(encoder, pipe_config);
2800*4882a593Smuzhiyun
2801*4882a593Smuzhiyun vlv_phy_pre_pll_enable(encoder, pipe_config);
2802*4882a593Smuzhiyun }
2803*4882a593Smuzhiyun
chv_hdmi_pre_pll_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)2804*4882a593Smuzhiyun static void chv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
2805*4882a593Smuzhiyun struct intel_encoder *encoder,
2806*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
2807*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2808*4882a593Smuzhiyun {
2809*4882a593Smuzhiyun intel_hdmi_prepare(encoder, pipe_config);
2810*4882a593Smuzhiyun
2811*4882a593Smuzhiyun chv_phy_pre_pll_enable(encoder, pipe_config);
2812*4882a593Smuzhiyun }
2813*4882a593Smuzhiyun
chv_hdmi_post_pll_disable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)2814*4882a593Smuzhiyun static void chv_hdmi_post_pll_disable(struct intel_atomic_state *state,
2815*4882a593Smuzhiyun struct intel_encoder *encoder,
2816*4882a593Smuzhiyun const struct intel_crtc_state *old_crtc_state,
2817*4882a593Smuzhiyun const struct drm_connector_state *old_conn_state)
2818*4882a593Smuzhiyun {
2819*4882a593Smuzhiyun chv_phy_post_pll_disable(encoder, old_crtc_state);
2820*4882a593Smuzhiyun }
2821*4882a593Smuzhiyun
vlv_hdmi_post_disable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)2822*4882a593Smuzhiyun static void vlv_hdmi_post_disable(struct intel_atomic_state *state,
2823*4882a593Smuzhiyun struct intel_encoder *encoder,
2824*4882a593Smuzhiyun const struct intel_crtc_state *old_crtc_state,
2825*4882a593Smuzhiyun const struct drm_connector_state *old_conn_state)
2826*4882a593Smuzhiyun {
2827*4882a593Smuzhiyun /* Reset lanes to avoid HDMI flicker (VLV w/a) */
2828*4882a593Smuzhiyun vlv_phy_reset_lanes(encoder, old_crtc_state);
2829*4882a593Smuzhiyun }
2830*4882a593Smuzhiyun
chv_hdmi_post_disable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * old_crtc_state,const struct drm_connector_state * old_conn_state)2831*4882a593Smuzhiyun static void chv_hdmi_post_disable(struct intel_atomic_state *state,
2832*4882a593Smuzhiyun struct intel_encoder *encoder,
2833*4882a593Smuzhiyun const struct intel_crtc_state *old_crtc_state,
2834*4882a593Smuzhiyun const struct drm_connector_state *old_conn_state)
2835*4882a593Smuzhiyun {
2836*4882a593Smuzhiyun struct drm_device *dev = encoder->base.dev;
2837*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
2838*4882a593Smuzhiyun
2839*4882a593Smuzhiyun vlv_dpio_get(dev_priv);
2840*4882a593Smuzhiyun
2841*4882a593Smuzhiyun /* Assert data lane reset */
2842*4882a593Smuzhiyun chv_data_lane_soft_reset(encoder, old_crtc_state, true);
2843*4882a593Smuzhiyun
2844*4882a593Smuzhiyun vlv_dpio_put(dev_priv);
2845*4882a593Smuzhiyun }
2846*4882a593Smuzhiyun
chv_hdmi_pre_enable(struct intel_atomic_state * state,struct intel_encoder * encoder,const struct intel_crtc_state * pipe_config,const struct drm_connector_state * conn_state)2847*4882a593Smuzhiyun static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
2848*4882a593Smuzhiyun struct intel_encoder *encoder,
2849*4882a593Smuzhiyun const struct intel_crtc_state *pipe_config,
2850*4882a593Smuzhiyun const struct drm_connector_state *conn_state)
2851*4882a593Smuzhiyun {
2852*4882a593Smuzhiyun struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
2853*4882a593Smuzhiyun struct drm_device *dev = encoder->base.dev;
2854*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
2855*4882a593Smuzhiyun
2856*4882a593Smuzhiyun chv_phy_pre_encoder_enable(encoder, pipe_config);
2857*4882a593Smuzhiyun
2858*4882a593Smuzhiyun /* FIXME: Program the support xxx V-dB */
2859*4882a593Smuzhiyun /* Use 800mV-0dB */
2860*4882a593Smuzhiyun chv_set_phy_signal_level(encoder, 128, 102, false);
2861*4882a593Smuzhiyun
2862*4882a593Smuzhiyun dig_port->set_infoframes(encoder,
2863*4882a593Smuzhiyun pipe_config->has_infoframe,
2864*4882a593Smuzhiyun pipe_config, conn_state);
2865*4882a593Smuzhiyun
2866*4882a593Smuzhiyun g4x_enable_hdmi(state, encoder, pipe_config, conn_state);
2867*4882a593Smuzhiyun
2868*4882a593Smuzhiyun vlv_wait_port_ready(dev_priv, dig_port, 0x0);
2869*4882a593Smuzhiyun
2870*4882a593Smuzhiyun /* Second common lane will stay alive on its own now */
2871*4882a593Smuzhiyun chv_phy_release_cl2_override(encoder);
2872*4882a593Smuzhiyun }
2873*4882a593Smuzhiyun
2874*4882a593Smuzhiyun static struct i2c_adapter *
intel_hdmi_get_i2c_adapter(struct drm_connector * connector)2875*4882a593Smuzhiyun intel_hdmi_get_i2c_adapter(struct drm_connector *connector)
2876*4882a593Smuzhiyun {
2877*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(connector->dev);
2878*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
2879*4882a593Smuzhiyun
2880*4882a593Smuzhiyun return intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
2881*4882a593Smuzhiyun }
2882*4882a593Smuzhiyun
intel_hdmi_create_i2c_symlink(struct drm_connector * connector)2883*4882a593Smuzhiyun static void intel_hdmi_create_i2c_symlink(struct drm_connector *connector)
2884*4882a593Smuzhiyun {
2885*4882a593Smuzhiyun struct drm_i915_private *i915 = to_i915(connector->dev);
2886*4882a593Smuzhiyun struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector);
2887*4882a593Smuzhiyun struct kobject *i2c_kobj = &adapter->dev.kobj;
2888*4882a593Smuzhiyun struct kobject *connector_kobj = &connector->kdev->kobj;
2889*4882a593Smuzhiyun int ret;
2890*4882a593Smuzhiyun
2891*4882a593Smuzhiyun ret = sysfs_create_link(connector_kobj, i2c_kobj, i2c_kobj->name);
2892*4882a593Smuzhiyun if (ret)
2893*4882a593Smuzhiyun drm_err(&i915->drm, "Failed to create i2c symlink (%d)\n", ret);
2894*4882a593Smuzhiyun }
2895*4882a593Smuzhiyun
intel_hdmi_remove_i2c_symlink(struct drm_connector * connector)2896*4882a593Smuzhiyun static void intel_hdmi_remove_i2c_symlink(struct drm_connector *connector)
2897*4882a593Smuzhiyun {
2898*4882a593Smuzhiyun struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector);
2899*4882a593Smuzhiyun struct kobject *i2c_kobj = &adapter->dev.kobj;
2900*4882a593Smuzhiyun struct kobject *connector_kobj = &connector->kdev->kobj;
2901*4882a593Smuzhiyun
2902*4882a593Smuzhiyun sysfs_remove_link(connector_kobj, i2c_kobj->name);
2903*4882a593Smuzhiyun }
2904*4882a593Smuzhiyun
2905*4882a593Smuzhiyun static int
intel_hdmi_connector_register(struct drm_connector * connector)2906*4882a593Smuzhiyun intel_hdmi_connector_register(struct drm_connector *connector)
2907*4882a593Smuzhiyun {
2908*4882a593Smuzhiyun int ret;
2909*4882a593Smuzhiyun
2910*4882a593Smuzhiyun ret = intel_connector_register(connector);
2911*4882a593Smuzhiyun if (ret)
2912*4882a593Smuzhiyun return ret;
2913*4882a593Smuzhiyun
2914*4882a593Smuzhiyun intel_hdmi_create_i2c_symlink(connector);
2915*4882a593Smuzhiyun
2916*4882a593Smuzhiyun return ret;
2917*4882a593Smuzhiyun }
2918*4882a593Smuzhiyun
intel_hdmi_connector_unregister(struct drm_connector * connector)2919*4882a593Smuzhiyun static void intel_hdmi_connector_unregister(struct drm_connector *connector)
2920*4882a593Smuzhiyun {
2921*4882a593Smuzhiyun struct cec_notifier *n = intel_attached_hdmi(to_intel_connector(connector))->cec_notifier;
2922*4882a593Smuzhiyun
2923*4882a593Smuzhiyun cec_notifier_conn_unregister(n);
2924*4882a593Smuzhiyun
2925*4882a593Smuzhiyun intel_hdmi_remove_i2c_symlink(connector);
2926*4882a593Smuzhiyun intel_connector_unregister(connector);
2927*4882a593Smuzhiyun }
2928*4882a593Smuzhiyun
2929*4882a593Smuzhiyun static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
2930*4882a593Smuzhiyun .detect = intel_hdmi_detect,
2931*4882a593Smuzhiyun .force = intel_hdmi_force,
2932*4882a593Smuzhiyun .fill_modes = drm_helper_probe_single_connector_modes,
2933*4882a593Smuzhiyun .atomic_get_property = intel_digital_connector_atomic_get_property,
2934*4882a593Smuzhiyun .atomic_set_property = intel_digital_connector_atomic_set_property,
2935*4882a593Smuzhiyun .late_register = intel_hdmi_connector_register,
2936*4882a593Smuzhiyun .early_unregister = intel_hdmi_connector_unregister,
2937*4882a593Smuzhiyun .destroy = intel_connector_destroy,
2938*4882a593Smuzhiyun .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
2939*4882a593Smuzhiyun .atomic_duplicate_state = intel_digital_connector_duplicate_state,
2940*4882a593Smuzhiyun };
2941*4882a593Smuzhiyun
2942*4882a593Smuzhiyun static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
2943*4882a593Smuzhiyun .get_modes = intel_hdmi_get_modes,
2944*4882a593Smuzhiyun .mode_valid = intel_hdmi_mode_valid,
2945*4882a593Smuzhiyun .atomic_check = intel_digital_connector_atomic_check,
2946*4882a593Smuzhiyun };
2947*4882a593Smuzhiyun
2948*4882a593Smuzhiyun static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
2949*4882a593Smuzhiyun .destroy = intel_encoder_destroy,
2950*4882a593Smuzhiyun };
2951*4882a593Smuzhiyun
2952*4882a593Smuzhiyun static void
intel_hdmi_add_properties(struct intel_hdmi * intel_hdmi,struct drm_connector * connector)2953*4882a593Smuzhiyun intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
2954*4882a593Smuzhiyun {
2955*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(connector->dev);
2956*4882a593Smuzhiyun struct intel_digital_port *dig_port =
2957*4882a593Smuzhiyun hdmi_to_dig_port(intel_hdmi);
2958*4882a593Smuzhiyun
2959*4882a593Smuzhiyun intel_attach_force_audio_property(connector);
2960*4882a593Smuzhiyun intel_attach_broadcast_rgb_property(connector);
2961*4882a593Smuzhiyun intel_attach_aspect_ratio_property(connector);
2962*4882a593Smuzhiyun
2963*4882a593Smuzhiyun /*
2964*4882a593Smuzhiyun * Attach Colorspace property for Non LSPCON based device
2965*4882a593Smuzhiyun * ToDo: This needs to be extended for LSPCON implementation
2966*4882a593Smuzhiyun * as well. Will be implemented separately.
2967*4882a593Smuzhiyun */
2968*4882a593Smuzhiyun if (!dig_port->lspcon.active)
2969*4882a593Smuzhiyun intel_attach_colorspace_property(connector);
2970*4882a593Smuzhiyun
2971*4882a593Smuzhiyun drm_connector_attach_content_type_property(connector);
2972*4882a593Smuzhiyun
2973*4882a593Smuzhiyun if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
2974*4882a593Smuzhiyun drm_object_attach_property(&connector->base,
2975*4882a593Smuzhiyun connector->dev->mode_config.hdr_output_metadata_property, 0);
2976*4882a593Smuzhiyun
2977*4882a593Smuzhiyun if (!HAS_GMCH(dev_priv))
2978*4882a593Smuzhiyun drm_connector_attach_max_bpc_property(connector, 8, 12);
2979*4882a593Smuzhiyun }
2980*4882a593Smuzhiyun
2981*4882a593Smuzhiyun /*
2982*4882a593Smuzhiyun * intel_hdmi_handle_sink_scrambling: handle sink scrambling/clock ratio setup
2983*4882a593Smuzhiyun * @encoder: intel_encoder
2984*4882a593Smuzhiyun * @connector: drm_connector
2985*4882a593Smuzhiyun * @high_tmds_clock_ratio = bool to indicate if the function needs to set
2986*4882a593Smuzhiyun * or reset the high tmds clock ratio for scrambling
2987*4882a593Smuzhiyun * @scrambling: bool to Indicate if the function needs to set or reset
2988*4882a593Smuzhiyun * sink scrambling
2989*4882a593Smuzhiyun *
2990*4882a593Smuzhiyun * This function handles scrambling on HDMI 2.0 capable sinks.
2991*4882a593Smuzhiyun * If required clock rate is > 340 Mhz && scrambling is supported by sink
2992*4882a593Smuzhiyun * it enables scrambling. This should be called before enabling the HDMI
2993*4882a593Smuzhiyun * 2.0 port, as the sink can choose to disable the scrambling if it doesn't
2994*4882a593Smuzhiyun * detect a scrambled clock within 100 ms.
2995*4882a593Smuzhiyun *
2996*4882a593Smuzhiyun * Returns:
2997*4882a593Smuzhiyun * True on success, false on failure.
2998*4882a593Smuzhiyun */
intel_hdmi_handle_sink_scrambling(struct intel_encoder * encoder,struct drm_connector * connector,bool high_tmds_clock_ratio,bool scrambling)2999*4882a593Smuzhiyun bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
3000*4882a593Smuzhiyun struct drm_connector *connector,
3001*4882a593Smuzhiyun bool high_tmds_clock_ratio,
3002*4882a593Smuzhiyun bool scrambling)
3003*4882a593Smuzhiyun {
3004*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3005*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
3006*4882a593Smuzhiyun struct drm_scrambling *sink_scrambling =
3007*4882a593Smuzhiyun &connector->display_info.hdmi.scdc.scrambling;
3008*4882a593Smuzhiyun struct i2c_adapter *adapter =
3009*4882a593Smuzhiyun intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
3010*4882a593Smuzhiyun
3011*4882a593Smuzhiyun if (!sink_scrambling->supported)
3012*4882a593Smuzhiyun return true;
3013*4882a593Smuzhiyun
3014*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
3015*4882a593Smuzhiyun "[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n",
3016*4882a593Smuzhiyun connector->base.id, connector->name,
3017*4882a593Smuzhiyun yesno(scrambling), high_tmds_clock_ratio ? 40 : 10);
3018*4882a593Smuzhiyun
3019*4882a593Smuzhiyun /* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */
3020*4882a593Smuzhiyun return drm_scdc_set_high_tmds_clock_ratio(adapter,
3021*4882a593Smuzhiyun high_tmds_clock_ratio) &&
3022*4882a593Smuzhiyun drm_scdc_set_scrambling(adapter, scrambling);
3023*4882a593Smuzhiyun }
3024*4882a593Smuzhiyun
chv_port_to_ddc_pin(struct drm_i915_private * dev_priv,enum port port)3025*4882a593Smuzhiyun static u8 chv_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
3026*4882a593Smuzhiyun {
3027*4882a593Smuzhiyun u8 ddc_pin;
3028*4882a593Smuzhiyun
3029*4882a593Smuzhiyun switch (port) {
3030*4882a593Smuzhiyun case PORT_B:
3031*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_DPB;
3032*4882a593Smuzhiyun break;
3033*4882a593Smuzhiyun case PORT_C:
3034*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_DPC;
3035*4882a593Smuzhiyun break;
3036*4882a593Smuzhiyun case PORT_D:
3037*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_DPD_CHV;
3038*4882a593Smuzhiyun break;
3039*4882a593Smuzhiyun default:
3040*4882a593Smuzhiyun MISSING_CASE(port);
3041*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_DPB;
3042*4882a593Smuzhiyun break;
3043*4882a593Smuzhiyun }
3044*4882a593Smuzhiyun return ddc_pin;
3045*4882a593Smuzhiyun }
3046*4882a593Smuzhiyun
bxt_port_to_ddc_pin(struct drm_i915_private * dev_priv,enum port port)3047*4882a593Smuzhiyun static u8 bxt_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
3048*4882a593Smuzhiyun {
3049*4882a593Smuzhiyun u8 ddc_pin;
3050*4882a593Smuzhiyun
3051*4882a593Smuzhiyun switch (port) {
3052*4882a593Smuzhiyun case PORT_B:
3053*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_1_BXT;
3054*4882a593Smuzhiyun break;
3055*4882a593Smuzhiyun case PORT_C:
3056*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_2_BXT;
3057*4882a593Smuzhiyun break;
3058*4882a593Smuzhiyun default:
3059*4882a593Smuzhiyun MISSING_CASE(port);
3060*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_1_BXT;
3061*4882a593Smuzhiyun break;
3062*4882a593Smuzhiyun }
3063*4882a593Smuzhiyun return ddc_pin;
3064*4882a593Smuzhiyun }
3065*4882a593Smuzhiyun
cnp_port_to_ddc_pin(struct drm_i915_private * dev_priv,enum port port)3066*4882a593Smuzhiyun static u8 cnp_port_to_ddc_pin(struct drm_i915_private *dev_priv,
3067*4882a593Smuzhiyun enum port port)
3068*4882a593Smuzhiyun {
3069*4882a593Smuzhiyun u8 ddc_pin;
3070*4882a593Smuzhiyun
3071*4882a593Smuzhiyun switch (port) {
3072*4882a593Smuzhiyun case PORT_B:
3073*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_1_BXT;
3074*4882a593Smuzhiyun break;
3075*4882a593Smuzhiyun case PORT_C:
3076*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_2_BXT;
3077*4882a593Smuzhiyun break;
3078*4882a593Smuzhiyun case PORT_D:
3079*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_4_CNP;
3080*4882a593Smuzhiyun break;
3081*4882a593Smuzhiyun case PORT_F:
3082*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_3_BXT;
3083*4882a593Smuzhiyun break;
3084*4882a593Smuzhiyun default:
3085*4882a593Smuzhiyun MISSING_CASE(port);
3086*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_1_BXT;
3087*4882a593Smuzhiyun break;
3088*4882a593Smuzhiyun }
3089*4882a593Smuzhiyun return ddc_pin;
3090*4882a593Smuzhiyun }
3091*4882a593Smuzhiyun
icl_port_to_ddc_pin(struct drm_i915_private * dev_priv,enum port port)3092*4882a593Smuzhiyun static u8 icl_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
3093*4882a593Smuzhiyun {
3094*4882a593Smuzhiyun enum phy phy = intel_port_to_phy(dev_priv, port);
3095*4882a593Smuzhiyun
3096*4882a593Smuzhiyun if (intel_phy_is_combo(dev_priv, phy))
3097*4882a593Smuzhiyun return GMBUS_PIN_1_BXT + port;
3098*4882a593Smuzhiyun else if (intel_phy_is_tc(dev_priv, phy))
3099*4882a593Smuzhiyun return GMBUS_PIN_9_TC1_ICP + intel_port_to_tc(dev_priv, port);
3100*4882a593Smuzhiyun
3101*4882a593Smuzhiyun drm_WARN(&dev_priv->drm, 1, "Unknown port:%c\n", port_name(port));
3102*4882a593Smuzhiyun return GMBUS_PIN_2_BXT;
3103*4882a593Smuzhiyun }
3104*4882a593Smuzhiyun
mcc_port_to_ddc_pin(struct drm_i915_private * dev_priv,enum port port)3105*4882a593Smuzhiyun static u8 mcc_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
3106*4882a593Smuzhiyun {
3107*4882a593Smuzhiyun enum phy phy = intel_port_to_phy(dev_priv, port);
3108*4882a593Smuzhiyun u8 ddc_pin;
3109*4882a593Smuzhiyun
3110*4882a593Smuzhiyun switch (phy) {
3111*4882a593Smuzhiyun case PHY_A:
3112*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_1_BXT;
3113*4882a593Smuzhiyun break;
3114*4882a593Smuzhiyun case PHY_B:
3115*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_2_BXT;
3116*4882a593Smuzhiyun break;
3117*4882a593Smuzhiyun case PHY_C:
3118*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_9_TC1_ICP;
3119*4882a593Smuzhiyun break;
3120*4882a593Smuzhiyun default:
3121*4882a593Smuzhiyun MISSING_CASE(phy);
3122*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_1_BXT;
3123*4882a593Smuzhiyun break;
3124*4882a593Smuzhiyun }
3125*4882a593Smuzhiyun return ddc_pin;
3126*4882a593Smuzhiyun }
3127*4882a593Smuzhiyun
rkl_port_to_ddc_pin(struct drm_i915_private * dev_priv,enum port port)3128*4882a593Smuzhiyun static u8 rkl_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
3129*4882a593Smuzhiyun {
3130*4882a593Smuzhiyun enum phy phy = intel_port_to_phy(dev_priv, port);
3131*4882a593Smuzhiyun
3132*4882a593Smuzhiyun WARN_ON(port == PORT_C);
3133*4882a593Smuzhiyun
3134*4882a593Smuzhiyun /*
3135*4882a593Smuzhiyun * Pin mapping for RKL depends on which PCH is present. With TGP, the
3136*4882a593Smuzhiyun * final two outputs use type-c pins, even though they're actually
3137*4882a593Smuzhiyun * combo outputs. With CMP, the traditional DDI A-D pins are used for
3138*4882a593Smuzhiyun * all outputs.
3139*4882a593Smuzhiyun */
3140*4882a593Smuzhiyun if (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && phy >= PHY_C)
3141*4882a593Smuzhiyun return GMBUS_PIN_9_TC1_ICP + phy - PHY_C;
3142*4882a593Smuzhiyun
3143*4882a593Smuzhiyun return GMBUS_PIN_1_BXT + phy;
3144*4882a593Smuzhiyun }
3145*4882a593Smuzhiyun
g4x_port_to_ddc_pin(struct drm_i915_private * dev_priv,enum port port)3146*4882a593Smuzhiyun static u8 g4x_port_to_ddc_pin(struct drm_i915_private *dev_priv,
3147*4882a593Smuzhiyun enum port port)
3148*4882a593Smuzhiyun {
3149*4882a593Smuzhiyun u8 ddc_pin;
3150*4882a593Smuzhiyun
3151*4882a593Smuzhiyun switch (port) {
3152*4882a593Smuzhiyun case PORT_B:
3153*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_DPB;
3154*4882a593Smuzhiyun break;
3155*4882a593Smuzhiyun case PORT_C:
3156*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_DPC;
3157*4882a593Smuzhiyun break;
3158*4882a593Smuzhiyun case PORT_D:
3159*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_DPD;
3160*4882a593Smuzhiyun break;
3161*4882a593Smuzhiyun default:
3162*4882a593Smuzhiyun MISSING_CASE(port);
3163*4882a593Smuzhiyun ddc_pin = GMBUS_PIN_DPB;
3164*4882a593Smuzhiyun break;
3165*4882a593Smuzhiyun }
3166*4882a593Smuzhiyun return ddc_pin;
3167*4882a593Smuzhiyun }
3168*4882a593Smuzhiyun
intel_hdmi_ddc_pin(struct intel_encoder * encoder)3169*4882a593Smuzhiyun static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
3170*4882a593Smuzhiyun {
3171*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3172*4882a593Smuzhiyun enum port port = encoder->port;
3173*4882a593Smuzhiyun u8 ddc_pin;
3174*4882a593Smuzhiyun
3175*4882a593Smuzhiyun ddc_pin = intel_bios_alternate_ddc_pin(encoder);
3176*4882a593Smuzhiyun if (ddc_pin) {
3177*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
3178*4882a593Smuzhiyun "Using DDC pin 0x%x for port %c (VBT)\n",
3179*4882a593Smuzhiyun ddc_pin, port_name(port));
3180*4882a593Smuzhiyun return ddc_pin;
3181*4882a593Smuzhiyun }
3182*4882a593Smuzhiyun
3183*4882a593Smuzhiyun if (IS_ROCKETLAKE(dev_priv))
3184*4882a593Smuzhiyun ddc_pin = rkl_port_to_ddc_pin(dev_priv, port);
3185*4882a593Smuzhiyun else if (HAS_PCH_MCC(dev_priv))
3186*4882a593Smuzhiyun ddc_pin = mcc_port_to_ddc_pin(dev_priv, port);
3187*4882a593Smuzhiyun else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
3188*4882a593Smuzhiyun ddc_pin = icl_port_to_ddc_pin(dev_priv, port);
3189*4882a593Smuzhiyun else if (HAS_PCH_CNP(dev_priv))
3190*4882a593Smuzhiyun ddc_pin = cnp_port_to_ddc_pin(dev_priv, port);
3191*4882a593Smuzhiyun else if (IS_GEN9_LP(dev_priv))
3192*4882a593Smuzhiyun ddc_pin = bxt_port_to_ddc_pin(dev_priv, port);
3193*4882a593Smuzhiyun else if (IS_CHERRYVIEW(dev_priv))
3194*4882a593Smuzhiyun ddc_pin = chv_port_to_ddc_pin(dev_priv, port);
3195*4882a593Smuzhiyun else
3196*4882a593Smuzhiyun ddc_pin = g4x_port_to_ddc_pin(dev_priv, port);
3197*4882a593Smuzhiyun
3198*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
3199*4882a593Smuzhiyun "Using DDC pin 0x%x for port %c (platform default)\n",
3200*4882a593Smuzhiyun ddc_pin, port_name(port));
3201*4882a593Smuzhiyun
3202*4882a593Smuzhiyun return ddc_pin;
3203*4882a593Smuzhiyun }
3204*4882a593Smuzhiyun
intel_infoframe_init(struct intel_digital_port * dig_port)3205*4882a593Smuzhiyun void intel_infoframe_init(struct intel_digital_port *dig_port)
3206*4882a593Smuzhiyun {
3207*4882a593Smuzhiyun struct drm_i915_private *dev_priv =
3208*4882a593Smuzhiyun to_i915(dig_port->base.base.dev);
3209*4882a593Smuzhiyun
3210*4882a593Smuzhiyun if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
3211*4882a593Smuzhiyun dig_port->write_infoframe = vlv_write_infoframe;
3212*4882a593Smuzhiyun dig_port->read_infoframe = vlv_read_infoframe;
3213*4882a593Smuzhiyun dig_port->set_infoframes = vlv_set_infoframes;
3214*4882a593Smuzhiyun dig_port->infoframes_enabled = vlv_infoframes_enabled;
3215*4882a593Smuzhiyun } else if (IS_G4X(dev_priv)) {
3216*4882a593Smuzhiyun dig_port->write_infoframe = g4x_write_infoframe;
3217*4882a593Smuzhiyun dig_port->read_infoframe = g4x_read_infoframe;
3218*4882a593Smuzhiyun dig_port->set_infoframes = g4x_set_infoframes;
3219*4882a593Smuzhiyun dig_port->infoframes_enabled = g4x_infoframes_enabled;
3220*4882a593Smuzhiyun } else if (HAS_DDI(dev_priv)) {
3221*4882a593Smuzhiyun if (dig_port->lspcon.active) {
3222*4882a593Smuzhiyun dig_port->write_infoframe = lspcon_write_infoframe;
3223*4882a593Smuzhiyun dig_port->read_infoframe = lspcon_read_infoframe;
3224*4882a593Smuzhiyun dig_port->set_infoframes = lspcon_set_infoframes;
3225*4882a593Smuzhiyun dig_port->infoframes_enabled = lspcon_infoframes_enabled;
3226*4882a593Smuzhiyun } else {
3227*4882a593Smuzhiyun dig_port->write_infoframe = hsw_write_infoframe;
3228*4882a593Smuzhiyun dig_port->read_infoframe = hsw_read_infoframe;
3229*4882a593Smuzhiyun dig_port->set_infoframes = hsw_set_infoframes;
3230*4882a593Smuzhiyun dig_port->infoframes_enabled = hsw_infoframes_enabled;
3231*4882a593Smuzhiyun }
3232*4882a593Smuzhiyun } else if (HAS_PCH_IBX(dev_priv)) {
3233*4882a593Smuzhiyun dig_port->write_infoframe = ibx_write_infoframe;
3234*4882a593Smuzhiyun dig_port->read_infoframe = ibx_read_infoframe;
3235*4882a593Smuzhiyun dig_port->set_infoframes = ibx_set_infoframes;
3236*4882a593Smuzhiyun dig_port->infoframes_enabled = ibx_infoframes_enabled;
3237*4882a593Smuzhiyun } else {
3238*4882a593Smuzhiyun dig_port->write_infoframe = cpt_write_infoframe;
3239*4882a593Smuzhiyun dig_port->read_infoframe = cpt_read_infoframe;
3240*4882a593Smuzhiyun dig_port->set_infoframes = cpt_set_infoframes;
3241*4882a593Smuzhiyun dig_port->infoframes_enabled = cpt_infoframes_enabled;
3242*4882a593Smuzhiyun }
3243*4882a593Smuzhiyun }
3244*4882a593Smuzhiyun
intel_hdmi_init_connector(struct intel_digital_port * dig_port,struct intel_connector * intel_connector)3245*4882a593Smuzhiyun void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
3246*4882a593Smuzhiyun struct intel_connector *intel_connector)
3247*4882a593Smuzhiyun {
3248*4882a593Smuzhiyun struct drm_connector *connector = &intel_connector->base;
3249*4882a593Smuzhiyun struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
3250*4882a593Smuzhiyun struct intel_encoder *intel_encoder = &dig_port->base;
3251*4882a593Smuzhiyun struct drm_device *dev = intel_encoder->base.dev;
3252*4882a593Smuzhiyun struct drm_i915_private *dev_priv = to_i915(dev);
3253*4882a593Smuzhiyun struct i2c_adapter *ddc;
3254*4882a593Smuzhiyun enum port port = intel_encoder->port;
3255*4882a593Smuzhiyun struct cec_connector_info conn_info;
3256*4882a593Smuzhiyun
3257*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
3258*4882a593Smuzhiyun "Adding HDMI connector on [ENCODER:%d:%s]\n",
3259*4882a593Smuzhiyun intel_encoder->base.base.id, intel_encoder->base.name);
3260*4882a593Smuzhiyun
3261*4882a593Smuzhiyun if (INTEL_GEN(dev_priv) < 12 && drm_WARN_ON(dev, port == PORT_A))
3262*4882a593Smuzhiyun return;
3263*4882a593Smuzhiyun
3264*4882a593Smuzhiyun if (drm_WARN(dev, dig_port->max_lanes < 4,
3265*4882a593Smuzhiyun "Not enough lanes (%d) for HDMI on [ENCODER:%d:%s]\n",
3266*4882a593Smuzhiyun dig_port->max_lanes, intel_encoder->base.base.id,
3267*4882a593Smuzhiyun intel_encoder->base.name))
3268*4882a593Smuzhiyun return;
3269*4882a593Smuzhiyun
3270*4882a593Smuzhiyun intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(intel_encoder);
3271*4882a593Smuzhiyun ddc = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
3272*4882a593Smuzhiyun
3273*4882a593Smuzhiyun drm_connector_init_with_ddc(dev, connector,
3274*4882a593Smuzhiyun &intel_hdmi_connector_funcs,
3275*4882a593Smuzhiyun DRM_MODE_CONNECTOR_HDMIA,
3276*4882a593Smuzhiyun ddc);
3277*4882a593Smuzhiyun drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
3278*4882a593Smuzhiyun
3279*4882a593Smuzhiyun connector->interlace_allowed = 1;
3280*4882a593Smuzhiyun connector->doublescan_allowed = 0;
3281*4882a593Smuzhiyun connector->stereo_allowed = 1;
3282*4882a593Smuzhiyun
3283*4882a593Smuzhiyun if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
3284*4882a593Smuzhiyun connector->ycbcr_420_allowed = true;
3285*4882a593Smuzhiyun
3286*4882a593Smuzhiyun intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
3287*4882a593Smuzhiyun
3288*4882a593Smuzhiyun if (HAS_DDI(dev_priv))
3289*4882a593Smuzhiyun intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
3290*4882a593Smuzhiyun else
3291*4882a593Smuzhiyun intel_connector->get_hw_state = intel_connector_get_hw_state;
3292*4882a593Smuzhiyun
3293*4882a593Smuzhiyun intel_hdmi_add_properties(intel_hdmi, connector);
3294*4882a593Smuzhiyun
3295*4882a593Smuzhiyun intel_connector_attach_encoder(intel_connector, intel_encoder);
3296*4882a593Smuzhiyun intel_hdmi->attached_connector = intel_connector;
3297*4882a593Smuzhiyun
3298*4882a593Smuzhiyun if (is_hdcp_supported(dev_priv, port)) {
3299*4882a593Smuzhiyun int ret = intel_hdcp_init(intel_connector, port,
3300*4882a593Smuzhiyun &intel_hdmi_hdcp_shim);
3301*4882a593Smuzhiyun if (ret)
3302*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm,
3303*4882a593Smuzhiyun "HDCP init failed, skipping.\n");
3304*4882a593Smuzhiyun }
3305*4882a593Smuzhiyun
3306*4882a593Smuzhiyun /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
3307*4882a593Smuzhiyun * 0xd. Failure to do so will result in spurious interrupts being
3308*4882a593Smuzhiyun * generated on the port when a cable is not attached.
3309*4882a593Smuzhiyun */
3310*4882a593Smuzhiyun if (IS_G45(dev_priv)) {
3311*4882a593Smuzhiyun u32 temp = intel_de_read(dev_priv, PEG_BAND_GAP_DATA);
3312*4882a593Smuzhiyun intel_de_write(dev_priv, PEG_BAND_GAP_DATA,
3313*4882a593Smuzhiyun (temp & ~0xf) | 0xd);
3314*4882a593Smuzhiyun }
3315*4882a593Smuzhiyun
3316*4882a593Smuzhiyun cec_fill_conn_info_from_drm(&conn_info, connector);
3317*4882a593Smuzhiyun
3318*4882a593Smuzhiyun intel_hdmi->cec_notifier =
3319*4882a593Smuzhiyun cec_notifier_conn_register(dev->dev, port_identifier(port),
3320*4882a593Smuzhiyun &conn_info);
3321*4882a593Smuzhiyun if (!intel_hdmi->cec_notifier)
3322*4882a593Smuzhiyun drm_dbg_kms(&dev_priv->drm, "CEC notifier get failed\n");
3323*4882a593Smuzhiyun }
3324*4882a593Smuzhiyun
3325*4882a593Smuzhiyun static enum intel_hotplug_state
intel_hdmi_hotplug(struct intel_encoder * encoder,struct intel_connector * connector)3326*4882a593Smuzhiyun intel_hdmi_hotplug(struct intel_encoder *encoder,
3327*4882a593Smuzhiyun struct intel_connector *connector)
3328*4882a593Smuzhiyun {
3329*4882a593Smuzhiyun enum intel_hotplug_state state;
3330*4882a593Smuzhiyun
3331*4882a593Smuzhiyun state = intel_encoder_hotplug(encoder, connector);
3332*4882a593Smuzhiyun
3333*4882a593Smuzhiyun /*
3334*4882a593Smuzhiyun * On many platforms the HDMI live state signal is known to be
3335*4882a593Smuzhiyun * unreliable, so we can't use it to detect if a sink is connected or
3336*4882a593Smuzhiyun * not. Instead we detect if it's connected based on whether we can
3337*4882a593Smuzhiyun * read the EDID or not. That in turn has a problem during disconnect,
3338*4882a593Smuzhiyun * since the HPD interrupt may be raised before the DDC lines get
3339*4882a593Smuzhiyun * disconnected (due to how the required length of DDC vs. HPD
3340*4882a593Smuzhiyun * connector pins are specified) and so we'll still be able to get a
3341*4882a593Smuzhiyun * valid EDID. To solve this schedule another detection cycle if this
3342*4882a593Smuzhiyun * time around we didn't detect any change in the sink's connection
3343*4882a593Smuzhiyun * status.
3344*4882a593Smuzhiyun */
3345*4882a593Smuzhiyun if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
3346*4882a593Smuzhiyun state = INTEL_HOTPLUG_RETRY;
3347*4882a593Smuzhiyun
3348*4882a593Smuzhiyun return state;
3349*4882a593Smuzhiyun }
3350*4882a593Smuzhiyun
intel_hdmi_init(struct drm_i915_private * dev_priv,i915_reg_t hdmi_reg,enum port port)3351*4882a593Smuzhiyun void intel_hdmi_init(struct drm_i915_private *dev_priv,
3352*4882a593Smuzhiyun i915_reg_t hdmi_reg, enum port port)
3353*4882a593Smuzhiyun {
3354*4882a593Smuzhiyun struct intel_digital_port *dig_port;
3355*4882a593Smuzhiyun struct intel_encoder *intel_encoder;
3356*4882a593Smuzhiyun struct intel_connector *intel_connector;
3357*4882a593Smuzhiyun
3358*4882a593Smuzhiyun dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
3359*4882a593Smuzhiyun if (!dig_port)
3360*4882a593Smuzhiyun return;
3361*4882a593Smuzhiyun
3362*4882a593Smuzhiyun intel_connector = intel_connector_alloc();
3363*4882a593Smuzhiyun if (!intel_connector) {
3364*4882a593Smuzhiyun kfree(dig_port);
3365*4882a593Smuzhiyun return;
3366*4882a593Smuzhiyun }
3367*4882a593Smuzhiyun
3368*4882a593Smuzhiyun intel_encoder = &dig_port->base;
3369*4882a593Smuzhiyun
3370*4882a593Smuzhiyun mutex_init(&dig_port->hdcp_mutex);
3371*4882a593Smuzhiyun
3372*4882a593Smuzhiyun drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
3373*4882a593Smuzhiyun &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
3374*4882a593Smuzhiyun "HDMI %c", port_name(port));
3375*4882a593Smuzhiyun
3376*4882a593Smuzhiyun intel_encoder->hotplug = intel_hdmi_hotplug;
3377*4882a593Smuzhiyun intel_encoder->compute_config = intel_hdmi_compute_config;
3378*4882a593Smuzhiyun if (HAS_PCH_SPLIT(dev_priv)) {
3379*4882a593Smuzhiyun intel_encoder->disable = pch_disable_hdmi;
3380*4882a593Smuzhiyun intel_encoder->post_disable = pch_post_disable_hdmi;
3381*4882a593Smuzhiyun } else {
3382*4882a593Smuzhiyun intel_encoder->disable = g4x_disable_hdmi;
3383*4882a593Smuzhiyun }
3384*4882a593Smuzhiyun intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
3385*4882a593Smuzhiyun intel_encoder->get_config = intel_hdmi_get_config;
3386*4882a593Smuzhiyun if (IS_CHERRYVIEW(dev_priv)) {
3387*4882a593Smuzhiyun intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable;
3388*4882a593Smuzhiyun intel_encoder->pre_enable = chv_hdmi_pre_enable;
3389*4882a593Smuzhiyun intel_encoder->enable = vlv_enable_hdmi;
3390*4882a593Smuzhiyun intel_encoder->post_disable = chv_hdmi_post_disable;
3391*4882a593Smuzhiyun intel_encoder->post_pll_disable = chv_hdmi_post_pll_disable;
3392*4882a593Smuzhiyun } else if (IS_VALLEYVIEW(dev_priv)) {
3393*4882a593Smuzhiyun intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable;
3394*4882a593Smuzhiyun intel_encoder->pre_enable = vlv_hdmi_pre_enable;
3395*4882a593Smuzhiyun intel_encoder->enable = vlv_enable_hdmi;
3396*4882a593Smuzhiyun intel_encoder->post_disable = vlv_hdmi_post_disable;
3397*4882a593Smuzhiyun } else {
3398*4882a593Smuzhiyun intel_encoder->pre_enable = intel_hdmi_pre_enable;
3399*4882a593Smuzhiyun if (HAS_PCH_CPT(dev_priv))
3400*4882a593Smuzhiyun intel_encoder->enable = cpt_enable_hdmi;
3401*4882a593Smuzhiyun else if (HAS_PCH_IBX(dev_priv))
3402*4882a593Smuzhiyun intel_encoder->enable = ibx_enable_hdmi;
3403*4882a593Smuzhiyun else
3404*4882a593Smuzhiyun intel_encoder->enable = g4x_enable_hdmi;
3405*4882a593Smuzhiyun }
3406*4882a593Smuzhiyun
3407*4882a593Smuzhiyun intel_encoder->type = INTEL_OUTPUT_HDMI;
3408*4882a593Smuzhiyun intel_encoder->power_domain = intel_port_to_power_domain(port);
3409*4882a593Smuzhiyun intel_encoder->port = port;
3410*4882a593Smuzhiyun if (IS_CHERRYVIEW(dev_priv)) {
3411*4882a593Smuzhiyun if (port == PORT_D)
3412*4882a593Smuzhiyun intel_encoder->pipe_mask = BIT(PIPE_C);
3413*4882a593Smuzhiyun else
3414*4882a593Smuzhiyun intel_encoder->pipe_mask = BIT(PIPE_A) | BIT(PIPE_B);
3415*4882a593Smuzhiyun } else {
3416*4882a593Smuzhiyun intel_encoder->pipe_mask = ~0;
3417*4882a593Smuzhiyun }
3418*4882a593Smuzhiyun intel_encoder->cloneable = 1 << INTEL_OUTPUT_ANALOG;
3419*4882a593Smuzhiyun intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
3420*4882a593Smuzhiyun /*
3421*4882a593Smuzhiyun * BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems
3422*4882a593Smuzhiyun * to work on real hardware. And since g4x can send infoframes to
3423*4882a593Smuzhiyun * only one port anyway, nothing is lost by allowing it.
3424*4882a593Smuzhiyun */
3425*4882a593Smuzhiyun if (IS_G4X(dev_priv))
3426*4882a593Smuzhiyun intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI;
3427*4882a593Smuzhiyun
3428*4882a593Smuzhiyun dig_port->hdmi.hdmi_reg = hdmi_reg;
3429*4882a593Smuzhiyun dig_port->dp.output_reg = INVALID_MMIO_REG;
3430*4882a593Smuzhiyun dig_port->max_lanes = 4;
3431*4882a593Smuzhiyun
3432*4882a593Smuzhiyun intel_infoframe_init(dig_port);
3433*4882a593Smuzhiyun
3434*4882a593Smuzhiyun dig_port->aux_ch = intel_bios_port_aux_ch(dev_priv, port);
3435*4882a593Smuzhiyun intel_hdmi_init_connector(dig_port, intel_connector);
3436*4882a593Smuzhiyun }
3437