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