blob: def29b387219a2eac89cde5c82bd9fc7b5e8ff71 [file] [log] [blame]
Jeff Boody28afec42012-01-18 15:47:46 -07001/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#ifndef __KGSL_SHAREDMEM_H
14#define __KGSL_SHAREDMEM_H
15
Jordan Croused17e9aa2011-10-12 16:57:48 -060016#include <linux/slab.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070017#include <linux/dma-mapping.h>
Jeff Boody28afec42012-01-18 15:47:46 -070018#include <linux/vmalloc.h>
Jeremy Gebben32660362011-11-03 09:59:51 -060019#include "kgsl_mmu.h"
Anshuman Danieecd5202012-02-17 19:52:49 +053020#include <linux/slab.h>
21#include <linux/kmemleak.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070022
23struct kgsl_device;
24struct kgsl_process_private;
25
26#define KGSL_CACHE_OP_INV 0x01
27#define KGSL_CACHE_OP_FLUSH 0x02
28#define KGSL_CACHE_OP_CLEAN 0x03
29
30/** Set if the memdesc describes cached memory */
31#define KGSL_MEMFLAGS_CACHED 0x00000001
Jeremy Gebben7faf9ec2012-03-21 14:09:55 -060032/** Set if the memdesc is mapped into all pagetables */
33#define KGSL_MEMFLAGS_GLOBAL 0x00000002
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070034
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070035extern struct kgsl_memdesc_ops kgsl_vmalloc_ops;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070036
37int kgsl_sharedmem_vmalloc(struct kgsl_memdesc *memdesc,
38 struct kgsl_pagetable *pagetable, size_t size);
39
40int kgsl_sharedmem_vmalloc_user(struct kgsl_memdesc *memdesc,
41 struct kgsl_pagetable *pagetable,
42 size_t size, int flags);
43
44int kgsl_sharedmem_alloc_coherent(struct kgsl_memdesc *memdesc, size_t size);
45
46int kgsl_sharedmem_ebimem_user(struct kgsl_memdesc *memdesc,
47 struct kgsl_pagetable *pagetable,
48 size_t size, int flags);
49
50int kgsl_sharedmem_ebimem(struct kgsl_memdesc *memdesc,
51 struct kgsl_pagetable *pagetable,
52 size_t size);
53
54void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc);
55
56int kgsl_sharedmem_readl(const struct kgsl_memdesc *memdesc,
57 uint32_t *dst,
58 unsigned int offsetbytes);
59
60int kgsl_sharedmem_writel(const struct kgsl_memdesc *memdesc,
61 unsigned int offsetbytes,
62 uint32_t src);
63
64int kgsl_sharedmem_set(const struct kgsl_memdesc *memdesc,
65 unsigned int offsetbytes, unsigned int value,
66 unsigned int sizebytes);
67
68void kgsl_cache_range_op(struct kgsl_memdesc *memdesc, int op);
69
70void kgsl_process_init_sysfs(struct kgsl_process_private *private);
71void kgsl_process_uninit_sysfs(struct kgsl_process_private *private);
72
73int kgsl_sharedmem_init_sysfs(void);
74void kgsl_sharedmem_uninit_sysfs(void);
75
Jeremy Gebben582fe312012-03-23 10:19:44 -060076static inline unsigned int kgsl_get_sg_pa(struct scatterlist *sg)
77{
78 /*
79 * Try sg_dma_address first to support ion carveout
80 * regions which do not work with sg_phys().
81 */
82 unsigned int pa = sg_dma_address(sg);
83 if (pa == 0)
84 pa = sg_phys(sg);
85 return pa;
86}
87
Harsh Vardhan Dwivedi8cb835b2012-03-29 17:23:11 -060088int
89kgsl_sharedmem_map_vma(struct vm_area_struct *vma,
90 const struct kgsl_memdesc *memdesc);
91
Jordan Crousea652a072012-04-06 16:26:33 -060092/*
93 * For relatively small sglists, it is preferable to use kzalloc
94 * rather than going down the vmalloc rat hole. If the size of
95 * the sglist is < PAGE_SIZE use kzalloc otherwise fallback to
96 * vmalloc
97 */
98
99static inline void *kgsl_sg_alloc(unsigned int sglen)
100{
101 if ((sglen * sizeof(struct scatterlist)) < PAGE_SIZE)
102 return kzalloc(sglen * sizeof(struct scatterlist), GFP_KERNEL);
103 else
104 return vmalloc(sglen * sizeof(struct scatterlist));
105}
106
107static inline void kgsl_sg_free(void *ptr, unsigned int sglen)
108{
109 if ((sglen * sizeof(struct scatterlist)) < PAGE_SIZE)
110 kfree(ptr);
111 else
112 vfree(ptr);
113}
114
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700115static inline int
Jordan Croused17e9aa2011-10-12 16:57:48 -0600116memdesc_sg_phys(struct kgsl_memdesc *memdesc,
117 unsigned int physaddr, unsigned int size)
118{
Jordan Crousea652a072012-04-06 16:26:33 -0600119 memdesc->sg = kgsl_sg_alloc(1);
Jordan Croused17e9aa2011-10-12 16:57:48 -0600120
Anshuman Danieecd5202012-02-17 19:52:49 +0530121 kmemleak_not_leak(memdesc->sg);
122
Jordan Croused17e9aa2011-10-12 16:57:48 -0600123 memdesc->sglen = 1;
124 sg_init_table(memdesc->sg, 1);
Jeremy Gebben582fe312012-03-23 10:19:44 -0600125 memdesc->sg[0].length = size;
126 memdesc->sg[0].offset = 0;
127 memdesc->sg[0].dma_address = physaddr;
Jordan Croused17e9aa2011-10-12 16:57:48 -0600128 return 0;
129}
130
131static inline int
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700132kgsl_allocate(struct kgsl_memdesc *memdesc,
133 struct kgsl_pagetable *pagetable, size_t size)
134{
Jeremy Gebben32660362011-11-03 09:59:51 -0600135 if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_NONE)
136 return kgsl_sharedmem_ebimem(memdesc, pagetable, size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137 return kgsl_sharedmem_vmalloc(memdesc, pagetable, size);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700138}
139
140static inline int
141kgsl_allocate_user(struct kgsl_memdesc *memdesc,
142 struct kgsl_pagetable *pagetable,
143 size_t size, unsigned int flags)
144{
Jeremy Gebben32660362011-11-03 09:59:51 -0600145 if (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_NONE)
146 return kgsl_sharedmem_ebimem_user(memdesc, pagetable, size,
147 flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700148 return kgsl_sharedmem_vmalloc_user(memdesc, pagetable, size, flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700149}
150
151static inline int
152kgsl_allocate_contiguous(struct kgsl_memdesc *memdesc, size_t size)
153{
154 int ret = kgsl_sharedmem_alloc_coherent(memdesc, size);
Jeremy Gebben32660362011-11-03 09:59:51 -0600155 if (!ret && (kgsl_mmu_get_mmutype() == KGSL_MMU_TYPE_NONE))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700156 memdesc->gpuaddr = memdesc->physaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700157 return ret;
158}
159
160#endif /* __KGSL_SHAREDMEM_H */