1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2023, Intel Corporation. 4 */ 5 6 #include "gem/i915_gem_internal.h" 7 #include "gem/i915_gem_lmem.h" 8 #include "i915_drv.h" 9 #include "i915_vma.h" 10 #include "intel_dsb_buffer.h" 11 12 struct intel_dsb_buffer { 13 u32 *cmd_buf; 14 struct i915_vma *vma; 15 size_t buf_size; 16 }; 17 18 u32 intel_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf) 19 { 20 return i915_ggtt_offset(dsb_buf->vma); 21 } 22 23 void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val) 24 { 25 dsb_buf->cmd_buf[idx] = val; 26 } 27 28 u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx) 29 { 30 return dsb_buf->cmd_buf[idx]; 31 } 32 33 void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size) 34 { 35 WARN_ON(idx > (dsb_buf->buf_size - size) / sizeof(*dsb_buf->cmd_buf)); 36 37 memset(&dsb_buf->cmd_buf[idx], val, size); 38 } 39 40 struct intel_dsb_buffer *intel_dsb_buffer_create(struct drm_device *drm, size_t size) 41 { 42 struct drm_i915_private *i915 = to_i915(drm); 43 struct intel_dsb_buffer *dsb_buf; 44 struct drm_i915_gem_object *obj; 45 struct i915_vma *vma; 46 u32 *buf; 47 int ret; 48 49 dsb_buf = kzalloc(sizeof(*dsb_buf), GFP_KERNEL); 50 if (!dsb_buf) 51 return ERR_PTR(-ENOMEM); 52 53 if (HAS_LMEM(i915)) { 54 obj = i915_gem_object_create_lmem(i915, PAGE_ALIGN(size), 55 I915_BO_ALLOC_CONTIGUOUS); 56 if (IS_ERR(obj)) { 57 ret = PTR_ERR(obj); 58 goto err; 59 } 60 } else { 61 obj = i915_gem_object_create_internal(i915, PAGE_ALIGN(size)); 62 if (IS_ERR(obj)) { 63 ret = PTR_ERR(obj); 64 goto err; 65 } 66 67 i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); 68 } 69 70 vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0); 71 if (IS_ERR(vma)) { 72 ret = PTR_ERR(vma); 73 i915_gem_object_put(obj); 74 goto err; 75 } 76 77 buf = i915_gem_object_pin_map_unlocked(vma->obj, I915_MAP_WC); 78 if (IS_ERR(buf)) { 79 ret = PTR_ERR(buf); 80 i915_vma_unpin_and_release(&vma, I915_VMA_RELEASE_MAP); 81 goto err; 82 } 83 84 dsb_buf->vma = vma; 85 dsb_buf->cmd_buf = buf; 86 dsb_buf->buf_size = size; 87 88 return dsb_buf; 89 90 err: 91 kfree(dsb_buf); 92 93 return ERR_PTR(ret); 94 } 95 96 void intel_dsb_buffer_cleanup(struct intel_dsb_buffer *dsb_buf) 97 { 98 i915_vma_unpin_and_release(&dsb_buf->vma, I915_VMA_RELEASE_MAP); 99 kfree(dsb_buf); 100 } 101 102 void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf) 103 { 104 i915_gem_object_flush_map(dsb_buf->vma->obj); 105 } 106