[PATCH] drm/i915/gvt: Fix virtual display setup for BXT/APL

Colin Xu Colin.Xu at intel.com
Tue Oct 13 06:19:12 UTC 2020


On 2020-10-13 10:18, Zhenyu Wang wrote:
> On 2020.10.12 12:51:59 +0800, Colin Xu wrote:
>> Program display related vregs to proper value at initialization, setup
>> virtual monitor and hotplug.
>>
> What does this fix? Does it fix virtual display probe or make vfio edid
> work properly or others? Pls describe more in details.
Without these changes, vGPU DDI/PLL state maybe inconsistent during each 
VM boot and in some configurations (i.e. host doesn't have display 
connected, or host connect a monitor on PORT_A or PORT_C instead of 
PORT_B), guest driver won't initialize display correctly thus leads to 
no guest desktop.
I'll revise the commit message.
>
>> Signed-off-by: Colin Xu <colin.xu at intel.com>
>> ---
>>   drivers/gpu/drm/i915/gvt/display.c | 183 ++++++++++++++++++++++++++++-
>>   drivers/gpu/drm/i915/gvt/mmio.c    |   5 +
>>   2 files changed, 185 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
>> index 7ba16ddfe75f..f69e23b6218d 100644
>> --- a/drivers/gpu/drm/i915/gvt/display.c
>> +++ b/drivers/gpu/drm/i915/gvt/display.c
>> @@ -173,21 +173,162 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
>>   	int pipe;
>>   
>>   	if (IS_BROXTON(dev_priv)) {
>> -		vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~(BXT_DE_PORT_HP_DDIA |
>> -			BXT_DE_PORT_HP_DDIB |
>> -			BXT_DE_PORT_HP_DDIC);
>> +		enum transcoder trans;
>> +		enum port port;
>> +
>> +		/* Clear PIPE, DDI, PHY, HPD before setting new */
>> +		vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
>> +			~(BXT_DE_PORT_HP_DDIA |
>> +			  BXT_DE_PORT_HP_DDIB |
>> +			  BXT_DE_PORT_HP_DDIC);
>> +
>> +		for_each_pipe(dev_priv, pipe) {
>> +			vgpu_vreg_t(vgpu, PIPECONF(pipe)) &=
>> +				~(PIPECONF_ENABLE | I965_PIPECONF_ACTIVE);
>> +			vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
>> +			vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
>> +			vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE;
>> +			vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
>> +		}
>> +
>> +		for (trans = TRANSCODER_A; trans <= TRANSCODER_EDP; trans++) {
>> +			vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(trans)) &=
>> +				~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
>> +				  TRANS_DDI_PORT_MASK | TRANS_DDI_FUNC_ENABLE);
>> +		}
>> +		vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
>> +			~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
>> +			  TRANS_DDI_PORT_MASK);
>> +
>> +		for (port = PORT_A; port <= PORT_C; port++) {
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) &=
>> +				~BXT_PHY_LANE_ENABLED;
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) |=
>> +				(BXT_PHY_CMNLANE_POWERDOWN_ACK |
>> +				 BXT_PHY_LANE_POWERDOWN_ACK);
>> +
>> +			vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(port)) &=
>> +				~(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
>> +				  PORT_PLL_REF_SEL | PORT_PLL_LOCK |
>> +				  PORT_PLL_ENABLE);
>> +
>> +			vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) &=
>> +				~(DDI_INIT_DISPLAY_DETECTED |
>> +				  DDI_BUF_CTL_ENABLE);
>> +			vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE;
>> +		}
>> +
>> +		vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1));
>> +		vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &=
>> +			~PHY_POWER_GOOD;
>> +		vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) &=
>> +			~PHY_POWER_GOOD;
>> +		vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) &= ~BIT(30);
>> +		vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) &= ~BIT(30);
>> +
>> +		vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIB_DETECTED;
>> +		vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIC_DETECTED;
>> +
>> +		/*
>> +		 * 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.
>> +		 */
>> +		vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
>> +		vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= I965_PIPECONF_ACTIVE;
>>   
>> +		/*
>> +		 * 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;
>> +
>> +		/* Enable per-DDI/PORT vreg */
>>   		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
>> +			vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(1);
>> +			vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) |=
>> +				PHY_POWER_GOOD;
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) |=
>> +				BIT(30);
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) |=
>> +				BXT_PHY_LANE_ENABLED;
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) &=
>> +				~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
>> +				  BXT_PHY_LANE_POWERDOWN_ACK);
>> +			vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_A)) |=
>> +				(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
>> +				 PORT_PLL_REF_SEL | PORT_PLL_LOCK |
>> +				 PORT_PLL_ENABLE);
>> +			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |=
>> +				(DDI_BUF_CTL_ENABLE | DDI_INIT_DISPLAY_DETECTED);
>> +			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) &=
>> +				~DDI_BUF_IS_IDLE;
>> +			vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |=
>> +				(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
>> +				 TRANS_DDI_FUNC_ENABLE);
>>   			vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
>>   				BXT_DE_PORT_HP_DDIA;
>>   		}
>>   
>>   		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
>> +			vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
>> +			vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
>> +			vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
>> +				PHY_POWER_GOOD;
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
>> +				BIT(30);
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) |=
>> +				BXT_PHY_LANE_ENABLED;
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) &=
>> +				~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
>> +				  BXT_PHY_LANE_POWERDOWN_ACK);
>> +			vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_B)) |=
>> +				(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
>> +				 PORT_PLL_REF_SEL | PORT_PLL_LOCK |
>> +				 PORT_PLL_ENABLE);
>> +			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |=
>> +				DDI_BUF_CTL_ENABLE;
>> +			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &=
>> +				~DDI_BUF_IS_IDLE;
>> +			vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
>> +				(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
>> +				 (PORT_B << TRANS_DDI_PORT_SHIFT) |
>> +				 TRANS_DDI_FUNC_ENABLE);
>>   			vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
>>   				BXT_DE_PORT_HP_DDIB;
>>   		}
>>   
>>   		if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
>> +			vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
>> +			vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
>> +			vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
>> +				PHY_POWER_GOOD;
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
>> +				BIT(30);
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
>> +				BXT_PHY_LANE_ENABLED;
>> +			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) &=
>> +				~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
>> +				  BXT_PHY_LANE_POWERDOWN_ACK);
>> +			vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_C)) |=
>> +				(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
>> +				 PORT_PLL_REF_SEL | PORT_PLL_LOCK |
>> +				 PORT_PLL_ENABLE);
>> +			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |=
>> +				DDI_BUF_CTL_ENABLE;
>> +			vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &=
>> +				~DDI_BUF_IS_IDLE;
>> +			vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
>> +				(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
>> +				 (PORT_B << TRANS_DDI_PORT_SHIFT) |
>> +				 TRANS_DDI_FUNC_ENABLE);
>>   			vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
>>   				BXT_DE_PORT_HP_DDIC;
>>   		}
>> @@ -519,6 +660,42 @@ void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected)
>>   		vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
>>   				PORTD_HOTPLUG_STATUS_MASK;
>>   		intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG);
>> +	} else if (IS_BROXTON(i915)) {
>> +		if (connected) {
>> +			if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
>> +				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
>> +					BXT_DE_PORT_HP_DDIA;
>> +			}
>> +			if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
>> +				vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
>> +					SFUSE_STRAP_DDIB_DETECTED;
>> +				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
>> +					BXT_DE_PORT_HP_DDIB;
>> +			}
>> +			if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
>> +				vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
>> +					SFUSE_STRAP_DDIC_DETECTED;
>> +				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
>> +					BXT_DE_PORT_HP_DDIC;
>> +			}
>> +		} else {
>> +			if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
>> +				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
>> +					~BXT_DE_PORT_HP_DDIA;
>> +			}
>> +			if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
>> +				vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
>> +					~SFUSE_STRAP_DDIB_DETECTED;
>> +				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
>> +					~BXT_DE_PORT_HP_DDIB;
>> +			}
>> +			if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
>> +				vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
>> +					~SFUSE_STRAP_DDIC_DETECTED;
>> +				vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
>> +					~BXT_DE_PORT_HP_DDIC;
>> +			}
>> +		}
>>   	}
>>   }
>>   
>> diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c
>> index b6811f6a230d..24210b1eaec5 100644
>> --- a/drivers/gpu/drm/i915/gvt/mmio.c
>> +++ b/drivers/gpu/drm/i915/gvt/mmio.c
>> @@ -280,6 +280,11 @@ void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr)
>>   			vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
>>   				    BXT_PHY_CMNLANE_POWERDOWN_ACK |
>>   				    BXT_PHY_LANE_POWERDOWN_ACK;
>> +			vgpu_vreg_t(vgpu, SKL_FUSE_STATUS) |=
>> +				SKL_FUSE_DOWNLOAD_STATUS |
>> +				SKL_FUSE_PG_DIST_STATUS(SKL_PG0) |
>> +				SKL_FUSE_PG_DIST_STATUS(SKL_PG1) |
>> +				SKL_FUSE_PG_DIST_STATUS(SKL_PG2);
>>   		}
>>   	} else {
>>   #define GVT_GEN8_MMIO_RESET_OFFSET		(0x44200)
>> -- 
>> 2.28.0
>>
>> _______________________________________________
>> intel-gvt-dev mailing list
>> intel-gvt-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev

-- 
Best Regards,
Colin Xu



More information about the intel-gvt-dev mailing list