blob: efa2b6e659d6ffe8d5dc58f774b6dbda4133eeed [file] [log] [blame]
Terje Bergstrom75471682013-03-22 16:34:01 +02001/*
2 * Tegra host1x Syncpoints
3 *
4 * Copyright (c) 2010-2013, NVIDIA Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __HOST1X_SYNCPT_H
20#define __HOST1X_SYNCPT_H
21
22#include <linux/atomic.h>
23#include <linux/kernel.h>
24#include <linux/sched.h>
25
26struct host1x;
27
28struct host1x_syncpt {
29 int id;
30 atomic_t min_val;
31 atomic_t max_val;
32 u32 base_val;
33 const char *name;
34 int client_managed;
35 struct host1x *host;
36 struct device *dev;
37};
38
39/* Initialize sync point array */
40int host1x_syncpt_init(struct host1x *host);
41
42/* Free sync point array */
43void host1x_syncpt_deinit(struct host1x *host);
44
45/*
46 * Read max. It indicates how many operations there are in queue, either in
47 * channel or in a software thread.
48 * */
49static inline u32 host1x_syncpt_read_max(struct host1x_syncpt *sp)
50{
51 smp_rmb();
52 return (u32)atomic_read(&sp->max_val);
53}
54
55/*
56 * Read min, which is a shadow of the current sync point value in hardware.
57 */
58static inline u32 host1x_syncpt_read_min(struct host1x_syncpt *sp)
59{
60 smp_rmb();
61 return (u32)atomic_read(&sp->min_val);
62}
63
64/* Return number of sync point supported. */
65int host1x_syncpt_nb_pts(struct host1x *host);
66
67/* Return number of wait bases supported. */
68int host1x_syncpt_nb_bases(struct host1x *host);
69
70/* Return number of mlocks supported. */
71int host1x_syncpt_nb_mlocks(struct host1x *host);
72
73/*
74 * Check sync point sanity. If max is larger than min, there have too many
75 * sync point increments.
76 *
77 * Client managed sync point are not tracked.
78 * */
79static inline bool host1x_syncpt_check_max(struct host1x_syncpt *sp, u32 real)
80{
81 u32 max;
82 if (sp->client_managed)
83 return true;
84 max = host1x_syncpt_read_max(sp);
85 return (s32)(max - real) >= 0;
86}
87
88/* Return true if sync point is client managed. */
89static inline int host1x_syncpt_client_managed(struct host1x_syncpt *sp)
90{
91 return sp->client_managed;
92}
93
94/*
95 * Returns true if syncpoint min == max, which means that there are no
96 * outstanding operations.
97 */
98static inline bool host1x_syncpt_idle(struct host1x_syncpt *sp)
99{
100 int min, max;
101 smp_rmb();
102 min = atomic_read(&sp->min_val);
103 max = atomic_read(&sp->max_val);
104 return (min == max);
105}
106
107/* Return pointer to struct denoting sync point id. */
108struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id);
109
110/* Request incrementing a sync point. */
111void host1x_syncpt_cpu_incr(struct host1x_syncpt *sp);
112
113/* Load current value from hardware to the shadow register. */
114u32 host1x_syncpt_load(struct host1x_syncpt *sp);
115
116/* Save host1x sync point state into shadow registers. */
117void host1x_syncpt_save(struct host1x *host);
118
119/* Reset host1x sync point state from shadow registers. */
120void host1x_syncpt_restore(struct host1x *host);
121
122/* Read current wait base value into shadow register and return it. */
123u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp);
124
125/* Increment sync point and its max. */
126void host1x_syncpt_incr(struct host1x_syncpt *sp);
127
128/* Indicate future operations by incrementing the sync point max. */
129u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs);
130
131/* Check if sync point id is valid. */
132static inline int host1x_syncpt_is_valid(struct host1x_syncpt *sp)
133{
134 return sp->id < host1x_syncpt_nb_pts(sp->host);
135}
136
137/* Return id of the sync point */
138u32 host1x_syncpt_id(struct host1x_syncpt *sp);
139
140/* Allocate a sync point for a device. */
141struct host1x_syncpt *host1x_syncpt_request(struct device *dev,
142 int client_managed);
143
144/* Free a sync point. */
145void host1x_syncpt_free(struct host1x_syncpt *sp);
146
147#endif