xref: /openbsd-src/sys/dev/pci/drm/i915/display/intel_frontbuffer.h (revision f005ef32267c16bdb134f0e9fa4477dbe07c263a)
1c349dbc7Sjsg /*
2c349dbc7Sjsg  * Copyright (c) 2014-2016 Intel Corporation
3c349dbc7Sjsg  *
4c349dbc7Sjsg  * Permission is hereby granted, free of charge, to any person obtaining a
5c349dbc7Sjsg  * copy of this software and associated documentation files (the "Software"),
6c349dbc7Sjsg  * to deal in the Software without restriction, including without limitation
7c349dbc7Sjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8c349dbc7Sjsg  * and/or sell copies of the Software, and to permit persons to whom the
9c349dbc7Sjsg  * Software is furnished to do so, subject to the following conditions:
10c349dbc7Sjsg  *
11c349dbc7Sjsg  * The above copyright notice and this permission notice (including the next
12c349dbc7Sjsg  * paragraph) shall be included in all copies or substantial portions of the
13c349dbc7Sjsg  * Software.
14c349dbc7Sjsg  *
15c349dbc7Sjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16c349dbc7Sjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17c349dbc7Sjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18c349dbc7Sjsg  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19c349dbc7Sjsg  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20c349dbc7Sjsg  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21c349dbc7Sjsg  * IN THE SOFTWARE.
22c349dbc7Sjsg  */
23c349dbc7Sjsg 
24c349dbc7Sjsg #ifndef __INTEL_FRONTBUFFER_H__
25c349dbc7Sjsg #define __INTEL_FRONTBUFFER_H__
26c349dbc7Sjsg 
27c349dbc7Sjsg #include <linux/atomic.h>
28*1bb76ff1Sjsg #include <linux/bits.h>
29c349dbc7Sjsg #include <linux/kref.h>
30c349dbc7Sjsg 
31*1bb76ff1Sjsg #include "i915_active_types.h"
32c349dbc7Sjsg 
33c349dbc7Sjsg struct drm_i915_private;
34c349dbc7Sjsg 
35c349dbc7Sjsg enum fb_op_origin {
36*1bb76ff1Sjsg 	ORIGIN_CPU = 0,
37c349dbc7Sjsg 	ORIGIN_CS,
38c349dbc7Sjsg 	ORIGIN_FLIP,
39c349dbc7Sjsg 	ORIGIN_DIRTYFB,
40*1bb76ff1Sjsg 	ORIGIN_CURSOR_UPDATE,
41c349dbc7Sjsg };
42c349dbc7Sjsg 
43c349dbc7Sjsg struct intel_frontbuffer {
44c349dbc7Sjsg 	struct kref ref;
45c349dbc7Sjsg 	atomic_t bits;
46c349dbc7Sjsg 	struct i915_active write;
47c349dbc7Sjsg 	struct drm_i915_gem_object *obj;
48c349dbc7Sjsg 	struct rcu_head rcu;
49c349dbc7Sjsg };
50c349dbc7Sjsg 
51*1bb76ff1Sjsg /*
52*1bb76ff1Sjsg  * Frontbuffer tracking bits. Set in obj->frontbuffer_bits while a gem bo is
53*1bb76ff1Sjsg  * considered to be the frontbuffer for the given plane interface-wise. This
54*1bb76ff1Sjsg  * doesn't mean that the hw necessarily already scans it out, but that any
55*1bb76ff1Sjsg  * rendering (by the cpu or gpu) will land in the frontbuffer eventually.
56*1bb76ff1Sjsg  *
57*1bb76ff1Sjsg  * We have one bit per pipe and per scanout plane type.
58*1bb76ff1Sjsg  */
59*1bb76ff1Sjsg #define INTEL_FRONTBUFFER_BITS_PER_PIPE 8
60*1bb76ff1Sjsg #define INTEL_FRONTBUFFER(pipe, plane_id) \
61*1bb76ff1Sjsg 	BIT((plane_id) + INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe));
62*1bb76ff1Sjsg #define INTEL_FRONTBUFFER_OVERLAY(pipe) \
63*1bb76ff1Sjsg 	BIT(INTEL_FRONTBUFFER_BITS_PER_PIPE - 1 + INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))
64*1bb76ff1Sjsg #define INTEL_FRONTBUFFER_ALL_MASK(pipe) \
65*1bb76ff1Sjsg 	GENMASK(INTEL_FRONTBUFFER_BITS_PER_PIPE * ((pipe) + 1) - 1,	\
66*1bb76ff1Sjsg 		INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))
67*1bb76ff1Sjsg 
68c349dbc7Sjsg void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
69c349dbc7Sjsg 				    unsigned frontbuffer_bits);
70c349dbc7Sjsg void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
71c349dbc7Sjsg 				     unsigned frontbuffer_bits);
72c349dbc7Sjsg void intel_frontbuffer_flip(struct drm_i915_private *i915,
73c349dbc7Sjsg 			    unsigned frontbuffer_bits);
74c349dbc7Sjsg 
75c349dbc7Sjsg void intel_frontbuffer_put(struct intel_frontbuffer *front);
76c349dbc7Sjsg 
77c349dbc7Sjsg struct intel_frontbuffer *
78c349dbc7Sjsg intel_frontbuffer_get(struct drm_i915_gem_object *obj);
79c349dbc7Sjsg 
80c349dbc7Sjsg void __intel_fb_invalidate(struct intel_frontbuffer *front,
81c349dbc7Sjsg 			   enum fb_op_origin origin,
82c349dbc7Sjsg 			   unsigned int frontbuffer_bits);
83c349dbc7Sjsg 
84c349dbc7Sjsg /**
85c349dbc7Sjsg  * intel_frontbuffer_invalidate - invalidate frontbuffer object
86c349dbc7Sjsg  * @front: GEM object to invalidate
87c349dbc7Sjsg  * @origin: which operation caused the invalidation
88c349dbc7Sjsg  *
89c349dbc7Sjsg  * This function gets called every time rendering on the given object starts and
90c349dbc7Sjsg  * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must
91c349dbc7Sjsg  * be invalidated. For ORIGIN_CS any subsequent invalidation will be delayed
92c349dbc7Sjsg  * until the rendering completes or a flip on this frontbuffer plane is
93c349dbc7Sjsg  * scheduled.
94c349dbc7Sjsg  */
intel_frontbuffer_invalidate(struct intel_frontbuffer * front,enum fb_op_origin origin)95c349dbc7Sjsg static inline bool intel_frontbuffer_invalidate(struct intel_frontbuffer *front,
96c349dbc7Sjsg 						enum fb_op_origin origin)
97c349dbc7Sjsg {
98c349dbc7Sjsg 	unsigned int frontbuffer_bits;
99c349dbc7Sjsg 
100c349dbc7Sjsg 	if (!front)
101c349dbc7Sjsg 		return false;
102c349dbc7Sjsg 
103c349dbc7Sjsg 	frontbuffer_bits = atomic_read(&front->bits);
104c349dbc7Sjsg 	if (!frontbuffer_bits)
105c349dbc7Sjsg 		return false;
106c349dbc7Sjsg 
107c349dbc7Sjsg 	__intel_fb_invalidate(front, origin, frontbuffer_bits);
108c349dbc7Sjsg 	return true;
109c349dbc7Sjsg }
110c349dbc7Sjsg 
111c349dbc7Sjsg void __intel_fb_flush(struct intel_frontbuffer *front,
112c349dbc7Sjsg 		      enum fb_op_origin origin,
113c349dbc7Sjsg 		      unsigned int frontbuffer_bits);
114c349dbc7Sjsg 
115c349dbc7Sjsg /**
116c349dbc7Sjsg  * intel_frontbuffer_flush - flush frontbuffer object
117c349dbc7Sjsg  * @front: GEM object to flush
118c349dbc7Sjsg  * @origin: which operation caused the flush
119c349dbc7Sjsg  *
120c349dbc7Sjsg  * This function gets called every time rendering on the given object has
121c349dbc7Sjsg  * completed and frontbuffer caching can be started again.
122c349dbc7Sjsg  */
intel_frontbuffer_flush(struct intel_frontbuffer * front,enum fb_op_origin origin)123c349dbc7Sjsg static inline void intel_frontbuffer_flush(struct intel_frontbuffer *front,
124c349dbc7Sjsg 					   enum fb_op_origin origin)
125c349dbc7Sjsg {
126c349dbc7Sjsg 	unsigned int frontbuffer_bits;
127c349dbc7Sjsg 
128c349dbc7Sjsg 	if (!front)
129c349dbc7Sjsg 		return;
130c349dbc7Sjsg 
131c349dbc7Sjsg 	frontbuffer_bits = atomic_read(&front->bits);
132c349dbc7Sjsg 	if (!frontbuffer_bits)
133c349dbc7Sjsg 		return;
134c349dbc7Sjsg 
135c349dbc7Sjsg 	__intel_fb_flush(front, origin, frontbuffer_bits);
136c349dbc7Sjsg }
137c349dbc7Sjsg 
138c349dbc7Sjsg void intel_frontbuffer_track(struct intel_frontbuffer *old,
139c349dbc7Sjsg 			     struct intel_frontbuffer *new,
140c349dbc7Sjsg 			     unsigned int frontbuffer_bits);
141c349dbc7Sjsg 
142c349dbc7Sjsg #endif /* __INTEL_FRONTBUFFER_H__ */
143