blob: 57c3451d558a311168e03e0390207647ea38b2cc [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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"
Jeff Boodyfe6c39c2012-08-09 13:54:50 -060025#include <linux/sync.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070026
27#define KGSL_TIMEOUT_NONE 0
28#define KGSL_TIMEOUT_DEFAULT 0xFFFFFFFF
Tarun Karra6e750d72013-01-04 10:28:40 -080029#define KGSL_TIMEOUT_PART 50 /* 50 msec */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070030
31#define FIRST_TIMEOUT (HZ / 2)
32
33
34/* KGSL device state is initialized to INIT when platform_probe *
35 * sucessfully initialized the device. Once a device has been opened *
36 * (started) it becomes active. NAP implies that only low latency *
37 * resources (for now clocks on some platforms) are off. SLEEP implies *
38 * that the KGSL module believes a device is idle (has been inactive *
39 * past its timer) and all system resources are released. SUSPEND is *
40 * requested by the kernel and will be enforced upon all open devices. */
41
42#define KGSL_STATE_NONE 0x00000000
43#define KGSL_STATE_INIT 0x00000001
44#define KGSL_STATE_ACTIVE 0x00000002
45#define KGSL_STATE_NAP 0x00000004
46#define KGSL_STATE_SLEEP 0x00000008
47#define KGSL_STATE_SUSPEND 0x00000010
48#define KGSL_STATE_HUNG 0x00000020
49#define KGSL_STATE_DUMP_AND_RECOVER 0x00000040
Suman Tatiraju24569022011-10-27 11:11:12 -070050#define KGSL_STATE_SLUMBER 0x00000080
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070051
52#define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK 0x1000000
53
54#define KGSL_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
55
56struct kgsl_device;
57struct platform_device;
58struct kgsl_device_private;
59struct kgsl_context;
60struct kgsl_power_stats;
Jordan Crouse313faf62012-11-20 15:12:28 -070061struct kgsl_event;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062
63struct kgsl_functable {
64 /* Mandatory functions - these functions must be implemented
65 by the client device. The driver will not check for a NULL
66 pointer before calling the hook.
67 */
68 void (*regread) (struct kgsl_device *device,
69 unsigned int offsetwords, unsigned int *value);
70 void (*regwrite) (struct kgsl_device *device,
71 unsigned int offsetwords, unsigned int value);
Jordan Crousea29a2e02012-08-14 09:09:23 -060072 int (*idle) (struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073 unsigned int (*isidle) (struct kgsl_device *device);
74 int (*suspend_context) (struct kgsl_device *device);
75 int (*start) (struct kgsl_device *device, unsigned int init_ram);
76 int (*stop) (struct kgsl_device *device);
77 int (*getproperty) (struct kgsl_device *device,
78 enum kgsl_property_type type, void *value,
79 unsigned int sizebytes);
80 int (*waittimestamp) (struct kgsl_device *device,
Carter Cooper7e7f02e2012-02-15 09:36:31 -070081 struct kgsl_context *context, unsigned int timestamp,
82 unsigned int msecs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070083 unsigned int (*readtimestamp) (struct kgsl_device *device,
Carter Cooper7e7f02e2012-02-15 09:36:31 -070084 struct kgsl_context *context, enum kgsl_timestamp_type type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070085 int (*issueibcmds) (struct kgsl_device_private *dev_priv,
86 struct kgsl_context *context, struct kgsl_ibdesc *ibdesc,
87 unsigned int sizedwords, uint32_t *timestamp,
88 unsigned int flags);
89 int (*setup_pt)(struct kgsl_device *device,
90 struct kgsl_pagetable *pagetable);
Jordan Crouse9f739212011-07-28 08:37:57 -060091 void (*cleanup_pt)(struct kgsl_device *device,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070092 struct kgsl_pagetable *pagetable);
93 void (*power_stats)(struct kgsl_device *device,
94 struct kgsl_power_stats *stats);
95 void (*irqctrl)(struct kgsl_device *device, int state);
Jordan Croused6535882012-06-20 08:22:16 -060096 unsigned int (*gpuid)(struct kgsl_device *device, unsigned int *chipid);
Jordan Crouse156cfbc2012-01-24 09:32:04 -070097 void * (*snapshot)(struct kgsl_device *device, void *snapshot,
98 int *remain, int hang);
Jordan Crouseb368e9b2012-04-27 14:01:59 -060099 irqreturn_t (*irq_handler)(struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100 /* Optional functions - these functions are not mandatory. The
101 driver will check that the function pointer is not NULL before
102 calling the hook */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -0600103 void (*setstate) (struct kgsl_device *device, unsigned int context_id,
104 uint32_t flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700105 int (*drawctxt_create) (struct kgsl_device *device,
106 struct kgsl_pagetable *pagetable, struct kgsl_context *context,
107 uint32_t flags);
108 void (*drawctxt_destroy) (struct kgsl_device *device,
109 struct kgsl_context *context);
110 long (*ioctl) (struct kgsl_device_private *dev_priv,
111 unsigned int cmd, void *data);
Jordan Crouseed7dd7f2012-03-29 13:16:02 -0600112 int (*setproperty) (struct kgsl_device *device,
113 enum kgsl_property_type type, void *value,
114 unsigned int sizebytes);
Harsh Vardhan Dwivedi715fb832012-05-18 00:24:18 -0600115 int (*postmortem_dump) (struct kgsl_device *device, int manual);
Jordan Crouseed8c2dd2013-01-28 16:58:45 -0700116 int (*next_event)(struct kgsl_device *device,
Jordan Crouse313faf62012-11-20 15:12:28 -0700117 struct kgsl_event *event);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700118};
119
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600120/* MH register values */
121struct kgsl_mh {
122 unsigned int mharb;
123 unsigned int mh_intf_cfg1;
124 unsigned int mh_intf_cfg2;
125 uint32_t mpu_base;
126 int mpu_range;
127};
128
Jordan Croused4bc9d22011-11-17 13:39:21 -0700129struct kgsl_event {
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700130 struct kgsl_context *context;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700131 uint32_t timestamp;
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700132 void (*func)(struct kgsl_device *, void *, u32, u32);
Jordan Croused4bc9d22011-11-17 13:39:21 -0700133 void *priv;
134 struct list_head list;
Shubhraprakash Dascb068072012-06-07 17:52:41 -0600135 void *owner;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700136};
137
138
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700139struct kgsl_device {
140 struct device *dev;
141 const char *name;
142 unsigned int ver_major;
143 unsigned int ver_minor;
144 uint32_t flags;
145 enum kgsl_deviceid id;
Jordan Crouse7501d452012-04-19 08:58:44 -0600146 unsigned long reg_phys;
147 void *reg_virt;
148 unsigned int reg_len;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700149 struct kgsl_memdesc memstore;
150 const char *iomemname;
151
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600152 struct kgsl_mh mh;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700153 struct kgsl_mmu mmu;
154 struct completion hwaccess_gate;
155 const struct kgsl_functable *ftbl;
156 struct work_struct idle_check_ws;
157 struct timer_list idle_timer;
158 struct kgsl_pwrctrl pwrctrl;
159 int open_count;
160
161 struct atomic_notifier_head ts_notifier_list;
162 struct mutex mutex;
163 uint32_t state;
164 uint32_t requested_state;
165
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700166 unsigned int active_cnt;
167 struct completion suspend_gate;
168
169 wait_queue_head_t wait_queue;
170 struct workqueue_struct *work_queue;
171 struct device *parentdev;
172 struct completion recovery_gate;
173 struct dentry *d_debugfs;
174 struct idr context_idr;
175 struct early_suspend display_off;
176
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700177 void *snapshot; /* Pointer to the snapshot memory region */
178 int snapshot_maxsize; /* Max size of the snapshot region */
179 int snapshot_size; /* Current size of the snapshot region */
180 u32 snapshot_timestamp; /* Timestamp of the last valid snapshot */
181 int snapshot_frozen; /* 1 if the snapshot output is frozen until
182 it gets read by the user. This avoids
183 losing the output on multiple hangs */
184 struct kobject snapshot_kobj;
185
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600186 /*
187 * List of GPU buffers that have been frozen in memory until they can be
188 * dumped
189 */
190 struct list_head snapshot_obj_list;
191
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700192 /* Logging levels */
193 int cmd_log;
194 int ctxt_log;
195 int drv_log;
196 int mem_log;
197 int pwr_log;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700198 struct kgsl_pwrscale pwrscale;
199 struct kobject pwrscale_kobj;
Steve Mucklef132c6c2012-06-06 18:30:57 -0700200 struct pm_qos_request pm_qos_req_dma;
Jordan Crouse1bf80aa2011-10-12 16:57:47 -0600201 struct work_struct ts_expired_ws;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700202 struct list_head events;
Jordan Crouseef3456c2013-01-04 16:46:51 -0700203 struct list_head events_pending_list;
Lucille Sylvester808eca22011-11-03 10:26:29 -0700204 s64 on_time;
Harsh Vardhan Dwivedi715fb832012-05-18 00:24:18 -0600205
206 /* Postmortem Control switches */
207 int pm_regs_enabled;
208 int pm_ib_enabled;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700209};
210
Jordan Crouseef3456c2013-01-04 16:46:51 -0700211void kgsl_process_events(struct work_struct *work);
212void kgsl_check_fences(struct work_struct *work);
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700213
214#define KGSL_DEVICE_COMMON_INIT(_dev) \
215 .hwaccess_gate = COMPLETION_INITIALIZER((_dev).hwaccess_gate),\
216 .suspend_gate = COMPLETION_INITIALIZER((_dev).suspend_gate),\
217 .recovery_gate = COMPLETION_INITIALIZER((_dev).recovery_gate),\
218 .ts_notifier_list = ATOMIC_NOTIFIER_INIT((_dev).ts_notifier_list),\
219 .idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
220 kgsl_idle_check),\
221 .ts_expired_ws = __WORK_INITIALIZER((_dev).ts_expired_ws,\
Jordan Crouseef3456c2013-01-04 16:46:51 -0700222 kgsl_process_events),\
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700223 .context_idr = IDR_INIT((_dev).context_idr),\
224 .events = LIST_HEAD_INIT((_dev).events),\
Jordan Crouseef3456c2013-01-04 16:46:51 -0700225 .events_pending_list = LIST_HEAD_INIT((_dev).events_pending_list), \
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700226 .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\
227 .mutex = __MUTEX_INITIALIZER((_dev).mutex),\
228 .state = KGSL_STATE_INIT,\
229 .ver_major = DRIVER_VERSION_MAJOR,\
Carter Cooper12481fd2012-06-05 11:18:34 -0600230 .ver_minor = DRIVER_VERSION_MINOR
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700231
Jordan Crouseef3456c2013-01-04 16:46:51 -0700232
233/**
234 * struct kgsl_context - Master structure for a KGSL context object
235 * @refcount - kref object for reference counting the context
236 * @id - integer identifier for the context
237 * @dev_priv - pointer to the owning device instance
238 * @devctxt - pointer to the device specific context information
239 * @reset_status - status indication whether a gpu reset occured and whether
240 * this context was responsible for causing it
241 * @wait_on_invalid_ts - flag indicating if this context has tried to wait on a
242 * bad timestamp
243 * @timeline - sync timeline used to create fences that can be signaled when a
244 * sync_pt timestamp expires
245 * @events - list head of pending events for this context
246 * @events_list - list node for the list of all contexts that have pending events
247 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700248struct kgsl_context {
Jeremy Gebben9ad86922012-05-08 15:33:23 -0600249 struct kref refcount;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700250 uint32_t id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700251 struct kgsl_device_private *dev_priv;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700252 void *devctxt;
Shubhraprakash Das2dfe5dd2012-02-10 13:49:53 -0700253 unsigned int reset_status;
Rajeev Kulkarni46ee1092012-12-14 14:47:55 -0800254 bool wait_on_invalid_ts;
Jeff Boodyfe6c39c2012-08-09 13:54:50 -0600255 struct sync_timeline *timeline;
Jordan Crouseef3456c2013-01-04 16:46:51 -0700256 struct list_head events;
257 struct list_head events_list;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700258};
259
260struct kgsl_process_private {
261 unsigned int refcnt;
262 pid_t pid;
263 spinlock_t mem_lock;
Jordan Crousec9559e42012-04-05 16:55:56 -0600264 struct rb_root mem_rb;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700265 struct kgsl_pagetable *pagetable;
266 struct list_head list;
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600267 struct kobject kobj;
Jeremy Gebbenddf93012012-09-25 10:57:38 -0600268 struct dentry *debug_root;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700269
270 struct {
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600271 unsigned int cur;
272 unsigned int max;
273 } stats[KGSL_MEM_ENTRY_MAX];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700274};
275
276struct kgsl_device_private {
277 struct kgsl_device *device;
278 struct kgsl_process_private *process_priv;
279};
280
281struct kgsl_power_stats {
282 s64 total_time;
283 s64 busy_time;
284};
285
286struct kgsl_device *kgsl_get_device(int dev_idx);
287
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600288static inline void kgsl_process_add_stats(struct kgsl_process_private *priv,
289 unsigned int type, size_t size)
290{
291 priv->stats[type].cur += size;
292 if (priv->stats[type].max < priv->stats[type].cur)
293 priv->stats[type].max = priv->stats[type].cur;
294}
295
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700296static inline void kgsl_regread(struct kgsl_device *device,
297 unsigned int offsetwords,
298 unsigned int *value)
299{
300 device->ftbl->regread(device, offsetwords, value);
301}
302
303static inline void kgsl_regwrite(struct kgsl_device *device,
304 unsigned int offsetwords,
305 unsigned int value)
306{
307 device->ftbl->regwrite(device, offsetwords, value);
308}
309
Jordan Crousea29a2e02012-08-14 09:09:23 -0600310static inline int kgsl_idle(struct kgsl_device *device)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700311{
Jordan Crousea29a2e02012-08-14 09:09:23 -0600312 return device->ftbl->idle(device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700313}
314
Jordan Croused6535882012-06-20 08:22:16 -0600315static inline unsigned int kgsl_gpuid(struct kgsl_device *device,
316 unsigned int *chipid)
Jordan Crousea0758f22011-12-07 11:19:22 -0700317{
Jordan Croused6535882012-06-20 08:22:16 -0600318 return device->ftbl->gpuid(device, chipid);
Jordan Crousea0758f22011-12-07 11:19:22 -0700319}
320
Jeremy Gebben731dac52012-05-10 11:13:42 -0600321static inline unsigned int kgsl_readtimestamp(struct kgsl_device *device,
322 struct kgsl_context *context,
323 enum kgsl_timestamp_type type)
324{
325 return device->ftbl->readtimestamp(device, context, type);
326}
327
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700328static inline int kgsl_create_device_sysfs_files(struct device *root,
329 const struct device_attribute **list)
330{
331 int ret = 0, i;
332 for (i = 0; list[i] != NULL; i++)
333 ret |= device_create_file(root, list[i]);
334 return ret;
335}
336
337static inline void kgsl_remove_device_sysfs_files(struct device *root,
338 const struct device_attribute **list)
339{
340 int i;
341 for (i = 0; list[i] != NULL; i++)
342 device_remove_file(root, list[i]);
343}
344
345static inline struct kgsl_mmu *
346kgsl_get_mmu(struct kgsl_device *device)
347{
348 return (struct kgsl_mmu *) (device ? &device->mmu : NULL);
349}
350
351static inline struct kgsl_device *kgsl_device_from_dev(struct device *dev)
352{
353 int i;
354
355 for (i = 0; i < KGSL_DEVICE_MAX; i++) {
356 if (kgsl_driver.devp[i] && kgsl_driver.devp[i]->dev == dev)
357 return kgsl_driver.devp[i];
358 }
359
360 return NULL;
361}
362
363static inline int kgsl_create_device_workqueue(struct kgsl_device *device)
364{
Steve Muckle3e042df2011-11-18 11:25:04 -0800365 device->work_queue = create_singlethread_workqueue(device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700366 if (!device->work_queue) {
Steve Muckle3e042df2011-11-18 11:25:04 -0800367 KGSL_DRV_ERR(device,
368 "create_singlethread_workqueue(%s) failed\n",
369 device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700370 return -EINVAL;
371 }
372 return 0;
373}
374
375static inline struct kgsl_context *
376kgsl_find_context(struct kgsl_device_private *dev_priv, uint32_t id)
377{
378 struct kgsl_context *ctxt =
379 idr_find(&dev_priv->device->context_idr, id);
380
381 /* Make sure that the context belongs to the current instance so
382 that other processes can't guess context IDs and mess things up */
383
384 return (ctxt && ctxt->dev_priv == dev_priv) ? ctxt : NULL;
385}
386
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700387int kgsl_check_timestamp(struct kgsl_device *device,
388 struct kgsl_context *context, unsigned int timestamp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700389
390int kgsl_register_ts_notifier(struct kgsl_device *device,
391 struct notifier_block *nb);
392
393int kgsl_unregister_ts_notifier(struct kgsl_device *device,
394 struct notifier_block *nb);
395
Jordan Crouseb368e9b2012-04-27 14:01:59 -0600396int kgsl_device_platform_probe(struct kgsl_device *device);
397
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700398void kgsl_device_platform_remove(struct kgsl_device *device);
399
Jeremy Gebbenb50f3312011-12-16 08:58:33 -0700400const char *kgsl_pwrstate_to_str(unsigned int state);
401
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700402int kgsl_device_snapshot_init(struct kgsl_device *device);
403int kgsl_device_snapshot(struct kgsl_device *device, int hang);
404void kgsl_device_snapshot_close(struct kgsl_device *device);
405
Jordan Croused8aa4be2012-04-18 09:31:07 -0600406static inline struct kgsl_device_platform_data *
407kgsl_device_get_drvdata(struct kgsl_device *dev)
408{
409 struct platform_device *pdev =
410 container_of(dev->parentdev, struct platform_device, dev);
411
412 return pdev->dev.platform_data;
413}
414
Jeremy Gebben9ad86922012-05-08 15:33:23 -0600415/**
416 * kgsl_context_get - Get context reference count
417 * @context
418 *
419 * Asynchronous code that holds a pointer to a context
420 * must hold a reference count on it. The kgsl device
421 * mutex must be held while the context reference count
422 * is changed.
423 */
424static inline void
425kgsl_context_get(struct kgsl_context *context)
426{
427 kref_get(&context->refcount);
428}
429
430void kgsl_context_destroy(struct kref *kref);
431
432/**
433 * kgsl_context_put - Release context reference count
434 * @context
435 *
436 */
437static inline void
438kgsl_context_put(struct kgsl_context *context)
439{
440 kref_put(&context->refcount, kgsl_context_destroy);
441}
442
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700443#endif /* __KGSL_DEVICE_H */