xref: /linux/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c (revision ea1f5729aa1bbe68f9a394e259288d6ff894b0aa)
1*ea1f5729SLucas Stach /*
2*ea1f5729SLucas Stach  * Copyright (C) 2017 Etnaviv Project
3*ea1f5729SLucas Stach  *
4*ea1f5729SLucas Stach  * This program is free software; you can redistribute it and/or modify it
5*ea1f5729SLucas Stach  * under the terms of the GNU General Public License version 2 as published by
6*ea1f5729SLucas Stach  * the Free Software Foundation.
7*ea1f5729SLucas Stach  *
8*ea1f5729SLucas Stach  * This program is distributed in the hope that it will be useful, but WITHOUT
9*ea1f5729SLucas Stach  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10*ea1f5729SLucas Stach  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11*ea1f5729SLucas Stach  * more details.
12*ea1f5729SLucas Stach  *
13*ea1f5729SLucas Stach  * You should have received a copy of the GNU General Public License along with
14*ea1f5729SLucas Stach  * this program.  If not, see <http://www.gnu.org/licenses/>.
15*ea1f5729SLucas Stach  */
16*ea1f5729SLucas Stach 
17*ea1f5729SLucas Stach #include "etnaviv_cmdbuf.h"
18*ea1f5729SLucas Stach #include "etnaviv_gpu.h"
19*ea1f5729SLucas Stach #include "etnaviv_mmu.h"
20*ea1f5729SLucas Stach 
21*ea1f5729SLucas Stach struct etnaviv_cmdbuf *etnaviv_cmdbuf_new(struct etnaviv_gpu *gpu, u32 size,
22*ea1f5729SLucas Stach 	size_t nr_bos)
23*ea1f5729SLucas Stach {
24*ea1f5729SLucas Stach 	struct etnaviv_cmdbuf *cmdbuf;
25*ea1f5729SLucas Stach 	size_t sz = size_vstruct(nr_bos, sizeof(cmdbuf->bo_map[0]),
26*ea1f5729SLucas Stach 				 sizeof(*cmdbuf));
27*ea1f5729SLucas Stach 
28*ea1f5729SLucas Stach 	cmdbuf = kzalloc(sz, GFP_KERNEL);
29*ea1f5729SLucas Stach 	if (!cmdbuf)
30*ea1f5729SLucas Stach 		return NULL;
31*ea1f5729SLucas Stach 
32*ea1f5729SLucas Stach 	if (gpu->mmu->version == ETNAVIV_IOMMU_V2)
33*ea1f5729SLucas Stach 		size = ALIGN(size, SZ_4K);
34*ea1f5729SLucas Stach 
35*ea1f5729SLucas Stach 	cmdbuf->vaddr = dma_alloc_wc(gpu->dev, size, &cmdbuf->paddr,
36*ea1f5729SLucas Stach 				     GFP_KERNEL);
37*ea1f5729SLucas Stach 	if (!cmdbuf->vaddr) {
38*ea1f5729SLucas Stach 		kfree(cmdbuf);
39*ea1f5729SLucas Stach 		return NULL;
40*ea1f5729SLucas Stach 	}
41*ea1f5729SLucas Stach 
42*ea1f5729SLucas Stach 	cmdbuf->gpu = gpu;
43*ea1f5729SLucas Stach 	cmdbuf->size = size;
44*ea1f5729SLucas Stach 
45*ea1f5729SLucas Stach 	return cmdbuf;
46*ea1f5729SLucas Stach }
47*ea1f5729SLucas Stach 
48*ea1f5729SLucas Stach void etnaviv_cmdbuf_free(struct etnaviv_cmdbuf *cmdbuf)
49*ea1f5729SLucas Stach {
50*ea1f5729SLucas Stach 	etnaviv_iommu_put_cmdbuf_va(cmdbuf->gpu, cmdbuf);
51*ea1f5729SLucas Stach 	dma_free_wc(cmdbuf->gpu->dev, cmdbuf->size, cmdbuf->vaddr,
52*ea1f5729SLucas Stach 		    cmdbuf->paddr);
53*ea1f5729SLucas Stach 	kfree(cmdbuf);
54*ea1f5729SLucas Stach }
55