1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Tegra host1x Syncpoints |
4 | * |
5 | * Copyright (c) 2010-2013, NVIDIA Corporation. |
6 | */ |
7 | |
8 | #ifndef __HOST1X_SYNCPT_H |
9 | #define __HOST1X_SYNCPT_H |
10 | |
11 | #include <linux/atomic.h> |
12 | #include <linux/host1x.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/kref.h> |
15 | #include <linux/sched.h> |
16 | |
17 | #include "fence.h" |
18 | #include "intr.h" |
19 | |
20 | struct host1x; |
21 | |
22 | /* Reserved for replacing an expired wait with a NOP */ |
23 | #define HOST1X_SYNCPT_RESERVED 0 |
24 | |
25 | struct host1x_syncpt_base { |
26 | unsigned int id; |
27 | bool requested; |
28 | }; |
29 | |
30 | struct host1x_syncpt { |
31 | struct kref ref; |
32 | |
33 | unsigned int id; |
34 | atomic_t min_val; |
35 | atomic_t max_val; |
36 | u32 base_val; |
37 | const char *name; |
38 | bool client_managed; |
39 | struct host1x *host; |
40 | struct host1x_syncpt_base *base; |
41 | |
42 | /* interrupt data */ |
43 | struct host1x_fence_list fences; |
44 | |
45 | /* |
46 | * If a submission incrementing this syncpoint fails, lock it so that |
47 | * further submission cannot be made until application has handled the |
48 | * failure. |
49 | */ |
50 | bool locked; |
51 | }; |
52 | |
53 | /* Initialize sync point array */ |
54 | int host1x_syncpt_init(struct host1x *host); |
55 | |
56 | /* Free sync point array */ |
57 | void host1x_syncpt_deinit(struct host1x *host); |
58 | |
59 | /* Return number of sync point supported. */ |
60 | unsigned int host1x_syncpt_nb_pts(struct host1x *host); |
61 | |
62 | /* Return number of wait bases supported. */ |
63 | unsigned int host1x_syncpt_nb_bases(struct host1x *host); |
64 | |
65 | /* Return number of mlocks supported. */ |
66 | unsigned int host1x_syncpt_nb_mlocks(struct host1x *host); |
67 | |
68 | /* |
69 | * Check sync point sanity. If max is larger than min, there have too many |
70 | * sync point increments. |
71 | * |
72 | * Client managed sync point are not tracked. |
73 | * */ |
74 | static inline bool host1x_syncpt_check_max(struct host1x_syncpt *sp, u32 real) |
75 | { |
76 | u32 max; |
77 | if (sp->client_managed) |
78 | return true; |
79 | max = host1x_syncpt_read_max(sp); |
80 | return (s32)(max - real) >= 0; |
81 | } |
82 | |
83 | /* Return true if sync point is client managed. */ |
84 | static inline bool host1x_syncpt_client_managed(struct host1x_syncpt *sp) |
85 | { |
86 | return sp->client_managed; |
87 | } |
88 | |
89 | /* |
90 | * Returns true if syncpoint min == max, which means that there are no |
91 | * outstanding operations. |
92 | */ |
93 | static inline bool host1x_syncpt_idle(struct host1x_syncpt *sp) |
94 | { |
95 | int min, max; |
96 | smp_rmb(); |
97 | min = atomic_read(v: &sp->min_val); |
98 | max = atomic_read(v: &sp->max_val); |
99 | return (min == max); |
100 | } |
101 | |
102 | /* Load current value from hardware to the shadow register. */ |
103 | u32 host1x_syncpt_load(struct host1x_syncpt *sp); |
104 | |
105 | /* Check if the given syncpoint value has already passed */ |
106 | bool host1x_syncpt_is_expired(struct host1x_syncpt *sp, u32 thresh); |
107 | |
108 | /* Save host1x sync point state into shadow registers. */ |
109 | void host1x_syncpt_save(struct host1x *host); |
110 | |
111 | /* Reset host1x sync point state from shadow registers. */ |
112 | void host1x_syncpt_restore(struct host1x *host); |
113 | |
114 | /* Read current wait base value into shadow register and return it. */ |
115 | u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp); |
116 | |
117 | /* Indicate future operations by incrementing the sync point max. */ |
118 | u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs); |
119 | |
120 | /* Check if sync point id is valid. */ |
121 | static inline int host1x_syncpt_is_valid(struct host1x_syncpt *sp) |
122 | { |
123 | return sp->id < host1x_syncpt_nb_pts(host: sp->host); |
124 | } |
125 | |
126 | static inline void host1x_syncpt_set_locked(struct host1x_syncpt *sp) |
127 | { |
128 | sp->locked = true; |
129 | } |
130 | |
131 | #endif |
132 | |