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

Colin Xu Colin.Xu at intel.com
Fri May 8 08:39:51 UTC 2020


On 2020-05-08 14:24, Zhenyu Wang wrote:
> On 2020.05.08 14:05:06 +0800, Colin Xu wrote:
>> 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.
>>
>> Signed-off-by: Colin Xu <colin.xu at intel.com>
>> ---
>>   drivers/gpu/drm/i915/gvt/display.c | 49 +++++++++++++++++++++++++++---
>>   1 file changed, 44 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
>> index a83df2f84eb9..a1696e9ce4b6 100644
>> --- a/drivers/gpu/drm/i915/gvt/display.c
>> +++ b/drivers/gpu/drm/i915/gvt/display.c
>> @@ -208,14 +208,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;
> Is this not required?

Based on PRM display chapter, LCPLL2_CTL is for DPLL1. GVT virtual 
display only simulate one path on PIPE_A and could use PORT_B or PORT_D 
based on the caller. Since DPLL0 can be bind to any PORT so in single 
display case it should be enough to use DPLL0(LCPLL1_CTL) only. When 
setting up different PORT, the patch will turn on the CLK for the 
selected DDI/PORT by setting DPLL_CTRL2.

In future if multiple displays are supported, we can see if use shared 
DPLL or assign different DPLL to different DDI/PORT.

>> -
>> +		/*
>> +		 * 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 |
>> @@ -236,6 +263,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 |
>> @@ -256,6 +289,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 |
>> -- 
>> 2.26.2
>>
>> _______________________________________________
>> intel-gvt-dev mailing list
>> intel-gvt-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev
>
> _______________________________________________
> 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