1112ed2d3SChris Wilson /*
2112ed2d3SChris Wilson  * SPDX-License-Identifier: MIT
3112ed2d3SChris Wilson  *
4112ed2d3SChris Wilson  * Copyright © 2019 Intel Corporation
5112ed2d3SChris Wilson  */
6112ed2d3SChris Wilson 
7112ed2d3SChris Wilson #ifndef __INTEL_CONTEXT_H__
8112ed2d3SChris Wilson #define __INTEL_CONTEXT_H__
9112ed2d3SChris Wilson 
10112ed2d3SChris Wilson #include <linux/lockdep.h>
11112ed2d3SChris Wilson 
1212c255b5SChris Wilson #include "i915_active.h"
13112ed2d3SChris Wilson #include "intel_context_types.h"
14112ed2d3SChris Wilson #include "intel_engine_types.h"
152871ea85SChris Wilson #include "intel_ring_types.h"
16e5dadff4SChris Wilson #include "intel_timeline_types.h"
17112ed2d3SChris Wilson 
18112ed2d3SChris Wilson void intel_context_init(struct intel_context *ce,
19112ed2d3SChris Wilson 			struct i915_gem_context *ctx,
20112ed2d3SChris Wilson 			struct intel_engine_cs *engine);
21df8cf31eSChris Wilson void intel_context_fini(struct intel_context *ce);
22112ed2d3SChris Wilson 
23112ed2d3SChris Wilson struct intel_context *
245e2a0419SChris Wilson intel_context_create(struct i915_gem_context *ctx,
25112ed2d3SChris Wilson 		     struct intel_engine_cs *engine);
26112ed2d3SChris Wilson 
275e2a0419SChris Wilson void intel_context_free(struct intel_context *ce);
285e2a0419SChris Wilson 
29112ed2d3SChris Wilson /**
306b736de5SChris Wilson  * intel_context_lock_pinned - Stablises the 'pinned' status of the HW context
316b736de5SChris Wilson  * @ce - the context
32112ed2d3SChris Wilson  *
33112ed2d3SChris Wilson  * Acquire a lock on the pinned status of the HW context, such that the context
34112ed2d3SChris Wilson  * can neither be bound to the GPU or unbound whilst the lock is held, i.e.
35112ed2d3SChris Wilson  * intel_context_is_pinned() remains stable.
36112ed2d3SChris Wilson  */
376b736de5SChris Wilson static inline int intel_context_lock_pinned(struct intel_context *ce)
386b736de5SChris Wilson 	__acquires(ce->pin_mutex)
396b736de5SChris Wilson {
406b736de5SChris Wilson 	return mutex_lock_interruptible(&ce->pin_mutex);
416b736de5SChris Wilson }
42112ed2d3SChris Wilson 
436b736de5SChris Wilson /**
446b736de5SChris Wilson  * intel_context_is_pinned - Reports the 'pinned' status
456b736de5SChris Wilson  * @ce - the context
466b736de5SChris Wilson  *
476b736de5SChris Wilson  * While in use by the GPU, the context, along with its ring and page
486b736de5SChris Wilson  * tables is pinned into memory and the GTT.
496b736de5SChris Wilson  *
506b736de5SChris Wilson  * Returns: true if the context is currently pinned for use by the GPU.
516b736de5SChris Wilson  */
52112ed2d3SChris Wilson static inline bool
53112ed2d3SChris Wilson intel_context_is_pinned(struct intel_context *ce)
54112ed2d3SChris Wilson {
55112ed2d3SChris Wilson 	return atomic_read(&ce->pin_count);
56112ed2d3SChris Wilson }
57112ed2d3SChris Wilson 
586b736de5SChris Wilson /**
596b736de5SChris Wilson  * intel_context_unlock_pinned - Releases the earlier locking of 'pinned' status
606b736de5SChris Wilson  * @ce - the context
616b736de5SChris Wilson  *
626b736de5SChris Wilson  * Releases the lock earlier acquired by intel_context_unlock_pinned().
636b736de5SChris Wilson  */
646b736de5SChris Wilson static inline void intel_context_unlock_pinned(struct intel_context *ce)
656b736de5SChris Wilson 	__releases(ce->pin_mutex)
666b736de5SChris Wilson {
676b736de5SChris Wilson 	mutex_unlock(&ce->pin_mutex);
686b736de5SChris Wilson }
69112ed2d3SChris Wilson 
70fa9f6681SChris Wilson int __intel_context_do_pin(struct intel_context *ce);
71fa9f6681SChris Wilson 
72fa9f6681SChris Wilson static inline int intel_context_pin(struct intel_context *ce)
73fa9f6681SChris Wilson {
74fa9f6681SChris Wilson 	if (likely(atomic_inc_not_zero(&ce->pin_count)))
75fa9f6681SChris Wilson 		return 0;
76fa9f6681SChris Wilson 
77fa9f6681SChris Wilson 	return __intel_context_do_pin(ce);
78fa9f6681SChris Wilson }
79112ed2d3SChris Wilson 
80112ed2d3SChris Wilson static inline void __intel_context_pin(struct intel_context *ce)
81112ed2d3SChris Wilson {
82112ed2d3SChris Wilson 	GEM_BUG_ON(!intel_context_is_pinned(ce));
83112ed2d3SChris Wilson 	atomic_inc(&ce->pin_count);
84112ed2d3SChris Wilson }
85112ed2d3SChris Wilson 
86112ed2d3SChris Wilson void intel_context_unpin(struct intel_context *ce);
87112ed2d3SChris Wilson 
886eee33e8SChris Wilson void intel_context_enter_engine(struct intel_context *ce);
896eee33e8SChris Wilson void intel_context_exit_engine(struct intel_context *ce);
906eee33e8SChris Wilson 
916eee33e8SChris Wilson static inline void intel_context_enter(struct intel_context *ce)
926eee33e8SChris Wilson {
936c69a454SChris Wilson 	lockdep_assert_held(&ce->timeline->mutex);
946eee33e8SChris Wilson 	if (!ce->active_count++)
956eee33e8SChris Wilson 		ce->ops->enter(ce);
966eee33e8SChris Wilson }
976eee33e8SChris Wilson 
986eee33e8SChris Wilson static inline void intel_context_mark_active(struct intel_context *ce)
996eee33e8SChris Wilson {
1006c69a454SChris Wilson 	lockdep_assert_held(&ce->timeline->mutex);
1016eee33e8SChris Wilson 	++ce->active_count;
1026eee33e8SChris Wilson }
1036eee33e8SChris Wilson 
1046eee33e8SChris Wilson static inline void intel_context_exit(struct intel_context *ce)
1056eee33e8SChris Wilson {
1066c69a454SChris Wilson 	lockdep_assert_held(&ce->timeline->mutex);
1076eee33e8SChris Wilson 	GEM_BUG_ON(!ce->active_count);
1086eee33e8SChris Wilson 	if (!--ce->active_count)
1096eee33e8SChris Wilson 		ce->ops->exit(ce);
1106eee33e8SChris Wilson }
1116eee33e8SChris Wilson 
112d8af05ffSChris Wilson int intel_context_active_acquire(struct intel_context *ce);
113d8af05ffSChris Wilson void intel_context_active_release(struct intel_context *ce);
114ce476c80SChris Wilson 
115112ed2d3SChris Wilson static inline struct intel_context *intel_context_get(struct intel_context *ce)
116112ed2d3SChris Wilson {
117112ed2d3SChris Wilson 	kref_get(&ce->ref);
118112ed2d3SChris Wilson 	return ce;
119112ed2d3SChris Wilson }
120112ed2d3SChris Wilson 
121112ed2d3SChris Wilson static inline void intel_context_put(struct intel_context *ce)
122112ed2d3SChris Wilson {
123112ed2d3SChris Wilson 	kref_put(&ce->ref, ce->ops->destroy);
124112ed2d3SChris Wilson }
125112ed2d3SChris Wilson 
126e5dadff4SChris Wilson static inline struct intel_timeline *__must_check
127f4d57d83SChris Wilson intel_context_timeline_lock(struct intel_context *ce)
12875d0a7f3SChris Wilson 	__acquires(&ce->timeline->mutex)
1292ccdf6a1SChris Wilson {
130e5dadff4SChris Wilson 	struct intel_timeline *tl = ce->timeline;
131e5dadff4SChris Wilson 	int err;
132e5dadff4SChris Wilson 
133e5dadff4SChris Wilson 	err = mutex_lock_interruptible(&tl->mutex);
134e5dadff4SChris Wilson 	if (err)
135e5dadff4SChris Wilson 		return ERR_PTR(err);
136e5dadff4SChris Wilson 
137e5dadff4SChris Wilson 	return tl;
1382ccdf6a1SChris Wilson }
1392ccdf6a1SChris Wilson 
140e5dadff4SChris Wilson static inline void intel_context_timeline_unlock(struct intel_timeline *tl)
141e5dadff4SChris Wilson 	__releases(&tl->mutex)
1422ccdf6a1SChris Wilson {
143e5dadff4SChris Wilson 	mutex_unlock(&tl->mutex);
1442ccdf6a1SChris Wilson }
1452ccdf6a1SChris Wilson 
146a9877da2SChris Wilson int intel_context_prepare_remote_request(struct intel_context *ce,
147a9877da2SChris Wilson 					 struct i915_request *rq);
148a9877da2SChris Wilson 
1495e2a0419SChris Wilson struct i915_request *intel_context_create_request(struct intel_context *ce);
1505e2a0419SChris Wilson 
15148ae397bSChris Wilson static inline struct intel_ring *__intel_context_ring_size(u64 sz)
15248ae397bSChris Wilson {
15348ae397bSChris Wilson 	return u64_to_ptr(struct intel_ring, sz);
15448ae397bSChris Wilson }
15548ae397bSChris Wilson 
156112ed2d3SChris Wilson #endif /* __INTEL_CONTEXT_H__ */
157