blob: b5c24f082c394c780260513611cf088f3b2067b6 [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
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#define KGSL_PAGETABLE_SIZE \
44ALIGN(KGSL_PAGETABLE_ENTRIES(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE) * \
45KGSL_PAGETABLE_ENTRY_SIZE, PAGE_SIZE)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070046
47#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
48#define KGSL_PAGETABLE_COUNT (CONFIG_MSM_KGSL_PAGE_TABLE_COUNT)
49#else
50#define KGSL_PAGETABLE_COUNT 1
51#endif
52
53/* Casting using container_of() for structures that kgsl owns. */
54#define KGSL_CONTAINER_OF(ptr, type, member) \
55 container_of(ptr, type, member)
56
57/* A macro for memory statistics - add the new size to the stat and if
58 the statisic is greater then _max, set _max
59*/
60
61#define KGSL_STATS_ADD(_size, _stat, _max) \
62 do { _stat += (_size); if (_stat > _max) _max = _stat; } while (0)
63
64struct kgsl_device;
65
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070066struct kgsl_driver {
67 struct cdev cdev;
68 dev_t major;
69 struct class *class;
70 /* Virtual device for managing the core */
71 struct device virtdev;
72 /* Kobjects for storing pagetable and process statistics */
73 struct kobject *ptkobj;
74 struct kobject *prockobj;
75 struct kgsl_device *devp[KGSL_DEVICE_MAX];
76
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070077 /* Global lilst of open processes */
78 struct list_head process_list;
79 /* Global list of pagetables */
80 struct list_head pagetable_list;
81 /* Spinlock for accessing the pagetable list */
82 spinlock_t ptlock;
83 /* Mutex for accessing the process list */
84 struct mutex process_mutex;
85
86 /* Mutex for protecting the device list */
87 struct mutex devlock;
88
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060089 void *ptpool;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070090
91 struct {
92 unsigned int vmalloc;
93 unsigned int vmalloc_max;
94 unsigned int coherent;
95 unsigned int coherent_max;
96 unsigned int mapped;
97 unsigned int mapped_max;
98 unsigned int histogram[16];
99 } stats;
100};
101
102extern struct kgsl_driver kgsl_driver;
103
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700104struct kgsl_pagetable;
105struct kgsl_memdesc_ops;
106
107/* shared memory allocation */
108struct kgsl_memdesc {
109 struct kgsl_pagetable *pagetable;
110 void *hostptr;
111 unsigned int gpuaddr;
112 unsigned int physaddr;
113 unsigned int size;
114 unsigned int priv;
Jordan Croused17e9aa2011-10-12 16:57:48 -0600115 struct scatterlist *sg;
116 unsigned int sglen;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700117 struct kgsl_memdesc_ops *ops;
118};
119
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600120/* List of different memory entry types */
121
122#define KGSL_MEM_ENTRY_KERNEL 0
123#define KGSL_MEM_ENTRY_PMEM 1
124#define KGSL_MEM_ENTRY_ASHMEM 2
125#define KGSL_MEM_ENTRY_USER 3
Jordan Crouse8eab35a2011-10-12 16:57:48 -0600126#define KGSL_MEM_ENTRY_ION 4
127#define KGSL_MEM_ENTRY_MAX 5
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600128
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700129struct kgsl_mem_entry {
130 struct kref refcount;
131 struct kgsl_memdesc memdesc;
132 int memtype;
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600133 void *priv_data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134 struct list_head list;
135 uint32_t free_timestamp;
136 /* back pointer to private structure under whose context this
137 * allocation is made */
138 struct kgsl_process_private *priv;
139};
140
141#ifdef CONFIG_MSM_KGSL_MMU_PAGE_FAULT
142#define MMU_CONFIG 2
143#else
144#define MMU_CONFIG 1
145#endif
146
147void kgsl_mem_entry_destroy(struct kref *kref);
148uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
149 unsigned int gpuaddr, unsigned int *size);
150struct kgsl_mem_entry *kgsl_sharedmem_find_region(
151 struct kgsl_process_private *private, unsigned int gpuaddr,
152 size_t size);
153
154extern const struct dev_pm_ops kgsl_pm_ops;
155
156struct early_suspend;
157int kgsl_suspend_driver(struct platform_device *pdev, pm_message_t state);
158int kgsl_resume_driver(struct platform_device *pdev);
159void kgsl_early_suspend_driver(struct early_suspend *h);
160void kgsl_late_resume_driver(struct early_suspend *h);
161
162#ifdef CONFIG_MSM_KGSL_DRM
163extern int kgsl_drm_init(struct platform_device *dev);
164extern void kgsl_drm_exit(void);
165extern void kgsl_gpu_mem_flush(int op);
166#else
167static inline int kgsl_drm_init(struct platform_device *dev)
168{
169 return 0;
170}
171
172static inline void kgsl_drm_exit(void)
173{
174}
175#endif
176
177static inline int kgsl_gpuaddr_in_memdesc(const struct kgsl_memdesc *memdesc,
178 unsigned int gpuaddr)
179{
180 if (gpuaddr >= memdesc->gpuaddr && (gpuaddr + sizeof(unsigned int)) <=
181 (memdesc->gpuaddr + memdesc->size)) {
182 return 1;
183 }
184 return 0;
185}
186
187static inline bool timestamp_cmp(unsigned int new, unsigned int old)
188{
189 int ts_diff = new - old;
190 return (ts_diff >= 0) || (ts_diff < -20000);
191}
192
193static inline void
194kgsl_mem_entry_get(struct kgsl_mem_entry *entry)
195{
196 kref_get(&entry->refcount);
197}
198
199static inline void
200kgsl_mem_entry_put(struct kgsl_mem_entry *entry)
201{
202 kref_put(&entry->refcount, kgsl_mem_entry_destroy);
203}
204
205#endif /* __KGSL_H */