Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0021  * SOFTWARE.
0022  *
0023  * Authors:
0024  *    Ke Yu
0025  *    Zhiyuan Lv <zhiyuan.lv@intel.com>
0026  *
0027  * Contributors:
0028  *    Terrence Xu <terrence.xu@intel.com>
0029  *    Changbin Du <changbin.du@intel.com>
0030  *    Bing Niu <bing.niu@intel.com>
0031  *    Zhi Wang <zhi.a.wang@intel.com>
0032  *
0033  */
0034 
0035 #include "i915_drv.h"
0036 #include "i915_reg.h"
0037 #include "gvt.h"
0038 
0039 static int get_edp_pipe(struct intel_vgpu *vgpu)
0040 {
0041     u32 data = vgpu_vreg(vgpu, _TRANS_DDI_FUNC_CTL_EDP);
0042     int pipe = -1;
0043 
0044     switch (data & TRANS_DDI_EDP_INPUT_MASK) {
0045     case TRANS_DDI_EDP_INPUT_A_ON:
0046     case TRANS_DDI_EDP_INPUT_A_ONOFF:
0047         pipe = PIPE_A;
0048         break;
0049     case TRANS_DDI_EDP_INPUT_B_ONOFF:
0050         pipe = PIPE_B;
0051         break;
0052     case TRANS_DDI_EDP_INPUT_C_ONOFF:
0053         pipe = PIPE_C;
0054         break;
0055     }
0056     return pipe;
0057 }
0058 
0059 static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
0060 {
0061     struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0062 
0063     if (!(vgpu_vreg_t(vgpu, PIPECONF(_PIPE_EDP)) & PIPECONF_ENABLE))
0064         return 0;
0065 
0066     if (!(vgpu_vreg(vgpu, _TRANS_DDI_FUNC_CTL_EDP) & TRANS_DDI_FUNC_ENABLE))
0067         return 0;
0068     return 1;
0069 }
0070 
0071 int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
0072 {
0073     struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0074 
0075     if (drm_WARN_ON(&dev_priv->drm,
0076             pipe < PIPE_A || pipe >= I915_MAX_PIPES))
0077         return -EINVAL;
0078 
0079     if (vgpu_vreg_t(vgpu, PIPECONF(pipe)) & PIPECONF_ENABLE)
0080         return 1;
0081 
0082     if (edp_pipe_is_enabled(vgpu) &&
0083             get_edp_pipe(vgpu) == pipe)
0084         return 1;
0085     return 0;
0086 }
0087 
0088 static unsigned char virtual_dp_monitor_edid[GVT_EDID_NUM][EDID_SIZE] = {
0089     {
0090 /* EDID with 1024x768 as its resolution */
0091         /*Header*/
0092         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0093         /* Vendor & Product Identification */
0094         0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17,
0095         /* Version & Revision */
0096         0x01, 0x04,
0097         /* Basic Display Parameters & Features */
0098         0xa5, 0x34, 0x20, 0x78, 0x23,
0099         /* Color Characteristics */
0100         0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54,
0101         /* Established Timings: maximum resolution is 1024x768 */
0102         0x21, 0x08, 0x00,
0103         /* Standard Timings. All invalid */
0104         0x00, 0xc0, 0x00, 0xc0, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00,
0105         0x00, 0x40, 0x00, 0x00, 0x00, 0x01,
0106         /* 18 Byte Data Blocks 1: invalid */
0107         0x00, 0x00, 0x80, 0xa0, 0x70, 0xb0,
0108         0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a,
0109         /* 18 Byte Data Blocks 2: invalid */
0110         0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a,
0111         0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0112         /* 18 Byte Data Blocks 3: invalid */
0113         0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
0114         0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20,
0115         /* 18 Byte Data Blocks 4: invalid */
0116         0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30,
0117         0x44, 0x58, 0x51, 0x0a, 0x20, 0x20,
0118         /* Extension Block Count */
0119         0x00,
0120         /* Checksum */
0121         0xef,
0122     },
0123     {
0124 /* EDID with 1920x1200 as its resolution */
0125         /*Header*/
0126         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
0127         /* Vendor & Product Identification */
0128         0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17,
0129         /* Version & Revision */
0130         0x01, 0x04,
0131         /* Basic Display Parameters & Features */
0132         0xa5, 0x34, 0x20, 0x78, 0x23,
0133         /* Color Characteristics */
0134         0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54,
0135         /* Established Timings: maximum resolution is 1024x768 */
0136         0x21, 0x08, 0x00,
0137         /*
0138          * Standard Timings.
0139          * below new resolutions can be supported:
0140          * 1920x1080, 1280x720, 1280x960, 1280x1024,
0141          * 1440x900, 1600x1200, 1680x1050
0142          */
0143         0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x40, 0x81, 0x80, 0x95, 0x00,
0144         0xa9, 0x40, 0xb3, 0x00, 0x01, 0x01,
0145         /* 18 Byte Data Blocks 1: max resolution is 1920x1200 */
0146         0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
0147         0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a,
0148         /* 18 Byte Data Blocks 2: invalid */
0149         0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a,
0150         0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0151         /* 18 Byte Data Blocks 3: invalid */
0152         0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
0153         0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20,
0154         /* 18 Byte Data Blocks 4: invalid */
0155         0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30,
0156         0x44, 0x58, 0x51, 0x0a, 0x20, 0x20,
0157         /* Extension Block Count */
0158         0x00,
0159         /* Checksum */
0160         0x45,
0161     },
0162 };
0163 
0164 #define DPCD_HEADER_SIZE        0xb
0165 
0166 /* let the virtual display supports DP1.2 */
0167 static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
0168     0x12, 0x014, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0169 };
0170 
0171 static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
0172 {
0173     struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0174     int pipe;
0175 
0176     if (IS_BROXTON(dev_priv)) {
0177         enum transcoder trans;
0178         enum port port;
0179 
0180         /* Clear PIPE, DDI, PHY, HPD before setting new */
0181         vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
0182             ~(GEN8_DE_PORT_HOTPLUG(HPD_PORT_A) |
0183               GEN8_DE_PORT_HOTPLUG(HPD_PORT_B) |
0184               GEN8_DE_PORT_HOTPLUG(HPD_PORT_C));
0185 
0186         for_each_pipe(dev_priv, pipe) {
0187             vgpu_vreg_t(vgpu, PIPECONF(pipe)) &=
0188                 ~(PIPECONF_ENABLE | PIPECONF_STATE_ENABLE);
0189             vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISP_ENABLE;
0190             vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
0191             vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE_MASK;
0192             vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
0193         }
0194 
0195         for (trans = TRANSCODER_A; trans <= TRANSCODER_EDP; trans++) {
0196             vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(trans)) &=
0197                 ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
0198                   TRANS_DDI_PORT_MASK | TRANS_DDI_FUNC_ENABLE);
0199         }
0200         vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
0201             ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
0202               TRANS_DDI_PORT_MASK);
0203 
0204         for (port = PORT_A; port <= PORT_C; port++) {
0205             vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) &=
0206                 ~BXT_PHY_LANE_ENABLED;
0207             vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) |=
0208                 (BXT_PHY_CMNLANE_POWERDOWN_ACK |
0209                  BXT_PHY_LANE_POWERDOWN_ACK);
0210 
0211             vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(port)) &=
0212                 ~(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
0213                   PORT_PLL_REF_SEL | PORT_PLL_LOCK |
0214                   PORT_PLL_ENABLE);
0215 
0216             vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) &=
0217                 ~(DDI_INIT_DISPLAY_DETECTED |
0218                   DDI_BUF_CTL_ENABLE);
0219             vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE;
0220         }
0221         vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
0222             ~(PORTA_HOTPLUG_ENABLE | PORTA_HOTPLUG_STATUS_MASK);
0223         vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
0224             ~(PORTB_HOTPLUG_ENABLE | PORTB_HOTPLUG_STATUS_MASK);
0225         vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
0226             ~(PORTC_HOTPLUG_ENABLE | PORTC_HOTPLUG_STATUS_MASK);
0227         /* No hpd_invert set in vgpu vbt, need to clear invert mask */
0228         vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= ~BXT_DDI_HPD_INVERT_MASK;
0229         vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HOTPLUG_MASK;
0230 
0231         vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1));
0232         vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &=
0233             ~PHY_POWER_GOOD;
0234         vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) &=
0235             ~PHY_POWER_GOOD;
0236         vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) &= ~BIT(30);
0237         vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) &= ~BIT(30);
0238 
0239         vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIB_DETECTED;
0240         vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIC_DETECTED;
0241 
0242         /*
0243          * Only 1 PIPE enabled in current vGPU display and PIPE_A is
0244          *  tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A,
0245          *   TRANSCODER_A can be enabled. PORT_x depends on the input of
0246          *   setup_virtual_dp_monitor.
0247          */
0248         vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
0249         vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_STATE_ENABLE;
0250 
0251         /*
0252          * Golden M/N are calculated based on:
0253          *   24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID),
0254          *   DP link clk 1620 MHz and non-constant_n.
0255          * TODO: calculate DP link symbol clk and stream clk m/n.
0256          */
0257         vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = TU_SIZE(64);
0258         vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
0259         vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
0260         vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
0261         vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
0262 
0263         /* Enable per-DDI/PORT vreg */
0264         if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
0265             vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(1);
0266             vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) |=
0267                 PHY_POWER_GOOD;
0268             vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) |=
0269                 BIT(30);
0270             vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) |=
0271                 BXT_PHY_LANE_ENABLED;
0272             vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) &=
0273                 ~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
0274                   BXT_PHY_LANE_POWERDOWN_ACK);
0275             vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_A)) |=
0276                 (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
0277                  PORT_PLL_REF_SEL | PORT_PLL_LOCK |
0278                  PORT_PLL_ENABLE);
0279             vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |=
0280                 (DDI_BUF_CTL_ENABLE | DDI_INIT_DISPLAY_DETECTED);
0281             vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) &=
0282                 ~DDI_BUF_IS_IDLE;
0283             vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |=
0284                 (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
0285                  TRANS_DDI_FUNC_ENABLE);
0286             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
0287                 PORTA_HOTPLUG_ENABLE;
0288             vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
0289                 GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
0290         }
0291 
0292         if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
0293             vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
0294             vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
0295             vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
0296                 PHY_POWER_GOOD;
0297             vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
0298                 BIT(30);
0299             vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) |=
0300                 BXT_PHY_LANE_ENABLED;
0301             vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) &=
0302                 ~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
0303                   BXT_PHY_LANE_POWERDOWN_ACK);
0304             vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_B)) |=
0305                 (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
0306                  PORT_PLL_REF_SEL | PORT_PLL_LOCK |
0307                  PORT_PLL_ENABLE);
0308             vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |=
0309                 DDI_BUF_CTL_ENABLE;
0310             vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &=
0311                 ~DDI_BUF_IS_IDLE;
0312             vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
0313                 (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
0314                  (PORT_B << TRANS_DDI_PORT_SHIFT) |
0315                  TRANS_DDI_FUNC_ENABLE);
0316             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
0317                 PORTB_HOTPLUG_ENABLE;
0318             vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
0319                 GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
0320         }
0321 
0322         if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
0323             vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
0324             vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
0325             vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
0326                 PHY_POWER_GOOD;
0327             vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
0328                 BIT(30);
0329             vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
0330                 BXT_PHY_LANE_ENABLED;
0331             vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) &=
0332                 ~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
0333                   BXT_PHY_LANE_POWERDOWN_ACK);
0334             vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_C)) |=
0335                 (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
0336                  PORT_PLL_REF_SEL | PORT_PLL_LOCK |
0337                  PORT_PLL_ENABLE);
0338             vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |=
0339                 DDI_BUF_CTL_ENABLE;
0340             vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &=
0341                 ~DDI_BUF_IS_IDLE;
0342             vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
0343                 (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
0344                  (PORT_B << TRANS_DDI_PORT_SHIFT) |
0345                  TRANS_DDI_FUNC_ENABLE);
0346             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
0347                 PORTC_HOTPLUG_ENABLE;
0348             vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
0349                 GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
0350         }
0351 
0352         return;
0353     }
0354 
0355     vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
0356             SDE_PORTC_HOTPLUG_CPT |
0357             SDE_PORTD_HOTPLUG_CPT);
0358 
0359     if (IS_SKYLAKE(dev_priv) ||
0360         IS_KABYLAKE(dev_priv) ||
0361         IS_COFFEELAKE(dev_priv) ||
0362         IS_COMETLAKE(dev_priv)) {
0363         vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTA_HOTPLUG_SPT |
0364                 SDE_PORTE_HOTPLUG_SPT);
0365         vgpu_vreg_t(vgpu, SKL_FUSE_STATUS) |=
0366                 SKL_FUSE_DOWNLOAD_STATUS |
0367                 SKL_FUSE_PG_DIST_STATUS(SKL_PG0) |
0368                 SKL_FUSE_PG_DIST_STATUS(SKL_PG1) |
0369                 SKL_FUSE_PG_DIST_STATUS(SKL_PG2);
0370         /*
0371          * Only 1 PIPE enabled in current vGPU display and PIPE_A is
0372          *  tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A,
0373          *   TRANSCODER_A can be enabled. PORT_x depends on the input of
0374          *   setup_virtual_dp_monitor, we can bind DPLL0 to any PORT_x
0375          *   so we fixed to DPLL0 here.
0376          * Setup DPLL0: DP link clk 1620 MHz, non SSC, DP Mode
0377          */
0378         vgpu_vreg_t(vgpu, DPLL_CTRL1) =
0379             DPLL_CTRL1_OVERRIDE(DPLL_ID_SKL_DPLL0);
0380         vgpu_vreg_t(vgpu, DPLL_CTRL1) |=
0381             DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, DPLL_ID_SKL_DPLL0);
0382         vgpu_vreg_t(vgpu, LCPLL1_CTL) =
0383             LCPLL_PLL_ENABLE | LCPLL_PLL_LOCK;
0384         vgpu_vreg_t(vgpu, DPLL_STATUS) = DPLL_LOCK(DPLL_ID_SKL_DPLL0);
0385         /*
0386          * Golden M/N are calculated based on:
0387          *   24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID),
0388          *   DP link clk 1620 MHz and non-constant_n.
0389          * TODO: calculate DP link symbol clk and stream clk m/n.
0390          */
0391         vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = TU_SIZE(64);
0392         vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
0393         vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
0394         vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
0395         vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
0396     }
0397 
0398     if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
0399         vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
0400             ~DPLL_CTRL2_DDI_CLK_OFF(PORT_B);
0401         vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
0402             DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_B);
0403         vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
0404             DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_B);
0405         vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
0406         vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
0407             ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
0408             TRANS_DDI_PORT_MASK);
0409         vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
0410             (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
0411             (PORT_B << TRANS_DDI_PORT_SHIFT) |
0412             TRANS_DDI_FUNC_ENABLE);
0413         if (IS_BROADWELL(dev_priv)) {
0414             vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_B)) &=
0415                 ~PORT_CLK_SEL_MASK;
0416             vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_B)) |=
0417                 PORT_CLK_SEL_LCPLL_810;
0418         }
0419         vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |= DDI_BUF_CTL_ENABLE;
0420         vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &= ~DDI_BUF_IS_IDLE;
0421         vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTB_HOTPLUG_CPT;
0422     }
0423 
0424     if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
0425         vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
0426             ~DPLL_CTRL2_DDI_CLK_OFF(PORT_C);
0427         vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
0428             DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_C);
0429         vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
0430             DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_C);
0431         vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT;
0432         vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
0433             ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
0434             TRANS_DDI_PORT_MASK);
0435         vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
0436             (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
0437             (PORT_C << TRANS_DDI_PORT_SHIFT) |
0438             TRANS_DDI_FUNC_ENABLE);
0439         if (IS_BROADWELL(dev_priv)) {
0440             vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_C)) &=
0441                 ~PORT_CLK_SEL_MASK;
0442             vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_C)) |=
0443                 PORT_CLK_SEL_LCPLL_810;
0444         }
0445         vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |= DDI_BUF_CTL_ENABLE;
0446         vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &= ~DDI_BUF_IS_IDLE;
0447         vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
0448     }
0449 
0450     if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D)) {
0451         vgpu_vreg_t(vgpu, DPLL_CTRL2) &=
0452             ~DPLL_CTRL2_DDI_CLK_OFF(PORT_D);
0453         vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
0454             DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_D);
0455         vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
0456             DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_D);
0457         vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT;
0458         vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
0459             ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
0460             TRANS_DDI_PORT_MASK);
0461         vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
0462             (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
0463             (PORT_D << TRANS_DDI_PORT_SHIFT) |
0464             TRANS_DDI_FUNC_ENABLE);
0465         if (IS_BROADWELL(dev_priv)) {
0466             vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_D)) &=
0467                 ~PORT_CLK_SEL_MASK;
0468             vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_D)) |=
0469                 PORT_CLK_SEL_LCPLL_810;
0470         }
0471         vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_D)) |= DDI_BUF_CTL_ENABLE;
0472         vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_D)) &= ~DDI_BUF_IS_IDLE;
0473         vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDID_DETECTED;
0474     }
0475 
0476     if ((IS_SKYLAKE(dev_priv) ||
0477          IS_KABYLAKE(dev_priv) ||
0478          IS_COFFEELAKE(dev_priv) ||
0479          IS_COMETLAKE(dev_priv)) &&
0480             intel_vgpu_has_monitor_on_port(vgpu, PORT_E)) {
0481         vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTE_HOTPLUG_SPT;
0482     }
0483 
0484     if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
0485         if (IS_BROADWELL(dev_priv))
0486             vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
0487                 GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
0488         else
0489             vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTA_HOTPLUG_SPT;
0490 
0491         vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |= DDI_INIT_DISPLAY_DETECTED;
0492     }
0493 
0494     /* Clear host CRT status, so guest couldn't detect this host CRT. */
0495     if (IS_BROADWELL(dev_priv))
0496         vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;
0497 
0498     /* Disable Primary/Sprite/Cursor plane */
0499     for_each_pipe(dev_priv, pipe) {
0500         vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISP_ENABLE;
0501         vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
0502         vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE_MASK;
0503         vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
0504     }
0505 
0506     vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
0507 }
0508 
0509 static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num)
0510 {
0511     struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num);
0512 
0513     kfree(port->edid);
0514     port->edid = NULL;
0515 
0516     kfree(port->dpcd);
0517     port->dpcd = NULL;
0518 }
0519 
0520 static enum hrtimer_restart vblank_timer_fn(struct hrtimer *data)
0521 {
0522     struct intel_vgpu_vblank_timer *vblank_timer;
0523     struct intel_vgpu *vgpu;
0524 
0525     vblank_timer = container_of(data, struct intel_vgpu_vblank_timer, timer);
0526     vgpu = container_of(vblank_timer, struct intel_vgpu, vblank_timer);
0527 
0528     /* Set vblank emulation request per-vGPU bit */
0529     intel_gvt_request_service(vgpu->gvt,
0530                   INTEL_GVT_REQUEST_EMULATE_VBLANK + vgpu->id);
0531     hrtimer_add_expires_ns(&vblank_timer->timer, vblank_timer->period);
0532     return HRTIMER_RESTART;
0533 }
0534 
0535 static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num,
0536                     int type, unsigned int resolution)
0537 {
0538     struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0539     struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num);
0540     struct intel_vgpu_vblank_timer *vblank_timer = &vgpu->vblank_timer;
0541 
0542     if (drm_WARN_ON(&i915->drm, resolution >= GVT_EDID_NUM))
0543         return -EINVAL;
0544 
0545     port->edid = kzalloc(sizeof(*(port->edid)), GFP_KERNEL);
0546     if (!port->edid)
0547         return -ENOMEM;
0548 
0549     port->dpcd = kzalloc(sizeof(*(port->dpcd)), GFP_KERNEL);
0550     if (!port->dpcd) {
0551         kfree(port->edid);
0552         return -ENOMEM;
0553     }
0554 
0555     memcpy(port->edid->edid_block, virtual_dp_monitor_edid[resolution],
0556             EDID_SIZE);
0557     port->edid->data_valid = true;
0558 
0559     memcpy(port->dpcd->data, dpcd_fix_data, DPCD_HEADER_SIZE);
0560     port->dpcd->data_valid = true;
0561     port->dpcd->data[DPCD_SINK_COUNT] = 0x1;
0562     port->type = type;
0563     port->id = resolution;
0564     port->vrefresh_k = GVT_DEFAULT_REFRESH_RATE * MSEC_PER_SEC;
0565     vgpu->display.port_num = port_num;
0566 
0567     /* Init hrtimer based on default refresh rate */
0568     hrtimer_init(&vblank_timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
0569     vblank_timer->timer.function = vblank_timer_fn;
0570     vblank_timer->vrefresh_k = port->vrefresh_k;
0571     vblank_timer->period = DIV64_U64_ROUND_CLOSEST(NSEC_PER_SEC * MSEC_PER_SEC, vblank_timer->vrefresh_k);
0572 
0573     emulate_monitor_status_change(vgpu);
0574 
0575     return 0;
0576 }
0577 
0578 /**
0579  * vgpu_update_vblank_emulation - Update per-vGPU vblank_timer
0580  * @vgpu: vGPU operated
0581  * @turnon: Turn ON/OFF vblank_timer
0582  *
0583  * This function is used to turn on/off or update the per-vGPU vblank_timer
0584  * when PIPECONF is enabled or disabled. vblank_timer period is also updated
0585  * if guest changed the refresh rate.
0586  *
0587  */
0588 void vgpu_update_vblank_emulation(struct intel_vgpu *vgpu, bool turnon)
0589 {
0590     struct intel_vgpu_vblank_timer *vblank_timer = &vgpu->vblank_timer;
0591     struct intel_vgpu_port *port =
0592         intel_vgpu_port(vgpu, vgpu->display.port_num);
0593 
0594     if (turnon) {
0595         /*
0596          * Skip the re-enable if already active and vrefresh unchanged.
0597          * Otherwise, stop timer if already active and restart with new
0598          *   period.
0599          */
0600         if (vblank_timer->vrefresh_k != port->vrefresh_k ||
0601             !hrtimer_active(&vblank_timer->timer)) {
0602             /* Stop timer before start with new period if active */
0603             if (hrtimer_active(&vblank_timer->timer))
0604                 hrtimer_cancel(&vblank_timer->timer);
0605 
0606             /* Make sure new refresh rate updated to timer period */
0607             vblank_timer->vrefresh_k = port->vrefresh_k;
0608             vblank_timer->period = DIV64_U64_ROUND_CLOSEST(NSEC_PER_SEC * MSEC_PER_SEC, vblank_timer->vrefresh_k);
0609             hrtimer_start(&vblank_timer->timer,
0610                       ktime_add_ns(ktime_get(), vblank_timer->period),
0611                       HRTIMER_MODE_ABS);
0612         }
0613     } else {
0614         /* Caller request to stop vblank */
0615         hrtimer_cancel(&vblank_timer->timer);
0616     }
0617 }
0618 
0619 static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe)
0620 {
0621     struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0622     struct intel_vgpu_irq *irq = &vgpu->irq;
0623     int vblank_event[] = {
0624         [PIPE_A] = PIPE_A_VBLANK,
0625         [PIPE_B] = PIPE_B_VBLANK,
0626         [PIPE_C] = PIPE_C_VBLANK,
0627     };
0628     int event;
0629 
0630     if (pipe < PIPE_A || pipe > PIPE_C)
0631         return;
0632 
0633     for_each_set_bit(event, irq->flip_done_event[pipe],
0634             INTEL_GVT_EVENT_MAX) {
0635         clear_bit(event, irq->flip_done_event[pipe]);
0636         if (!pipe_is_enabled(vgpu, pipe))
0637             continue;
0638 
0639         intel_vgpu_trigger_virtual_event(vgpu, event);
0640     }
0641 
0642     if (pipe_is_enabled(vgpu, pipe)) {
0643         vgpu_vreg_t(vgpu, PIPE_FRMCOUNT_G4X(pipe))++;
0644         intel_vgpu_trigger_virtual_event(vgpu, vblank_event[pipe]);
0645     }
0646 }
0647 
0648 void intel_vgpu_emulate_vblank(struct intel_vgpu *vgpu)
0649 {
0650     int pipe;
0651 
0652     mutex_lock(&vgpu->vgpu_lock);
0653     for_each_pipe(vgpu->gvt->gt->i915, pipe)
0654         emulate_vblank_on_pipe(vgpu, pipe);
0655     mutex_unlock(&vgpu->vgpu_lock);
0656 }
0657 
0658 /**
0659  * intel_vgpu_emulate_hotplug - trigger hotplug event for vGPU
0660  * @vgpu: a vGPU
0661  * @connected: link state
0662  *
0663  * This function is used to trigger hotplug interrupt for vGPU
0664  *
0665  */
0666 void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected)
0667 {
0668     struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0669 
0670     /* TODO: add more platforms support */
0671     if (IS_SKYLAKE(i915) ||
0672         IS_KABYLAKE(i915) ||
0673         IS_COFFEELAKE(i915) ||
0674         IS_COMETLAKE(i915)) {
0675         if (connected) {
0676             vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
0677                 SFUSE_STRAP_DDID_DETECTED;
0678             vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT;
0679         } else {
0680             vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
0681                 ~SFUSE_STRAP_DDID_DETECTED;
0682             vgpu_vreg_t(vgpu, SDEISR) &= ~SDE_PORTD_HOTPLUG_CPT;
0683         }
0684         vgpu_vreg_t(vgpu, SDEIIR) |= SDE_PORTD_HOTPLUG_CPT;
0685         vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
0686                 PORTD_HOTPLUG_STATUS_MASK;
0687         intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG);
0688     } else if (IS_BROXTON(i915)) {
0689         if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
0690             if (connected) {
0691                 vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
0692                     GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
0693             } else {
0694                 vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
0695                     ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
0696             }
0697             vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
0698                 GEN8_DE_PORT_HOTPLUG(HPD_PORT_A);
0699             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
0700                 ~PORTA_HOTPLUG_STATUS_MASK;
0701             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
0702                 PORTA_HOTPLUG_LONG_DETECT;
0703             intel_vgpu_trigger_virtual_event(vgpu, DP_A_HOTPLUG);
0704         }
0705         if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
0706             if (connected) {
0707                 vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
0708                     GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
0709                 vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
0710                     SFUSE_STRAP_DDIB_DETECTED;
0711             } else {
0712                 vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
0713                     ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
0714                 vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
0715                     ~SFUSE_STRAP_DDIB_DETECTED;
0716             }
0717             vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
0718                 GEN8_DE_PORT_HOTPLUG(HPD_PORT_B);
0719             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
0720                 ~PORTB_HOTPLUG_STATUS_MASK;
0721             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
0722                 PORTB_HOTPLUG_LONG_DETECT;
0723             intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
0724         }
0725         if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
0726             if (connected) {
0727                 vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
0728                     GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
0729                 vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
0730                     SFUSE_STRAP_DDIC_DETECTED;
0731             } else {
0732                 vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
0733                     ~GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
0734                 vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
0735                     ~SFUSE_STRAP_DDIC_DETECTED;
0736             }
0737             vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
0738                 GEN8_DE_PORT_HOTPLUG(HPD_PORT_C);
0739             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
0740                 ~PORTC_HOTPLUG_STATUS_MASK;
0741             vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
0742                 PORTC_HOTPLUG_LONG_DETECT;
0743             intel_vgpu_trigger_virtual_event(vgpu, DP_C_HOTPLUG);
0744         }
0745     }
0746 }
0747 
0748 /**
0749  * intel_vgpu_clean_display - clean vGPU virtual display emulation
0750  * @vgpu: a vGPU
0751  *
0752  * This function is used to clean vGPU virtual display emulation stuffs
0753  *
0754  */
0755 void intel_vgpu_clean_display(struct intel_vgpu *vgpu)
0756 {
0757     struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0758 
0759     if (IS_SKYLAKE(dev_priv) ||
0760         IS_KABYLAKE(dev_priv) ||
0761         IS_COFFEELAKE(dev_priv) ||
0762         IS_COMETLAKE(dev_priv))
0763         clean_virtual_dp_monitor(vgpu, PORT_D);
0764     else
0765         clean_virtual_dp_monitor(vgpu, PORT_B);
0766 
0767     vgpu_update_vblank_emulation(vgpu, false);
0768 }
0769 
0770 /**
0771  * intel_vgpu_init_display- initialize vGPU virtual display emulation
0772  * @vgpu: a vGPU
0773  * @resolution: resolution index for intel_vgpu_edid
0774  *
0775  * This function is used to initialize vGPU virtual display emulation stuffs
0776  *
0777  * Returns:
0778  * Zero on success, negative error code if failed.
0779  *
0780  */
0781 int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 resolution)
0782 {
0783     struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0784 
0785     intel_vgpu_init_i2c_edid(vgpu);
0786 
0787     if (IS_SKYLAKE(dev_priv) ||
0788         IS_KABYLAKE(dev_priv) ||
0789         IS_COFFEELAKE(dev_priv) ||
0790         IS_COMETLAKE(dev_priv))
0791         return setup_virtual_dp_monitor(vgpu, PORT_D, GVT_DP_D,
0792                         resolution);
0793     else
0794         return setup_virtual_dp_monitor(vgpu, PORT_B, GVT_DP_B,
0795                         resolution);
0796 }
0797 
0798 /**
0799  * intel_vgpu_reset_display- reset vGPU virtual display emulation
0800  * @vgpu: a vGPU
0801  *
0802  * This function is used to reset vGPU virtual display emulation stuffs
0803  *
0804  */
0805 void intel_vgpu_reset_display(struct intel_vgpu *vgpu)
0806 {
0807     emulate_monitor_status_change(vgpu);
0808 }