drm/i915/gvt: Init PHY related registers for BXT
authorColin Xu <colin.xu@intel.com>
Mon, 17 Sep 2018 04:19:03 +0000 (12:19 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Tue, 18 Sep 2018 02:37:29 +0000 (10:37 +0800)
Recent patch fixed the call trace
"ERROR Port B enabled but PHY powered down? (PHY_CTL 00000000)".
but introduced another similar call trace shown as:
"ERROR Port C enabled but PHY powered down? (PHY_CTL 00000200)".
The call trace will appear when host and guest enabled different ports,
i.e. host using PORT C or neither PORT is enabled, while guest is always
using PORT B as simulated by gvt. The issue is actually covered previously
before the commit and reverals now when the commit do the right thing.

On BXT, some PHY registers are initialized by vbios, before i915 loaded.
Later i915 will re-program some, or skip some based on the implementation.
The initialized mmio for guest i915 is done by gvt, based on the snapshot
taken from host. If host and guest have different PORT enabled, some
DPIO PHY mmios that gvt initialized for guest i915 will not match the
simualted monitor for guest, which leads to guest i915 print the calltrace
when it's trying to enable PHY and PORT.

The solution is to init these DPIO PHY registers to default value, then
guest i915 will program them to reasonable value based on the default
powerwell table and enabled PORT. Together with the old patch, all similar
call trace in guest kernel on BXT can be resolved.

v2: Move PHY register init to intel_vgpu_reset_mmio (Min)
v3: Do not delete empty line in issue fix patch. (zhenyu)

Fixes: c8ab5ac30ccc ("drm/i915/gvt: Make correct handling to vreg
BXT_PHY_CTL_FAMILY")
Reviewed-by: He, Min <min.he@intel.com>
Signed-off-by: Colin Xu <colin.xu@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/mmio.c

index 994366035364b7576db8ed2ec1036d417cc39d9c..9bb9a85c992ca16a13552af798d8e47e3061dd52 100644 (file)
@@ -244,6 +244,34 @@ void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr)
 
                /* set the bit 0:2(Core C-State ) to C0 */
                vgpu_vreg_t(vgpu, GEN6_GT_CORE_STATUS) = 0;
+
+               if (IS_BROXTON(vgpu->gvt->dev_priv)) {
+                       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, 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_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_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;
+               }
        } else {
 #define GVT_GEN8_MMIO_RESET_OFFSET             (0x44200)
                /* only reset the engine related, so starting with 0x44200