blob: 3dafbb93aa4ba5e43cf1a6a7ae0e2630f7bb62a6 [file] [log] [blame]
Jordan Crouse0fdf3a02012-03-16 14:53:41 -06001/* Copyright (c) 2008-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_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
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070027/*cache coherency ops */
28#define DRM_KGSL_GEM_CACHE_OP_TO_DEV 0x0001
29#define DRM_KGSL_GEM_CACHE_OP_FROM_DEV 0x0002
30
31/* The size of each entry in a page table */
32#define KGSL_PAGETABLE_ENTRY_SIZE 4
33
34/* Pagetable Virtual Address base */
35#define KGSL_PAGETABLE_BASE 0x66000000
36
37/* Extra accounting entries needed in the pagetable */
38#define KGSL_PT_EXTRA_ENTRIES 16
39
40#define KGSL_PAGETABLE_ENTRIES(_sz) (((_sz) >> PAGE_SHIFT) + \
41 KGSL_PT_EXTRA_ENTRIES)
42
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070043#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
44#define KGSL_PAGETABLE_COUNT (CONFIG_MSM_KGSL_PAGE_TABLE_COUNT)
45#else
46#define KGSL_PAGETABLE_COUNT 1
47#endif
48
49/* Casting using container_of() for structures that kgsl owns. */
50#define KGSL_CONTAINER_OF(ptr, type, member) \
51 container_of(ptr, type, member)
52
53/* A macro for memory statistics - add the new size to the stat and if
54 the statisic is greater then _max, set _max
55*/
56
57#define KGSL_STATS_ADD(_size, _stat, _max) \
58 do { _stat += (_size); if (_stat > _max) _max = _stat; } while (0)
59
60struct kgsl_device;
61
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062struct kgsl_driver {
63 struct cdev cdev;
64 dev_t major;
65 struct class *class;
66 /* Virtual device for managing the core */
67 struct device virtdev;
68 /* Kobjects for storing pagetable and process statistics */
69 struct kobject *ptkobj;
70 struct kobject *prockobj;
71 struct kgsl_device *devp[KGSL_DEVICE_MAX];
72
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073 /* Global lilst of open processes */
74 struct list_head process_list;
75 /* Global list of pagetables */
76 struct list_head pagetable_list;
77 /* Spinlock for accessing the pagetable list */
78 spinlock_t ptlock;
79 /* Mutex for accessing the process list */
80 struct mutex process_mutex;
81
82 /* Mutex for protecting the device list */
83 struct mutex devlock;
84
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060085 void *ptpool;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070086
87 struct {
88 unsigned int vmalloc;
89 unsigned int vmalloc_max;
90 unsigned int coherent;
91 unsigned int coherent_max;
92 unsigned int mapped;
93 unsigned int mapped_max;
94 unsigned int histogram[16];
95 } stats;
96};
97
98extern struct kgsl_driver kgsl_driver;
99
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100struct kgsl_pagetable;
101struct kgsl_memdesc_ops;
102
103/* shared memory allocation */
104struct kgsl_memdesc {
105 struct kgsl_pagetable *pagetable;
106 void *hostptr;
107 unsigned int gpuaddr;
108 unsigned int physaddr;
109 unsigned int size;
110 unsigned int priv;
Jordan Croused17e9aa2011-10-12 16:57:48 -0600111 struct scatterlist *sg;
112 unsigned int sglen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700113 struct kgsl_memdesc_ops *ops;
114};
115
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600116/* List of different memory entry types */
117
118#define KGSL_MEM_ENTRY_KERNEL 0
119#define KGSL_MEM_ENTRY_PMEM 1
120#define KGSL_MEM_ENTRY_ASHMEM 2
121#define KGSL_MEM_ENTRY_USER 3
Jordan Crouse8eab35a2011-10-12 16:57:48 -0600122#define KGSL_MEM_ENTRY_ION 4
123#define KGSL_MEM_ENTRY_MAX 5
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600124
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600125/* List of flags */
126
127#define KGSL_MEM_ENTRY_FROZEN (1 << 0)
128
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700129struct kgsl_mem_entry {
130 struct kref refcount;
131 struct kgsl_memdesc memdesc;
132 int memtype;
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600133 int flags;
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600134 void *priv_data;
Jordan Crousec9559e42012-04-05 16:55:56 -0600135 struct rb_node node;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700136 uint32_t free_timestamp;
137 /* back pointer to private structure under whose context this
138 * allocation is made */
139 struct kgsl_process_private *priv;
140};
141
142#ifdef CONFIG_MSM_KGSL_MMU_PAGE_FAULT
143#define MMU_CONFIG 2
144#else
145#define MMU_CONFIG 1
146#endif
147
148void kgsl_mem_entry_destroy(struct kref *kref);
Jordan Crouse0fdf3a02012-03-16 14:53:41 -0600149
150struct kgsl_mem_entry *kgsl_get_mem_entry(unsigned int ptbase,
151 unsigned int gpuaddr, unsigned int size);
152
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700153struct kgsl_mem_entry *kgsl_sharedmem_find_region(
154 struct kgsl_process_private *private, unsigned int gpuaddr,
155 size_t size);
156
157extern const struct dev_pm_ops kgsl_pm_ops;
158
159struct early_suspend;
160int kgsl_suspend_driver(struct platform_device *pdev, pm_message_t state);
161int kgsl_resume_driver(struct platform_device *pdev);
162void kgsl_early_suspend_driver(struct early_suspend *h);
163void kgsl_late_resume_driver(struct early_suspend *h);
164
165#ifdef CONFIG_MSM_KGSL_DRM
166extern int kgsl_drm_init(struct platform_device *dev);
167extern void kgsl_drm_exit(void);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700168#else
169static inline int kgsl_drm_init(struct platform_device *dev)
170{
171 return 0;
172}
173
174static inline void kgsl_drm_exit(void)
175{
176}
177#endif
178
179static inline int kgsl_gpuaddr_in_memdesc(const struct kgsl_memdesc *memdesc,
Jeremy Gebben16e80fa2011-11-30 15:56:29 -0700180 unsigned int gpuaddr, unsigned int size)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700181{
Jeremy Gebben16e80fa2011-11-30 15:56:29 -0700182 if (gpuaddr >= memdesc->gpuaddr &&
183 ((gpuaddr + size) <= (memdesc->gpuaddr + memdesc->size))) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700184 return 1;
185 }
186 return 0;
187}
Jeremy Gebben16e80fa2011-11-30 15:56:29 -0700188static inline uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
189 unsigned int gpuaddr)
190{
191 if (memdesc->hostptr == NULL || memdesc->gpuaddr == 0 ||
192 (gpuaddr < memdesc->gpuaddr ||
193 gpuaddr >= memdesc->gpuaddr + memdesc->size))
194 return NULL;
195
196 return memdesc->hostptr + (gpuaddr - memdesc->gpuaddr);
197}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700198
Jordan Crousee6239dd2011-11-17 13:39:21 -0700199static inline int timestamp_cmp(unsigned int new, unsigned int old)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700200{
201 int ts_diff = new - old;
Jordan Crousee6239dd2011-11-17 13:39:21 -0700202
203 if (ts_diff == 0)
204 return 0;
205
Shubhraprakash Das3dd73752012-02-21 11:22:59 -0700206 return ((ts_diff > 0) || (ts_diff < -25000)) ? 1 : -1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700207}
208
209static inline void
210kgsl_mem_entry_get(struct kgsl_mem_entry *entry)
211{
212 kref_get(&entry->refcount);
213}
214
215static inline void
216kgsl_mem_entry_put(struct kgsl_mem_entry *entry)
217{
218 kref_put(&entry->refcount, kgsl_mem_entry_destroy);
219}
220
221#endif /* __KGSL_H */