video: tegra: host: Syncpoints deliver waitbases
[linux-3.10.git] / drivers / video / tegra / host / nvhost_syncpt.h
1 /*
2  * drivers/video/tegra/host/nvhost_syncpt.h
3  *
4  * Tegra Graphics Host Syncpoints
5  *
6  * Copyright (c) 2010-2012, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifndef __NVHOST_SYNCPT_H
22 #define __NVHOST_SYNCPT_H
23
24 #include <linux/kernel.h>
25 #include <linux/sched.h>
26 #include <linux/nvhost.h>
27 #include <linux/atomic.h>
28
29 struct nvhost_syncpt;
30
31 /* Attribute struct for sysfs min and max attributes */
32 struct nvhost_syncpt_attr {
33         struct kobj_attribute attr;
34         struct nvhost_master *host;
35         int id;
36 };
37
38 struct nvhost_capability_node {
39         struct kobj_attribute attr;
40         struct nvhost_syncpt *sp;
41         int (*func)(struct nvhost_syncpt *sp);
42 };
43
44 struct nvhost_syncpt {
45         struct kobject *kobj;
46         atomic_t *min_val;
47         atomic_t *max_val;
48         u32 *base_val;
49         atomic_t *lock_counts;
50         const char **syncpt_names;
51         struct nvhost_syncpt_attr *syncpt_attrs;
52
53         struct kobject *caps_kobj;
54         struct nvhost_capability_node *caps_nodes;
55 };
56
57 int nvhost_syncpt_init(struct platform_device *, struct nvhost_syncpt *);
58 void nvhost_syncpt_deinit(struct nvhost_syncpt *);
59
60 #define syncpt_to_dev(sp) container_of(sp, struct nvhost_master, syncpt)
61 #define SYNCPT_CHECK_PERIOD (2 * HZ)
62 #define MAX_STUCK_CHECK_COUNT 15
63
64 /**
65  * Updates the value sent to hardware.
66  */
67 static inline u32 nvhost_syncpt_incr_max(struct nvhost_syncpt *sp,
68                                         u32 id, u32 incrs)
69 {
70         return (u32)atomic_add_return(incrs, &sp->max_val[id]);
71 }
72
73 /**
74  * Updated the value sent to hardware.
75  */
76 static inline u32 nvhost_syncpt_set_max(struct nvhost_syncpt *sp,
77                                         u32 id, u32 val)
78 {
79         atomic_set(&sp->max_val[id], val);
80         smp_wmb();
81         return val;
82 }
83
84 static inline u32 nvhost_syncpt_read_max(struct nvhost_syncpt *sp, u32 id)
85 {
86         smp_rmb();
87         return (u32)atomic_read(&sp->max_val[id]);
88 }
89
90 static inline u32 nvhost_syncpt_read_min(struct nvhost_syncpt *sp, u32 id)
91 {
92         smp_rmb();
93         return (u32)atomic_read(&sp->min_val[id]);
94 }
95
96 int nvhost_syncpt_client_managed(struct nvhost_syncpt *sp, u32 id);
97 int nvhost_syncpt_nb_pts(struct nvhost_syncpt *sp);
98 int nvhost_syncpt_nb_bases(struct nvhost_syncpt *sp);
99 int nvhost_syncpt_nb_mlocks(struct nvhost_syncpt *sp);
100 void nvhost_syncpt_set_manager(struct nvhost_syncpt *sp, int id, bool client);
101
102 static inline bool nvhost_syncpt_check_max(struct nvhost_syncpt *sp,
103                 u32 id, u32 real)
104 {
105         u32 max;
106         if (nvhost_syncpt_client_managed(sp, id))
107                 return true;
108         max = nvhost_syncpt_read_max(sp, id);
109         return (s32)(max - real) >= 0;
110 }
111
112 /**
113  * Returns true if syncpoint min == max
114  */
115 static inline bool nvhost_syncpt_min_eq_max(struct nvhost_syncpt *sp, u32 id)
116 {
117         int min, max;
118         smp_rmb();
119         min = atomic_read(&sp->min_val[id]);
120         max = atomic_read(&sp->max_val[id]);
121         return (min == max);
122 }
123
124 int nvhost_syncpt_get_waitbase(struct nvhost_channel *ch, int id);
125
126 void nvhost_syncpt_cpu_incr(struct nvhost_syncpt *sp, u32 id);
127
128 u32 nvhost_syncpt_update_min(struct nvhost_syncpt *sp, u32 id);
129 bool nvhost_syncpt_is_expired(struct nvhost_syncpt *sp, u32 id, u32 thresh);
130
131 void nvhost_syncpt_save(struct nvhost_syncpt *sp);
132
133 void nvhost_syncpt_reset(struct nvhost_syncpt *sp);
134 void nvhost_syncpt_reset_client(struct platform_device *pdev);
135
136 u32 nvhost_syncpt_read(struct nvhost_syncpt *sp, u32 id);
137 u32 nvhost_syncpt_read_wait_base(struct nvhost_syncpt *sp, u32 id);
138 void nvhost_syncpt_cpu_set_wait_base(struct platform_device *pdev, u32 id,
139                                         u32 val);
140
141 void nvhost_syncpt_incr(struct nvhost_syncpt *sp, u32 id);
142
143 int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, u32 thresh,
144                         u32 timeout, u32 *value);
145
146 static inline int nvhost_syncpt_wait(struct nvhost_syncpt *sp, u32 id, u32 thresh)
147 {
148         return nvhost_syncpt_wait_timeout(sp, id, thresh,
149                                           MAX_SCHEDULE_TIMEOUT, NULL);
150 }
151
152 int nvhost_syncpt_patch_wait(struct nvhost_syncpt *sp, void *patch_addr);
153
154 void nvhost_syncpt_debug(struct nvhost_syncpt *sp);
155
156 static inline int nvhost_syncpt_is_valid(struct nvhost_syncpt *sp, u32 id)
157 {
158         return id != NVSYNCPT_INVALID && id < nvhost_syncpt_nb_pts(sp);
159 }
160
161 int nvhost_mutex_try_lock(struct nvhost_syncpt *sp, int idx);
162
163 void nvhost_mutex_unlock(struct nvhost_syncpt *sp, int idx);
164
165 #endif