blob: d464cf1f2aca0400e6b1305b0215b6360226a089 [file] [log] [blame]
Jordan Crouse156cfbc2012-01-24 09:32:04 -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_DEVICE_H
14#define __KGSL_DEVICE_H
15
16#include <linux/idr.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070017#include <linux/pm_qos.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070018#include <linux/earlysuspend.h>
19
20#include "kgsl.h"
21#include "kgsl_mmu.h"
22#include "kgsl_pwrctrl.h"
23#include "kgsl_log.h"
24#include "kgsl_pwrscale.h"
25
26#define KGSL_TIMEOUT_NONE 0
27#define KGSL_TIMEOUT_DEFAULT 0xFFFFFFFF
28
29#define FIRST_TIMEOUT (HZ / 2)
30
31
32/* KGSL device state is initialized to INIT when platform_probe *
33 * sucessfully initialized the device. Once a device has been opened *
34 * (started) it becomes active. NAP implies that only low latency *
35 * resources (for now clocks on some platforms) are off. SLEEP implies *
36 * that the KGSL module believes a device is idle (has been inactive *
37 * past its timer) and all system resources are released. SUSPEND is *
38 * requested by the kernel and will be enforced upon all open devices. */
39
40#define KGSL_STATE_NONE 0x00000000
41#define KGSL_STATE_INIT 0x00000001
42#define KGSL_STATE_ACTIVE 0x00000002
43#define KGSL_STATE_NAP 0x00000004
44#define KGSL_STATE_SLEEP 0x00000008
45#define KGSL_STATE_SUSPEND 0x00000010
46#define KGSL_STATE_HUNG 0x00000020
47#define KGSL_STATE_DUMP_AND_RECOVER 0x00000040
Suman Tatiraju24569022011-10-27 11:11:12 -070048#define KGSL_STATE_SLUMBER 0x00000080
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070049
50#define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK 0x1000000
51
52#define KGSL_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
53
54struct kgsl_device;
55struct platform_device;
56struct kgsl_device_private;
57struct kgsl_context;
58struct kgsl_power_stats;
59
60struct kgsl_functable {
61 /* Mandatory functions - these functions must be implemented
62 by the client device. The driver will not check for a NULL
63 pointer before calling the hook.
64 */
65 void (*regread) (struct kgsl_device *device,
66 unsigned int offsetwords, unsigned int *value);
67 void (*regwrite) (struct kgsl_device *device,
68 unsigned int offsetwords, unsigned int value);
69 int (*idle) (struct kgsl_device *device, unsigned int timeout);
70 unsigned int (*isidle) (struct kgsl_device *device);
71 int (*suspend_context) (struct kgsl_device *device);
72 int (*start) (struct kgsl_device *device, unsigned int init_ram);
73 int (*stop) (struct kgsl_device *device);
74 int (*getproperty) (struct kgsl_device *device,
75 enum kgsl_property_type type, void *value,
76 unsigned int sizebytes);
77 int (*waittimestamp) (struct kgsl_device *device,
Carter Cooper7e7f02e2012-02-15 09:36:31 -070078 struct kgsl_context *context, unsigned int timestamp,
79 unsigned int msecs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070080 unsigned int (*readtimestamp) (struct kgsl_device *device,
Carter Cooper7e7f02e2012-02-15 09:36:31 -070081 struct kgsl_context *context, enum kgsl_timestamp_type type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070082 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);
Jordan Croused6535882012-06-20 08:22:16 -060093 unsigned int (*gpuid)(struct kgsl_device *device, unsigned int *chipid);
Jordan Crouse156cfbc2012-01-24 09:32:04 -070094 void * (*snapshot)(struct kgsl_device *device, void *snapshot,
95 int *remain, int hang);
Jordan Crouseb368e9b2012-04-27 14:01:59 -060096 irqreturn_t (*irq_handler)(struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070097 /* Optional functions - these functions are not mandatory. The
98 driver will check that the function pointer is not NULL before
99 calling the hook */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -0600100 void (*setstate) (struct kgsl_device *device, unsigned int context_id,
101 uint32_t flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700102 int (*drawctxt_create) (struct kgsl_device *device,
103 struct kgsl_pagetable *pagetable, struct kgsl_context *context,
104 uint32_t flags);
105 void (*drawctxt_destroy) (struct kgsl_device *device,
106 struct kgsl_context *context);
107 long (*ioctl) (struct kgsl_device_private *dev_priv,
108 unsigned int cmd, void *data);
Jordan Crouseed7dd7f2012-03-29 13:16:02 -0600109 int (*setproperty) (struct kgsl_device *device,
110 enum kgsl_property_type type, void *value,
111 unsigned int sizebytes);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700112};
113
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600114/* MH register values */
115struct kgsl_mh {
116 unsigned int mharb;
117 unsigned int mh_intf_cfg1;
118 unsigned int mh_intf_cfg2;
119 uint32_t mpu_base;
120 int mpu_range;
121};
122
Jordan Croused4bc9d22011-11-17 13:39:21 -0700123struct kgsl_event {
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700124 struct kgsl_context *context;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700125 uint32_t timestamp;
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700126 void (*func)(struct kgsl_device *, void *, u32, u32);
Jordan Croused4bc9d22011-11-17 13:39:21 -0700127 void *priv;
128 struct list_head list;
Shubhraprakash Dascb068072012-06-07 17:52:41 -0600129 void *owner;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700130};
131
132
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133struct kgsl_device {
134 struct device *dev;
135 const char *name;
136 unsigned int ver_major;
137 unsigned int ver_minor;
138 uint32_t flags;
139 enum kgsl_deviceid id;
Jordan Crouse7501d452012-04-19 08:58:44 -0600140 unsigned long reg_phys;
141 void *reg_virt;
142 unsigned int reg_len;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700143 struct kgsl_memdesc memstore;
144 const char *iomemname;
145
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600146 struct kgsl_mh mh;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700147 struct kgsl_mmu mmu;
148 struct completion hwaccess_gate;
149 const struct kgsl_functable *ftbl;
150 struct work_struct idle_check_ws;
151 struct timer_list idle_timer;
152 struct kgsl_pwrctrl pwrctrl;
153 int open_count;
154
155 struct atomic_notifier_head ts_notifier_list;
156 struct mutex mutex;
157 uint32_t state;
158 uint32_t requested_state;
159
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700160 unsigned int last_expired_ctxt_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700161 unsigned int active_cnt;
162 struct completion suspend_gate;
163
164 wait_queue_head_t wait_queue;
165 struct workqueue_struct *work_queue;
166 struct device *parentdev;
167 struct completion recovery_gate;
168 struct dentry *d_debugfs;
169 struct idr context_idr;
170 struct early_suspend display_off;
171
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700172 void *snapshot; /* Pointer to the snapshot memory region */
173 int snapshot_maxsize; /* Max size of the snapshot region */
174 int snapshot_size; /* Current size of the snapshot region */
175 u32 snapshot_timestamp; /* Timestamp of the last valid snapshot */
176 int snapshot_frozen; /* 1 if the snapshot output is frozen until
177 it gets read by the user. This avoids
178 losing the output on multiple hangs */
179 struct kobject snapshot_kobj;
180
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600181 /*
182 * List of GPU buffers that have been frozen in memory until they can be
183 * dumped
184 */
185 struct list_head snapshot_obj_list;
186
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700187 /* Logging levels */
188 int cmd_log;
189 int ctxt_log;
190 int drv_log;
191 int mem_log;
192 int pwr_log;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700193 struct kgsl_pwrscale pwrscale;
194 struct kobject pwrscale_kobj;
Steve Mucklef132c6c2012-06-06 18:30:57 -0700195 struct pm_qos_request pm_qos_req_dma;
Jordan Crouse1bf80aa2011-10-12 16:57:47 -0600196 struct work_struct ts_expired_ws;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700197 struct list_head events;
Lucille Sylvester808eca22011-11-03 10:26:29 -0700198 s64 on_time;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700199};
200
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700201void kgsl_timestamp_expired(struct work_struct *work);
202
203#define KGSL_DEVICE_COMMON_INIT(_dev) \
204 .hwaccess_gate = COMPLETION_INITIALIZER((_dev).hwaccess_gate),\
205 .suspend_gate = COMPLETION_INITIALIZER((_dev).suspend_gate),\
206 .recovery_gate = COMPLETION_INITIALIZER((_dev).recovery_gate),\
207 .ts_notifier_list = ATOMIC_NOTIFIER_INIT((_dev).ts_notifier_list),\
208 .idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
209 kgsl_idle_check),\
210 .ts_expired_ws = __WORK_INITIALIZER((_dev).ts_expired_ws,\
211 kgsl_timestamp_expired),\
212 .context_idr = IDR_INIT((_dev).context_idr),\
213 .events = LIST_HEAD_INIT((_dev).events),\
214 .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\
215 .mutex = __MUTEX_INITIALIZER((_dev).mutex),\
216 .state = KGSL_STATE_INIT,\
217 .ver_major = DRIVER_VERSION_MAJOR,\
218 .ver_minor = DRIVER_VERSION_MINOR,\
219 .last_expired_ctxt_id = KGSL_CONTEXT_INVALID
220
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700221struct kgsl_context {
Jeremy Gebben9ad86922012-05-08 15:33:23 -0600222 struct kref refcount;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700223 uint32_t id;
224
225 /* Pointer to the owning device instance */
226 struct kgsl_device_private *dev_priv;
227
228 /* Pointer to the device specific context information */
229 void *devctxt;
Shubhraprakash Das2dfe5dd2012-02-10 13:49:53 -0700230 /*
231 * Status indicating whether a gpu reset occurred and whether this
232 * context was responsible for causing it
233 */
234 unsigned int reset_status;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700235};
236
237struct kgsl_process_private {
238 unsigned int refcnt;
239 pid_t pid;
240 spinlock_t mem_lock;
Jordan Crousec9559e42012-04-05 16:55:56 -0600241 struct rb_root mem_rb;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700242 struct kgsl_pagetable *pagetable;
243 struct list_head list;
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600244 struct kobject kobj;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700245
246 struct {
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600247 unsigned int cur;
248 unsigned int max;
249 } stats[KGSL_MEM_ENTRY_MAX];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700250};
251
252struct kgsl_device_private {
253 struct kgsl_device *device;
254 struct kgsl_process_private *process_priv;
255};
256
257struct kgsl_power_stats {
258 s64 total_time;
259 s64 busy_time;
260};
261
262struct kgsl_device *kgsl_get_device(int dev_idx);
263
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600264static inline void kgsl_process_add_stats(struct kgsl_process_private *priv,
265 unsigned int type, size_t size)
266{
267 priv->stats[type].cur += size;
268 if (priv->stats[type].max < priv->stats[type].cur)
269 priv->stats[type].max = priv->stats[type].cur;
270}
271
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700272static inline void kgsl_regread(struct kgsl_device *device,
273 unsigned int offsetwords,
274 unsigned int *value)
275{
276 device->ftbl->regread(device, offsetwords, value);
277}
278
279static inline void kgsl_regwrite(struct kgsl_device *device,
280 unsigned int offsetwords,
281 unsigned int value)
282{
283 device->ftbl->regwrite(device, offsetwords, value);
284}
285
286static inline int kgsl_idle(struct kgsl_device *device, unsigned int timeout)
287{
288 return device->ftbl->idle(device, timeout);
289}
290
Jordan Croused6535882012-06-20 08:22:16 -0600291static inline unsigned int kgsl_gpuid(struct kgsl_device *device,
292 unsigned int *chipid)
Jordan Crousea0758f22011-12-07 11:19:22 -0700293{
Jordan Croused6535882012-06-20 08:22:16 -0600294 return device->ftbl->gpuid(device, chipid);
Jordan Crousea0758f22011-12-07 11:19:22 -0700295}
296
Jeremy Gebben731dac52012-05-10 11:13:42 -0600297static inline unsigned int kgsl_readtimestamp(struct kgsl_device *device,
298 struct kgsl_context *context,
299 enum kgsl_timestamp_type type)
300{
301 return device->ftbl->readtimestamp(device, context, type);
302}
303
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700304static inline int kgsl_create_device_sysfs_files(struct device *root,
305 const struct device_attribute **list)
306{
307 int ret = 0, i;
308 for (i = 0; list[i] != NULL; i++)
309 ret |= device_create_file(root, list[i]);
310 return ret;
311}
312
313static inline void kgsl_remove_device_sysfs_files(struct device *root,
314 const struct device_attribute **list)
315{
316 int i;
317 for (i = 0; list[i] != NULL; i++)
318 device_remove_file(root, list[i]);
319}
320
321static inline struct kgsl_mmu *
322kgsl_get_mmu(struct kgsl_device *device)
323{
324 return (struct kgsl_mmu *) (device ? &device->mmu : NULL);
325}
326
327static inline struct kgsl_device *kgsl_device_from_dev(struct device *dev)
328{
329 int i;
330
331 for (i = 0; i < KGSL_DEVICE_MAX; i++) {
332 if (kgsl_driver.devp[i] && kgsl_driver.devp[i]->dev == dev)
333 return kgsl_driver.devp[i];
334 }
335
336 return NULL;
337}
338
339static inline int kgsl_create_device_workqueue(struct kgsl_device *device)
340{
Steve Muckle3e042df2011-11-18 11:25:04 -0800341 device->work_queue = create_singlethread_workqueue(device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700342 if (!device->work_queue) {
Steve Muckle3e042df2011-11-18 11:25:04 -0800343 KGSL_DRV_ERR(device,
344 "create_singlethread_workqueue(%s) failed\n",
345 device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700346 return -EINVAL;
347 }
348 return 0;
349}
350
351static inline struct kgsl_context *
352kgsl_find_context(struct kgsl_device_private *dev_priv, uint32_t id)
353{
354 struct kgsl_context *ctxt =
355 idr_find(&dev_priv->device->context_idr, id);
356
357 /* Make sure that the context belongs to the current instance so
358 that other processes can't guess context IDs and mess things up */
359
360 return (ctxt && ctxt->dev_priv == dev_priv) ? ctxt : NULL;
361}
362
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700363int kgsl_check_timestamp(struct kgsl_device *device,
364 struct kgsl_context *context, unsigned int timestamp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700365
366int kgsl_register_ts_notifier(struct kgsl_device *device,
367 struct notifier_block *nb);
368
369int kgsl_unregister_ts_notifier(struct kgsl_device *device,
370 struct notifier_block *nb);
371
Jordan Crouseb368e9b2012-04-27 14:01:59 -0600372int kgsl_device_platform_probe(struct kgsl_device *device);
373
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700374void kgsl_device_platform_remove(struct kgsl_device *device);
375
Jeremy Gebbenb50f3312011-12-16 08:58:33 -0700376const char *kgsl_pwrstate_to_str(unsigned int state);
377
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700378int kgsl_device_snapshot_init(struct kgsl_device *device);
379int kgsl_device_snapshot(struct kgsl_device *device, int hang);
380void kgsl_device_snapshot_close(struct kgsl_device *device);
381
Jordan Croused8aa4be2012-04-18 09:31:07 -0600382static inline struct kgsl_device_platform_data *
383kgsl_device_get_drvdata(struct kgsl_device *dev)
384{
385 struct platform_device *pdev =
386 container_of(dev->parentdev, struct platform_device, dev);
387
388 return pdev->dev.platform_data;
389}
390
Jeremy Gebben9ad86922012-05-08 15:33:23 -0600391/**
392 * kgsl_context_get - Get context reference count
393 * @context
394 *
395 * Asynchronous code that holds a pointer to a context
396 * must hold a reference count on it. The kgsl device
397 * mutex must be held while the context reference count
398 * is changed.
399 */
400static inline void
401kgsl_context_get(struct kgsl_context *context)
402{
403 kref_get(&context->refcount);
404}
405
406void kgsl_context_destroy(struct kref *kref);
407
408/**
409 * kgsl_context_put - Release context reference count
410 * @context
411 *
412 */
413static inline void
414kgsl_context_put(struct kgsl_context *context)
415{
416 kref_put(&context->refcount, kgsl_context_destroy);
417}
418
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700419#endif /* __KGSL_DEVICE_H */