xref: /linux/drivers/gpu/drm/xe/xe_bb.c (revision dd08ebf6c3525a7ea2186e636df064ea47281987)
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 ? &gt->kernel_bb_pool :
25 			      &gt->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