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