blob: 06432f98376a7b8f9bb3bc2aad7758f6528cf969 [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>
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,
78 unsigned int timestamp, unsigned int msecs);
79 unsigned int (*readtimestamp) (struct kgsl_device *device,
80 enum kgsl_timestamp_type type);
81 int (*issueibcmds) (struct kgsl_device_private *dev_priv,
82 struct kgsl_context *context, struct kgsl_ibdesc *ibdesc,
83 unsigned int sizedwords, uint32_t *timestamp,
84 unsigned int flags);
85 int (*setup_pt)(struct kgsl_device *device,
86 struct kgsl_pagetable *pagetable);
Jordan Crouse9f739212011-07-28 08:37:57 -060087 void (*cleanup_pt)(struct kgsl_device *device,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070088 struct kgsl_pagetable *pagetable);
89 void (*power_stats)(struct kgsl_device *device,
90 struct kgsl_power_stats *stats);
91 void (*irqctrl)(struct kgsl_device *device, int state);
Jordan Crousea0758f22011-12-07 11:19:22 -070092 unsigned int (*gpuid)(struct kgsl_device *device);
Jordan Crouse156cfbc2012-01-24 09:32:04 -070093 void * (*snapshot)(struct kgsl_device *device, void *snapshot,
94 int *remain, int hang);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095 /* Optional functions - these functions are not mandatory. The
96 driver will check that the function pointer is not NULL before
97 calling the hook */
98 void (*setstate) (struct kgsl_device *device, uint32_t flags);
99 int (*drawctxt_create) (struct kgsl_device *device,
100 struct kgsl_pagetable *pagetable, struct kgsl_context *context,
101 uint32_t flags);
102 void (*drawctxt_destroy) (struct kgsl_device *device,
103 struct kgsl_context *context);
104 long (*ioctl) (struct kgsl_device_private *dev_priv,
105 unsigned int cmd, void *data);
106};
107
108struct kgsl_memregion {
109 unsigned char *mmio_virt_base;
110 unsigned int mmio_phys_base;
111 uint32_t gpu_base;
112 unsigned int sizebytes;
113};
114
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600115/* MH register values */
116struct kgsl_mh {
117 unsigned int mharb;
118 unsigned int mh_intf_cfg1;
119 unsigned int mh_intf_cfg2;
120 uint32_t mpu_base;
121 int mpu_range;
122};
123
Jordan Croused4bc9d22011-11-17 13:39:21 -0700124struct kgsl_event {
125 uint32_t timestamp;
126 void (*func)(struct kgsl_device *, void *, u32);
127 void *priv;
128 struct list_head list;
Jeremy Gebbenfd87f9a2012-02-10 07:06:09 -0700129 struct kgsl_device_private *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;
140 struct kgsl_memregion regspace;
141 struct kgsl_memdesc memstore;
142 const char *iomemname;
143
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600144 struct kgsl_mh mh;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700145 struct kgsl_mmu mmu;
146 struct completion hwaccess_gate;
147 const struct kgsl_functable *ftbl;
148 struct work_struct idle_check_ws;
149 struct timer_list idle_timer;
150 struct kgsl_pwrctrl pwrctrl;
151 int open_count;
152
153 struct atomic_notifier_head ts_notifier_list;
154 struct mutex mutex;
155 uint32_t state;
156 uint32_t requested_state;
157
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700158 unsigned int active_cnt;
159 struct completion suspend_gate;
160
161 wait_queue_head_t wait_queue;
162 struct workqueue_struct *work_queue;
163 struct device *parentdev;
164 struct completion recovery_gate;
165 struct dentry *d_debugfs;
166 struct idr context_idr;
167 struct early_suspend display_off;
168
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700169 void *snapshot; /* Pointer to the snapshot memory region */
170 int snapshot_maxsize; /* Max size of the snapshot region */
171 int snapshot_size; /* Current size of the snapshot region */
172 u32 snapshot_timestamp; /* Timestamp of the last valid snapshot */
173 int snapshot_frozen; /* 1 if the snapshot output is frozen until
174 it gets read by the user. This avoids
175 losing the output on multiple hangs */
176 struct kobject snapshot_kobj;
177
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700178 /* Logging levels */
179 int cmd_log;
180 int ctxt_log;
181 int drv_log;
182 int mem_log;
183 int pwr_log;
184 struct wake_lock idle_wakelock;
185 struct kgsl_pwrscale pwrscale;
186 struct kobject pwrscale_kobj;
Jordan Crouse1bf80aa2011-10-12 16:57:47 -0600187 struct work_struct ts_expired_ws;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700188 struct list_head events;
Lucille Sylvester808eca22011-11-03 10:26:29 -0700189 s64 on_time;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190};
191
192struct kgsl_context {
193 uint32_t id;
194
195 /* Pointer to the owning device instance */
196 struct kgsl_device_private *dev_priv;
197
198 /* Pointer to the device specific context information */
199 void *devctxt;
Shubhraprakash Das2dfe5dd2012-02-10 13:49:53 -0700200 /*
201 * Status indicating whether a gpu reset occurred and whether this
202 * context was responsible for causing it
203 */
204 unsigned int reset_status;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700205};
206
207struct kgsl_process_private {
208 unsigned int refcnt;
209 pid_t pid;
210 spinlock_t mem_lock;
211 struct list_head mem_list;
212 struct kgsl_pagetable *pagetable;
213 struct list_head list;
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600214 struct kobject kobj;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700215
216 struct {
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600217 unsigned int cur;
218 unsigned int max;
219 } stats[KGSL_MEM_ENTRY_MAX];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700220};
221
222struct kgsl_device_private {
223 struct kgsl_device *device;
224 struct kgsl_process_private *process_priv;
225};
226
227struct kgsl_power_stats {
228 s64 total_time;
229 s64 busy_time;
230};
231
232struct kgsl_device *kgsl_get_device(int dev_idx);
233
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600234static inline void kgsl_process_add_stats(struct kgsl_process_private *priv,
235 unsigned int type, size_t size)
236{
237 priv->stats[type].cur += size;
238 if (priv->stats[type].max < priv->stats[type].cur)
239 priv->stats[type].max = priv->stats[type].cur;
240}
241
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700242static inline void kgsl_regread(struct kgsl_device *device,
243 unsigned int offsetwords,
244 unsigned int *value)
245{
246 device->ftbl->regread(device, offsetwords, value);
247}
248
249static inline void kgsl_regwrite(struct kgsl_device *device,
250 unsigned int offsetwords,
251 unsigned int value)
252{
253 device->ftbl->regwrite(device, offsetwords, value);
254}
255
256static inline int kgsl_idle(struct kgsl_device *device, unsigned int timeout)
257{
258 return device->ftbl->idle(device, timeout);
259}
260
Jordan Crousea0758f22011-12-07 11:19:22 -0700261static inline unsigned int kgsl_gpuid(struct kgsl_device *device)
262{
263 return device->ftbl->gpuid(device);
264}
265
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700266static inline int kgsl_create_device_sysfs_files(struct device *root,
267 const struct device_attribute **list)
268{
269 int ret = 0, i;
270 for (i = 0; list[i] != NULL; i++)
271 ret |= device_create_file(root, list[i]);
272 return ret;
273}
274
275static inline void kgsl_remove_device_sysfs_files(struct device *root,
276 const struct device_attribute **list)
277{
278 int i;
279 for (i = 0; list[i] != NULL; i++)
280 device_remove_file(root, list[i]);
281}
282
283static inline struct kgsl_mmu *
284kgsl_get_mmu(struct kgsl_device *device)
285{
286 return (struct kgsl_mmu *) (device ? &device->mmu : NULL);
287}
288
289static inline struct kgsl_device *kgsl_device_from_dev(struct device *dev)
290{
291 int i;
292
293 for (i = 0; i < KGSL_DEVICE_MAX; i++) {
294 if (kgsl_driver.devp[i] && kgsl_driver.devp[i]->dev == dev)
295 return kgsl_driver.devp[i];
296 }
297
298 return NULL;
299}
300
301static inline int kgsl_create_device_workqueue(struct kgsl_device *device)
302{
Steve Muckle3e042df2011-11-18 11:25:04 -0800303 device->work_queue = create_singlethread_workqueue(device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700304 if (!device->work_queue) {
Steve Muckle3e042df2011-11-18 11:25:04 -0800305 KGSL_DRV_ERR(device,
306 "create_singlethread_workqueue(%s) failed\n",
307 device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700308 return -EINVAL;
309 }
310 return 0;
311}
312
313static inline struct kgsl_context *
314kgsl_find_context(struct kgsl_device_private *dev_priv, uint32_t id)
315{
316 struct kgsl_context *ctxt =
317 idr_find(&dev_priv->device->context_idr, id);
318
319 /* Make sure that the context belongs to the current instance so
320 that other processes can't guess context IDs and mess things up */
321
322 return (ctxt && ctxt->dev_priv == dev_priv) ? ctxt : NULL;
323}
324
325int kgsl_check_timestamp(struct kgsl_device *device, unsigned int timestamp);
326
327int kgsl_register_ts_notifier(struct kgsl_device *device,
328 struct notifier_block *nb);
329
330int kgsl_unregister_ts_notifier(struct kgsl_device *device,
331 struct notifier_block *nb);
332
333int kgsl_device_platform_probe(struct kgsl_device *device,
334 irqreturn_t (*dev_isr) (int, void*));
335void kgsl_device_platform_remove(struct kgsl_device *device);
336
Jeremy Gebbenb50f3312011-12-16 08:58:33 -0700337const char *kgsl_pwrstate_to_str(unsigned int state);
338
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700339int kgsl_device_snapshot_init(struct kgsl_device *device);
340int kgsl_device_snapshot(struct kgsl_device *device, int hang);
341void kgsl_device_snapshot_close(struct kgsl_device *device);
342
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700343#endif /* __KGSL_DEVICE_H */