blob: cd11bd9db160ff711f1688eeecf6ed1e91f68663 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
2 *
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_H
14#define __KGSL_H
15
16#include <linux/types.h>
17#include <linux/msm_kgsl.h>
18#include <linux/platform_device.h>
19#include <linux/clk.h>
20#include <linux/interrupt.h>
21#include <linux/mutex.h>
22#include <linux/cdev.h>
23#include <linux/regulator/consumer.h>
24
25#define KGSL_NAME "kgsl"
26
27/* Flags to control whether to flush or invalidate a cached memory range */
28#define KGSL_CACHE_INV 0x00000000
29#define KGSL_CACHE_CLEAN 0x00000001
30#define KGSL_CACHE_FLUSH 0x00000002
31
32#define KGSL_CACHE_USER_ADDR 0x00000010
33#define KGSL_CACHE_VMALLOC_ADDR 0x00000020
34
35/*cache coherency ops */
36#define DRM_KGSL_GEM_CACHE_OP_TO_DEV 0x0001
37#define DRM_KGSL_GEM_CACHE_OP_FROM_DEV 0x0002
38
39/* The size of each entry in a page table */
40#define KGSL_PAGETABLE_ENTRY_SIZE 4
41
42/* Pagetable Virtual Address base */
43#define KGSL_PAGETABLE_BASE 0x66000000
44
45/* Extra accounting entries needed in the pagetable */
46#define KGSL_PT_EXTRA_ENTRIES 16
47
48#define KGSL_PAGETABLE_ENTRIES(_sz) (((_sz) >> PAGE_SHIFT) + \
49 KGSL_PT_EXTRA_ENTRIES)
50
51#ifdef CONFIG_MSM_KGSL_MMU
52#define KGSL_PAGETABLE_SIZE \
53ALIGN(KGSL_PAGETABLE_ENTRIES(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE) * \
54KGSL_PAGETABLE_ENTRY_SIZE, PAGE_SIZE)
55#else
56#define KGSL_PAGETABLE_SIZE 0
57#endif
58
59#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
60#define KGSL_PAGETABLE_COUNT (CONFIG_MSM_KGSL_PAGE_TABLE_COUNT)
61#else
62#define KGSL_PAGETABLE_COUNT 1
63#endif
64
65/* Casting using container_of() for structures that kgsl owns. */
66#define KGSL_CONTAINER_OF(ptr, type, member) \
67 container_of(ptr, type, member)
68
69/* A macro for memory statistics - add the new size to the stat and if
70 the statisic is greater then _max, set _max
71*/
72
73#define KGSL_STATS_ADD(_size, _stat, _max) \
74 do { _stat += (_size); if (_stat > _max) _max = _stat; } while (0)
75
76struct kgsl_device;
77
78struct kgsl_ptpool {
79 size_t ptsize;
80 struct mutex lock;
81 struct list_head list;
82 int entries;
83 int static_entries;
84 int chunks;
85};
86
87struct kgsl_driver {
88 struct cdev cdev;
89 dev_t major;
90 struct class *class;
91 /* Virtual device for managing the core */
92 struct device virtdev;
93 /* Kobjects for storing pagetable and process statistics */
94 struct kobject *ptkobj;
95 struct kobject *prockobj;
96 struct kgsl_device *devp[KGSL_DEVICE_MAX];
97
98 uint32_t flags_debug;
99
100 /* Global lilst of open processes */
101 struct list_head process_list;
102 /* Global list of pagetables */
103 struct list_head pagetable_list;
104 /* Spinlock for accessing the pagetable list */
105 spinlock_t ptlock;
106 /* Mutex for accessing the process list */
107 struct mutex process_mutex;
108
109 /* Mutex for protecting the device list */
110 struct mutex devlock;
111
112 struct kgsl_ptpool ptpool;
113
114 struct {
115 unsigned int vmalloc;
116 unsigned int vmalloc_max;
117 unsigned int coherent;
118 unsigned int coherent_max;
119 unsigned int mapped;
120 unsigned int mapped_max;
121 unsigned int histogram[16];
122 } stats;
123};
124
125extern struct kgsl_driver kgsl_driver;
126
127#define KGSL_USER_MEMORY 1
128#define KGSL_MAPPED_MEMORY 2
129
130struct kgsl_pagetable;
131struct kgsl_memdesc_ops;
132
133/* shared memory allocation */
134struct kgsl_memdesc {
135 struct kgsl_pagetable *pagetable;
136 void *hostptr;
137 unsigned int gpuaddr;
138 unsigned int physaddr;
139 unsigned int size;
140 unsigned int priv;
141 struct kgsl_memdesc_ops *ops;
142};
143
144struct kgsl_mem_entry {
145 struct kref refcount;
146 struct kgsl_memdesc memdesc;
147 int memtype;
148 struct file *file_ptr;
149 struct list_head list;
150 uint32_t free_timestamp;
151 /* back pointer to private structure under whose context this
152 * allocation is made */
153 struct kgsl_process_private *priv;
154};
155
156#ifdef CONFIG_MSM_KGSL_MMU_PAGE_FAULT
157#define MMU_CONFIG 2
158#else
159#define MMU_CONFIG 1
160#endif
161
162void kgsl_mem_entry_destroy(struct kref *kref);
163uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
164 unsigned int gpuaddr, unsigned int *size);
165struct kgsl_mem_entry *kgsl_sharedmem_find_region(
166 struct kgsl_process_private *private, unsigned int gpuaddr,
167 size_t size);
168
169extern const struct dev_pm_ops kgsl_pm_ops;
170
171struct early_suspend;
172int kgsl_suspend_driver(struct platform_device *pdev, pm_message_t state);
173int kgsl_resume_driver(struct platform_device *pdev);
174void kgsl_early_suspend_driver(struct early_suspend *h);
175void kgsl_late_resume_driver(struct early_suspend *h);
176
177#ifdef CONFIG_MSM_KGSL_DRM
178extern int kgsl_drm_init(struct platform_device *dev);
179extern void kgsl_drm_exit(void);
180extern void kgsl_gpu_mem_flush(int op);
181#else
182static inline int kgsl_drm_init(struct platform_device *dev)
183{
184 return 0;
185}
186
187static inline void kgsl_drm_exit(void)
188{
189}
190#endif
191
192static inline int kgsl_gpuaddr_in_memdesc(const struct kgsl_memdesc *memdesc,
193 unsigned int gpuaddr)
194{
195 if (gpuaddr >= memdesc->gpuaddr && (gpuaddr + sizeof(unsigned int)) <=
196 (memdesc->gpuaddr + memdesc->size)) {
197 return 1;
198 }
199 return 0;
200}
201
202static inline bool timestamp_cmp(unsigned int new, unsigned int old)
203{
204 int ts_diff = new - old;
205 return (ts_diff >= 0) || (ts_diff < -20000);
206}
207
208static inline void
209kgsl_mem_entry_get(struct kgsl_mem_entry *entry)
210{
211 kref_get(&entry->refcount);
212}
213
214static inline void
215kgsl_mem_entry_put(struct kgsl_mem_entry *entry)
216{
217 kref_put(&entry->refcount, kgsl_mem_entry_destroy);
218}
219
220#endif /* __KGSL_H */