1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "xe_bb.h" 7 8 #include "regs/xe_gpu_commands.h" 9 #include "xe_device.h" 10 #include "xe_engine_types.h" 11 #include "xe_gt.h" 12 #include "xe_hw_fence.h" 13 #include "xe_sa.h" 14 #include "xe_sched_job.h" 15 #include "xe_vm_types.h" 16 17 static int bb_prefetch(struct xe_gt *gt) 18 { 19 struct xe_device *xe = gt_to_xe(gt); 20 21 if (GRAPHICS_VERx100(xe) >= 1250 && !xe_gt_is_media_type(gt)) 22 /* 23 * RCS and CCS require 1K, although other engines would be 24 * okay with 512. 25 */ 26 return SZ_1K; 27 else 28 return SZ_512; 29 } 30 31 struct xe_bb *xe_bb_new(struct xe_gt *gt, u32 dwords, bool usm) 32 { 33 struct xe_tile *tile = gt_to_tile(gt); 34 struct xe_bb *bb = kmalloc(sizeof(*bb), GFP_KERNEL); 35 int err; 36 37 if (!bb) 38 return ERR_PTR(-ENOMEM); 39 40 /* 41 * We need to allocate space for the requested number of dwords, 42 * one additional MI_BATCH_BUFFER_END dword, and additional buffer 43 * space to accomodate the platform-specific hardware prefetch 44 * requirements. 45 */ 46 bb->bo = xe_sa_bo_new(!usm ? tile->mem.kernel_bb_pool : gt->usm.bb_pool, 47 4 * (dwords + 1) + bb_prefetch(gt)); 48 if (IS_ERR(bb->bo)) { 49 err = PTR_ERR(bb->bo); 50 goto err; 51 } 52 53 bb->cs = xe_sa_bo_cpu_addr(bb->bo); 54 bb->len = 0; 55 56 return bb; 57 err: 58 kfree(bb); 59 return ERR_PTR(err); 60 } 61 62 static struct xe_sched_job * 63 __xe_bb_create_job(struct xe_engine *kernel_eng, struct xe_bb *bb, u64 *addr) 64 { 65 u32 size = drm_suballoc_size(bb->bo); 66 67 bb->cs[bb->len++] = MI_BATCH_BUFFER_END; 68 69 WARN_ON(bb->len * 4 + bb_prefetch(kernel_eng->gt) > size); 70 71 xe_sa_bo_flush_write(bb->bo); 72 73 return xe_sched_job_create(kernel_eng, addr); 74 } 75 76 struct xe_sched_job *xe_bb_create_wa_job(struct xe_engine *wa_eng, 77 struct xe_bb *bb, u64 batch_base_ofs) 78 { 79 u64 addr = batch_base_ofs + drm_suballoc_soffset(bb->bo); 80 81 XE_BUG_ON(!(wa_eng->vm->flags & XE_VM_FLAG_MIGRATION)); 82 83 return __xe_bb_create_job(wa_eng, bb, &addr); 84 } 85 86 struct xe_sched_job *xe_bb_create_migration_job(struct xe_engine *kernel_eng, 87 struct xe_bb *bb, 88 u64 batch_base_ofs, 89 u32 second_idx) 90 { 91 u64 addr[2] = { 92 batch_base_ofs + drm_suballoc_soffset(bb->bo), 93 batch_base_ofs + drm_suballoc_soffset(bb->bo) + 94 4 * second_idx, 95 }; 96 97 BUG_ON(second_idx > bb->len); 98 BUG_ON(!(kernel_eng->vm->flags & XE_VM_FLAG_MIGRATION)); 99 100 return __xe_bb_create_job(kernel_eng, bb, addr); 101 } 102 103 struct xe_sched_job *xe_bb_create_job(struct xe_engine *kernel_eng, 104 struct xe_bb *bb) 105 { 106 u64 addr = xe_sa_bo_gpu_addr(bb->bo); 107 108 BUG_ON(kernel_eng->vm && kernel_eng->vm->flags & XE_VM_FLAG_MIGRATION); 109 return __xe_bb_create_job(kernel_eng, bb, &addr); 110 } 111 112 void xe_bb_free(struct xe_bb *bb, struct dma_fence *fence) 113 { 114 if (!bb) 115 return; 116 117 xe_sa_bo_free(bb->bo, fence); 118 kfree(bb); 119 } 120