18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the next 128c2ecf20Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 138c2ecf20Sopenharmony_ci * Software. 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 168c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 178c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 188c2ecf20Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 198c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 208c2ecf20Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 218c2ecf20Sopenharmony_ci * SOFTWARE. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Authors: 248c2ecf20Sopenharmony_ci * Ke Yu 258c2ecf20Sopenharmony_ci * Kevin Tian <kevin.tian@intel.com> 268c2ecf20Sopenharmony_ci * Dexuan Cui 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * Contributors: 298c2ecf20Sopenharmony_ci * Tina Zhang <tina.zhang@intel.com> 308c2ecf20Sopenharmony_ci * Min He <min.he@intel.com> 318c2ecf20Sopenharmony_ci * Niu Bing <bing.niu@intel.com> 328c2ecf20Sopenharmony_ci * Zhi Wang <zhi.a.wang@intel.com> 338c2ecf20Sopenharmony_ci * 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#include "i915_drv.h" 378c2ecf20Sopenharmony_ci#include "gvt.h" 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/** 408c2ecf20Sopenharmony_ci * intel_vgpu_gpa_to_mmio_offset - translate a GPA to MMIO offset 418c2ecf20Sopenharmony_ci * @vgpu: a vGPU 428c2ecf20Sopenharmony_ci * @gpa: guest physical address 438c2ecf20Sopenharmony_ci * 448c2ecf20Sopenharmony_ci * Returns: 458c2ecf20Sopenharmony_ci * Zero on success, negative error code if failed 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ciint intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci u64 gttmmio_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_0); 508c2ecf20Sopenharmony_ci return gpa - gttmmio_gpa; 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define reg_is_mmio(gvt, reg) \ 548c2ecf20Sopenharmony_ci (reg >= 0 && reg < gvt->device_info.mmio_size) 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#define reg_is_gtt(gvt, reg) \ 578c2ecf20Sopenharmony_ci (reg >= gvt->device_info.gtt_start_offset \ 588c2ecf20Sopenharmony_ci && reg < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt)) 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, u64 pa, 618c2ecf20Sopenharmony_ci void *p_data, unsigned int bytes, bool read) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci struct intel_gvt *gvt = NULL; 648c2ecf20Sopenharmony_ci void *pt = NULL; 658c2ecf20Sopenharmony_ci unsigned int offset = 0; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci if (!vgpu || !p_data) 688c2ecf20Sopenharmony_ci return; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci gvt = vgpu->gvt; 718c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 728c2ecf20Sopenharmony_ci offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa); 738c2ecf20Sopenharmony_ci if (reg_is_mmio(gvt, offset)) { 748c2ecf20Sopenharmony_ci if (read) 758c2ecf20Sopenharmony_ci intel_vgpu_default_mmio_read(vgpu, offset, p_data, 768c2ecf20Sopenharmony_ci bytes); 778c2ecf20Sopenharmony_ci else 788c2ecf20Sopenharmony_ci intel_vgpu_default_mmio_write(vgpu, offset, p_data, 798c2ecf20Sopenharmony_ci bytes); 808c2ecf20Sopenharmony_ci } else if (reg_is_gtt(gvt, offset)) { 818c2ecf20Sopenharmony_ci offset -= gvt->device_info.gtt_start_offset; 828c2ecf20Sopenharmony_ci pt = vgpu->gtt.ggtt_mm->ggtt_mm.virtual_ggtt + offset; 838c2ecf20Sopenharmony_ci if (read) 848c2ecf20Sopenharmony_ci memcpy(p_data, pt, bytes); 858c2ecf20Sopenharmony_ci else 868c2ecf20Sopenharmony_ci memcpy(pt, p_data, bytes); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci } 898c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 908c2ecf20Sopenharmony_ci} 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci/** 938c2ecf20Sopenharmony_ci * intel_vgpu_emulate_mmio_read - emulate MMIO read 948c2ecf20Sopenharmony_ci * @vgpu: a vGPU 958c2ecf20Sopenharmony_ci * @pa: guest physical address 968c2ecf20Sopenharmony_ci * @p_data: data return buffer 978c2ecf20Sopenharmony_ci * @bytes: access data length 988c2ecf20Sopenharmony_ci * 998c2ecf20Sopenharmony_ci * Returns: 1008c2ecf20Sopenharmony_ci * Zero on success, negative error code if failed 1018c2ecf20Sopenharmony_ci */ 1028c2ecf20Sopenharmony_ciint intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, u64 pa, 1038c2ecf20Sopenharmony_ci void *p_data, unsigned int bytes) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 1068c2ecf20Sopenharmony_ci struct drm_i915_private *i915 = gvt->gt->i915; 1078c2ecf20Sopenharmony_ci unsigned int offset = 0; 1088c2ecf20Sopenharmony_ci int ret = -EINVAL; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci if (vgpu->failsafe) { 1118c2ecf20Sopenharmony_ci failsafe_emulate_mmio_rw(vgpu, pa, p_data, bytes, true); 1128c2ecf20Sopenharmony_ci return 0; 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, bytes > 8)) 1198c2ecf20Sopenharmony_ci goto err; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci if (reg_is_gtt(gvt, offset)) { 1228c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, 4) && 1238c2ecf20Sopenharmony_ci !IS_ALIGNED(offset, 8))) 1248c2ecf20Sopenharmony_ci goto err; 1258c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, bytes != 4 && bytes != 8)) 1268c2ecf20Sopenharmony_ci goto err; 1278c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, 1288c2ecf20Sopenharmony_ci !reg_is_gtt(gvt, offset + bytes - 1))) 1298c2ecf20Sopenharmony_ci goto err; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci ret = intel_vgpu_emulate_ggtt_mmio_read(vgpu, offset, 1328c2ecf20Sopenharmony_ci p_data, bytes); 1338c2ecf20Sopenharmony_ci if (ret) 1348c2ecf20Sopenharmony_ci goto err; 1358c2ecf20Sopenharmony_ci goto out; 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci if (drm_WARN_ON_ONCE(&i915->drm, !reg_is_mmio(gvt, offset))) { 1398c2ecf20Sopenharmony_ci ret = intel_gvt_hypervisor_read_gpa(vgpu, pa, p_data, bytes); 1408c2ecf20Sopenharmony_ci goto out; 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, !reg_is_mmio(gvt, offset + bytes - 1))) 1448c2ecf20Sopenharmony_ci goto err; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci if (!intel_gvt_mmio_is_unalign(gvt, offset)) { 1478c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, bytes))) 1488c2ecf20Sopenharmony_ci goto err; 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci ret = intel_vgpu_mmio_reg_rw(vgpu, offset, p_data, bytes, true); 1528c2ecf20Sopenharmony_ci if (ret < 0) 1538c2ecf20Sopenharmony_ci goto err; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci intel_gvt_mmio_set_accessed(gvt, offset); 1568c2ecf20Sopenharmony_ci ret = 0; 1578c2ecf20Sopenharmony_ci goto out; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cierr: 1608c2ecf20Sopenharmony_ci gvt_vgpu_err("fail to emulate MMIO read %08x len %d\n", 1618c2ecf20Sopenharmony_ci offset, bytes); 1628c2ecf20Sopenharmony_ciout: 1638c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 1648c2ecf20Sopenharmony_ci return ret; 1658c2ecf20Sopenharmony_ci} 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci/** 1688c2ecf20Sopenharmony_ci * intel_vgpu_emulate_mmio_write - emulate MMIO write 1698c2ecf20Sopenharmony_ci * @vgpu: a vGPU 1708c2ecf20Sopenharmony_ci * @pa: guest physical address 1718c2ecf20Sopenharmony_ci * @p_data: write data buffer 1728c2ecf20Sopenharmony_ci * @bytes: access data length 1738c2ecf20Sopenharmony_ci * 1748c2ecf20Sopenharmony_ci * Returns: 1758c2ecf20Sopenharmony_ci * Zero on success, negative error code if failed 1768c2ecf20Sopenharmony_ci */ 1778c2ecf20Sopenharmony_ciint intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, u64 pa, 1788c2ecf20Sopenharmony_ci void *p_data, unsigned int bytes) 1798c2ecf20Sopenharmony_ci{ 1808c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 1818c2ecf20Sopenharmony_ci struct drm_i915_private *i915 = gvt->gt->i915; 1828c2ecf20Sopenharmony_ci unsigned int offset = 0; 1838c2ecf20Sopenharmony_ci int ret = -EINVAL; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci if (vgpu->failsafe) { 1868c2ecf20Sopenharmony_ci failsafe_emulate_mmio_rw(vgpu, pa, p_data, bytes, false); 1878c2ecf20Sopenharmony_ci return 0; 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, bytes > 8)) 1958c2ecf20Sopenharmony_ci goto err; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci if (reg_is_gtt(gvt, offset)) { 1988c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, !IS_ALIGNED(offset, 4) && 1998c2ecf20Sopenharmony_ci !IS_ALIGNED(offset, 8))) 2008c2ecf20Sopenharmony_ci goto err; 2018c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, bytes != 4 && bytes != 8)) 2028c2ecf20Sopenharmony_ci goto err; 2038c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, 2048c2ecf20Sopenharmony_ci !reg_is_gtt(gvt, offset + bytes - 1))) 2058c2ecf20Sopenharmony_ci goto err; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci ret = intel_vgpu_emulate_ggtt_mmio_write(vgpu, offset, 2088c2ecf20Sopenharmony_ci p_data, bytes); 2098c2ecf20Sopenharmony_ci if (ret) 2108c2ecf20Sopenharmony_ci goto err; 2118c2ecf20Sopenharmony_ci goto out; 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci if (drm_WARN_ON_ONCE(&i915->drm, !reg_is_mmio(gvt, offset))) { 2158c2ecf20Sopenharmony_ci ret = intel_gvt_hypervisor_write_gpa(vgpu, pa, p_data, bytes); 2168c2ecf20Sopenharmony_ci goto out; 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci ret = intel_vgpu_mmio_reg_rw(vgpu, offset, p_data, bytes, false); 2208c2ecf20Sopenharmony_ci if (ret < 0) 2218c2ecf20Sopenharmony_ci goto err; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci intel_gvt_mmio_set_accessed(gvt, offset); 2248c2ecf20Sopenharmony_ci ret = 0; 2258c2ecf20Sopenharmony_ci goto out; 2268c2ecf20Sopenharmony_cierr: 2278c2ecf20Sopenharmony_ci gvt_vgpu_err("fail to emulate MMIO write %08x len %d\n", offset, 2288c2ecf20Sopenharmony_ci bytes); 2298c2ecf20Sopenharmony_ciout: 2308c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 2318c2ecf20Sopenharmony_ci return ret; 2328c2ecf20Sopenharmony_ci} 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci/** 2368c2ecf20Sopenharmony_ci * intel_vgpu_reset_mmio - reset virtual MMIO space 2378c2ecf20Sopenharmony_ci * @vgpu: a vGPU 2388c2ecf20Sopenharmony_ci * @dmlr: whether this is device model level reset 2398c2ecf20Sopenharmony_ci */ 2408c2ecf20Sopenharmony_civoid intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 2438c2ecf20Sopenharmony_ci const struct intel_gvt_device_info *info = &gvt->device_info; 2448c2ecf20Sopenharmony_ci void *mmio = gvt->firmware.mmio; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci if (dmlr) { 2478c2ecf20Sopenharmony_ci memcpy(vgpu->mmio.vreg, mmio, info->mmio_size); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, GEN6_GT_THREAD_STATUS_REG) = 0; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci /* set the bit 0:2(Core C-State ) to C0 */ 2528c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, GEN6_GT_CORE_STATUS) = 0; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci /* uc reset hw expect GS_MIA_IN_RESET */ 2558c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, GUC_STATUS) |= GS_MIA_IN_RESET; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci if (IS_BROXTON(vgpu->gvt->gt->i915)) { 2588c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= 2598c2ecf20Sopenharmony_ci ~(BIT(0) | BIT(1)); 2608c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &= 2618c2ecf20Sopenharmony_ci ~PHY_POWER_GOOD; 2628c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) &= 2638c2ecf20Sopenharmony_ci ~PHY_POWER_GOOD; 2648c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) &= 2658c2ecf20Sopenharmony_ci ~BIT(30); 2668c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) &= 2678c2ecf20Sopenharmony_ci ~BIT(30); 2688c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) &= 2698c2ecf20Sopenharmony_ci ~BXT_PHY_LANE_ENABLED; 2708c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) |= 2718c2ecf20Sopenharmony_ci BXT_PHY_CMNLANE_POWERDOWN_ACK | 2728c2ecf20Sopenharmony_ci BXT_PHY_LANE_POWERDOWN_ACK; 2738c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) &= 2748c2ecf20Sopenharmony_ci ~BXT_PHY_LANE_ENABLED; 2758c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) |= 2768c2ecf20Sopenharmony_ci BXT_PHY_CMNLANE_POWERDOWN_ACK | 2778c2ecf20Sopenharmony_ci BXT_PHY_LANE_POWERDOWN_ACK; 2788c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) &= 2798c2ecf20Sopenharmony_ci ~BXT_PHY_LANE_ENABLED; 2808c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |= 2818c2ecf20Sopenharmony_ci BXT_PHY_CMNLANE_POWERDOWN_ACK | 2828c2ecf20Sopenharmony_ci BXT_PHY_LANE_POWERDOWN_ACK; 2838c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, SKL_FUSE_STATUS) |= 2848c2ecf20Sopenharmony_ci SKL_FUSE_DOWNLOAD_STATUS | 2858c2ecf20Sopenharmony_ci SKL_FUSE_PG_DIST_STATUS(SKL_PG0) | 2868c2ecf20Sopenharmony_ci SKL_FUSE_PG_DIST_STATUS(SKL_PG1) | 2878c2ecf20Sopenharmony_ci SKL_FUSE_PG_DIST_STATUS(SKL_PG2); 2888c2ecf20Sopenharmony_ci } 2898c2ecf20Sopenharmony_ci } else { 2908c2ecf20Sopenharmony_ci#define GVT_GEN8_MMIO_RESET_OFFSET (0x44200) 2918c2ecf20Sopenharmony_ci /* only reset the engine related, so starting with 0x44200 2928c2ecf20Sopenharmony_ci * interrupt include DE,display mmio related will not be 2938c2ecf20Sopenharmony_ci * touched 2948c2ecf20Sopenharmony_ci */ 2958c2ecf20Sopenharmony_ci memcpy(vgpu->mmio.vreg, mmio, GVT_GEN8_MMIO_RESET_OFFSET); 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci/** 3018c2ecf20Sopenharmony_ci * intel_vgpu_init_mmio - init MMIO space 3028c2ecf20Sopenharmony_ci * @vgpu: a vGPU 3038c2ecf20Sopenharmony_ci * 3048c2ecf20Sopenharmony_ci * Returns: 3058c2ecf20Sopenharmony_ci * Zero on success, negative error code if failed 3068c2ecf20Sopenharmony_ci */ 3078c2ecf20Sopenharmony_ciint intel_vgpu_init_mmio(struct intel_vgpu *vgpu) 3088c2ecf20Sopenharmony_ci{ 3098c2ecf20Sopenharmony_ci const struct intel_gvt_device_info *info = &vgpu->gvt->device_info; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci vgpu->mmio.vreg = vzalloc(info->mmio_size); 3128c2ecf20Sopenharmony_ci if (!vgpu->mmio.vreg) 3138c2ecf20Sopenharmony_ci return -ENOMEM; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci intel_vgpu_reset_mmio(vgpu, true); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci return 0; 3188c2ecf20Sopenharmony_ci} 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci/** 3218c2ecf20Sopenharmony_ci * intel_vgpu_clean_mmio - clean MMIO space 3228c2ecf20Sopenharmony_ci * @vgpu: a vGPU 3238c2ecf20Sopenharmony_ci * 3248c2ecf20Sopenharmony_ci */ 3258c2ecf20Sopenharmony_civoid intel_vgpu_clean_mmio(struct intel_vgpu *vgpu) 3268c2ecf20Sopenharmony_ci{ 3278c2ecf20Sopenharmony_ci vfree(vgpu->mmio.vreg); 3288c2ecf20Sopenharmony_ci vgpu->mmio.vreg = NULL; 3298c2ecf20Sopenharmony_ci} 330