blob: 334b29f655f1fcf07f1a927bae353ff0fc642d2e [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>
17#include <linux/wakelock.h>
Lucille Sylvester10297892012-02-27 13:54:47 -070018#include <linux/pm_qos_params.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070019#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,
Carter Cooper7e7f02e2012-02-15 09:36:31 -070079 struct kgsl_context *context, unsigned int timestamp,
80 unsigned int msecs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070081 unsigned int (*readtimestamp) (struct kgsl_device *device,
Carter Cooper7e7f02e2012-02-15 09:36:31 -070082 struct kgsl_context *context, enum kgsl_timestamp_type type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070083 int (*issueibcmds) (struct kgsl_device_private *dev_priv,
84 struct kgsl_context *context, struct kgsl_ibdesc *ibdesc,
85 unsigned int sizedwords, uint32_t *timestamp,
86 unsigned int flags);
87 int (*setup_pt)(struct kgsl_device *device,
88 struct kgsl_pagetable *pagetable);
Jordan Crouse9f739212011-07-28 08:37:57 -060089 void (*cleanup_pt)(struct kgsl_device *device,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070090 struct kgsl_pagetable *pagetable);
91 void (*power_stats)(struct kgsl_device *device,
92 struct kgsl_power_stats *stats);
93 void (*irqctrl)(struct kgsl_device *device, int state);
Jordan Crousea0758f22011-12-07 11:19:22 -070094 unsigned int (*gpuid)(struct kgsl_device *device);
Jordan Crouse156cfbc2012-01-24 09:32:04 -070095 void * (*snapshot)(struct kgsl_device *device, void *snapshot,
96 int *remain, int hang);
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 */
100 void (*setstate) (struct kgsl_device *device, uint32_t flags);
101 int (*drawctxt_create) (struct kgsl_device *device,
102 struct kgsl_pagetable *pagetable, struct kgsl_context *context,
103 uint32_t flags);
104 void (*drawctxt_destroy) (struct kgsl_device *device,
105 struct kgsl_context *context);
106 long (*ioctl) (struct kgsl_device_private *dev_priv,
107 unsigned int cmd, void *data);
Jordan Crouseed7dd7f2012-03-29 13:16:02 -0600108 int (*setproperty) (struct kgsl_device *device,
109 enum kgsl_property_type type, void *value,
110 unsigned int sizebytes);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700111};
112
113struct kgsl_memregion {
114 unsigned char *mmio_virt_base;
115 unsigned int mmio_phys_base;
116 uint32_t gpu_base;
117 unsigned int sizebytes;
118};
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;
Jeremy Gebbenfd87f9a2012-02-10 07:06:09 -0700135 struct kgsl_device_private *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;
146 struct kgsl_memregion regspace;
147 struct kgsl_memdesc memstore;
148 const char *iomemname;
149
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600150 struct kgsl_mh mh;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700151 struct kgsl_mmu mmu;
152 struct completion hwaccess_gate;
153 const struct kgsl_functable *ftbl;
154 struct work_struct idle_check_ws;
155 struct timer_list idle_timer;
156 struct kgsl_pwrctrl pwrctrl;
157 int open_count;
158
159 struct atomic_notifier_head ts_notifier_list;
160 struct mutex mutex;
161 uint32_t state;
162 uint32_t requested_state;
163
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700164 unsigned int last_expired_ctxt_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700165 unsigned int active_cnt;
166 struct completion suspend_gate;
167
168 wait_queue_head_t wait_queue;
169 struct workqueue_struct *work_queue;
170 struct device *parentdev;
171 struct completion recovery_gate;
172 struct dentry *d_debugfs;
173 struct idr context_idr;
174 struct early_suspend display_off;
175
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700176 void *snapshot; /* Pointer to the snapshot memory region */
177 int snapshot_maxsize; /* Max size of the snapshot region */
178 int snapshot_size; /* Current size of the snapshot region */
179 u32 snapshot_timestamp; /* Timestamp of the last valid snapshot */
180 int snapshot_frozen; /* 1 if the snapshot output is frozen until
181 it gets read by the user. This avoids
182 losing the output on multiple hangs */
183 struct kobject snapshot_kobj;
184
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600185 /*
186 * List of GPU buffers that have been frozen in memory until they can be
187 * dumped
188 */
189 struct list_head snapshot_obj_list;
190
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700191 /* Logging levels */
192 int cmd_log;
193 int ctxt_log;
194 int drv_log;
195 int mem_log;
196 int pwr_log;
197 struct wake_lock idle_wakelock;
198 struct kgsl_pwrscale pwrscale;
199 struct kobject pwrscale_kobj;
Lucille Sylvester10297892012-02-27 13:54:47 -0700200 struct pm_qos_request_list 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;
Lucille Sylvester808eca22011-11-03 10:26:29 -0700203 s64 on_time;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700204};
205
206struct kgsl_context {
207 uint32_t id;
208
209 /* Pointer to the owning device instance */
210 struct kgsl_device_private *dev_priv;
211
212 /* Pointer to the device specific context information */
213 void *devctxt;
Shubhraprakash Das2dfe5dd2012-02-10 13:49:53 -0700214 /*
215 * Status indicating whether a gpu reset occurred and whether this
216 * context was responsible for causing it
217 */
218 unsigned int reset_status;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700219};
220
221struct kgsl_process_private {
222 unsigned int refcnt;
223 pid_t pid;
224 spinlock_t mem_lock;
Jordan Crousec9559e42012-04-05 16:55:56 -0600225 struct rb_root mem_rb;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700226 struct kgsl_pagetable *pagetable;
227 struct list_head list;
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600228 struct kobject kobj;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700229
230 struct {
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600231 unsigned int cur;
232 unsigned int max;
233 } stats[KGSL_MEM_ENTRY_MAX];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700234};
235
236struct kgsl_device_private {
237 struct kgsl_device *device;
238 struct kgsl_process_private *process_priv;
239};
240
241struct kgsl_power_stats {
242 s64 total_time;
243 s64 busy_time;
244};
245
246struct kgsl_device *kgsl_get_device(int dev_idx);
247
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600248static inline void kgsl_process_add_stats(struct kgsl_process_private *priv,
249 unsigned int type, size_t size)
250{
251 priv->stats[type].cur += size;
252 if (priv->stats[type].max < priv->stats[type].cur)
253 priv->stats[type].max = priv->stats[type].cur;
254}
255
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700256static inline void kgsl_regread(struct kgsl_device *device,
257 unsigned int offsetwords,
258 unsigned int *value)
259{
260 device->ftbl->regread(device, offsetwords, value);
261}
262
263static inline void kgsl_regwrite(struct kgsl_device *device,
264 unsigned int offsetwords,
265 unsigned int value)
266{
267 device->ftbl->regwrite(device, offsetwords, value);
268}
269
270static inline int kgsl_idle(struct kgsl_device *device, unsigned int timeout)
271{
272 return device->ftbl->idle(device, timeout);
273}
274
Jordan Crousea0758f22011-12-07 11:19:22 -0700275static inline unsigned int kgsl_gpuid(struct kgsl_device *device)
276{
277 return device->ftbl->gpuid(device);
278}
279
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700280static inline int kgsl_create_device_sysfs_files(struct device *root,
281 const struct device_attribute **list)
282{
283 int ret = 0, i;
284 for (i = 0; list[i] != NULL; i++)
285 ret |= device_create_file(root, list[i]);
286 return ret;
287}
288
289static inline void kgsl_remove_device_sysfs_files(struct device *root,
290 const struct device_attribute **list)
291{
292 int i;
293 for (i = 0; list[i] != NULL; i++)
294 device_remove_file(root, list[i]);
295}
296
297static inline struct kgsl_mmu *
298kgsl_get_mmu(struct kgsl_device *device)
299{
300 return (struct kgsl_mmu *) (device ? &device->mmu : NULL);
301}
302
303static inline struct kgsl_device *kgsl_device_from_dev(struct device *dev)
304{
305 int i;
306
307 for (i = 0; i < KGSL_DEVICE_MAX; i++) {
308 if (kgsl_driver.devp[i] && kgsl_driver.devp[i]->dev == dev)
309 return kgsl_driver.devp[i];
310 }
311
312 return NULL;
313}
314
315static inline int kgsl_create_device_workqueue(struct kgsl_device *device)
316{
Steve Muckle3e042df2011-11-18 11:25:04 -0800317 device->work_queue = create_singlethread_workqueue(device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700318 if (!device->work_queue) {
Steve Muckle3e042df2011-11-18 11:25:04 -0800319 KGSL_DRV_ERR(device,
320 "create_singlethread_workqueue(%s) failed\n",
321 device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700322 return -EINVAL;
323 }
324 return 0;
325}
326
327static inline struct kgsl_context *
328kgsl_find_context(struct kgsl_device_private *dev_priv, uint32_t id)
329{
330 struct kgsl_context *ctxt =
331 idr_find(&dev_priv->device->context_idr, id);
332
333 /* Make sure that the context belongs to the current instance so
334 that other processes can't guess context IDs and mess things up */
335
336 return (ctxt && ctxt->dev_priv == dev_priv) ? ctxt : NULL;
337}
338
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700339int kgsl_check_timestamp(struct kgsl_device *device,
340 struct kgsl_context *context, unsigned int timestamp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700341
342int kgsl_register_ts_notifier(struct kgsl_device *device,
343 struct notifier_block *nb);
344
345int kgsl_unregister_ts_notifier(struct kgsl_device *device,
346 struct notifier_block *nb);
347
348int kgsl_device_platform_probe(struct kgsl_device *device,
349 irqreturn_t (*dev_isr) (int, void*));
350void kgsl_device_platform_remove(struct kgsl_device *device);
351
Jeremy Gebbenb50f3312011-12-16 08:58:33 -0700352const char *kgsl_pwrstate_to_str(unsigned int state);
353
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700354int kgsl_device_snapshot_init(struct kgsl_device *device);
355int kgsl_device_snapshot(struct kgsl_device *device, int hang);
356void kgsl_device_snapshot_close(struct kgsl_device *device);
357
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700358#endif /* __KGSL_DEVICE_H */