[PATCH V5] drm/i915/gvt: Fix virtual display setup for BXT/APL
Zhenyu Wang
zhenyuw at linux.intel.com
Tue Nov 10 06:27:51 UTC 2020
On 2020.11.09 15:39:22 +0800, Colin Xu wrote:
> Program display related vregs to proper value at initialization, setup
> virtual monitor and hotplug.
>
> vGPU virtual display vregs inherit the value from pregs. The virtual DP
> monitor is always setup on PORT_B for BXT/APL. However the host may
> connect monitor on other PORT or without any monitor connected. Without
> properly setup PIPE/DDI/PLL related vregs, guest driver may not setup
> the virutal display as expected, and the guest desktop may not be
> created.
> Since only one virtual display is supported, enable PIPE_A only. And
> enable transcoder/DDI/PLL based on which port is setup for BXT/APL.
>
> V2:
> Revise commit message.
>
> V3:
> set_edid should on PORT_B for BXT.
> Inject hpd event for BXT.
>
> V4:
> Temporarily disable vfio edid on BXT/APL until issue fixed.
>
> V5:
> Rebase to use new HPD define GEN8_DE_PORT_HOTPLUG for BXT.
> Put vfio edid disabling on BXT/APL to a separate patch.
>
> Signed-off-by: Colin Xu <colin.xu at intel.com>
> ---
Acked-by: Zhenyu Wang <zhenyuw at linux.intel.com>
> drivers/gpu/drm/i915/gvt/display.c | 179 +++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/gvt/mmio.c | 5 +
> 2 files changed, 184 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
> index 5b5c71a0b4af..5c1fcac260d3 100644
> --- a/drivers/gpu/drm/i915/gvt/display.c
> +++ b/drivers/gpu/drm/i915/gvt/display.c
> @@ -173,22 +173,162 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
> int pipe;
>
> if (IS_BROXTON(dev_priv)) {
> + enum transcoder trans;
> + enum port port;
> +
> + /* Clear PIPE, DDI, PHY, HPD before setting new */
> vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
> ~(GEN8_DE_PORT_HOTPLUG(HPD_PORT_A) |
> GEN8_DE_PORT_HOTPLUG(HPD_PORT_B) |
> GEN8_DE_PORT_HOTPLUG(HPD_PORT_C));
>
> + 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) |=
> GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
> }
>
> 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) |=
> GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
> }
>
> 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) |=
> GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
> }
> @@ -520,6 +660,45 @@ 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) |=
> + GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
> + }
> + 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) |=
> + GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
> + }
> + 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) |=
> + GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
> + }
> + } else {
> + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
> + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
> + ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
> + }
> + 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) &=
> + ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
> + }
> + 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) &=
> + ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
> + }
> + }
> + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
> + PORTB_HOTPLUG_STATUS_MASK;
> + intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
> }
> }
>
> 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.29.2
>
> _______________________________________________
> intel-gvt-dev mailing list
> intel-gvt-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev
--
$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/intel-gvt-dev/attachments/20201110/6b5ab0d6/attachment-0001.sig>
More information about the intel-gvt-dev
mailing list