1139749Simp/*
2126177Srik * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
3126177Srik *
4126177Srik * Permission is hereby granted, free of charge, to any person obtaining a
5126177Srik * copy of this software and associated documentation files (the "Software"),
6126177Srik * to deal in the Software without restriction, including without limitation
7126177Srik * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8126177Srik * and/or sell copies of the Software, and to permit persons to whom the
9126177Srik * Software is furnished to do so, subject to the following conditions:
10126177Srik *
11126177Srik * The above copyright notice and this permission notice (including the next
12126177Srik * paragraph) shall be included in all copies or substantial portions of the
13126177Srik * Software.
14126177Srik *
15126177Srik * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16126177Srik * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17126177Srik * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18126177Srik * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19126177Srik * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20126177Srik * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21126177Srik * SOFTWARE.
22126177Srik *
23126177Srik * Authors:
24126177Srik *    Ke Yu
25126177Srik *    Zhiyuan Lv <zhiyuan.lv@intel.com>
26126177Srik *
27126177Srik * Contributors:
28126177Srik *    Terrence Xu <terrence.xu@intel.com>
29126177Srik *    Changbin Du <changbin.du@intel.com>
30126177Srik *    Bing Niu <bing.niu@intel.com>
31126177Srik *    Zhi Wang <zhi.a.wang@intel.com>
32126177Srik *
33126177Srik */
34126177Srik
35126177Srik#include "i915_drv.h"
36126177Srik#include "i915_reg.h"
37126177Srik#include "gvt.h"
38126177Srik
39126177Srik#include "display/intel_display.h"
40126177Srik#include "display/intel_dpio_phy.h"
41126177Srik
42126177Srikstatic int get_edp_pipe(struct intel_vgpu *vgpu)
43126177Srik{
44126177Srik	u32 data = vgpu_vreg(vgpu, _TRANS_DDI_FUNC_CTL_EDP);
45126177Srik	int pipe = -1;
46126177Srik
47126177Srik	switch (data & TRANS_DDI_EDP_INPUT_MASK) {
48126177Srik	case TRANS_DDI_EDP_INPUT_A_ON:
49126177Srik	case TRANS_DDI_EDP_INPUT_A_ONOFF:
50126177Srik		pipe = PIPE_A;
51126177Srik		break;
52126177Srik	case TRANS_DDI_EDP_INPUT_B_ONOFF:
53126177Srik		pipe = PIPE_B;
54126177Srik		break;
55126177Srik	case TRANS_DDI_EDP_INPUT_C_ONOFF:
56126177Srik		pipe = PIPE_C;
57126177Srik		break;
58126177Srik	}
59126177Srik	return pipe;
60126177Srik}
61126177Srik
62126177Srikstatic int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
63126177Srik{
64126177Srik	struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
65126177Srik
66126177Srik	if (!(vgpu_vreg_t(vgpu, TRANSCONF(TRANSCODER_EDP)) & TRANSCONF_ENABLE))
67126177Srik		return 0;
68126177Srik
69126177Srik	if (!(vgpu_vreg(vgpu, _TRANS_DDI_FUNC_CTL_EDP) & TRANS_DDI_FUNC_ENABLE))
70126177Srik		return 0;
71126177Srik	return 1;
72126177Srik}
73126177Srik
74126177Srikint pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
75126177Srik{
76126177Srik	struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
77126177Srik
78126177Srik	if (drm_WARN_ON(&dev_priv->drm,
79126177Srik			pipe < PIPE_A || pipe >= I915_MAX_PIPES))
80126177Srik		return -EINVAL;
81126177Srik
82126177Srik	if (vgpu_vreg_t(vgpu, TRANSCONF(pipe)) & TRANSCONF_ENABLE)
83126177Srik		return 1;
84126177Srik
85126177Srik	if (edp_pipe_is_enabled(vgpu) &&
86126177Srik			get_edp_pipe(vgpu) == pipe)
87126177Srik		return 1;
88126177Srik	return 0;
89126177Srik}
90126177Srik
91126177Srikstatic unsigned char virtual_dp_monitor_edid[GVT_EDID_NUM][EDID_SIZE] = {
92126177Srik	{
93126177Srik/* EDID with 1024x768 as its resolution */
94126177Srik		/*Header*/
95126177Srik		0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
96126177Srik		/* Vendor & Product Identification */
97126177Srik		0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17,
98126177Srik		/* Version & Revision */
99126177Srik		0x01, 0x04,
100126177Srik		/* Basic Display Parameters & Features */
101126177Srik		0xa5, 0x34, 0x20, 0x78, 0x23,
102126177Srik		/* Color Characteristics */
103126177Srik		0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54,
104126177Srik		/* Established Timings: maximum resolution is 1024x768 */
105126177Srik		0x21, 0x08, 0x00,
106126177Srik		/* Standard Timings. All invalid */
107126177Srik		0x00, 0xc0, 0x00, 0xc0, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00,
108126177Srik		0x00, 0x40, 0x00, 0x00, 0x00, 0x01,
109126177Srik		/* 18 Byte Data Blocks 1: invalid */
110126177Srik		0x00, 0x00, 0x80, 0xa0, 0x70, 0xb0,
111126177Srik		0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a,
112126177Srik		/* 18 Byte Data Blocks 2: invalid */
113126177Srik		0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a,
114126177Srik		0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
115126177Srik		/* 18 Byte Data Blocks 3: invalid */
116126177Srik		0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
117126177Srik		0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20,
118126177Srik		/* 18 Byte Data Blocks 4: invalid */
119126177Srik		0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30,
120126177Srik		0x44, 0x58, 0x51, 0x0a, 0x20, 0x20,
121126177Srik		/* Extension Block Count */
122126177Srik		0x00,
123126177Srik		/* Checksum */
124126177Srik		0xef,
125126177Srik	},
126126177Srik	{
127126177Srik/* EDID with 1920x1200 as its resolution */
128126177Srik		/*Header*/
129126177Srik		0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
130126177Srik		/* Vendor & Product Identification */
131126177Srik		0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17,
132126177Srik		/* Version & Revision */
133126177Srik		0x01, 0x04,
134126177Srik		/* Basic Display Parameters & Features */
135126177Srik		0xa5, 0x34, 0x20, 0x78, 0x23,
136126177Srik		/* Color Characteristics */
137126177Srik		0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54,
138126177Srik		/* Established Timings: maximum resolution is 1024x768 */
139126177Srik		0x21, 0x08, 0x00,
140126177Srik		/*
141126177Srik		 * Standard Timings.
142126177Srik		 * below new resolutions can be supported:
143126177Srik		 * 1920x1080, 1280x720, 1280x960, 1280x1024,
144126177Srik		 * 1440x900, 1600x1200, 1680x1050
145126177Srik		 */
146126177Srik		0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x40, 0x81, 0x80, 0x95, 0x00,
147126177Srik		0xa9, 0x40, 0xb3, 0x00, 0x01, 0x01,
148126177Srik		/* 18 Byte Data Blocks 1: max resolution is 1920x1200 */
149126177Srik		0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
150126177Srik		0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a,
151126177Srik		/* 18 Byte Data Blocks 2: invalid */
152126177Srik		0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a,
153126177Srik		0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
154126601Sbms		/* 18 Byte Data Blocks 3: invalid */
155126177Srik		0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
156126177Srik		0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20,
157126177Srik		/* 18 Byte Data Blocks 4: invalid */
158126177Srik		0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30,
159126177Srik		0x44, 0x58, 0x51, 0x0a, 0x20, 0x20,
160126177Srik		/* Extension Block Count */
161126177Srik		0x00,
162126177Srik		/* Checksum */
163126177Srik		0x45,
164126177Srik	},
165126177Srik};
166126177Srik
167126177Srik#define DPCD_HEADER_SIZE        0xb
168126177Srik
169126177Srik/* let the virtual display supports DP1.2 */
170126177Srikstatic u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
171126177Srik	0x12, 0x014, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
172126177Srik};
173126177Srik
174126177Srikstatic void emulate_monitor_status_change(struct intel_vgpu *vgpu)
175126177Srik{
176126177Srik	struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
177126177Srik	int pipe;
178126177Srik
179126177Srik	if (IS_BROXTON(dev_priv)) {
180126601Sbms		enum transcoder trans;
181126177Srik		enum port port;
182126177Srik
183126177Srik		/* Clear PIPE, DDI, PHY, HPD before setting new */
184126177Srik		vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
185126177Srik			~(GEN8_DE_PORT_HOTPLUG(HPD_PORT_A) |
186126177Srik			  GEN8_DE_PORT_HOTPLUG(HPD_PORT_B) |
187126177Srik			  GEN8_DE_PORT_HOTPLUG(HPD_PORT_C));
188126177Srik
189126177Srik		for_each_pipe(dev_priv, pipe) {
190126177Srik			vgpu_vreg_t(vgpu, TRANSCONF(pipe)) &=
191126177Srik				~(TRANSCONF_ENABLE | TRANSCONF_STATE_ENABLE);
192126177Srik			vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISP_ENABLE;
193126177Srik			vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
194126177Srik			vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE_MASK;
195126177Srik			vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
196126177Srik		}
197126177Srik
198126177Srik		for (trans = TRANSCODER_A; trans <= TRANSCODER_EDP; trans++) {
199126177Srik			vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(trans)) &=
200126177Srik				~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
201126177Srik				  TRANS_DDI_PORT_MASK | TRANS_DDI_FUNC_ENABLE);
202126601Sbms		}
203126177Srik		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
204126177Srik			~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
205126177Srik			  TRANS_DDI_PORT_MASK);
206126177Srik
207126177Srik		for (port = PORT_A; port <= PORT_C; port++) {
208126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) &=
209126177Srik				~BXT_PHY_LANE_ENABLED;
210126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) |=
211126177Srik				(BXT_PHY_CMNLANE_POWERDOWN_ACK |
212126601Sbms				 BXT_PHY_LANE_POWERDOWN_ACK);
213126177Srik
214126177Srik			vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(port)) &=
215126177Srik				~(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
216126177Srik				  PORT_PLL_REF_SEL | PORT_PLL_LOCK |
217126177Srik				  PORT_PLL_ENABLE);
218126601Sbms
219126177Srik			vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) &=
220126177Srik				~(DDI_INIT_DISPLAY_DETECTED |
221126177Srik				  DDI_BUF_CTL_ENABLE);
222126177Srik			vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE;
223126177Srik		}
224126177Srik		vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
225126177Srik			~(PORTA_HOTPLUG_ENABLE | PORTA_HOTPLUG_STATUS_MASK);
226126177Srik		vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
227126177Srik			~(PORTB_HOTPLUG_ENABLE | PORTB_HOTPLUG_STATUS_MASK);
228126177Srik		vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
229126177Srik			~(PORTC_HOTPLUG_ENABLE | PORTC_HOTPLUG_STATUS_MASK);
230126177Srik		/* No hpd_invert set in vgpu vbt, need to clear invert mask */
231126177Srik		vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= ~BXT_DDI_HPD_INVERT_MASK;
232126177Srik		vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HOTPLUG_MASK;
233126177Srik
234126601Sbms		vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1));
235126177Srik		vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &=
236126601Sbms			~PHY_POWER_GOOD;
237126177Srik		vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) &=
238126177Srik			~PHY_POWER_GOOD;
239126177Srik		vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) &= ~BIT(30);
240126177Srik		vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) &= ~BIT(30);
241126177Srik
242126177Srik		vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIB_DETECTED;
243126177Srik		vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIC_DETECTED;
244126177Srik
245126177Srik		/*
246126177Srik		 * Only 1 PIPE enabled in current vGPU display and PIPE_A is
247126177Srik		 *  tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A,
248126177Srik		 *   TRANSCODER_A can be enabled. PORT_x depends on the input of
249126177Srik		 *   setup_virtual_dp_monitor.
250126177Srik		 */
251126177Srik		vgpu_vreg_t(vgpu, TRANSCONF(TRANSCODER_A)) |= TRANSCONF_ENABLE;
252126177Srik		vgpu_vreg_t(vgpu, TRANSCONF(TRANSCODER_A)) |= TRANSCONF_STATE_ENABLE;
253126177Srik
254126177Srik		/*
255126177Srik		 * Golden M/N are calculated based on:
256126177Srik		 *   24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID),
257126177Srik		 *   DP link clk 1620 MHz and non-constant_n.
258126177Srik		 * TODO: calculate DP link symbol clk and stream clk m/n.
259126177Srik		 */
260126177Srik		vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = TU_SIZE(64);
261126177Srik		vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
262126177Srik		vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
263126177Srik		vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
264126177Srik		vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
265126177Srik
266126177Srik		/* Enable per-DDI/PORT vreg */
267126177Srik		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
268126177Srik			vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(1);
269126177Srik			vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) |=
270126177Srik				PHY_POWER_GOOD;
271126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) |=
272126177Srik				BIT(30);
273126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) |=
274126177Srik				BXT_PHY_LANE_ENABLED;
275126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) &=
276126177Srik				~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
277126177Srik				  BXT_PHY_LANE_POWERDOWN_ACK);
278126177Srik			vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_A)) |=
279126177Srik				(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
280126177Srik				 PORT_PLL_REF_SEL | PORT_PLL_LOCK |
281126177Srik				 PORT_PLL_ENABLE);
282126177Srik			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |=
283126177Srik				(DDI_BUF_CTL_ENABLE | DDI_INIT_DISPLAY_DETECTED);
284126177Srik			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) &=
285126177Srik				~DDI_BUF_IS_IDLE;
286126177Srik			vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |=
287126177Srik				(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
288126177Srik				 TRANS_DDI_FUNC_ENABLE);
289126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
290126177Srik				PORTA_HOTPLUG_ENABLE;
291126177Srik			vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
292126177Srik				GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
293126177Srik		}
294126177Srik
295126177Srik		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
296126177Srik			vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
297126177Srik			vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
298126177Srik			vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
299126177Srik				PHY_POWER_GOOD;
300126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
301126177Srik				BIT(30);
302126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) |=
303126177Srik				BXT_PHY_LANE_ENABLED;
304126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) &=
305126177Srik				~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
306126177Srik				  BXT_PHY_LANE_POWERDOWN_ACK);
307126177Srik			vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_B)) |=
308126177Srik				(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
309126177Srik				 PORT_PLL_REF_SEL | PORT_PLL_LOCK |
310126177Srik				 PORT_PLL_ENABLE);
311126177Srik			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |=
312126177Srik				DDI_BUF_CTL_ENABLE;
313126177Srik			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &=
314126177Srik				~DDI_BUF_IS_IDLE;
315126177Srik			vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
316126177Srik				(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
317126177Srik				 (PORT_B << TRANS_DDI_PORT_SHIFT) |
318126177Srik				 TRANS_DDI_FUNC_ENABLE);
319126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
320126177Srik				PORTB_HOTPLUG_ENABLE;
321126177Srik			vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
322126177Srik				GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
323126177Srik		}
324126177Srik
325126177Srik		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
326126177Srik			vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
327126177Srik			vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
328126177Srik			vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
329126177Srik				PHY_POWER_GOOD;
330126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
331126177Srik				BIT(30);
332126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
333126177Srik				BXT_PHY_LANE_ENABLED;
334126177Srik			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) &=
335126177Srik				~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
336126177Srik				  BXT_PHY_LANE_POWERDOWN_ACK);
337126177Srik			vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_C)) |=
338126177Srik				(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
339126177Srik				 PORT_PLL_REF_SEL | PORT_PLL_LOCK |
340126177Srik				 PORT_PLL_ENABLE);
341126177Srik			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |=
342126177Srik				DDI_BUF_CTL_ENABLE;
343126177Srik			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &=
344126177Srik				~DDI_BUF_IS_IDLE;
345126177Srik			vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
346126177Srik				(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
347126177Srik				 (PORT_B << TRANS_DDI_PORT_SHIFT) |
348126177Srik				 TRANS_DDI_FUNC_ENABLE);
349126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
350126177Srik				PORTC_HOTPLUG_ENABLE;
351126177Srik			vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
352126177Srik				GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
353126177Srik		}
354126177Srik
355126177Srik		return;
356126177Srik	}
357126177Srik
358126177Srik	vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
359126177Srik			SDE_PORTC_HOTPLUG_CPT |
360126177Srik			SDE_PORTD_HOTPLUG_CPT);
361126177Srik
362126177Srik	if (IS_SKYLAKE(dev_priv) ||
363126177Srik	    IS_KABYLAKE(dev_priv) ||
364126177Srik	    IS_COFFEELAKE(dev_priv) ||
365126177Srik	    IS_COMETLAKE(dev_priv)) {
366126177Srik		vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTA_HOTPLUG_SPT |
367126177Srik				SDE_PORTE_HOTPLUG_SPT);
368126177Srik		vgpu_vreg_t(vgpu, SKL_FUSE_STATUS) |=
369126177Srik				SKL_FUSE_DOWNLOAD_STATUS |
370126177Srik				SKL_FUSE_PG_DIST_STATUS(SKL_PG0) |
371126177Srik				SKL_FUSE_PG_DIST_STATUS(SKL_PG1) |
372126177Srik				SKL_FUSE_PG_DIST_STATUS(SKL_PG2);
373126177Srik		/*
374126177Srik		 * Only 1 PIPE enabled in current vGPU display and PIPE_A is
375126177Srik		 *  tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A,
376126177Srik		 *   TRANSCODER_A can be enabled. PORT_x depends on the input of
377126177Srik		 *   setup_virtual_dp_monitor, we can bind DPLL0 to any PORT_x
378126177Srik		 *   so we fixed to DPLL0 here.
379126177Srik		 * Setup DPLL0: DP link clk 1620 MHz, non SSC, DP Mode
380126177Srik		 */
381126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL1) =
382126177Srik			DPLL_CTRL1_OVERRIDE(DPLL_ID_SKL_DPLL0);
383126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL1) |=
384126177Srik			DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, DPLL_ID_SKL_DPLL0);
385126177Srik		vgpu_vreg_t(vgpu, LCPLL1_CTL) =
386126177Srik			LCPLL_PLL_ENABLE | LCPLL_PLL_LOCK;
387126177Srik		vgpu_vreg_t(vgpu, DPLL_STATUS) = DPLL_LOCK(DPLL_ID_SKL_DPLL0);
388126177Srik		/*
389126177Srik		 * Golden M/N are calculated based on:
390126177Srik		 *   24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID),
391126177Srik		 *   DP link clk 1620 MHz and non-constant_n.
392126177Srik		 * TODO: calculate DP link symbol clk and stream clk m/n.
393126177Srik		 */
394126177Srik		vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = TU_SIZE(64);
395126177Srik		vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
396126177Srik		vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
397126177Srik		vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
398126177Srik		vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
399126177Srik	}
400126177Srik
401126177Srik	if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
402126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
403126177Srik			~DPLL_CTRL2_DDI_CLK_OFF(PORT_B);
404126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
405126177Srik			DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_B);
406126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
407126177Srik			DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_B);
408126177Srik		vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
409126177Srik		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
410126177Srik			~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
411126177Srik			TRANS_DDI_PORT_MASK);
412126177Srik		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
413126177Srik			(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
414126177Srik			(PORT_B << TRANS_DDI_PORT_SHIFT) |
415126177Srik			TRANS_DDI_FUNC_ENABLE);
416126177Srik		if (IS_BROADWELL(dev_priv)) {
417126177Srik			vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_B)) &=
418126177Srik				~PORT_CLK_SEL_MASK;
419126177Srik			vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_B)) |=
420126177Srik				PORT_CLK_SEL_LCPLL_810;
421126177Srik		}
422126177Srik		vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |= DDI_BUF_CTL_ENABLE;
423126177Srik		vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &= ~DDI_BUF_IS_IDLE;
424126177Srik		vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTB_HOTPLUG_CPT;
425126177Srik	}
426126177Srik
427126177Srik	if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
428126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
429126177Srik			~DPLL_CTRL2_DDI_CLK_OFF(PORT_C);
430126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
431126177Srik			DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_C);
432126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
433126177Srik			DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_C);
434126177Srik		vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT;
435126177Srik		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
436126177Srik			~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
437126177Srik			TRANS_DDI_PORT_MASK);
438126177Srik		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
439126177Srik			(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
440126177Srik			(PORT_C << TRANS_DDI_PORT_SHIFT) |
441126177Srik			TRANS_DDI_FUNC_ENABLE);
442126177Srik		if (IS_BROADWELL(dev_priv)) {
443126177Srik			vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_C)) &=
444126177Srik				~PORT_CLK_SEL_MASK;
445126177Srik			vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_C)) |=
446126177Srik				PORT_CLK_SEL_LCPLL_810;
447126177Srik		}
448126177Srik		vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |= DDI_BUF_CTL_ENABLE;
449126177Srik		vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &= ~DDI_BUF_IS_IDLE;
450126177Srik		vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
451126177Srik	}
452126177Srik
453126177Srik	if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D)) {
454126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
455126177Srik			~DPLL_CTRL2_DDI_CLK_OFF(PORT_D);
456126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
457126177Srik			DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_D);
458126177Srik		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
459126177Srik			DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_D);
460126177Srik		vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT;
461126177Srik		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
462126177Srik			~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
463126177Srik			TRANS_DDI_PORT_MASK);
464126177Srik		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
465126177Srik			(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
466126177Srik			(PORT_D << TRANS_DDI_PORT_SHIFT) |
467126177Srik			TRANS_DDI_FUNC_ENABLE);
468126177Srik		if (IS_BROADWELL(dev_priv)) {
469126177Srik			vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_D)) &=
470126177Srik				~PORT_CLK_SEL_MASK;
471126177Srik			vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_D)) |=
472126177Srik				PORT_CLK_SEL_LCPLL_810;
473126177Srik		}
474126177Srik		vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_D)) |= DDI_BUF_CTL_ENABLE;
475126177Srik		vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_D)) &= ~DDI_BUF_IS_IDLE;
476126177Srik		vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDID_DETECTED;
477126177Srik	}
478126177Srik
479126177Srik	if ((IS_SKYLAKE(dev_priv) ||
480126177Srik	     IS_KABYLAKE(dev_priv) ||
481126177Srik	     IS_COFFEELAKE(dev_priv) ||
482126177Srik	     IS_COMETLAKE(dev_priv)) &&
483126177Srik			intel_vgpu_has_monitor_on_port(vgpu, PORT_E)) {
484126177Srik		vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTE_HOTPLUG_SPT;
485126177Srik	}
486126177Srik
487126177Srik	if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
488126177Srik		if (IS_BROADWELL(dev_priv))
489126177Srik			vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
490126177Srik				GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
491126177Srik		else
492126177Srik			vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTA_HOTPLUG_SPT;
493126177Srik
494126177Srik		vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |= DDI_INIT_DISPLAY_DETECTED;
495126177Srik	}
496126177Srik
497126177Srik	/* Clear host CRT status, so guest couldn't detect this host CRT. */
498126177Srik	if (IS_BROADWELL(dev_priv))
499126177Srik		vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;
500126177Srik
501126177Srik	/* Disable Primary/Sprite/Cursor plane */
502126177Srik	for_each_pipe(dev_priv, pipe) {
503126177Srik		vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISP_ENABLE;
504126177Srik		vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
505126177Srik		vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE_MASK;
506126177Srik		vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
507126177Srik	}
508126177Srik
509126177Srik	vgpu_vreg_t(vgpu, TRANSCONF(TRANSCODER_A)) |= TRANSCONF_ENABLE;
510126177Srik}
511126177Srik
512126177Srikstatic void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num)
513126177Srik{
514126177Srik	struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num);
515126177Srik
516126177Srik	kfree(port->edid);
517126177Srik	port->edid = NULL;
518126177Srik
519126177Srik	kfree(port->dpcd);
520126177Srik	port->dpcd = NULL;
521126177Srik}
522126177Srik
523126177Srikstatic enum hrtimer_restart vblank_timer_fn(struct hrtimer *data)
524126177Srik{
525126177Srik	struct intel_vgpu_vblank_timer *vblank_timer;
526126177Srik	struct intel_vgpu *vgpu;
527126177Srik
528126177Srik	vblank_timer = container_of(data, struct intel_vgpu_vblank_timer, timer);
529126177Srik	vgpu = container_of(vblank_timer, struct intel_vgpu, vblank_timer);
530126177Srik
531126177Srik	/* Set vblank emulation request per-vGPU bit */
532126177Srik	intel_gvt_request_service(vgpu->gvt,
533126177Srik				  INTEL_GVT_REQUEST_EMULATE_VBLANK + vgpu->id);
534126177Srik	hrtimer_add_expires_ns(&vblank_timer->timer, vblank_timer->period);
535126177Srik	return HRTIMER_RESTART;
536126177Srik}
537126177Srik
538126177Srikstatic int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num,
539126177Srik				    int type, unsigned int resolution)
540126177Srik{
541126177Srik	struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
542126177Srik	struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num);
543126177Srik	struct intel_vgpu_vblank_timer *vblank_timer = &vgpu->vblank_timer;
544126177Srik
545126177Srik	if (drm_WARN_ON(&i915->drm, resolution >= GVT_EDID_NUM))
546126177Srik		return -EINVAL;
547126177Srik
548126177Srik	port->edid = kzalloc(sizeof(*(port->edid)), GFP_KERNEL);
549126177Srik	if (!port->edid)
550126177Srik		return -ENOMEM;
551126177Srik
552126177Srik	port->dpcd = kzalloc(sizeof(*(port->dpcd)), GFP_KERNEL);
553126177Srik	if (!port->dpcd) {
554126177Srik		kfree(port->edid);
555126177Srik		return -ENOMEM;
556126177Srik	}
557126177Srik
558126177Srik	memcpy(port->edid->edid_block, virtual_dp_monitor_edid[resolution],
559126177Srik			EDID_SIZE);
560126177Srik	port->edid->data_valid = true;
561126177Srik
562126177Srik	memcpy(port->dpcd->data, dpcd_fix_data, DPCD_HEADER_SIZE);
563126177Srik	port->dpcd->data_valid = true;
564126177Srik	port->dpcd->data[DPCD_SINK_COUNT] = 0x1;
565126177Srik	port->type = type;
566126177Srik	port->id = resolution;
567126177Srik	port->vrefresh_k = GVT_DEFAULT_REFRESH_RATE * MSEC_PER_SEC;
568126177Srik	vgpu->display.port_num = port_num;
569126177Srik
570126177Srik	/* Init hrtimer based on default refresh rate */
571126177Srik	hrtimer_init(&vblank_timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
572126177Srik	vblank_timer->timer.function = vblank_timer_fn;
573126177Srik	vblank_timer->vrefresh_k = port->vrefresh_k;
574126177Srik	vblank_timer->period = DIV64_U64_ROUND_CLOSEST(NSEC_PER_SEC * MSEC_PER_SEC, vblank_timer->vrefresh_k);
575126177Srik
576126177Srik	emulate_monitor_status_change(vgpu);
577126177Srik
578126177Srik	return 0;
579126177Srik}
580126177Srik
581126177Srik/**
582126177Srik * vgpu_update_vblank_emulation - Update per-vGPU vblank_timer
583126177Srik * @vgpu: vGPU operated
584126177Srik * @turnon: Turn ON/OFF vblank_timer
585126177Srik *
586126177Srik * This function is used to turn on/off or update the per-vGPU vblank_timer
587126177Srik * when TRANSCONF is enabled or disabled. vblank_timer period is also updated
588126177Srik * if guest changed the refresh rate.
589126177Srik *
590126177Srik */
591126177Srikvoid vgpu_update_vblank_emulation(struct intel_vgpu *vgpu, bool turnon)
592126177Srik{
593126177Srik	struct intel_vgpu_vblank_timer *vblank_timer = &vgpu->vblank_timer;
594126177Srik	struct intel_vgpu_port *port =
595126177Srik		intel_vgpu_port(vgpu, vgpu->display.port_num);
596126177Srik
597126177Srik	if (turnon) {
598126177Srik		/*
599126177Srik		 * Skip the re-enable if already active and vrefresh unchanged.
600126177Srik		 * Otherwise, stop timer if already active and restart with new
601126177Srik		 *   period.
602126177Srik		 */
603126177Srik		if (vblank_timer->vrefresh_k != port->vrefresh_k ||
604126177Srik		    !hrtimer_active(&vblank_timer->timer)) {
605126177Srik			/* Stop timer before start with new period if active */
606126177Srik			if (hrtimer_active(&vblank_timer->timer))
607126177Srik				hrtimer_cancel(&vblank_timer->timer);
608126177Srik
609126177Srik			/* Make sure new refresh rate updated to timer period */
610126177Srik			vblank_timer->vrefresh_k = port->vrefresh_k;
611126177Srik			vblank_timer->period = DIV64_U64_ROUND_CLOSEST(NSEC_PER_SEC * MSEC_PER_SEC, vblank_timer->vrefresh_k);
612126177Srik			hrtimer_start(&vblank_timer->timer,
613126177Srik				      ktime_add_ns(ktime_get(), vblank_timer->period),
614126177Srik				      HRTIMER_MODE_ABS);
615126177Srik		}
616126177Srik	} else {
617126177Srik		/* Caller request to stop vblank */
618126177Srik		hrtimer_cancel(&vblank_timer->timer);
619126177Srik	}
620126177Srik}
621126177Srik
622126177Srikstatic void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe)
623126177Srik{
624126177Srik	struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
625126177Srik	struct intel_vgpu_irq *irq = &vgpu->irq;
626126177Srik	int vblank_event[] = {
627126177Srik		[PIPE_A] = PIPE_A_VBLANK,
628126177Srik		[PIPE_B] = PIPE_B_VBLANK,
629126177Srik		[PIPE_C] = PIPE_C_VBLANK,
630126177Srik	};
631126177Srik	int event;
632126177Srik
633126177Srik	if (pipe < PIPE_A || pipe > PIPE_C)
634126177Srik		return;
635126177Srik
636126177Srik	for_each_set_bit(event, irq->flip_done_event[pipe],
637126177Srik			INTEL_GVT_EVENT_MAX) {
638126177Srik		clear_bit(event, irq->flip_done_event[pipe]);
639126177Srik		if (!pipe_is_enabled(vgpu, pipe))
640126177Srik			continue;
641126177Srik
642126177Srik		intel_vgpu_trigger_virtual_event(vgpu, event);
643126177Srik	}
644126177Srik
645126177Srik	if (pipe_is_enabled(vgpu, pipe)) {
646126177Srik		vgpu_vreg_t(vgpu, PIPE_FRMCOUNT_G4X(pipe))++;
647126177Srik		intel_vgpu_trigger_virtual_event(vgpu, vblank_event[pipe]);
648126177Srik	}
649126177Srik}
650126177Srik
651126177Srikvoid intel_vgpu_emulate_vblank(struct intel_vgpu *vgpu)
652126177Srik{
653126177Srik	int pipe;
654126177Srik
655126177Srik	mutex_lock(&vgpu->vgpu_lock);
656126177Srik	for_each_pipe(vgpu->gvt->gt->i915, pipe)
657126177Srik		emulate_vblank_on_pipe(vgpu, pipe);
658126177Srik	mutex_unlock(&vgpu->vgpu_lock);
659126177Srik}
660126177Srik
661126177Srik/**
662126177Srik * intel_vgpu_emulate_hotplug - trigger hotplug event for vGPU
663126177Srik * @vgpu: a vGPU
664126177Srik * @connected: link state
665126177Srik *
666126177Srik * This function is used to trigger hotplug interrupt for vGPU
667126177Srik *
668126177Srik */
669126177Srikvoid intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected)
670126177Srik{
671126177Srik	struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
672126177Srik
673126177Srik	/* TODO: add more platforms support */
674126177Srik	if (IS_SKYLAKE(i915) ||
675126177Srik	    IS_KABYLAKE(i915) ||
676126177Srik	    IS_COFFEELAKE(i915) ||
677126177Srik	    IS_COMETLAKE(i915)) {
678126177Srik		if (connected) {
679126177Srik			vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
680126177Srik				SFUSE_STRAP_DDID_DETECTED;
681126177Srik			vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT;
682126177Srik		} else {
683126177Srik			vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
684126177Srik				~SFUSE_STRAP_DDID_DETECTED;
685126177Srik			vgpu_vreg_t(vgpu, SDEISR) &= ~SDE_PORTD_HOTPLUG_CPT;
686126177Srik		}
687126177Srik		vgpu_vreg_t(vgpu, SDEIIR) |= SDE_PORTD_HOTPLUG_CPT;
688126177Srik		vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
689126177Srik				PORTD_HOTPLUG_STATUS_MASK;
690126177Srik		intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG);
691126177Srik	} else if (IS_BROXTON(i915)) {
692126177Srik		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
693126177Srik			if (connected) {
694126177Srik				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
695126177Srik					GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
696126177Srik			} else {
697126177Srik				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
698126177Srik					~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
699126177Srik			}
700126177Srik			vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
701126177Srik				GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
702126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
703126177Srik				~PORTA_HOTPLUG_STATUS_MASK;
704126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
705126177Srik				PORTA_HOTPLUG_LONG_DETECT;
706126177Srik			intel_vgpu_trigger_virtual_event(vgpu, DP_A_HOTPLUG);
707126177Srik		}
708126177Srik		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
709126177Srik			if (connected) {
710126177Srik				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
711126177Srik					GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
712126177Srik				vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
713126177Srik					SFUSE_STRAP_DDIB_DETECTED;
714126177Srik			} else {
715126177Srik				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
716126177Srik					~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
717126177Srik				vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
718126177Srik					~SFUSE_STRAP_DDIB_DETECTED;
719126177Srik			}
720126177Srik			vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
721126177Srik				GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
722126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
723126177Srik				~PORTB_HOTPLUG_STATUS_MASK;
724126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
725126177Srik				PORTB_HOTPLUG_LONG_DETECT;
726126177Srik			intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
727126177Srik		}
728126177Srik		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
729126177Srik			if (connected) {
730126177Srik				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
731126177Srik					GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
732126177Srik				vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
733126177Srik					SFUSE_STRAP_DDIC_DETECTED;
734126177Srik			} else {
735126177Srik				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
736126177Srik					~GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
737126177Srik				vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
738126177Srik					~SFUSE_STRAP_DDIC_DETECTED;
739126177Srik			}
740126177Srik			vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
741126177Srik				GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
742126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
743126177Srik				~PORTC_HOTPLUG_STATUS_MASK;
744126177Srik			vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
745126177Srik				PORTC_HOTPLUG_LONG_DETECT;
746126177Srik			intel_vgpu_trigger_virtual_event(vgpu, DP_C_HOTPLUG);
747126177Srik		}
748126177Srik	}
749126177Srik}
750126177Srik
751126177Srik/**
752126177Srik * intel_vgpu_clean_display - clean vGPU virtual display emulation
753126177Srik * @vgpu: a vGPU
754126177Srik *
755126177Srik * This function is used to clean vGPU virtual display emulation stuffs
756126177Srik *
757126177Srik */
758126177Srikvoid intel_vgpu_clean_display(struct intel_vgpu *vgpu)
759126177Srik{
760126177Srik	struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
761126177Srik
762126177Srik	if (IS_SKYLAKE(dev_priv) ||
763126177Srik	    IS_KABYLAKE(dev_priv) ||
764126177Srik	    IS_COFFEELAKE(dev_priv) ||
765126177Srik	    IS_COMETLAKE(dev_priv))
766126177Srik		clean_virtual_dp_monitor(vgpu, PORT_D);
767126177Srik	else
768126177Srik		clean_virtual_dp_monitor(vgpu, PORT_B);
769126177Srik
770126177Srik	vgpu_update_vblank_emulation(vgpu, false);
771126177Srik}
772126177Srik
773126177Srik/**
774126177Srik * intel_vgpu_init_display- initialize vGPU virtual display emulation
775126177Srik * @vgpu: a vGPU
776126177Srik * @resolution: resolution index for intel_vgpu_edid
777126177Srik *
778126177Srik * This function is used to initialize vGPU virtual display emulation stuffs
779126177Srik *
780126177Srik * Returns:
781126177Srik * Zero on success, negative error code if failed.
782126177Srik *
783126177Srik */
784126177Srikint intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 resolution)
785126177Srik{
786126177Srik	struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
787126177Srik
788126177Srik	intel_vgpu_init_i2c_edid(vgpu);
789126177Srik
790126177Srik	if (IS_SKYLAKE(dev_priv) ||
791126177Srik	    IS_KABYLAKE(dev_priv) ||
792126177Srik	    IS_COFFEELAKE(dev_priv) ||
793126177Srik	    IS_COMETLAKE(dev_priv))
794126177Srik		return setup_virtual_dp_monitor(vgpu, PORT_D, GVT_DP_D,
795126177Srik						resolution);
796126177Srik	else
797126177Srik		return setup_virtual_dp_monitor(vgpu, PORT_B, GVT_DP_B,
798126177Srik						resolution);
799126177Srik}
800126177Srik
801126177Srik/**
802126177Srik * intel_vgpu_reset_display- reset vGPU virtual display emulation
803126177Srik * @vgpu: a vGPU
804126177Srik *
805126177Srik * This function is used to reset vGPU virtual display emulation stuffs
806126177Srik *
807126177Srik */
808126177Srikvoid intel_vgpu_reset_display(struct intel_vgpu *vgpu)
809126177Srik{
810126177Srik	emulate_monitor_status_change(vgpu);
811126177Srik}
812126177Srik