1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/mm.h>
27
28
29#include "dm_services.h"
30#include "dc.h"
31
32
33#include "core_types.h"
34#include "transform.h"
35#include "dpp.h"
36
37
38
39
40static void construct(struct dc_context *ctx, struct dc_plane_state *plane_state)
41{
42 plane_state->ctx = ctx;
43
44 plane_state->gamma_correction = dc_create_gamma();
45 if (plane_state->gamma_correction != NULL)
46 plane_state->gamma_correction->is_identity = true;
47
48 plane_state->in_transfer_func = dc_create_transfer_func();
49 if (plane_state->in_transfer_func != NULL) {
50 plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
51 plane_state->in_transfer_func->ctx = ctx;
52 }
53#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
54 plane_state->in_shaper_func = dc_create_transfer_func();
55 if (plane_state->in_shaper_func != NULL) {
56 plane_state->in_shaper_func->type = TF_TYPE_BYPASS;
57 plane_state->in_shaper_func->ctx = ctx;
58 }
59
60 plane_state->lut3d_func = dc_create_3dlut_func();
61 if (plane_state->lut3d_func != NULL) {
62 plane_state->lut3d_func->ctx = ctx;
63 plane_state->lut3d_func->initialized = false;
64 }
65 plane_state->blend_tf = dc_create_transfer_func();
66 if (plane_state->blend_tf != NULL) {
67 plane_state->blend_tf->type = TF_TYPE_BYPASS;
68 plane_state->blend_tf->ctx = ctx;
69 }
70
71#endif
72}
73
74static void destruct(struct dc_plane_state *plane_state)
75{
76 if (plane_state->gamma_correction != NULL) {
77 dc_gamma_release(&plane_state->gamma_correction);
78 }
79 if (plane_state->in_transfer_func != NULL) {
80 dc_transfer_func_release(
81 plane_state->in_transfer_func);
82 plane_state->in_transfer_func = NULL;
83 }
84#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
85 if (plane_state->in_shaper_func != NULL) {
86 dc_transfer_func_release(
87 plane_state->in_shaper_func);
88 plane_state->in_shaper_func = NULL;
89 }
90 if (plane_state->lut3d_func != NULL) {
91 dc_3dlut_func_release(
92 plane_state->lut3d_func);
93 plane_state->lut3d_func = NULL;
94 }
95 if (plane_state->blend_tf != NULL) {
96 dc_transfer_func_release(
97 plane_state->blend_tf);
98 plane_state->blend_tf = NULL;
99 }
100
101#endif
102}
103
104
105
106
107void enable_surface_flip_reporting(struct dc_plane_state *plane_state,
108 uint32_t controller_id)
109{
110 plane_state->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1;
111
112}
113
114struct dc_plane_state *dc_create_plane_state(struct dc *dc)
115{
116 struct dc *core_dc = dc;
117
118 struct dc_plane_state *plane_state = kvzalloc(sizeof(*plane_state),
119 GFP_KERNEL);
120
121 if (NULL == plane_state)
122 return NULL;
123
124 kref_init(&plane_state->refcount);
125 construct(core_dc->ctx, plane_state);
126
127 return plane_state;
128}
129
130
131
132
133
134
135
136
137
138
139
140
141const struct dc_plane_status *dc_plane_get_status(
142 const struct dc_plane_state *plane_state)
143{
144 const struct dc_plane_status *plane_status;
145 struct dc *core_dc;
146 int i;
147
148 if (!plane_state ||
149 !plane_state->ctx ||
150 !plane_state->ctx->dc) {
151 ASSERT(0);
152 return NULL;
153 }
154
155 plane_status = &plane_state->status;
156 core_dc = plane_state->ctx->dc;
157
158 if (core_dc->current_state == NULL)
159 return NULL;
160
161
162 for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
163 struct pipe_ctx *pipe_ctx =
164 &core_dc->current_state->res_ctx.pipe_ctx[i];
165
166 if (pipe_ctx->plane_state != plane_state)
167 continue;
168
169 pipe_ctx->plane_state->status.is_flip_pending = false;
170
171 break;
172 }
173
174 for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
175 struct pipe_ctx *pipe_ctx =
176 &core_dc->current_state->res_ctx.pipe_ctx[i];
177
178 if (pipe_ctx->plane_state != plane_state)
179 continue;
180
181 core_dc->hwss.update_pending_status(pipe_ctx);
182 }
183
184 return plane_status;
185}
186
187void dc_plane_state_retain(struct dc_plane_state *plane_state)
188{
189 kref_get(&plane_state->refcount);
190}
191
192static void dc_plane_state_free(struct kref *kref)
193{
194 struct dc_plane_state *plane_state = container_of(kref, struct dc_plane_state, refcount);
195 destruct(plane_state);
196 kvfree(plane_state);
197}
198
199void dc_plane_state_release(struct dc_plane_state *plane_state)
200{
201 kref_put(&plane_state->refcount, dc_plane_state_free);
202}
203
204void dc_gamma_retain(struct dc_gamma *gamma)
205{
206 kref_get(&gamma->refcount);
207}
208
209static void dc_gamma_free(struct kref *kref)
210{
211 struct dc_gamma *gamma = container_of(kref, struct dc_gamma, refcount);
212 kvfree(gamma);
213}
214
215void dc_gamma_release(struct dc_gamma **gamma)
216{
217 kref_put(&(*gamma)->refcount, dc_gamma_free);
218 *gamma = NULL;
219}
220
221struct dc_gamma *dc_create_gamma(void)
222{
223 struct dc_gamma *gamma = kvzalloc(sizeof(*gamma), GFP_KERNEL);
224
225 if (gamma == NULL)
226 goto alloc_fail;
227
228 kref_init(&gamma->refcount);
229 return gamma;
230
231alloc_fail:
232 return NULL;
233}
234
235void dc_transfer_func_retain(struct dc_transfer_func *tf)
236{
237 kref_get(&tf->refcount);
238}
239
240static void dc_transfer_func_free(struct kref *kref)
241{
242 struct dc_transfer_func *tf = container_of(kref, struct dc_transfer_func, refcount);
243 kvfree(tf);
244}
245
246void dc_transfer_func_release(struct dc_transfer_func *tf)
247{
248 kref_put(&tf->refcount, dc_transfer_func_free);
249}
250
251struct dc_transfer_func *dc_create_transfer_func(void)
252{
253 struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL);
254
255 if (tf == NULL)
256 goto alloc_fail;
257
258 kref_init(&tf->refcount);
259
260 return tf;
261
262alloc_fail:
263 return NULL;
264}
265
266#if defined(CONFIG_DRM_AMD_DC_DCN2_0)
267static void dc_3dlut_func_free(struct kref *kref)
268{
269 struct dc_3dlut *lut = container_of(kref, struct dc_3dlut, refcount);
270
271 kvfree(lut);
272}
273
274struct dc_3dlut *dc_create_3dlut_func(void)
275{
276 struct dc_3dlut *lut = kvzalloc(sizeof(*lut), GFP_KERNEL);
277
278 if (lut == NULL)
279 goto alloc_fail;
280
281 kref_init(&lut->refcount);
282 lut->initialized = false;
283
284 return lut;
285
286alloc_fail:
287 return NULL;
288
289}
290
291void dc_3dlut_func_release(struct dc_3dlut *lut)
292{
293 kref_put(&lut->refcount, dc_3dlut_func_free);
294}
295
296void dc_3dlut_func_retain(struct dc_3dlut *lut)
297{
298 kref_get(&lut->refcount);
299}
300#endif
301
302
303