Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6da57562 authored by Colin Xu's avatar Colin Xu Committed by Greg Kroah-Hartman
Browse files

drm/i915/gvt: Init DPLL/DDI vreg for virtual display instead of inheritance.



commit f965b68188ab59a40a421ced1b05a2fea638465c upstream.

Init value of some display vregs rea inherited from host pregs. When
host display in different status, i.e. all monitors unpluged, different
display configurations, etc., GVT virtual display setup don't consistent
thus may lead to guest driver consider display goes malfunctional.

The added init vreg values are based on PRMs and fixed by calcuation
from current configuration (only PIPE_A) and the virtual EDID.

Fixes: 04d348ae ("drm/i915/gvt: vGPU display virtualization")
Acked-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarColin Xu <colin.xu@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20200508060506.216250-1-colin.xu@intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f0cd63e5
Loading
Loading
Loading
Loading
+44 −5
Original line number Diff line number Diff line
@@ -206,14 +206,41 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
				SKL_FUSE_PG_DIST_STATUS(SKL_PG0) |
				SKL_FUSE_PG_DIST_STATUS(SKL_PG1) |
				SKL_FUSE_PG_DIST_STATUS(SKL_PG2);
		vgpu_vreg_t(vgpu, LCPLL1_CTL) |=
				LCPLL_PLL_ENABLE |
				LCPLL_PLL_LOCK;
		vgpu_vreg_t(vgpu, LCPLL2_CTL) |= LCPLL_PLL_ENABLE;

		/*
		 * Only 1 PIPE enabled in current vGPU display and PIPE_A is
		 *  tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A,
		 *   TRANSCODER_A can be enabled. PORT_x depends on the input of
		 *   setup_virtual_dp_monitor, we can bind DPLL0 to any PORT_x
		 *   so we fixed to DPLL0 here.
		 * Setup DPLL0: DP link clk 1620 MHz, non SSC, DP Mode
		 */
		vgpu_vreg_t(vgpu, DPLL_CTRL1) =
			DPLL_CTRL1_OVERRIDE(DPLL_ID_SKL_DPLL0);
		vgpu_vreg_t(vgpu, DPLL_CTRL1) |=
			DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, DPLL_ID_SKL_DPLL0);
		vgpu_vreg_t(vgpu, LCPLL1_CTL) =
			LCPLL_PLL_ENABLE | LCPLL_PLL_LOCK;
		vgpu_vreg_t(vgpu, DPLL_STATUS) = DPLL_LOCK(DPLL_ID_SKL_DPLL0);
		/*
		 * Golden M/N are calculated based on:
		 *   24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID),
		 *   DP link clk 1620 MHz and non-constant_n.
		 * TODO: calculate DP link symbol clk and stream clk m/n.
		 */
		vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = 63 << TU_SIZE_SHIFT;
		vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
		vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
		vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
		vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
	}

	if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
		vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
			~DPLL_CTRL2_DDI_CLK_OFF(PORT_B);
		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
			DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_B);
		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
			DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_B);
		vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
			~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
@@ -234,6 +261,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
	}

	if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
		vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
			~DPLL_CTRL2_DDI_CLK_OFF(PORT_C);
		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
			DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_C);
		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
			DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_C);
		vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT;
		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
			~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
@@ -254,6 +287,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
	}

	if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D)) {
		vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
			~DPLL_CTRL2_DDI_CLK_OFF(PORT_D);
		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
			DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_D);
		vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
			DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_D);
		vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT;
		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
			~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |