1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "xe_bb.h" 7 #include "xe_sa.h" 8 #include "xe_device.h" 9 #include "xe_engine_types.h" 10 #include "xe_hw_fence.h" 11 #include "xe_sched_job.h" 12 #include "xe_vm_types.h" 13 14 #include "gt/intel_gpu_commands.h" 15 16 struct xe_bb *xe_bb_new(struct xe_gt *gt, u32 dwords, bool usm) 17 { 18 struct xe_bb *bb = kmalloc(sizeof(*bb), GFP_KERNEL); 19 int err; 20 21 if (!bb) 22 return ERR_PTR(-ENOMEM); 23 24 bb->bo = xe_sa_bo_new(!usm ? >->kernel_bb_pool : 25 >->usm.bb_pool, 4 * dwords + 4); 26 if (IS_ERR(bb->bo)) { 27 err = PTR_ERR(bb->bo); 28 goto err; 29 } 30 31 bb->cs = xe_sa_bo_cpu_addr(bb->bo); 32 bb->len = 0; 33 34 return bb; 35 err: 36 kfree(bb); 37 return ERR_PTR(err); 38 } 39 40 static struct xe_sched_job * 41 __xe_bb_create_job(struct xe_engine *kernel_eng, struct xe_bb *bb, u64 *addr) 42 { 43 u32 size = drm_suballoc_size(bb->bo); 44 45 XE_BUG_ON((bb->len * 4 + 1) > size); 46 47 bb->cs[bb->len++] = MI_BATCH_BUFFER_END; 48 49 xe_sa_bo_flush_write(bb->bo); 50 51 return xe_sched_job_create(kernel_eng, addr); 52 } 53 54 struct xe_sched_job *xe_bb_create_wa_job(struct xe_engine *wa_eng, 55 struct xe_bb *bb, u64 batch_base_ofs) 56 { 57 u64 addr = batch_base_ofs + drm_suballoc_soffset(bb->bo); 58 59 XE_BUG_ON(!(wa_eng->vm->flags & XE_VM_FLAG_MIGRATION)); 60 61 return __xe_bb_create_job(wa_eng, bb, &addr); 62 } 63 64 struct xe_sched_job *xe_bb_create_migration_job(struct xe_engine *kernel_eng, 65 struct xe_bb *bb, 66 u64 batch_base_ofs, 67 u32 second_idx) 68 { 69 u64 addr[2] = { 70 batch_base_ofs + drm_suballoc_soffset(bb->bo), 71 batch_base_ofs + drm_suballoc_soffset(bb->bo) + 72 4 * second_idx, 73 }; 74 75 BUG_ON(second_idx > bb->len); 76 BUG_ON(!(kernel_eng->vm->flags & XE_VM_FLAG_MIGRATION)); 77 78 return __xe_bb_create_job(kernel_eng, bb, addr); 79 } 80 81 struct xe_sched_job *xe_bb_create_job(struct xe_engine *kernel_eng, 82 struct xe_bb *bb) 83 { 84 u64 addr = xe_sa_bo_gpu_addr(bb->bo); 85 86 BUG_ON(kernel_eng->vm && kernel_eng->vm->flags & XE_VM_FLAG_MIGRATION); 87 return __xe_bb_create_job(kernel_eng, bb, &addr); 88 } 89 90 void xe_bb_free(struct xe_bb *bb, struct dma_fence *fence) 91 { 92 if (!bb) 93 return; 94 95 xe_sa_bo_free(bb->bo, fence); 96 kfree(bb); 97 } 98