--- /dev/null
+From 4ceb06e7c336f4a8d3f3b6ac9a4fea2e9c97dc07 Mon Sep 17 00:00:00 2001
+From: Colin Xu <colin.xu@intel.com>
+Date: Tue, 1 Dec 2020 14:03:29 +0800
+Subject: drm/i915/gvt: Fix vfio_edid issue for BXT/APL
+
+From: Colin Xu <colin.xu@intel.com>
+
+commit 4ceb06e7c336f4a8d3f3b6ac9a4fea2e9c97dc07 upstream.
+
+BXT/APL has different isr/irr/hpd regs compared with other GEN9. If not
+setting these regs bits correctly according to the emulated monitor
+(currently a DP on PORT_B), although gvt still triggers a virtual HPD
+event, the guest driver won't detect a valid HPD pulse thus no full
+display detection will be executed to read the updated EDID.
+
+With this patch, the vfio_edid is enabled again on BXT/APL, which is
+previously disabled.
+
+Fixes: 642403e3599e ("drm/i915/gvt: Temporarily disable vfio_edid for BXT/APL")
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20201201060329.142375-1-colin.xu@intel.com
+Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/gvt/display.c | 83 +++++++++++++++++++++++++++----------
+ drivers/gpu/drm/i915/gvt/vgpu.c | 5 --
+ 2 files changed, 63 insertions(+), 25 deletions(-)
+
+--- a/drivers/gpu/drm/i915/gvt/display.c
++++ b/drivers/gpu/drm/i915/gvt/display.c
+@@ -216,6 +216,15 @@ static void emulate_monitor_status_chang
+ DDI_BUF_CTL_ENABLE);
+ vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE;
+ }
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~(PORTA_HOTPLUG_ENABLE | PORTA_HOTPLUG_STATUS_MASK);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~(PORTB_HOTPLUG_ENABLE | PORTB_HOTPLUG_STATUS_MASK);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~(PORTC_HOTPLUG_ENABLE | PORTC_HOTPLUG_STATUS_MASK);
++ /* No hpd_invert set in vgpu vbt, need to clear invert mask */
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= ~BXT_DDI_HPD_INVERT_MASK;
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HOTPLUG_MASK;
+
+ vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1));
+ vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &=
+@@ -272,6 +281,8 @@ static void emulate_monitor_status_chang
+ 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, PCH_PORT_HOTPLUG) |=
++ PORTA_HOTPLUG_ENABLE;
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIA;
+ }
+@@ -300,6 +311,8 @@ static void emulate_monitor_status_chang
+ (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
+ (PORT_B << TRANS_DDI_PORT_SHIFT) |
+ TRANS_DDI_FUNC_ENABLE);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTB_HOTPLUG_ENABLE;
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIB;
+ }
+@@ -328,6 +341,8 @@ static void emulate_monitor_status_chang
+ (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
+ (PORT_B << TRANS_DDI_PORT_SHIFT) |
+ TRANS_DDI_FUNC_ENABLE);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTC_HOTPLUG_ENABLE;
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIC;
+ }
+@@ -660,38 +675,62 @@ void intel_vgpu_emulate_hotplug(struct i
+ 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_A)) {
++ if (connected) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
++ BXT_DE_PORT_HP_DDIA;
++ } else {
++ 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, GEN8_DE_PORT_IIR) |=
++ BXT_DE_PORT_HP_DDIA;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~PORTA_HOTPLUG_STATUS_MASK;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTA_HOTPLUG_LONG_DETECT;
++ intel_vgpu_trigger_virtual_event(vgpu, DP_A_HOTPLUG);
++ }
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
++ if (connected) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
++ BXT_DE_PORT_HP_DDIB;
+ 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)) {
++ } else {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
++ ~BXT_DE_PORT_HP_DDIB;
+ 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, GEN8_DE_PORT_IIR) |=
++ BXT_DE_PORT_HP_DDIB;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~PORTB_HOTPLUG_STATUS_MASK;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTB_HOTPLUG_LONG_DETECT;
++ intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
++ }
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
++ if (connected) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
++ BXT_DE_PORT_HP_DDIC;
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
++ SFUSE_STRAP_DDIC_DETECTED;
++ } else {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
++ ~BXT_DE_PORT_HP_DDIC;
+ vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
+ ~SFUSE_STRAP_DDIC_DETECTED;
+- vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HP_DDIC;
+ }
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
++ BXT_DE_PORT_HP_DDIC;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~PORTC_HOTPLUG_STATUS_MASK;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTC_HOTPLUG_LONG_DETECT;
++ intel_vgpu_trigger_virtual_event(vgpu, DP_C_HOTPLUG);
+ }
+- vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
+- PORTB_HOTPLUG_STATUS_MASK;
+- intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
+ }
+ }
+
+--- a/drivers/gpu/drm/i915/gvt/vgpu.c
++++ b/drivers/gpu/drm/i915/gvt/vgpu.c
+@@ -437,10 +437,9 @@ static struct intel_vgpu *__intel_gvt_cr
+ if (ret)
+ goto out_clean_sched_policy;
+
+- if (IS_BROADWELL(dev_priv))
++ if (IS_BROADWELL(dev_priv) || IS_BROXTON(dev_priv))
+ ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B);
+- /* FixMe: Re-enable APL/BXT once vfio_edid enabled */
+- else if (!IS_BROXTON(dev_priv))
++ else
+ ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D);
+ if (ret)
+ goto out_clean_sched_policy;
--- /dev/null
+From a5a8ef937cfa79167f4b2a5602092b8d14fd6b9a Mon Sep 17 00:00:00 2001
+From: Colin Xu <colin.xu@intel.com>
+Date: Mon, 9 Nov 2020 15:39:22 +0800
+Subject: drm/i915/gvt: Fix virtual display setup for BXT/APL
+
+From: Colin Xu <colin.xu@intel.com>
+
+commit a5a8ef937cfa79167f4b2a5602092b8d14fd6b9a upstream.
+
+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.
+
+Acked-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20201109073922.757759-1-colin.xu@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/gvt/display.c | 173 +++++++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/i915/gvt/mmio.c | 5 +
+ 2 files changed, 178 insertions(+)
+
+--- a/drivers/gpu/drm/i915/gvt/display.c
++++ b/drivers/gpu/drm/i915/gvt/display.c
+@@ -173,21 +173,161 @@ static void emulate_monitor_status_chang
+ 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) &= ~(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 +659,39 @@ void intel_vgpu_emulate_hotplug(struct i
+ 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;
++ }
++ }
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTB_HOTPLUG_STATUS_MASK;
++ intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
+ }
+ }
+
+--- 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_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)
--- /dev/null
+From 4fff19ae427548d8c37260c975a4b20d3c040ec6 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Wed, 17 Feb 2021 13:32:05 +0100
+Subject: drm/qxl: use ttm bo priorities
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+
+commit 4fff19ae427548d8c37260c975a4b20d3c040ec6 upstream.
+
+Allow to set priorities for buffer objects. Use priority 1 for surface
+and cursor command releases. Use priority 0 for drawing command
+releases. That way the short-living drawing commands are first in line
+when it comes to eviction, making it *much* less likely that
+ttm_bo_mem_force_space() picks something which can't be evicted and
+throws an error after waiting a while without success.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: http://patchwork.freedesktop.org/patch/msgid/20210217123213.2199186-4-kraxel@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/qxl/qxl_cmd.c | 2 +-
+ drivers/gpu/drm/qxl/qxl_display.c | 4 ++--
+ drivers/gpu/drm/qxl/qxl_gem.c | 2 +-
+ drivers/gpu/drm/qxl/qxl_object.c | 5 +++--
+ drivers/gpu/drm/qxl/qxl_object.h | 1 +
+ drivers/gpu/drm/qxl/qxl_release.c | 18 ++++++++++++------
+ 6 files changed, 20 insertions(+), 12 deletions(-)
+
+--- a/drivers/gpu/drm/qxl/qxl_cmd.c
++++ b/drivers/gpu/drm/qxl/qxl_cmd.c
+@@ -268,7 +268,7 @@ int qxl_alloc_bo_reserved(struct qxl_dev
+ int ret;
+
+ ret = qxl_bo_create(qdev, size, false /* not kernel - device */,
+- false, QXL_GEM_DOMAIN_VRAM, NULL, &bo);
++ false, QXL_GEM_DOMAIN_VRAM, 0, NULL, &bo);
+ if (ret) {
+ DRM_ERROR("failed to allocate VRAM BO\n");
+ return ret;
+--- a/drivers/gpu/drm/qxl/qxl_display.c
++++ b/drivers/gpu/drm/qxl/qxl_display.c
+@@ -791,8 +791,8 @@ static int qxl_plane_prepare_fb(struct d
+ qdev->dumb_shadow_bo = NULL;
+ }
+ qxl_bo_create(qdev, surf.height * surf.stride,
+- true, true, QXL_GEM_DOMAIN_SURFACE, &surf,
+- &qdev->dumb_shadow_bo);
++ true, true, QXL_GEM_DOMAIN_SURFACE, 0,
++ &surf, &qdev->dumb_shadow_bo);
+ }
+ if (user_bo->shadow != qdev->dumb_shadow_bo) {
+ if (user_bo->shadow) {
+--- a/drivers/gpu/drm/qxl/qxl_gem.c
++++ b/drivers/gpu/drm/qxl/qxl_gem.c
+@@ -55,7 +55,7 @@ int qxl_gem_object_create(struct qxl_dev
+ /* At least align on page size */
+ if (alignment < PAGE_SIZE)
+ alignment = PAGE_SIZE;
+- r = qxl_bo_create(qdev, size, kernel, false, initial_domain, surf, &qbo);
++ r = qxl_bo_create(qdev, size, kernel, false, initial_domain, 0, surf, &qbo);
+ if (r) {
+ if (r != -ERESTARTSYS)
+ DRM_ERROR(
+--- a/drivers/gpu/drm/qxl/qxl_object.c
++++ b/drivers/gpu/drm/qxl/qxl_object.c
+@@ -103,8 +103,8 @@ static const struct drm_gem_object_funcs
+ .print_info = drm_gem_ttm_print_info,
+ };
+
+-int qxl_bo_create(struct qxl_device *qdev,
+- unsigned long size, bool kernel, bool pinned, u32 domain,
++int qxl_bo_create(struct qxl_device *qdev, unsigned long size,
++ bool kernel, bool pinned, u32 domain, u32 priority,
+ struct qxl_surface *surf,
+ struct qxl_bo **bo_ptr)
+ {
+@@ -137,6 +137,7 @@ int qxl_bo_create(struct qxl_device *qde
+
+ qxl_ttm_placement_from_domain(bo, domain, pinned);
+
++ bo->tbo.priority = priority;
+ r = ttm_bo_init(&qdev->mman.bdev, &bo->tbo, size, type,
+ &bo->placement, 0, !kernel, size,
+ NULL, NULL, &qxl_ttm_bo_destroy);
+--- a/drivers/gpu/drm/qxl/qxl_object.h
++++ b/drivers/gpu/drm/qxl/qxl_object.h
+@@ -84,6 +84,7 @@ static inline int qxl_bo_wait(struct qxl
+ extern int qxl_bo_create(struct qxl_device *qdev,
+ unsigned long size,
+ bool kernel, bool pinned, u32 domain,
++ u32 priority,
+ struct qxl_surface *surf,
+ struct qxl_bo **bo_ptr);
+ extern int qxl_bo_kmap(struct qxl_bo *bo, void **ptr);
+--- a/drivers/gpu/drm/qxl/qxl_release.c
++++ b/drivers/gpu/drm/qxl/qxl_release.c
+@@ -199,11 +199,12 @@ qxl_release_free(struct qxl_device *qdev
+ }
+
+ static int qxl_release_bo_alloc(struct qxl_device *qdev,
+- struct qxl_bo **bo)
++ struct qxl_bo **bo,
++ u32 priority)
+ {
+ /* pin releases bo's they are too messy to evict */
+ return qxl_bo_create(qdev, PAGE_SIZE, false, true,
+- QXL_GEM_DOMAIN_VRAM, NULL, bo);
++ QXL_GEM_DOMAIN_VRAM, priority, NULL, bo);
+ }
+
+ int qxl_release_list_add(struct qxl_release *release, struct qxl_bo *bo)
+@@ -326,13 +327,18 @@ int qxl_alloc_release_reserved(struct qx
+ int ret = 0;
+ union qxl_release_info *info;
+ int cur_idx;
++ u32 priority;
+
+- if (type == QXL_RELEASE_DRAWABLE)
++ if (type == QXL_RELEASE_DRAWABLE) {
+ cur_idx = 0;
+- else if (type == QXL_RELEASE_SURFACE_CMD)
++ priority = 0;
++ } else if (type == QXL_RELEASE_SURFACE_CMD) {
+ cur_idx = 1;
+- else if (type == QXL_RELEASE_CURSOR_CMD)
++ priority = 1;
++ } else if (type == QXL_RELEASE_CURSOR_CMD) {
+ cur_idx = 2;
++ priority = 1;
++ }
+ else {
+ DRM_ERROR("got illegal type: %d\n", type);
+ return -EINVAL;
+@@ -352,7 +358,7 @@ int qxl_alloc_release_reserved(struct qx
+ qdev->current_release_bo[cur_idx] = NULL;
+ }
+ if (!qdev->current_release_bo[cur_idx]) {
+- ret = qxl_release_bo_alloc(qdev, &qdev->current_release_bo[cur_idx]);
++ ret = qxl_release_bo_alloc(qdev, &qdev->current_release_bo[cur_idx], priority);
+ if (ret) {
+ mutex_unlock(&qdev->release_mutex);
+ qxl_release_free(qdev, *release);
rtw88-fix-array-overrun-in-rtw_get_tx_power_params.patch
mt76-fix-potential-dma-mapping-leak.patch
fddi-defxx-make-mmio-the-configuration-default-except-for-eisa.patch
+drm-i915-gvt-fix-virtual-display-setup-for-bxt-apl.patch
+drm-i915-gvt-fix-vfio_edid-issue-for-bxt-apl.patch
+drm-qxl-use-ttm-bo-priorities.patch