1 1.1 riastrad /* $NetBSD: display.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice (including the next 14 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the 15 1.1 riastrad * Software. 16 1.1 riastrad * 17 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 1.1 riastrad * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 1.1 riastrad * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 1.1 riastrad * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 1.1 riastrad * SOFTWARE. 24 1.1 riastrad * 25 1.1 riastrad * Authors: 26 1.1 riastrad * Ke Yu 27 1.1 riastrad * Zhiyuan Lv <zhiyuan.lv (at) intel.com> 28 1.1 riastrad * 29 1.1 riastrad * Contributors: 30 1.1 riastrad * Terrence Xu <terrence.xu (at) intel.com> 31 1.1 riastrad * Changbin Du <changbin.du (at) intel.com> 32 1.1 riastrad * Bing Niu <bing.niu (at) intel.com> 33 1.1 riastrad * Zhi Wang <zhi.a.wang (at) intel.com> 34 1.1 riastrad * 35 1.1 riastrad */ 36 1.1 riastrad 37 1.1 riastrad #include <sys/cdefs.h> 38 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: display.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $"); 39 1.1 riastrad 40 1.1 riastrad #include "i915_drv.h" 41 1.1 riastrad #include "gvt.h" 42 1.1 riastrad 43 1.1 riastrad static int get_edp_pipe(struct intel_vgpu *vgpu) 44 1.1 riastrad { 45 1.1 riastrad u32 data = vgpu_vreg(vgpu, _TRANS_DDI_FUNC_CTL_EDP); 46 1.1 riastrad int pipe = -1; 47 1.1 riastrad 48 1.1 riastrad switch (data & TRANS_DDI_EDP_INPUT_MASK) { 49 1.1 riastrad case TRANS_DDI_EDP_INPUT_A_ON: 50 1.1 riastrad case TRANS_DDI_EDP_INPUT_A_ONOFF: 51 1.1 riastrad pipe = PIPE_A; 52 1.1 riastrad break; 53 1.1 riastrad case TRANS_DDI_EDP_INPUT_B_ONOFF: 54 1.1 riastrad pipe = PIPE_B; 55 1.1 riastrad break; 56 1.1 riastrad case TRANS_DDI_EDP_INPUT_C_ONOFF: 57 1.1 riastrad pipe = PIPE_C; 58 1.1 riastrad break; 59 1.1 riastrad } 60 1.1 riastrad return pipe; 61 1.1 riastrad } 62 1.1 riastrad 63 1.1 riastrad static int edp_pipe_is_enabled(struct intel_vgpu *vgpu) 64 1.1 riastrad { 65 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 66 1.1 riastrad 67 1.1 riastrad if (!(vgpu_vreg_t(vgpu, PIPECONF(_PIPE_EDP)) & PIPECONF_ENABLE)) 68 1.1 riastrad return 0; 69 1.1 riastrad 70 1.1 riastrad if (!(vgpu_vreg(vgpu, _TRANS_DDI_FUNC_CTL_EDP) & TRANS_DDI_FUNC_ENABLE)) 71 1.1 riastrad return 0; 72 1.1 riastrad return 1; 73 1.1 riastrad } 74 1.1 riastrad 75 1.1 riastrad int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe) 76 1.1 riastrad { 77 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 78 1.1 riastrad 79 1.1 riastrad if (WARN_ON(pipe < PIPE_A || pipe >= I915_MAX_PIPES)) 80 1.1 riastrad return -EINVAL; 81 1.1 riastrad 82 1.1 riastrad if (vgpu_vreg_t(vgpu, PIPECONF(pipe)) & PIPECONF_ENABLE) 83 1.1 riastrad return 1; 84 1.1 riastrad 85 1.1 riastrad if (edp_pipe_is_enabled(vgpu) && 86 1.1 riastrad get_edp_pipe(vgpu) == pipe) 87 1.1 riastrad return 1; 88 1.1 riastrad return 0; 89 1.1 riastrad } 90 1.1 riastrad 91 1.1 riastrad static unsigned char virtual_dp_monitor_edid[GVT_EDID_NUM][EDID_SIZE] = { 92 1.1 riastrad { 93 1.1 riastrad /* EDID with 1024x768 as its resolution */ 94 1.1 riastrad /*Header*/ 95 1.1 riastrad 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 96 1.1 riastrad /* Vendor & Product Identification */ 97 1.1 riastrad 0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17, 98 1.1 riastrad /* Version & Revision */ 99 1.1 riastrad 0x01, 0x04, 100 1.1 riastrad /* Basic Display Parameters & Features */ 101 1.1 riastrad 0xa5, 0x34, 0x20, 0x78, 0x23, 102 1.1 riastrad /* Color Characteristics */ 103 1.1 riastrad 0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54, 104 1.1 riastrad /* Established Timings: maximum resolution is 1024x768 */ 105 1.1 riastrad 0x21, 0x08, 0x00, 106 1.1 riastrad /* Standard Timings. All invalid */ 107 1.1 riastrad 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00, 108 1.1 riastrad 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 109 1.1 riastrad /* 18 Byte Data Blocks 1: invalid */ 110 1.1 riastrad 0x00, 0x00, 0x80, 0xa0, 0x70, 0xb0, 111 1.1 riastrad 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a, 112 1.1 riastrad /* 18 Byte Data Blocks 2: invalid */ 113 1.1 riastrad 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a, 114 1.1 riastrad 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 115 1.1 riastrad /* 18 Byte Data Blocks 3: invalid */ 116 1.1 riastrad 0x00, 0x00, 0x00, 0xfc, 0x00, 0x48, 117 1.1 riastrad 0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20, 118 1.1 riastrad /* 18 Byte Data Blocks 4: invalid */ 119 1.1 riastrad 0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30, 120 1.1 riastrad 0x44, 0x58, 0x51, 0x0a, 0x20, 0x20, 121 1.1 riastrad /* Extension Block Count */ 122 1.1 riastrad 0x00, 123 1.1 riastrad /* Checksum */ 124 1.1 riastrad 0xef, 125 1.1 riastrad }, 126 1.1 riastrad { 127 1.1 riastrad /* EDID with 1920x1200 as its resolution */ 128 1.1 riastrad /*Header*/ 129 1.1 riastrad 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 130 1.1 riastrad /* Vendor & Product Identification */ 131 1.1 riastrad 0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17, 132 1.1 riastrad /* Version & Revision */ 133 1.1 riastrad 0x01, 0x04, 134 1.1 riastrad /* Basic Display Parameters & Features */ 135 1.1 riastrad 0xa5, 0x34, 0x20, 0x78, 0x23, 136 1.1 riastrad /* Color Characteristics */ 137 1.1 riastrad 0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54, 138 1.1 riastrad /* Established Timings: maximum resolution is 1024x768 */ 139 1.1 riastrad 0x21, 0x08, 0x00, 140 1.1 riastrad /* 141 1.1 riastrad * Standard Timings. 142 1.1 riastrad * below new resolutions can be supported: 143 1.1 riastrad * 1920x1080, 1280x720, 1280x960, 1280x1024, 144 1.1 riastrad * 1440x900, 1600x1200, 1680x1050 145 1.1 riastrad */ 146 1.1 riastrad 0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x40, 0x81, 0x80, 0x95, 0x00, 147 1.1 riastrad 0xa9, 0x40, 0xb3, 0x00, 0x01, 0x01, 148 1.1 riastrad /* 18 Byte Data Blocks 1: max resolution is 1920x1200 */ 149 1.1 riastrad 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0, 150 1.1 riastrad 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a, 151 1.1 riastrad /* 18 Byte Data Blocks 2: invalid */ 152 1.1 riastrad 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a, 153 1.1 riastrad 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 154 1.1 riastrad /* 18 Byte Data Blocks 3: invalid */ 155 1.1 riastrad 0x00, 0x00, 0x00, 0xfc, 0x00, 0x48, 156 1.1 riastrad 0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20, 157 1.1 riastrad /* 18 Byte Data Blocks 4: invalid */ 158 1.1 riastrad 0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30, 159 1.1 riastrad 0x44, 0x58, 0x51, 0x0a, 0x20, 0x20, 160 1.1 riastrad /* Extension Block Count */ 161 1.1 riastrad 0x00, 162 1.1 riastrad /* Checksum */ 163 1.1 riastrad 0x45, 164 1.1 riastrad }, 165 1.1 riastrad }; 166 1.1 riastrad 167 1.1 riastrad #define DPCD_HEADER_SIZE 0xb 168 1.1 riastrad 169 1.1 riastrad /* let the virtual display supports DP1.2 */ 170 1.1 riastrad static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = { 171 1.1 riastrad 0x12, 0x014, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 172 1.1 riastrad }; 173 1.1 riastrad 174 1.1 riastrad static void emulate_monitor_status_change(struct intel_vgpu *vgpu) 175 1.1 riastrad { 176 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 177 1.1 riastrad int pipe; 178 1.1 riastrad 179 1.1 riastrad if (IS_BROXTON(dev_priv)) { 180 1.1 riastrad vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~(BXT_DE_PORT_HP_DDIA | 181 1.1 riastrad BXT_DE_PORT_HP_DDIB | 182 1.1 riastrad BXT_DE_PORT_HP_DDIC); 183 1.1 riastrad 184 1.1 riastrad if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { 185 1.1 riastrad vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= 186 1.1 riastrad BXT_DE_PORT_HP_DDIA; 187 1.1 riastrad } 188 1.1 riastrad 189 1.1 riastrad if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { 190 1.1 riastrad vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= 191 1.1 riastrad BXT_DE_PORT_HP_DDIB; 192 1.1 riastrad } 193 1.1 riastrad 194 1.1 riastrad if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { 195 1.1 riastrad vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= 196 1.1 riastrad BXT_DE_PORT_HP_DDIC; 197 1.1 riastrad } 198 1.1 riastrad 199 1.1 riastrad return; 200 1.1 riastrad } 201 1.1 riastrad 202 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT | 203 1.1 riastrad SDE_PORTC_HOTPLUG_CPT | 204 1.1 riastrad SDE_PORTD_HOTPLUG_CPT); 205 1.1 riastrad 206 1.1 riastrad if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) || 207 1.1 riastrad IS_COFFEELAKE(dev_priv)) { 208 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTA_HOTPLUG_SPT | 209 1.1 riastrad SDE_PORTE_HOTPLUG_SPT); 210 1.1 riastrad vgpu_vreg_t(vgpu, SKL_FUSE_STATUS) |= 211 1.1 riastrad SKL_FUSE_DOWNLOAD_STATUS | 212 1.1 riastrad SKL_FUSE_PG_DIST_STATUS(SKL_PG0) | 213 1.1 riastrad SKL_FUSE_PG_DIST_STATUS(SKL_PG1) | 214 1.1 riastrad SKL_FUSE_PG_DIST_STATUS(SKL_PG2); 215 1.1 riastrad vgpu_vreg_t(vgpu, LCPLL1_CTL) |= 216 1.1 riastrad LCPLL_PLL_ENABLE | 217 1.1 riastrad LCPLL_PLL_LOCK; 218 1.1 riastrad vgpu_vreg_t(vgpu, LCPLL2_CTL) |= LCPLL_PLL_ENABLE; 219 1.1 riastrad 220 1.1 riastrad } 221 1.1 riastrad 222 1.1 riastrad if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { 223 1.1 riastrad vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED; 224 1.1 riastrad vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= 225 1.1 riastrad ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | 226 1.1 riastrad TRANS_DDI_PORT_MASK); 227 1.1 riastrad vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |= 228 1.1 riastrad (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DVI | 229 1.1 riastrad (PORT_B << TRANS_DDI_PORT_SHIFT) | 230 1.1 riastrad TRANS_DDI_FUNC_ENABLE); 231 1.1 riastrad if (IS_BROADWELL(dev_priv)) { 232 1.1 riastrad vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_B)) &= 233 1.1 riastrad ~PORT_CLK_SEL_MASK; 234 1.1 riastrad vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_B)) |= 235 1.1 riastrad PORT_CLK_SEL_LCPLL_810; 236 1.1 riastrad } 237 1.1 riastrad vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |= DDI_BUF_CTL_ENABLE; 238 1.1 riastrad vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &= ~DDI_BUF_IS_IDLE; 239 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTB_HOTPLUG_CPT; 240 1.1 riastrad } 241 1.1 riastrad 242 1.1 riastrad if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { 243 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT; 244 1.1 riastrad vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= 245 1.1 riastrad ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | 246 1.1 riastrad TRANS_DDI_PORT_MASK); 247 1.1 riastrad vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |= 248 1.1 riastrad (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DVI | 249 1.1 riastrad (PORT_C << TRANS_DDI_PORT_SHIFT) | 250 1.1 riastrad TRANS_DDI_FUNC_ENABLE); 251 1.1 riastrad if (IS_BROADWELL(dev_priv)) { 252 1.1 riastrad vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_C)) &= 253 1.1 riastrad ~PORT_CLK_SEL_MASK; 254 1.1 riastrad vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_C)) |= 255 1.1 riastrad PORT_CLK_SEL_LCPLL_810; 256 1.1 riastrad } 257 1.1 riastrad vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |= DDI_BUF_CTL_ENABLE; 258 1.1 riastrad vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &= ~DDI_BUF_IS_IDLE; 259 1.1 riastrad vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED; 260 1.1 riastrad } 261 1.1 riastrad 262 1.1 riastrad if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D)) { 263 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT; 264 1.1 riastrad vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= 265 1.1 riastrad ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | 266 1.1 riastrad TRANS_DDI_PORT_MASK); 267 1.1 riastrad vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |= 268 1.1 riastrad (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DVI | 269 1.1 riastrad (PORT_D << TRANS_DDI_PORT_SHIFT) | 270 1.1 riastrad TRANS_DDI_FUNC_ENABLE); 271 1.1 riastrad if (IS_BROADWELL(dev_priv)) { 272 1.1 riastrad vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_D)) &= 273 1.1 riastrad ~PORT_CLK_SEL_MASK; 274 1.1 riastrad vgpu_vreg_t(vgpu, PORT_CLK_SEL(PORT_D)) |= 275 1.1 riastrad PORT_CLK_SEL_LCPLL_810; 276 1.1 riastrad } 277 1.1 riastrad vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_D)) |= DDI_BUF_CTL_ENABLE; 278 1.1 riastrad vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_D)) &= ~DDI_BUF_IS_IDLE; 279 1.1 riastrad vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDID_DETECTED; 280 1.1 riastrad } 281 1.1 riastrad 282 1.1 riastrad if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) || 283 1.1 riastrad IS_COFFEELAKE(dev_priv)) && 284 1.1 riastrad intel_vgpu_has_monitor_on_port(vgpu, PORT_E)) { 285 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTE_HOTPLUG_SPT; 286 1.1 riastrad } 287 1.1 riastrad 288 1.1 riastrad if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { 289 1.1 riastrad if (IS_BROADWELL(dev_priv)) 290 1.1 riastrad vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= 291 1.1 riastrad GEN8_PORT_DP_A_HOTPLUG; 292 1.1 riastrad else 293 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTA_HOTPLUG_SPT; 294 1.1 riastrad 295 1.1 riastrad vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |= DDI_INIT_DISPLAY_DETECTED; 296 1.1 riastrad } 297 1.1 riastrad 298 1.1 riastrad /* Clear host CRT status, so guest couldn't detect this host CRT. */ 299 1.1 riastrad if (IS_BROADWELL(dev_priv)) 300 1.1 riastrad vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; 301 1.1 riastrad 302 1.1 riastrad /* Disable Primary/Sprite/Cursor plane */ 303 1.1 riastrad for_each_pipe(dev_priv, pipe) { 304 1.1 riastrad vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE; 305 1.1 riastrad vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE; 306 1.1 riastrad vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE; 307 1.1 riastrad vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE; 308 1.1 riastrad } 309 1.1 riastrad 310 1.1 riastrad vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; 311 1.1 riastrad } 312 1.1 riastrad 313 1.1 riastrad static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num) 314 1.1 riastrad { 315 1.1 riastrad struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num); 316 1.1 riastrad 317 1.1 riastrad kfree(port->edid); 318 1.1 riastrad port->edid = NULL; 319 1.1 riastrad 320 1.1 riastrad kfree(port->dpcd); 321 1.1 riastrad port->dpcd = NULL; 322 1.1 riastrad } 323 1.1 riastrad 324 1.1 riastrad static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, 325 1.1 riastrad int type, unsigned int resolution) 326 1.1 riastrad { 327 1.1 riastrad struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num); 328 1.1 riastrad 329 1.1 riastrad if (WARN_ON(resolution >= GVT_EDID_NUM)) 330 1.1 riastrad return -EINVAL; 331 1.1 riastrad 332 1.1 riastrad port->edid = kzalloc(sizeof(*(port->edid)), GFP_KERNEL); 333 1.1 riastrad if (!port->edid) 334 1.1 riastrad return -ENOMEM; 335 1.1 riastrad 336 1.1 riastrad port->dpcd = kzalloc(sizeof(*(port->dpcd)), GFP_KERNEL); 337 1.1 riastrad if (!port->dpcd) { 338 1.1 riastrad kfree(port->edid); 339 1.1 riastrad return -ENOMEM; 340 1.1 riastrad } 341 1.1 riastrad 342 1.1 riastrad memcpy(port->edid->edid_block, virtual_dp_monitor_edid[resolution], 343 1.1 riastrad EDID_SIZE); 344 1.1 riastrad port->edid->data_valid = true; 345 1.1 riastrad 346 1.1 riastrad memcpy(port->dpcd->data, dpcd_fix_data, DPCD_HEADER_SIZE); 347 1.1 riastrad port->dpcd->data_valid = true; 348 1.1 riastrad port->dpcd->data[DPCD_SINK_COUNT] = 0x1; 349 1.1 riastrad port->type = type; 350 1.1 riastrad port->id = resolution; 351 1.1 riastrad 352 1.1 riastrad emulate_monitor_status_change(vgpu); 353 1.1 riastrad 354 1.1 riastrad return 0; 355 1.1 riastrad } 356 1.1 riastrad 357 1.1 riastrad /** 358 1.1 riastrad * intel_gvt_check_vblank_emulation - check if vblank emulation timer should 359 1.1 riastrad * be turned on/off when a virtual pipe is enabled/disabled. 360 1.1 riastrad * @gvt: a GVT device 361 1.1 riastrad * 362 1.1 riastrad * This function is used to turn on/off vblank timer according to currently 363 1.1 riastrad * enabled/disabled virtual pipes. 364 1.1 riastrad * 365 1.1 riastrad */ 366 1.1 riastrad void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt) 367 1.1 riastrad { 368 1.1 riastrad struct intel_gvt_irq *irq = &gvt->irq; 369 1.1 riastrad struct intel_vgpu *vgpu; 370 1.1 riastrad int pipe, id; 371 1.1 riastrad int found = false; 372 1.1 riastrad 373 1.1 riastrad mutex_lock(&gvt->lock); 374 1.1 riastrad for_each_active_vgpu(gvt, vgpu, id) { 375 1.1 riastrad for (pipe = 0; pipe < I915_MAX_PIPES; pipe++) { 376 1.1 riastrad if (pipe_is_enabled(vgpu, pipe)) { 377 1.1 riastrad found = true; 378 1.1 riastrad break; 379 1.1 riastrad } 380 1.1 riastrad } 381 1.1 riastrad if (found) 382 1.1 riastrad break; 383 1.1 riastrad } 384 1.1 riastrad 385 1.1 riastrad /* all the pipes are disabled */ 386 1.1 riastrad if (!found) 387 1.1 riastrad hrtimer_cancel(&irq->vblank_timer.timer); 388 1.1 riastrad else 389 1.1 riastrad hrtimer_start(&irq->vblank_timer.timer, 390 1.1 riastrad ktime_add_ns(ktime_get(), irq->vblank_timer.period), 391 1.1 riastrad HRTIMER_MODE_ABS); 392 1.1 riastrad mutex_unlock(&gvt->lock); 393 1.1 riastrad } 394 1.1 riastrad 395 1.1 riastrad static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe) 396 1.1 riastrad { 397 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 398 1.1 riastrad struct intel_vgpu_irq *irq = &vgpu->irq; 399 1.1 riastrad int vblank_event[] = { 400 1.1 riastrad [PIPE_A] = PIPE_A_VBLANK, 401 1.1 riastrad [PIPE_B] = PIPE_B_VBLANK, 402 1.1 riastrad [PIPE_C] = PIPE_C_VBLANK, 403 1.1 riastrad }; 404 1.1 riastrad int event; 405 1.1 riastrad 406 1.1 riastrad if (pipe < PIPE_A || pipe > PIPE_C) 407 1.1 riastrad return; 408 1.1 riastrad 409 1.1 riastrad for_each_set_bit(event, irq->flip_done_event[pipe], 410 1.1 riastrad INTEL_GVT_EVENT_MAX) { 411 1.1 riastrad clear_bit(event, irq->flip_done_event[pipe]); 412 1.1 riastrad if (!pipe_is_enabled(vgpu, pipe)) 413 1.1 riastrad continue; 414 1.1 riastrad 415 1.1 riastrad intel_vgpu_trigger_virtual_event(vgpu, event); 416 1.1 riastrad } 417 1.1 riastrad 418 1.1 riastrad if (pipe_is_enabled(vgpu, pipe)) { 419 1.1 riastrad vgpu_vreg_t(vgpu, PIPE_FRMCOUNT_G4X(pipe))++; 420 1.1 riastrad intel_vgpu_trigger_virtual_event(vgpu, vblank_event[pipe]); 421 1.1 riastrad } 422 1.1 riastrad } 423 1.1 riastrad 424 1.1 riastrad static void emulate_vblank(struct intel_vgpu *vgpu) 425 1.1 riastrad { 426 1.1 riastrad int pipe; 427 1.1 riastrad 428 1.1 riastrad mutex_lock(&vgpu->vgpu_lock); 429 1.1 riastrad for_each_pipe(vgpu->gvt->dev_priv, pipe) 430 1.1 riastrad emulate_vblank_on_pipe(vgpu, pipe); 431 1.1 riastrad mutex_unlock(&vgpu->vgpu_lock); 432 1.1 riastrad } 433 1.1 riastrad 434 1.1 riastrad /** 435 1.1 riastrad * intel_gvt_emulate_vblank - trigger vblank events for vGPUs on GVT device 436 1.1 riastrad * @gvt: a GVT device 437 1.1 riastrad * 438 1.1 riastrad * This function is used to trigger vblank interrupts for vGPUs on GVT device 439 1.1 riastrad * 440 1.1 riastrad */ 441 1.1 riastrad void intel_gvt_emulate_vblank(struct intel_gvt *gvt) 442 1.1 riastrad { 443 1.1 riastrad struct intel_vgpu *vgpu; 444 1.1 riastrad int id; 445 1.1 riastrad 446 1.1 riastrad mutex_lock(&gvt->lock); 447 1.1 riastrad for_each_active_vgpu(gvt, vgpu, id) 448 1.1 riastrad emulate_vblank(vgpu); 449 1.1 riastrad mutex_unlock(&gvt->lock); 450 1.1 riastrad } 451 1.1 riastrad 452 1.1 riastrad /** 453 1.1 riastrad * intel_vgpu_emulate_hotplug - trigger hotplug event for vGPU 454 1.1 riastrad * @vgpu: a vGPU 455 1.1 riastrad * @connected: link state 456 1.1 riastrad * 457 1.1 riastrad * This function is used to trigger hotplug interrupt for vGPU 458 1.1 riastrad * 459 1.1 riastrad */ 460 1.1 riastrad void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected) 461 1.1 riastrad { 462 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 463 1.1 riastrad 464 1.1 riastrad /* TODO: add more platforms support */ 465 1.1 riastrad if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { 466 1.1 riastrad if (connected) { 467 1.1 riastrad vgpu_vreg_t(vgpu, SFUSE_STRAP) |= 468 1.1 riastrad SFUSE_STRAP_DDID_DETECTED; 469 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT; 470 1.1 riastrad } else { 471 1.1 riastrad vgpu_vreg_t(vgpu, SFUSE_STRAP) &= 472 1.1 riastrad ~SFUSE_STRAP_DDID_DETECTED; 473 1.1 riastrad vgpu_vreg_t(vgpu, SDEISR) &= ~SDE_PORTD_HOTPLUG_CPT; 474 1.1 riastrad } 475 1.1 riastrad vgpu_vreg_t(vgpu, SDEIIR) |= SDE_PORTD_HOTPLUG_CPT; 476 1.1 riastrad vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= 477 1.1 riastrad PORTD_HOTPLUG_STATUS_MASK; 478 1.1 riastrad intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG); 479 1.1 riastrad } 480 1.1 riastrad } 481 1.1 riastrad 482 1.1 riastrad /** 483 1.1 riastrad * intel_vgpu_clean_display - clean vGPU virtual display emulation 484 1.1 riastrad * @vgpu: a vGPU 485 1.1 riastrad * 486 1.1 riastrad * This function is used to clean vGPU virtual display emulation stuffs 487 1.1 riastrad * 488 1.1 riastrad */ 489 1.1 riastrad void intel_vgpu_clean_display(struct intel_vgpu *vgpu) 490 1.1 riastrad { 491 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 492 1.1 riastrad 493 1.1 riastrad if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) || 494 1.1 riastrad IS_COFFEELAKE(dev_priv)) 495 1.1 riastrad clean_virtual_dp_monitor(vgpu, PORT_D); 496 1.1 riastrad else 497 1.1 riastrad clean_virtual_dp_monitor(vgpu, PORT_B); 498 1.1 riastrad } 499 1.1 riastrad 500 1.1 riastrad /** 501 1.1 riastrad * intel_vgpu_init_display- initialize vGPU virtual display emulation 502 1.1 riastrad * @vgpu: a vGPU 503 1.1 riastrad * @resolution: resolution index for intel_vgpu_edid 504 1.1 riastrad * 505 1.1 riastrad * This function is used to initialize vGPU virtual display emulation stuffs 506 1.1 riastrad * 507 1.1 riastrad * Returns: 508 1.1 riastrad * Zero on success, negative error code if failed. 509 1.1 riastrad * 510 1.1 riastrad */ 511 1.1 riastrad int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 resolution) 512 1.1 riastrad { 513 1.1 riastrad struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 514 1.1 riastrad 515 1.1 riastrad intel_vgpu_init_i2c_edid(vgpu); 516 1.1 riastrad 517 1.1 riastrad if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) || 518 1.1 riastrad IS_COFFEELAKE(dev_priv)) 519 1.1 riastrad return setup_virtual_dp_monitor(vgpu, PORT_D, GVT_DP_D, 520 1.1 riastrad resolution); 521 1.1 riastrad else 522 1.1 riastrad return setup_virtual_dp_monitor(vgpu, PORT_B, GVT_DP_B, 523 1.1 riastrad resolution); 524 1.1 riastrad } 525 1.1 riastrad 526 1.1 riastrad /** 527 1.1 riastrad * intel_vgpu_reset_display- reset vGPU virtual display emulation 528 1.1 riastrad * @vgpu: a vGPU 529 1.1 riastrad * 530 1.1 riastrad * This function is used to reset vGPU virtual display emulation stuffs 531 1.1 riastrad * 532 1.1 riastrad */ 533 1.1 riastrad void intel_vgpu_reset_display(struct intel_vgpu *vgpu) 534 1.1 riastrad { 535 1.1 riastrad emulate_monitor_status_change(vgpu); 536 1.1 riastrad } 537