• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #ifndef __DRV_MEDIA_MEM_H__
20 #define __DRV_MEDIA_MEM_H__
21 
22 #include <linux/scatterlist.h>
23 #include <linux/semaphore.h>
24 #include <asm/cacheflush.h>
25 #include <linux/version.h>
26 #include "hi_type.h"
27 #include "drv_mmz.h"
28 #include "drv_mmz_ioctl.h"
29 
30 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
31 #include <linux/ion.h>
32 #else
33 #include <linux/dma-buf.h>
34 #endif
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 #define HIL_MAX_NAME_LEN 16
41 extern int g_mmz_print_level;
42 
43 #ifndef hi_mmz_print
44 #ifdef CONFIG_SUPPORT_CA_RELEASE
45 #define hi_mmz_print(LEVEL, fmt, args...)
46 #else
47 #define hi_mmz_print(LEVEL, fmt, args...)                         \
48     do {                                                          \
49         if (g_mmz_print_level > LEVEL) {                          \
50             printk("%s[%d]: " fmt, __func__, __LINE__, ##args);   \
51         }                                                         \
52     } while (0)
53 #endif
54 #endif
55 #define MMZ_FATAL_PRINT_LEVEL 0
56 #define MMZ_ERROR_PRINT_LEVEL 1
57 #define MMZ_WARN_PRINT_LEVEL  2
58 #define MMZ_INFO_PRINT_LEVEL  3
59 #define MMZ_DEBUG_PRINT_LEVEL 4
60 
61 #define hi_mmz_fatal(fmt, args...) hi_mmz_print(0, fmt, ##args)
62 #define hi_mmz_error(fmt, args...) hi_mmz_print(1, fmt, ##args)
63 #define hi_mmz_warn(fmt, args...)  hi_mmz_print(2, fmt, ##args)
64 #define hi_mmz_info(fmt, args...)  hi_mmz_print(3, fmt, ##args)
65 #define hi_mmz_debug(fmt, args...) hi_mmz_print(4, fmt, ##args)
66 
67 #ifdef CONFIG_64BIT
68 /* need to rm when linux-4.14 to support flush cache all in aarch64   */
69 #if (LINUX_VERSION_CODE > (KERNEL_VERSION(4,14,0)))
flush_cache_all(void)70 static inline void flush_cache_all(void)
71 {
72     return;
73 }
74 #endif
75 #define mmz_flush_dcache_all  flush_cache_all
76 #define mmz_flush_dcache_area __flush_dcache_area
77 #else
78 #define mmz_flush_dcache_all  __cpuc_flush_kern_all
79 #define mmz_flush_dcache_area __cpuc_flush_dcache_area
80 #endif
81 
82 /* alloc status */
83 #define HI_USER_ALLOC   0
84 #define HI_KERNEL_ALLOC (1 << 0)
85 
86 /* unmap mode */
87 #define EXCEPTION_FLAG  0
88 #define NORMAL_FLAG     (1 << 0)
89 
90 /* just for inf */
91 struct hil_media_memory_zone {
92     char name[HIL_MAX_NAME_LEN];
93     HI_U32 gfp;
94     HI_U32 zone_start;
95     HI_U32 nbytes;
96     struct list_head list;
97     int iommu;
98     struct rb_root root;
99 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
100     HI_U32 heap_id_mask;
101 #else
102     struct dma_heap *heap;
103 #endif
104     void (*destructor)(const void *);
105 };
106 typedef struct hil_media_memory_zone hil_mmz_t;
107 
108 #define HIL_MMZ_FMT        "PHYS(0x%08X, 0x%08X), GFP = %u, nBYTES = %uKB,   NAME = \"%s\""
109 #define hil_mmz_fmt_arg(p) (p)->zone_start, (p)->zone_start + (p)->nbytes - 1, (p)->gfp, (p)->nbytes / SZ_1K, (p)->name
110 
111 /* for inf & usr */
112 struct mmb_kdata {
113     void *kvirt;
114     HI_U32 kmap_ref;
115     HI_U32 map_cached;
116 };
117 
118 struct mmb_udata {
119     pid_t tgid;
120     void *uvirt;
121     struct list_head list;
122     HI_U32 map_ref;
123     int map_fd;
124     HI_U32 unmap_flag; /* indicate if normal unmapd or process killed by system */
125     struct {
126         HI_U32 prot : 8;   /* PROT_READ or PROT_WRITE */
127         HI_U32 flags : 12; /* MAP_SHARED or MAP_PRIVATE */
128         HI_U32 map_cached : 1;
129         HI_U32 reserved : 11; /* reserved, do not use */
130     };
131 };
132 
133 struct hil_media_memory_block {
134     char name[HIL_MAX_NAME_LEN];
135     struct hil_media_memory_zone *zone;
136 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
137     struct ion_handle *handle;  /* to buffer in ion */
138     struct ion_client *client;
139 #else
140     struct dma_buf *handle;
141 #endif
142     struct rb_node node;    /* cma node */
143     struct rb_node s_node;  /* smmu/iommu node */
144     HI_U32 iommu_addr;
145     HI_U32 phys_addr;
146     HI_U32 sec_smmu;
147     struct mmb_kdata *kdata;
148     struct list_head ulist;
149     HI_U32 length;
150     int iommu;  /* 0: cma mem , 1: iommu when allocating */
151     int cma_smmu_ref;
152     int phy_ref;
153     int map_ref;       /* all map:user space and kernel space */
154     int sec_smmu_ref;  /* sec smmu ref in secure os */
155     int sec_flag;      /* 1: means the mem is sec mem   0: the mem is no sec mem */
156     int flag;          /* indicate whether this buffer allocated in kernel space or not */
157     pid_t owner_id;    /* The owner process who alloc the mem */
158     spinlock_t u_lock;
159 };
160 typedef struct hil_media_memory_block hil_mmb_t;
161 
162 struct mmz_userdev_info {
163     pid_t tpid;
164     pid_t mmap_tpid;
165     struct semaphore sem;
166     void *private_data;
167     void *tmp;
168 };
169 
170 #define HIL_MMB_MAP2KERN        (1 << 0)
171 #define HIL_MMB_MAP2KERN_CACHED (1 << 1)
172 #define HIL_MMB_RELEASED        (1 << 2)
173 
174 #ifdef HI_SMMU_SUPPORT
175 #define HIL_MMB_FMT         "phys(0x%08X, 0x%08X), smmu = (0x%08X, 0x%08X),kvirt = %pK, length = %uKB,    name = \"%s\""
176 #define hil_mmb_fmt_arg(p)  (p)->phys_addr, (unsigned int)mmz_grain_align((p)->phys_addr + (p)->length) - 1, \
177                             (p)->iommu_addr, (unsigned int)mmz_grain_align((p)->iommu_addr + (p)->length) - 1, \
178                             ((p)->kdata == NULL) ? NULL : (p)->kdata->kvirt, (p)->length / SZ_1K, (p)->name
179 #else
180 #define HIL_MMB_FMT         "phys(0x%08X, 0x%08X),kvirt = %pK, length = %uKB,    name = \"%s\""
181 #define hil_mmb_fmt_arg(p)  (p)->phys_addr, (unsigned int)mmz_grain_align((p)->phys_addr + (p)->length) - 1, \
182                             ((p)->kdata == NULL) ? NULL : (p)->kdata->kvirt, (p)->length / SZ_1K, (p)->name
183 #endif
184 
185 extern struct list_head g_mmz_list;
186 extern struct semaphore g_mmz_lock;
187 struct mmz_iommu {
188     struct ion_client *client;
189 };
190 
191 /* ******** nAPI_0 for inf ******** */
192 extern hil_mmz_t *hil_mmz_create(const char *name, HI_U32 gfp, HI_U32 zone_start, HI_U32 nbytes);
193 extern int hil_mmz_destroy(const hil_mmz_t *zone);
194 extern int hil_mmz_register(hil_mmz_t *zone);
195 extern int hil_mmz_unregister(hil_mmz_t *zone);
196 extern hil_mmb_t *hil_mmb_getby_phys(HI_U32 addr, HI_U32 iommu);
197 extern hil_mmb_t *hil_mmb_getby_kvirt(const void *virt);
198 extern hil_mmb_t *hil_mmb_getby_sec_addr(HI_U32 sec_addr, HI_U32 iommu);
199 extern int set_sec_mmb_flag(u32 addr, int iommu);
200 extern int clr_sec_mmb_flag(u32 addr, int iommu);
201 extern int is_sec_mem(u32 addr, int iommu);
202 extern int sec_delay_release_for_mem(u32 addr, int iommu);
203 extern int sec_mmb_get(u32 addr, int iommu, u32 sec_smmu);
204 extern int sec_mmb_put(u32 addr, int iommu);
205 
206 extern int mmb_get(u32 addr, int iommu);
207 extern int mmb_put(u32 addr, int iommu);
208 
209 extern int mmb_ref_query(u32 addr, int iommu, u32 *ref);
210 extern int sec_mmb_query_ref(HI_U32 sec_addr, int iommu, HI_U32 *ref);
211 extern int mem_source_query(u32 iommu_addr, int *source);
212 extern int sec_mem_source_query(u32 iommu_addr, int *source);
213 extern void *hil_mmb_map2kern(hil_mmb_t *mmb);
214 extern void *hil_mmb_map2kern_cached(hil_mmb_t *mmb);
215 extern int hil_mmb_unmap(hil_mmb_t *mmb, const void *addr);
216 extern hil_mmb_t *hil_mmbinfo_getby_kvirt(const void *virt);
217 
218 /* ********* API_1 for inf & usr ******** */
219 extern hil_mmb_t *hil_mmb_alloc(const char *name, HI_U32 size, HI_U32 align, const char *mmz_name, int kbuf);
220 extern int hil_mmb_free(hil_mmb_t *mmb);
221 extern mmb_addr_t hil_mmb_cma_mapto_iommu(mmb_addr_t addr, int iommu);
222 extern int hil_mmb_cma_unmapfrom_iommu(mmb_addr_t addr, int iommu);
223 extern struct sg_table *hil_get_meminfo(const hil_mmb_t *mmb);
224 
225 extern int mmz_read_proc(struct seq_file *m, void *v);
226 extern int mmz_write_proc(struct file *file, const char __user *buffer, HI_U32 count, void *data);
227 #ifndef DMABUF_FLUSH_CACHE
228 void flush_outer_cache_range(mmb_addr_t phyaddr, mmb_addr_t len, HI_U32 iommu);
229 void flush_inner_cache(const void *viraddr, HI_U32 len);
230 #endif
231 int hi_drv_mmz_init(void);
232 void hi_drv_mmz_exit(void);
233 
234 #ifdef __cplusplus
235 }
236 #endif
237 
238 #endif
239