133c8d948SJani Nikula // SPDX-License-Identifier: MIT 233c8d948SJani Nikula /* Copyright © 2025 Intel Corporation */ 333c8d948SJani Nikula 433c8d948SJani Nikula #include "gem/i915_gem_stolen.h" 533c8d948SJani Nikula #include "xe_res_cursor.h" 633c8d948SJani Nikula #include "xe_ttm_stolen_mgr.h" 733c8d948SJani Nikula #include "xe_validation.h" 833c8d948SJani Nikula 9f74bab2dSJani Nikula struct intel_stolen_node { 10e8848d3dSJani Nikula struct xe_device *xe; 11f74bab2dSJani Nikula struct xe_bo *bo; 12f74bab2dSJani Nikula }; 13f74bab2dSJani Nikula 14*d630a1bdSJani Nikula int i915_gem_stolen_insert_node_in_range(struct intel_stolen_node *node, u64 size, 15*d630a1bdSJani Nikula unsigned int align, u64 start, u64 end) 1633c8d948SJani Nikula { 17994c74eaSJani Nikula struct xe_device *xe = node->xe; 18994c74eaSJani Nikula 1933c8d948SJani Nikula struct xe_bo *bo; 2033c8d948SJani Nikula int err = 0; 2133c8d948SJani Nikula u32 flags = XE_BO_FLAG_PINNED | XE_BO_FLAG_STOLEN; 2233c8d948SJani Nikula 2333c8d948SJani Nikula if (start < SZ_4K) 2433c8d948SJani Nikula start = SZ_4K; 2533c8d948SJani Nikula 2633c8d948SJani Nikula if (align) { 2733c8d948SJani Nikula size = ALIGN(size, align); 2833c8d948SJani Nikula start = ALIGN(start, align); 2933c8d948SJani Nikula } 3033c8d948SJani Nikula 3133c8d948SJani Nikula bo = xe_bo_create_pin_range_novm(xe, xe_device_get_root_tile(xe), 3233c8d948SJani Nikula size, start, end, ttm_bo_type_kernel, flags); 3333c8d948SJani Nikula if (IS_ERR(bo)) { 3433c8d948SJani Nikula err = PTR_ERR(bo); 3533c8d948SJani Nikula bo = NULL; 3633c8d948SJani Nikula return err; 3733c8d948SJani Nikula } 3833c8d948SJani Nikula 3933c8d948SJani Nikula node->bo = bo; 4033c8d948SJani Nikula 4133c8d948SJani Nikula return err; 4233c8d948SJani Nikula } 4333c8d948SJani Nikula 44*d630a1bdSJani Nikula int i915_gem_stolen_insert_node(struct intel_stolen_node *node, u64 size, unsigned int align) 4533c8d948SJani Nikula { 4633c8d948SJani Nikula /* Not used on xe */ 4733c8d948SJani Nikula WARN_ON(1); 4833c8d948SJani Nikula 4933c8d948SJani Nikula return -ENODEV; 5033c8d948SJani Nikula } 5133c8d948SJani Nikula 52994c74eaSJani Nikula void i915_gem_stolen_remove_node(struct intel_stolen_node *node) 5333c8d948SJani Nikula { 5433c8d948SJani Nikula xe_bo_unpin_map_no_vm(node->bo); 5533c8d948SJani Nikula node->bo = NULL; 5633c8d948SJani Nikula } 5733c8d948SJani Nikula 58d3741f2cSJani Nikula bool i915_gem_stolen_initialized(struct drm_device *drm) 5933c8d948SJani Nikula { 60d3741f2cSJani Nikula struct xe_device *xe = to_xe_device(drm); 61d3741f2cSJani Nikula 6233c8d948SJani Nikula return ttm_manager_type(&xe->ttm, XE_PL_STOLEN); 6333c8d948SJani Nikula } 6433c8d948SJani Nikula 6533c8d948SJani Nikula bool i915_gem_stolen_node_allocated(const struct intel_stolen_node *node) 6633c8d948SJani Nikula { 6733c8d948SJani Nikula return node->bo; 6833c8d948SJani Nikula } 6933c8d948SJani Nikula 7033c8d948SJani Nikula u32 i915_gem_stolen_node_offset(struct intel_stolen_node *node) 7133c8d948SJani Nikula { 7233c8d948SJani Nikula struct xe_res_cursor res; 7333c8d948SJani Nikula 7433c8d948SJani Nikula xe_res_first(node->bo->ttm.resource, 0, 4096, &res); 7533c8d948SJani Nikula return res.start; 7633c8d948SJani Nikula } 7733c8d948SJani Nikula 7833c8d948SJani Nikula /* Used for < gen4. These are not supported by Xe */ 79d3741f2cSJani Nikula u64 i915_gem_stolen_area_address(struct drm_device *drm) 8033c8d948SJani Nikula { 8133c8d948SJani Nikula WARN_ON(1); 8233c8d948SJani Nikula 8333c8d948SJani Nikula return 0; 8433c8d948SJani Nikula } 8533c8d948SJani Nikula 8633c8d948SJani Nikula /* Used for gen9 specific WA. Gen9 is not supported by Xe */ 87d3741f2cSJani Nikula u64 i915_gem_stolen_area_size(struct drm_device *drm) 8833c8d948SJani Nikula { 8933c8d948SJani Nikula WARN_ON(1); 9033c8d948SJani Nikula 9133c8d948SJani Nikula return 0; 9233c8d948SJani Nikula } 9333c8d948SJani Nikula 94994c74eaSJani Nikula u64 i915_gem_stolen_node_address(struct intel_stolen_node *node) 9533c8d948SJani Nikula { 96994c74eaSJani Nikula struct xe_device *xe = node->xe; 97994c74eaSJani Nikula 9833c8d948SJani Nikula return xe_ttm_stolen_gpu_offset(xe) + i915_gem_stolen_node_offset(node); 9933c8d948SJani Nikula } 10033c8d948SJani Nikula 10133c8d948SJani Nikula u64 i915_gem_stolen_node_size(const struct intel_stolen_node *node) 10233c8d948SJani Nikula { 10333c8d948SJani Nikula return node->bo->ttm.base.size; 10433c8d948SJani Nikula } 105f74bab2dSJani Nikula 106f74bab2dSJani Nikula struct intel_stolen_node *i915_gem_stolen_node_alloc(struct drm_device *drm) 107f74bab2dSJani Nikula { 108e8848d3dSJani Nikula struct xe_device *xe = to_xe_device(drm); 109f74bab2dSJani Nikula struct intel_stolen_node *node; 110f74bab2dSJani Nikula 111f74bab2dSJani Nikula node = kzalloc(sizeof(*node), GFP_KERNEL); 112f74bab2dSJani Nikula if (!node) 113f74bab2dSJani Nikula return NULL; 114f74bab2dSJani Nikula 115e8848d3dSJani Nikula node->xe = xe; 116e8848d3dSJani Nikula 117f74bab2dSJani Nikula return node; 118f74bab2dSJani Nikula } 119f74bab2dSJani Nikula 120f74bab2dSJani Nikula void i915_gem_stolen_node_free(const struct intel_stolen_node *node) 121f74bab2dSJani Nikula { 122f74bab2dSJani Nikula kfree(node); 123f74bab2dSJani Nikula } 124