MALI: utgard: upgrade DDK to r6p1-01rel0
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / mali400 / mali / linux / mali_memory_secure.c
1 /*
2  * Copyright (C) 2010-2016 ARM Limited. All rights reserved.
3  * 
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  * 
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10
11 #include "mali_kernel_common.h"
12 #include "mali_memory.h"
13 #include "mali_memory_secure.h"
14 #include "mali_osk.h"
15 #include <linux/mutex.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/dma-buf.h>
18
19 _mali_osk_errcode_t mali_mem_secure_attach_dma_buf(mali_mem_secure *secure_mem, u32 size, int mem_fd)
20 {
21         struct dma_buf *buf;
22         MALI_DEBUG_ASSERT_POINTER(secure_mem);
23
24         /* get dma buffer */
25         buf = dma_buf_get(mem_fd);
26         if (IS_ERR_OR_NULL(buf)) {
27                 MALI_DEBUG_PRINT_ERROR(("Failed to get dma buf!\n"));
28                 return _MALI_OSK_ERR_FAULT;
29         }
30
31         if (size != buf->size) {
32                 MALI_DEBUG_PRINT_ERROR(("The secure mem size not match to the dma buf size!\n"));
33                 goto failed_alloc_mem;
34         }
35
36         secure_mem->buf =  buf;
37         secure_mem->attachment = dma_buf_attach(secure_mem->buf, &mali_platform_device->dev);
38         if (NULL == secure_mem->attachment) {
39                 MALI_DEBUG_PRINT_ERROR(("Failed to get dma buf attachment!\n"));
40                 goto failed_dma_attach;
41         }
42
43         secure_mem->sgt = dma_buf_map_attachment(secure_mem->attachment, DMA_BIDIRECTIONAL);
44         if (IS_ERR_OR_NULL(secure_mem->sgt)) {
45                 MALI_DEBUG_PRINT_ERROR(("Failed to map dma buf attachment\n"));
46                 goto  failed_dma_map;
47         }
48
49         secure_mem->count = size / MALI_MMU_PAGE_SIZE;
50
51         return _MALI_OSK_ERR_OK;
52
53 failed_dma_map:
54         dma_buf_detach(secure_mem->buf, secure_mem->attachment);
55 failed_dma_attach:
56 failed_alloc_mem:
57         dma_buf_put(buf);
58         return _MALI_OSK_ERR_FAULT;
59 }
60
61 _mali_osk_errcode_t mali_mem_secure_mali_map(mali_mem_secure *secure_mem, struct mali_session_data *session, u32 vaddr, u32 props)
62 {
63         struct mali_page_directory *pagedir;
64         struct scatterlist *sg;
65         u32 virt = vaddr;
66         u32 prop = props;
67         int i;
68
69         MALI_DEBUG_ASSERT_POINTER(secure_mem);
70         MALI_DEBUG_ASSERT_POINTER(secure_mem->sgt);
71         MALI_DEBUG_ASSERT_POINTER(session);
72
73         pagedir = session->page_directory;
74
75         for_each_sg(secure_mem->sgt->sgl, sg, secure_mem->sgt->nents, i) {
76                 u32 size = sg_dma_len(sg);
77                 dma_addr_t phys = sg_dma_address(sg);
78
79                 /* sg must be page aligned. */
80                 MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE);
81                 MALI_DEBUG_ASSERT(0 == (phys & ~(uintptr_t)0xFFFFFFFF));
82
83                 mali_mmu_pagedir_update(pagedir, virt, phys, size, prop);
84
85                 MALI_DEBUG_PRINT(3, ("The secure mem physical address: 0x%x gpu virtual address: 0x%x! \n", phys, virt));
86                 virt += size;
87         }
88
89         return _MALI_OSK_ERR_OK;
90 }
91
92 void mali_mem_secure_mali_unmap(mali_mem_allocation *alloc)
93 {
94         struct mali_session_data *session;
95         MALI_DEBUG_ASSERT_POINTER(alloc);
96         session = alloc->session;
97         MALI_DEBUG_ASSERT_POINTER(session);
98
99         mali_session_memory_lock(session);
100         mali_mem_mali_map_free(session, alloc->psize, alloc->mali_vma_node.vm_node.start,
101                                alloc->flags);
102         mali_session_memory_unlock(session);
103 }
104
105
106 int mali_mem_secure_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma)
107 {
108
109         int ret = 0;
110         struct scatterlist *sg;
111         mali_mem_secure *secure_mem = &mem_bkend->secure_mem;
112         unsigned long addr = vma->vm_start;
113         int i;
114
115         MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_SECURE);
116
117         for_each_sg(secure_mem->sgt->sgl, sg, secure_mem->sgt->nents, i) {
118                 phys_addr_t phys;
119                 dma_addr_t dev_addr;
120                 u32 size, j;
121                 dev_addr = sg_dma_address(sg);
122 #if defined(CONFIG_ARM64) ||LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
123                 phys =  dma_to_phys(&mali_platform_device->dev, dev_addr);
124 #else
125                 phys = page_to_phys(pfn_to_page(dma_to_pfn(&mali_platform_device->dev, dev_addr)));
126 #endif
127                 size = sg_dma_len(sg);
128                 MALI_DEBUG_ASSERT(0 == size % _MALI_OSK_MALI_PAGE_SIZE);
129
130                 for (j = 0; j < size / _MALI_OSK_MALI_PAGE_SIZE; j++) {
131                         ret = vm_insert_pfn(vma, addr, PFN_DOWN(phys));
132
133                         if (unlikely(0 != ret)) {
134                                 return -EFAULT;
135                         }
136                         addr += _MALI_OSK_MALI_PAGE_SIZE;
137                         phys += _MALI_OSK_MALI_PAGE_SIZE;
138
139                         MALI_DEBUG_PRINT(3, ("The secure mem physical address: 0x%x , cpu virtual address: 0x%x! \n", phys, addr));
140                 }
141         }
142         return ret;
143 }
144
145 u32 mali_mem_secure_release(mali_mem_backend *mem_bkend)
146 {
147         struct mali_mem_secure *mem;
148         mali_mem_allocation *alloc = mem_bkend->mali_allocation;
149         u32 free_pages_nr = 0;
150         MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_SECURE);
151
152         mem = &mem_bkend->secure_mem;
153         MALI_DEBUG_ASSERT_POINTER(mem->attachment);
154         MALI_DEBUG_ASSERT_POINTER(mem->buf);
155         MALI_DEBUG_ASSERT_POINTER(mem->sgt);
156         /* Unmap the memory from the mali virtual address space. */
157         mali_mem_secure_mali_unmap(alloc);
158         mutex_lock(&mem_bkend->mutex);
159         dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL);
160         dma_buf_detach(mem->buf, mem->attachment);
161         dma_buf_put(mem->buf);
162         mutex_unlock(&mem_bkend->mutex);
163
164         free_pages_nr = mem->count;
165
166         return free_pages_nr;
167 }
168
169