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 * Kevin Tian <kevin.tian@intel.com> 258c2ecf20Sopenharmony_ci * Dexuan Cui 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * Contributors: 288c2ecf20Sopenharmony_ci * Pei Zhang <pei.zhang@intel.com> 298c2ecf20Sopenharmony_ci * Min He <min.he@intel.com> 308c2ecf20Sopenharmony_ci * Niu Bing <bing.niu@intel.com> 318c2ecf20Sopenharmony_ci * Yulei Zhang <yulei.zhang@intel.com> 328c2ecf20Sopenharmony_ci * Zhenyu Wang <zhenyuw@linux.intel.com> 338c2ecf20Sopenharmony_ci * Zhi Wang <zhi.a.wang@intel.com> 348c2ecf20Sopenharmony_ci * 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include "i915_drv.h" 388c2ecf20Sopenharmony_ci#include "gt/intel_ggtt_fencing.h" 398c2ecf20Sopenharmony_ci#include "gvt.h" 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic int alloc_gm(struct intel_vgpu *vgpu, bool high_gm) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 448c2ecf20Sopenharmony_ci struct intel_gt *gt = gvt->gt; 458c2ecf20Sopenharmony_ci unsigned int flags; 468c2ecf20Sopenharmony_ci u64 start, end, size; 478c2ecf20Sopenharmony_ci struct drm_mm_node *node; 488c2ecf20Sopenharmony_ci int ret; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci if (high_gm) { 518c2ecf20Sopenharmony_ci node = &vgpu->gm.high_gm_node; 528c2ecf20Sopenharmony_ci size = vgpu_hidden_sz(vgpu); 538c2ecf20Sopenharmony_ci start = ALIGN(gvt_hidden_gmadr_base(gvt), I915_GTT_PAGE_SIZE); 548c2ecf20Sopenharmony_ci end = ALIGN(gvt_hidden_gmadr_end(gvt), I915_GTT_PAGE_SIZE); 558c2ecf20Sopenharmony_ci flags = PIN_HIGH; 568c2ecf20Sopenharmony_ci } else { 578c2ecf20Sopenharmony_ci node = &vgpu->gm.low_gm_node; 588c2ecf20Sopenharmony_ci size = vgpu_aperture_sz(vgpu); 598c2ecf20Sopenharmony_ci start = ALIGN(gvt_aperture_gmadr_base(gvt), I915_GTT_PAGE_SIZE); 608c2ecf20Sopenharmony_ci end = ALIGN(gvt_aperture_gmadr_end(gvt), I915_GTT_PAGE_SIZE); 618c2ecf20Sopenharmony_ci flags = PIN_MAPPABLE; 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci mutex_lock(>->ggtt->vm.mutex); 658c2ecf20Sopenharmony_ci mmio_hw_access_pre(gt); 668c2ecf20Sopenharmony_ci ret = i915_gem_gtt_insert(>->ggtt->vm, node, 678c2ecf20Sopenharmony_ci size, I915_GTT_PAGE_SIZE, 688c2ecf20Sopenharmony_ci I915_COLOR_UNEVICTABLE, 698c2ecf20Sopenharmony_ci start, end, flags); 708c2ecf20Sopenharmony_ci mmio_hw_access_post(gt); 718c2ecf20Sopenharmony_ci mutex_unlock(>->ggtt->vm.mutex); 728c2ecf20Sopenharmony_ci if (ret) 738c2ecf20Sopenharmony_ci gvt_err("fail to alloc %s gm space from host\n", 748c2ecf20Sopenharmony_ci high_gm ? "high" : "low"); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci return ret; 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic int alloc_vgpu_gm(struct intel_vgpu *vgpu) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 828c2ecf20Sopenharmony_ci struct intel_gt *gt = gvt->gt; 838c2ecf20Sopenharmony_ci int ret; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci ret = alloc_gm(vgpu, false); 868c2ecf20Sopenharmony_ci if (ret) 878c2ecf20Sopenharmony_ci return ret; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci ret = alloc_gm(vgpu, true); 908c2ecf20Sopenharmony_ci if (ret) 918c2ecf20Sopenharmony_ci goto out_free_aperture; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci gvt_dbg_core("vgpu%d: alloc low GM start %llx size %llx\n", vgpu->id, 948c2ecf20Sopenharmony_ci vgpu_aperture_offset(vgpu), vgpu_aperture_sz(vgpu)); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci gvt_dbg_core("vgpu%d: alloc high GM start %llx size %llx\n", vgpu->id, 978c2ecf20Sopenharmony_ci vgpu_hidden_offset(vgpu), vgpu_hidden_sz(vgpu)); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci return 0; 1008c2ecf20Sopenharmony_ciout_free_aperture: 1018c2ecf20Sopenharmony_ci mutex_lock(>->ggtt->vm.mutex); 1028c2ecf20Sopenharmony_ci drm_mm_remove_node(&vgpu->gm.low_gm_node); 1038c2ecf20Sopenharmony_ci mutex_unlock(>->ggtt->vm.mutex); 1048c2ecf20Sopenharmony_ci return ret; 1058c2ecf20Sopenharmony_ci} 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic void free_vgpu_gm(struct intel_vgpu *vgpu) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 1108c2ecf20Sopenharmony_ci struct intel_gt *gt = gvt->gt; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci mutex_lock(>->ggtt->vm.mutex); 1138c2ecf20Sopenharmony_ci drm_mm_remove_node(&vgpu->gm.low_gm_node); 1148c2ecf20Sopenharmony_ci drm_mm_remove_node(&vgpu->gm.high_gm_node); 1158c2ecf20Sopenharmony_ci mutex_unlock(>->ggtt->vm.mutex); 1168c2ecf20Sopenharmony_ci} 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/** 1198c2ecf20Sopenharmony_ci * intel_vgpu_write_fence - write fence registers owned by a vGPU 1208c2ecf20Sopenharmony_ci * @vgpu: vGPU instance 1218c2ecf20Sopenharmony_ci * @fence: vGPU fence register number 1228c2ecf20Sopenharmony_ci * @value: Fence register value to be written 1238c2ecf20Sopenharmony_ci * 1248c2ecf20Sopenharmony_ci * This function is used to write fence registers owned by a vGPU. The vGPU 1258c2ecf20Sopenharmony_ci * fence register number will be translated into HW fence register number. 1268c2ecf20Sopenharmony_ci * 1278c2ecf20Sopenharmony_ci */ 1288c2ecf20Sopenharmony_civoid intel_vgpu_write_fence(struct intel_vgpu *vgpu, 1298c2ecf20Sopenharmony_ci u32 fence, u64 value) 1308c2ecf20Sopenharmony_ci{ 1318c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 1328c2ecf20Sopenharmony_ci struct drm_i915_private *i915 = gvt->gt->i915; 1338c2ecf20Sopenharmony_ci struct intel_uncore *uncore = gvt->gt->uncore; 1348c2ecf20Sopenharmony_ci struct i915_fence_reg *reg; 1358c2ecf20Sopenharmony_ci i915_reg_t fence_reg_lo, fence_reg_hi; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci assert_rpm_wakelock_held(uncore->rpm); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, fence >= vgpu_fence_sz(vgpu))) 1408c2ecf20Sopenharmony_ci return; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci reg = vgpu->fence.regs[fence]; 1438c2ecf20Sopenharmony_ci if (drm_WARN_ON(&i915->drm, !reg)) 1448c2ecf20Sopenharmony_ci return; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci fence_reg_lo = FENCE_REG_GEN6_LO(reg->id); 1478c2ecf20Sopenharmony_ci fence_reg_hi = FENCE_REG_GEN6_HI(reg->id); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci intel_uncore_write(uncore, fence_reg_lo, 0); 1508c2ecf20Sopenharmony_ci intel_uncore_posting_read(uncore, fence_reg_lo); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci intel_uncore_write(uncore, fence_reg_hi, upper_32_bits(value)); 1538c2ecf20Sopenharmony_ci intel_uncore_write(uncore, fence_reg_lo, lower_32_bits(value)); 1548c2ecf20Sopenharmony_ci intel_uncore_posting_read(uncore, fence_reg_lo); 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic void _clear_vgpu_fence(struct intel_vgpu *vgpu) 1588c2ecf20Sopenharmony_ci{ 1598c2ecf20Sopenharmony_ci int i; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci for (i = 0; i < vgpu_fence_sz(vgpu); i++) 1628c2ecf20Sopenharmony_ci intel_vgpu_write_fence(vgpu, i, 0); 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic void free_vgpu_fence(struct intel_vgpu *vgpu) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 1688c2ecf20Sopenharmony_ci struct intel_uncore *uncore = gvt->gt->uncore; 1698c2ecf20Sopenharmony_ci struct i915_fence_reg *reg; 1708c2ecf20Sopenharmony_ci intel_wakeref_t wakeref; 1718c2ecf20Sopenharmony_ci u32 i; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci if (drm_WARN_ON(&gvt->gt->i915->drm, !vgpu_fence_sz(vgpu))) 1748c2ecf20Sopenharmony_ci return; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci wakeref = intel_runtime_pm_get(uncore->rpm); 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci mutex_lock(&gvt->gt->ggtt->vm.mutex); 1798c2ecf20Sopenharmony_ci _clear_vgpu_fence(vgpu); 1808c2ecf20Sopenharmony_ci for (i = 0; i < vgpu_fence_sz(vgpu); i++) { 1818c2ecf20Sopenharmony_ci reg = vgpu->fence.regs[i]; 1828c2ecf20Sopenharmony_ci i915_unreserve_fence(reg); 1838c2ecf20Sopenharmony_ci vgpu->fence.regs[i] = NULL; 1848c2ecf20Sopenharmony_ci } 1858c2ecf20Sopenharmony_ci mutex_unlock(&gvt->gt->ggtt->vm.mutex); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci intel_runtime_pm_put(uncore->rpm, wakeref); 1888c2ecf20Sopenharmony_ci} 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic int alloc_vgpu_fence(struct intel_vgpu *vgpu) 1918c2ecf20Sopenharmony_ci{ 1928c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 1938c2ecf20Sopenharmony_ci struct intel_uncore *uncore = gvt->gt->uncore; 1948c2ecf20Sopenharmony_ci struct i915_fence_reg *reg; 1958c2ecf20Sopenharmony_ci intel_wakeref_t wakeref; 1968c2ecf20Sopenharmony_ci int i; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci wakeref = intel_runtime_pm_get(uncore->rpm); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* Request fences from host */ 2018c2ecf20Sopenharmony_ci mutex_lock(&gvt->gt->ggtt->vm.mutex); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci for (i = 0; i < vgpu_fence_sz(vgpu); i++) { 2048c2ecf20Sopenharmony_ci reg = i915_reserve_fence(gvt->gt->ggtt); 2058c2ecf20Sopenharmony_ci if (IS_ERR(reg)) 2068c2ecf20Sopenharmony_ci goto out_free_fence; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci vgpu->fence.regs[i] = reg; 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci _clear_vgpu_fence(vgpu); 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci mutex_unlock(&gvt->gt->ggtt->vm.mutex); 2148c2ecf20Sopenharmony_ci intel_runtime_pm_put(uncore->rpm, wakeref); 2158c2ecf20Sopenharmony_ci return 0; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ciout_free_fence: 2188c2ecf20Sopenharmony_ci gvt_vgpu_err("Failed to alloc fences\n"); 2198c2ecf20Sopenharmony_ci /* Return fences to host, if fail */ 2208c2ecf20Sopenharmony_ci for (i = 0; i < vgpu_fence_sz(vgpu); i++) { 2218c2ecf20Sopenharmony_ci reg = vgpu->fence.regs[i]; 2228c2ecf20Sopenharmony_ci if (!reg) 2238c2ecf20Sopenharmony_ci continue; 2248c2ecf20Sopenharmony_ci i915_unreserve_fence(reg); 2258c2ecf20Sopenharmony_ci vgpu->fence.regs[i] = NULL; 2268c2ecf20Sopenharmony_ci } 2278c2ecf20Sopenharmony_ci mutex_unlock(&gvt->gt->ggtt->vm.mutex); 2288c2ecf20Sopenharmony_ci intel_runtime_pm_put_unchecked(uncore->rpm); 2298c2ecf20Sopenharmony_ci return -ENOSPC; 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic void free_resource(struct intel_vgpu *vgpu) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci gvt->gm.vgpu_allocated_low_gm_size -= vgpu_aperture_sz(vgpu); 2378c2ecf20Sopenharmony_ci gvt->gm.vgpu_allocated_high_gm_size -= vgpu_hidden_sz(vgpu); 2388c2ecf20Sopenharmony_ci gvt->fence.vgpu_allocated_fence_num -= vgpu_fence_sz(vgpu); 2398c2ecf20Sopenharmony_ci} 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_cistatic int alloc_resource(struct intel_vgpu *vgpu, 2428c2ecf20Sopenharmony_ci struct intel_vgpu_creation_params *param) 2438c2ecf20Sopenharmony_ci{ 2448c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 2458c2ecf20Sopenharmony_ci unsigned long request, avail, max, taken; 2468c2ecf20Sopenharmony_ci const char *item; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci if (!param->low_gm_sz || !param->high_gm_sz || !param->fence_sz) { 2498c2ecf20Sopenharmony_ci gvt_vgpu_err("Invalid vGPU creation params\n"); 2508c2ecf20Sopenharmony_ci return -EINVAL; 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci item = "low GM space"; 2548c2ecf20Sopenharmony_ci max = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE; 2558c2ecf20Sopenharmony_ci taken = gvt->gm.vgpu_allocated_low_gm_size; 2568c2ecf20Sopenharmony_ci avail = max - taken; 2578c2ecf20Sopenharmony_ci request = MB_TO_BYTES(param->low_gm_sz); 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci if (request > avail) 2608c2ecf20Sopenharmony_ci goto no_enough_resource; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci vgpu_aperture_sz(vgpu) = ALIGN(request, I915_GTT_PAGE_SIZE); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci item = "high GM space"; 2658c2ecf20Sopenharmony_ci max = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE; 2668c2ecf20Sopenharmony_ci taken = gvt->gm.vgpu_allocated_high_gm_size; 2678c2ecf20Sopenharmony_ci avail = max - taken; 2688c2ecf20Sopenharmony_ci request = MB_TO_BYTES(param->high_gm_sz); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci if (request > avail) 2718c2ecf20Sopenharmony_ci goto no_enough_resource; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci vgpu_hidden_sz(vgpu) = ALIGN(request, I915_GTT_PAGE_SIZE); 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci item = "fence"; 2768c2ecf20Sopenharmony_ci max = gvt_fence_sz(gvt) - HOST_FENCE; 2778c2ecf20Sopenharmony_ci taken = gvt->fence.vgpu_allocated_fence_num; 2788c2ecf20Sopenharmony_ci avail = max - taken; 2798c2ecf20Sopenharmony_ci request = param->fence_sz; 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci if (request > avail) 2828c2ecf20Sopenharmony_ci goto no_enough_resource; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci vgpu_fence_sz(vgpu) = request; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci gvt->gm.vgpu_allocated_low_gm_size += MB_TO_BYTES(param->low_gm_sz); 2878c2ecf20Sopenharmony_ci gvt->gm.vgpu_allocated_high_gm_size += MB_TO_BYTES(param->high_gm_sz); 2888c2ecf20Sopenharmony_ci gvt->fence.vgpu_allocated_fence_num += param->fence_sz; 2898c2ecf20Sopenharmony_ci return 0; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_cino_enough_resource: 2928c2ecf20Sopenharmony_ci gvt_err("fail to allocate resource %s\n", item); 2938c2ecf20Sopenharmony_ci gvt_err("request %luMB avail %luMB max %luMB taken %luMB\n", 2948c2ecf20Sopenharmony_ci BYTES_TO_MB(request), BYTES_TO_MB(avail), 2958c2ecf20Sopenharmony_ci BYTES_TO_MB(max), BYTES_TO_MB(taken)); 2968c2ecf20Sopenharmony_ci return -ENOSPC; 2978c2ecf20Sopenharmony_ci} 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci/** 3008c2ecf20Sopenharmony_ci * inte_gvt_free_vgpu_resource - free HW resource owned by a vGPU 3018c2ecf20Sopenharmony_ci * @vgpu: a vGPU 3028c2ecf20Sopenharmony_ci * 3038c2ecf20Sopenharmony_ci * This function is used to free the HW resource owned by a vGPU. 3048c2ecf20Sopenharmony_ci * 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_civoid intel_vgpu_free_resource(struct intel_vgpu *vgpu) 3078c2ecf20Sopenharmony_ci{ 3088c2ecf20Sopenharmony_ci free_vgpu_gm(vgpu); 3098c2ecf20Sopenharmony_ci free_vgpu_fence(vgpu); 3108c2ecf20Sopenharmony_ci free_resource(vgpu); 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci/** 3148c2ecf20Sopenharmony_ci * intel_vgpu_reset_resource - reset resource state owned by a vGPU 3158c2ecf20Sopenharmony_ci * @vgpu: a vGPU 3168c2ecf20Sopenharmony_ci * 3178c2ecf20Sopenharmony_ci * This function is used to reset resource state owned by a vGPU. 3188c2ecf20Sopenharmony_ci * 3198c2ecf20Sopenharmony_ci */ 3208c2ecf20Sopenharmony_civoid intel_vgpu_reset_resource(struct intel_vgpu *vgpu) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 3238c2ecf20Sopenharmony_ci intel_wakeref_t wakeref; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci with_intel_runtime_pm(gvt->gt->uncore->rpm, wakeref) 3268c2ecf20Sopenharmony_ci _clear_vgpu_fence(vgpu); 3278c2ecf20Sopenharmony_ci} 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci/** 3308c2ecf20Sopenharmony_ci * intel_alloc_vgpu_resource - allocate HW resource for a vGPU 3318c2ecf20Sopenharmony_ci * @vgpu: vGPU 3328c2ecf20Sopenharmony_ci * @param: vGPU creation params 3338c2ecf20Sopenharmony_ci * 3348c2ecf20Sopenharmony_ci * This function is used to allocate HW resource for a vGPU. User specifies 3358c2ecf20Sopenharmony_ci * the resource configuration through the creation params. 3368c2ecf20Sopenharmony_ci * 3378c2ecf20Sopenharmony_ci * Returns: 3388c2ecf20Sopenharmony_ci * zero on success, negative error code if failed. 3398c2ecf20Sopenharmony_ci * 3408c2ecf20Sopenharmony_ci */ 3418c2ecf20Sopenharmony_ciint intel_vgpu_alloc_resource(struct intel_vgpu *vgpu, 3428c2ecf20Sopenharmony_ci struct intel_vgpu_creation_params *param) 3438c2ecf20Sopenharmony_ci{ 3448c2ecf20Sopenharmony_ci int ret; 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci ret = alloc_resource(vgpu, param); 3478c2ecf20Sopenharmony_ci if (ret) 3488c2ecf20Sopenharmony_ci return ret; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci ret = alloc_vgpu_gm(vgpu); 3518c2ecf20Sopenharmony_ci if (ret) 3528c2ecf20Sopenharmony_ci goto out_free_resource; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci ret = alloc_vgpu_fence(vgpu); 3558c2ecf20Sopenharmony_ci if (ret) 3568c2ecf20Sopenharmony_ci goto out_free_vgpu_gm; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci return 0; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ciout_free_vgpu_gm: 3618c2ecf20Sopenharmony_ci free_vgpu_gm(vgpu); 3628c2ecf20Sopenharmony_ciout_free_resource: 3638c2ecf20Sopenharmony_ci free_resource(vgpu); 3648c2ecf20Sopenharmony_ci return ret; 3658c2ecf20Sopenharmony_ci} 366