blob: 6ae925844967e3e95b8208b7d8d0565e39ca03ea [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2002,2007-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_DEVICE_H
14#define __KGSL_DEVICE_H
15
16#include <linux/idr.h>
17#include <linux/wakelock.h>
18#include <linux/pm_qos_params.h>
19#include <linux/earlysuspend.h>
20
21#include "kgsl.h"
22#include "kgsl_mmu.h"
23#include "kgsl_pwrctrl.h"
24#include "kgsl_log.h"
25#include "kgsl_pwrscale.h"
26
27#define KGSL_TIMEOUT_NONE 0
28#define KGSL_TIMEOUT_DEFAULT 0xFFFFFFFF
29
30#define FIRST_TIMEOUT (HZ / 2)
31
32
33/* KGSL device state is initialized to INIT when platform_probe *
34 * sucessfully initialized the device. Once a device has been opened *
35 * (started) it becomes active. NAP implies that only low latency *
36 * resources (for now clocks on some platforms) are off. SLEEP implies *
37 * that the KGSL module believes a device is idle (has been inactive *
38 * past its timer) and all system resources are released. SUSPEND is *
39 * requested by the kernel and will be enforced upon all open devices. */
40
41#define KGSL_STATE_NONE 0x00000000
42#define KGSL_STATE_INIT 0x00000001
43#define KGSL_STATE_ACTIVE 0x00000002
44#define KGSL_STATE_NAP 0x00000004
45#define KGSL_STATE_SLEEP 0x00000008
46#define KGSL_STATE_SUSPEND 0x00000010
47#define KGSL_STATE_HUNG 0x00000020
48#define KGSL_STATE_DUMP_AND_RECOVER 0x00000040
Suman Tatiraju24569022011-10-27 11:11:12 -070049#define KGSL_STATE_SLUMBER 0x00000080
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070050
51#define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK 0x1000000
52
53#define KGSL_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
54
55struct kgsl_device;
56struct platform_device;
57struct kgsl_device_private;
58struct kgsl_context;
59struct kgsl_power_stats;
60
61struct kgsl_functable {
62 /* Mandatory functions - these functions must be implemented
63 by the client device. The driver will not check for a NULL
64 pointer before calling the hook.
65 */
66 void (*regread) (struct kgsl_device *device,
67 unsigned int offsetwords, unsigned int *value);
68 void (*regwrite) (struct kgsl_device *device,
69 unsigned int offsetwords, unsigned int value);
70 int (*idle) (struct kgsl_device *device, unsigned int timeout);
71 unsigned int (*isidle) (struct kgsl_device *device);
72 int (*suspend_context) (struct kgsl_device *device);
73 int (*start) (struct kgsl_device *device, unsigned int init_ram);
74 int (*stop) (struct kgsl_device *device);
75 int (*getproperty) (struct kgsl_device *device,
76 enum kgsl_property_type type, void *value,
77 unsigned int sizebytes);
78 int (*waittimestamp) (struct kgsl_device *device,
79 unsigned int timestamp, unsigned int msecs);
80 unsigned int (*readtimestamp) (struct kgsl_device *device,
81 enum kgsl_timestamp_type type);
82 int (*issueibcmds) (struct kgsl_device_private *dev_priv,
83 struct kgsl_context *context, struct kgsl_ibdesc *ibdesc,
84 unsigned int sizedwords, uint32_t *timestamp,
85 unsigned int flags);
86 int (*setup_pt)(struct kgsl_device *device,
87 struct kgsl_pagetable *pagetable);
Jordan Crouse9f739212011-07-28 08:37:57 -060088 void (*cleanup_pt)(struct kgsl_device *device,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070089 struct kgsl_pagetable *pagetable);
90 void (*power_stats)(struct kgsl_device *device,
91 struct kgsl_power_stats *stats);
92 void (*irqctrl)(struct kgsl_device *device, int state);
93 /* Optional functions - these functions are not mandatory. The
94 driver will check that the function pointer is not NULL before
95 calling the hook */
96 void (*setstate) (struct kgsl_device *device, uint32_t flags);
97 int (*drawctxt_create) (struct kgsl_device *device,
98 struct kgsl_pagetable *pagetable, struct kgsl_context *context,
99 uint32_t flags);
100 void (*drawctxt_destroy) (struct kgsl_device *device,
101 struct kgsl_context *context);
102 long (*ioctl) (struct kgsl_device_private *dev_priv,
103 unsigned int cmd, void *data);
104};
105
106struct kgsl_memregion {
107 unsigned char *mmio_virt_base;
108 unsigned int mmio_phys_base;
109 uint32_t gpu_base;
110 unsigned int sizebytes;
111};
112
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600113/* MH register values */
114struct kgsl_mh {
115 unsigned int mharb;
116 unsigned int mh_intf_cfg1;
117 unsigned int mh_intf_cfg2;
118 uint32_t mpu_base;
119 int mpu_range;
120};
121
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700122struct kgsl_device {
123 struct device *dev;
124 const char *name;
125 unsigned int ver_major;
126 unsigned int ver_minor;
127 uint32_t flags;
128 enum kgsl_deviceid id;
129 struct kgsl_memregion regspace;
130 struct kgsl_memdesc memstore;
131 const char *iomemname;
132
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600133 struct kgsl_mh mh;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134 struct kgsl_mmu mmu;
135 struct completion hwaccess_gate;
136 const struct kgsl_functable *ftbl;
137 struct work_struct idle_check_ws;
138 struct timer_list idle_timer;
139 struct kgsl_pwrctrl pwrctrl;
140 int open_count;
141
142 struct atomic_notifier_head ts_notifier_list;
143 struct mutex mutex;
144 uint32_t state;
145 uint32_t requested_state;
146
147 struct list_head memqueue;
148 unsigned int active_cnt;
149 struct completion suspend_gate;
150
151 wait_queue_head_t wait_queue;
152 struct workqueue_struct *work_queue;
153 struct device *parentdev;
154 struct completion recovery_gate;
155 struct dentry *d_debugfs;
156 struct idr context_idr;
157 struct early_suspend display_off;
158
159 /* Logging levels */
160 int cmd_log;
161 int ctxt_log;
162 int drv_log;
163 int mem_log;
164 int pwr_log;
165 struct wake_lock idle_wakelock;
166 struct kgsl_pwrscale pwrscale;
167 struct kobject pwrscale_kobj;
168 struct pm_qos_request_list pm_qos_req_dma;
Jordan Crouse1bf80aa2011-10-12 16:57:47 -0600169 struct work_struct ts_expired_ws;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700170};
171
172struct kgsl_context {
173 uint32_t id;
174
175 /* Pointer to the owning device instance */
176 struct kgsl_device_private *dev_priv;
177
178 /* Pointer to the device specific context information */
179 void *devctxt;
180};
181
182struct kgsl_process_private {
183 unsigned int refcnt;
184 pid_t pid;
185 spinlock_t mem_lock;
186 struct list_head mem_list;
187 struct kgsl_pagetable *pagetable;
188 struct list_head list;
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600189 struct kobject kobj;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190
191 struct {
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600192 unsigned int cur;
193 unsigned int max;
194 } stats[KGSL_MEM_ENTRY_MAX];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700195};
196
197struct kgsl_device_private {
198 struct kgsl_device *device;
199 struct kgsl_process_private *process_priv;
200};
201
202struct kgsl_power_stats {
203 s64 total_time;
204 s64 busy_time;
205};
206
207struct kgsl_device *kgsl_get_device(int dev_idx);
208
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600209static inline void kgsl_process_add_stats(struct kgsl_process_private *priv,
210 unsigned int type, size_t size)
211{
212 priv->stats[type].cur += size;
213 if (priv->stats[type].max < priv->stats[type].cur)
214 priv->stats[type].max = priv->stats[type].cur;
215}
216
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700217static inline void kgsl_regread(struct kgsl_device *device,
218 unsigned int offsetwords,
219 unsigned int *value)
220{
221 device->ftbl->regread(device, offsetwords, value);
222}
223
224static inline void kgsl_regwrite(struct kgsl_device *device,
225 unsigned int offsetwords,
226 unsigned int value)
227{
228 device->ftbl->regwrite(device, offsetwords, value);
229}
230
231static inline int kgsl_idle(struct kgsl_device *device, unsigned int timeout)
232{
233 return device->ftbl->idle(device, timeout);
234}
235
236static inline int kgsl_create_device_sysfs_files(struct device *root,
237 const struct device_attribute **list)
238{
239 int ret = 0, i;
240 for (i = 0; list[i] != NULL; i++)
241 ret |= device_create_file(root, list[i]);
242 return ret;
243}
244
245static inline void kgsl_remove_device_sysfs_files(struct device *root,
246 const struct device_attribute **list)
247{
248 int i;
249 for (i = 0; list[i] != NULL; i++)
250 device_remove_file(root, list[i]);
251}
252
253static inline struct kgsl_mmu *
254kgsl_get_mmu(struct kgsl_device *device)
255{
256 return (struct kgsl_mmu *) (device ? &device->mmu : NULL);
257}
258
259static inline struct kgsl_device *kgsl_device_from_dev(struct device *dev)
260{
261 int i;
262
263 for (i = 0; i < KGSL_DEVICE_MAX; i++) {
264 if (kgsl_driver.devp[i] && kgsl_driver.devp[i]->dev == dev)
265 return kgsl_driver.devp[i];
266 }
267
268 return NULL;
269}
270
271static inline int kgsl_create_device_workqueue(struct kgsl_device *device)
272{
273 device->work_queue = create_workqueue(device->name);
274 if (!device->work_queue) {
275 KGSL_DRV_ERR(device, "create_workqueue(%s) failed\n",
276 device->name);
277 return -EINVAL;
278 }
279 return 0;
280}
281
282static inline struct kgsl_context *
283kgsl_find_context(struct kgsl_device_private *dev_priv, uint32_t id)
284{
285 struct kgsl_context *ctxt =
286 idr_find(&dev_priv->device->context_idr, id);
287
288 /* Make sure that the context belongs to the current instance so
289 that other processes can't guess context IDs and mess things up */
290
291 return (ctxt && ctxt->dev_priv == dev_priv) ? ctxt : NULL;
292}
293
294int kgsl_check_timestamp(struct kgsl_device *device, unsigned int timestamp);
295
296int kgsl_register_ts_notifier(struct kgsl_device *device,
297 struct notifier_block *nb);
298
299int kgsl_unregister_ts_notifier(struct kgsl_device *device,
300 struct notifier_block *nb);
301
302int kgsl_device_platform_probe(struct kgsl_device *device,
303 irqreturn_t (*dev_isr) (int, void*));
304void kgsl_device_platform_remove(struct kgsl_device *device);
305
306#endif /* __KGSL_DEVICE_H */