1
2
3
4
5
6
7#include "komeda_dev.h"
8#include "komeda_kms.h"
9
10static void
11komeda_component_state_reset(struct komeda_component_state *st)
12{
13 st->binding_user = NULL;
14 st->affected_inputs = st->active_inputs;
15 st->active_inputs = 0;
16 st->changed_active_inputs = 0;
17}
18
19static struct drm_private_state *
20komeda_layer_atomic_duplicate_state(struct drm_private_obj *obj)
21{
22 struct komeda_layer_state *st;
23
24 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
25 if (!st)
26 return NULL;
27
28 komeda_component_state_reset(&st->base);
29 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
30
31 return &st->base.obj;
32}
33
34static void
35komeda_layer_atomic_destroy_state(struct drm_private_obj *obj,
36 struct drm_private_state *state)
37{
38 struct komeda_layer_state *st = to_layer_st(priv_to_comp_st(state));
39
40 kfree(st);
41}
42
43static const struct drm_private_state_funcs komeda_layer_obj_funcs = {
44 .atomic_duplicate_state = komeda_layer_atomic_duplicate_state,
45 .atomic_destroy_state = komeda_layer_atomic_destroy_state,
46};
47
48static int komeda_layer_obj_add(struct komeda_kms_dev *kms,
49 struct komeda_layer *layer)
50{
51 struct komeda_layer_state *st;
52
53 st = kzalloc(sizeof(*st), GFP_KERNEL);
54 if (!st)
55 return -ENOMEM;
56
57 st->base.component = &layer->base;
58 drm_atomic_private_obj_init(&kms->base, &layer->base.obj, &st->base.obj,
59 &komeda_layer_obj_funcs);
60 return 0;
61}
62
63static struct drm_private_state *
64komeda_scaler_atomic_duplicate_state(struct drm_private_obj *obj)
65{
66 struct komeda_scaler_state *st;
67
68 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
69 if (!st)
70 return NULL;
71
72 komeda_component_state_reset(&st->base);
73 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
74
75 return &st->base.obj;
76}
77
78static void
79komeda_scaler_atomic_destroy_state(struct drm_private_obj *obj,
80 struct drm_private_state *state)
81{
82 kfree(to_scaler_st(priv_to_comp_st(state)));
83}
84
85static const struct drm_private_state_funcs komeda_scaler_obj_funcs = {
86 .atomic_duplicate_state = komeda_scaler_atomic_duplicate_state,
87 .atomic_destroy_state = komeda_scaler_atomic_destroy_state,
88};
89
90static int komeda_scaler_obj_add(struct komeda_kms_dev *kms,
91 struct komeda_scaler *scaler)
92{
93 struct komeda_scaler_state *st;
94
95 st = kzalloc(sizeof(*st), GFP_KERNEL);
96 if (!st)
97 return -ENOMEM;
98
99 st->base.component = &scaler->base;
100 drm_atomic_private_obj_init(&kms->base,
101 &scaler->base.obj, &st->base.obj,
102 &komeda_scaler_obj_funcs);
103 return 0;
104}
105
106static struct drm_private_state *
107komeda_compiz_atomic_duplicate_state(struct drm_private_obj *obj)
108{
109 struct komeda_compiz_state *st;
110
111 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
112 if (!st)
113 return NULL;
114
115 komeda_component_state_reset(&st->base);
116 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
117
118 return &st->base.obj;
119}
120
121static void
122komeda_compiz_atomic_destroy_state(struct drm_private_obj *obj,
123 struct drm_private_state *state)
124{
125 kfree(to_compiz_st(priv_to_comp_st(state)));
126}
127
128static const struct drm_private_state_funcs komeda_compiz_obj_funcs = {
129 .atomic_duplicate_state = komeda_compiz_atomic_duplicate_state,
130 .atomic_destroy_state = komeda_compiz_atomic_destroy_state,
131};
132
133static int komeda_compiz_obj_add(struct komeda_kms_dev *kms,
134 struct komeda_compiz *compiz)
135{
136 struct komeda_compiz_state *st;
137
138 st = kzalloc(sizeof(*st), GFP_KERNEL);
139 if (!st)
140 return -ENOMEM;
141
142 st->base.component = &compiz->base;
143 drm_atomic_private_obj_init(&kms->base, &compiz->base.obj, &st->base.obj,
144 &komeda_compiz_obj_funcs);
145
146 return 0;
147}
148
149static struct drm_private_state *
150komeda_splitter_atomic_duplicate_state(struct drm_private_obj *obj)
151{
152 struct komeda_splitter_state *st;
153
154 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
155 if (!st)
156 return NULL;
157
158 komeda_component_state_reset(&st->base);
159 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
160
161 return &st->base.obj;
162}
163
164static void
165komeda_splitter_atomic_destroy_state(struct drm_private_obj *obj,
166 struct drm_private_state *state)
167{
168 kfree(to_splitter_st(priv_to_comp_st(state)));
169}
170
171static const struct drm_private_state_funcs komeda_splitter_obj_funcs = {
172 .atomic_duplicate_state = komeda_splitter_atomic_duplicate_state,
173 .atomic_destroy_state = komeda_splitter_atomic_destroy_state,
174};
175
176static int komeda_splitter_obj_add(struct komeda_kms_dev *kms,
177 struct komeda_splitter *splitter)
178{
179 struct komeda_splitter_state *st;
180
181 st = kzalloc(sizeof(*st), GFP_KERNEL);
182 if (!st)
183 return -ENOMEM;
184
185 st->base.component = &splitter->base;
186 drm_atomic_private_obj_init(&kms->base,
187 &splitter->base.obj, &st->base.obj,
188 &komeda_splitter_obj_funcs);
189
190 return 0;
191}
192
193static struct drm_private_state *
194komeda_merger_atomic_duplicate_state(struct drm_private_obj *obj)
195{
196 struct komeda_merger_state *st;
197
198 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
199 if (!st)
200 return NULL;
201
202 komeda_component_state_reset(&st->base);
203 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
204
205 return &st->base.obj;
206}
207
208static void komeda_merger_atomic_destroy_state(struct drm_private_obj *obj,
209 struct drm_private_state *state)
210{
211 kfree(to_merger_st(priv_to_comp_st(state)));
212}
213
214static const struct drm_private_state_funcs komeda_merger_obj_funcs = {
215 .atomic_duplicate_state = komeda_merger_atomic_duplicate_state,
216 .atomic_destroy_state = komeda_merger_atomic_destroy_state,
217};
218
219static int komeda_merger_obj_add(struct komeda_kms_dev *kms,
220 struct komeda_merger *merger)
221{
222 struct komeda_merger_state *st;
223
224 st = kzalloc(sizeof(*st), GFP_KERNEL);
225 if (!st)
226 return -ENOMEM;
227
228 st->base.component = &merger->base;
229 drm_atomic_private_obj_init(&kms->base,
230 &merger->base.obj, &st->base.obj,
231 &komeda_merger_obj_funcs);
232
233 return 0;
234}
235
236static struct drm_private_state *
237komeda_improc_atomic_duplicate_state(struct drm_private_obj *obj)
238{
239 struct komeda_improc_state *st;
240
241 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
242 if (!st)
243 return NULL;
244
245 komeda_component_state_reset(&st->base);
246 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
247
248 return &st->base.obj;
249}
250
251static void
252komeda_improc_atomic_destroy_state(struct drm_private_obj *obj,
253 struct drm_private_state *state)
254{
255 kfree(to_improc_st(priv_to_comp_st(state)));
256}
257
258static const struct drm_private_state_funcs komeda_improc_obj_funcs = {
259 .atomic_duplicate_state = komeda_improc_atomic_duplicate_state,
260 .atomic_destroy_state = komeda_improc_atomic_destroy_state,
261};
262
263static int komeda_improc_obj_add(struct komeda_kms_dev *kms,
264 struct komeda_improc *improc)
265{
266 struct komeda_improc_state *st;
267
268 st = kzalloc(sizeof(*st), GFP_KERNEL);
269 if (!st)
270 return -ENOMEM;
271
272 st->base.component = &improc->base;
273 drm_atomic_private_obj_init(&kms->base, &improc->base.obj, &st->base.obj,
274 &komeda_improc_obj_funcs);
275
276 return 0;
277}
278
279static struct drm_private_state *
280komeda_timing_ctrlr_atomic_duplicate_state(struct drm_private_obj *obj)
281{
282 struct komeda_timing_ctrlr_state *st;
283
284 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
285 if (!st)
286 return NULL;
287
288 komeda_component_state_reset(&st->base);
289 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj);
290
291 return &st->base.obj;
292}
293
294static void
295komeda_timing_ctrlr_atomic_destroy_state(struct drm_private_obj *obj,
296 struct drm_private_state *state)
297{
298 kfree(to_ctrlr_st(priv_to_comp_st(state)));
299}
300
301static const struct drm_private_state_funcs komeda_timing_ctrlr_obj_funcs = {
302 .atomic_duplicate_state = komeda_timing_ctrlr_atomic_duplicate_state,
303 .atomic_destroy_state = komeda_timing_ctrlr_atomic_destroy_state,
304};
305
306static int komeda_timing_ctrlr_obj_add(struct komeda_kms_dev *kms,
307 struct komeda_timing_ctrlr *ctrlr)
308{
309 struct komeda_compiz_state *st;
310
311 st = kzalloc(sizeof(*st), GFP_KERNEL);
312 if (!st)
313 return -ENOMEM;
314
315 st->base.component = &ctrlr->base;
316 drm_atomic_private_obj_init(&kms->base, &ctrlr->base.obj, &st->base.obj,
317 &komeda_timing_ctrlr_obj_funcs);
318
319 return 0;
320}
321
322static struct drm_private_state *
323komeda_pipeline_atomic_duplicate_state(struct drm_private_obj *obj)
324{
325 struct komeda_pipeline_state *st;
326
327 st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL);
328 if (!st)
329 return NULL;
330
331 st->active_comps = 0;
332
333 __drm_atomic_helper_private_obj_duplicate_state(obj, &st->obj);
334
335 return &st->obj;
336}
337
338static void
339komeda_pipeline_atomic_destroy_state(struct drm_private_obj *obj,
340 struct drm_private_state *state)
341{
342 kfree(priv_to_pipe_st(state));
343}
344
345static const struct drm_private_state_funcs komeda_pipeline_obj_funcs = {
346 .atomic_duplicate_state = komeda_pipeline_atomic_duplicate_state,
347 .atomic_destroy_state = komeda_pipeline_atomic_destroy_state,
348};
349
350static int komeda_pipeline_obj_add(struct komeda_kms_dev *kms,
351 struct komeda_pipeline *pipe)
352{
353 struct komeda_pipeline_state *st;
354
355 st = kzalloc(sizeof(*st), GFP_KERNEL);
356 if (!st)
357 return -ENOMEM;
358
359 st->pipe = pipe;
360 drm_atomic_private_obj_init(&kms->base, &pipe->obj, &st->obj,
361 &komeda_pipeline_obj_funcs);
362
363 return 0;
364}
365
366int komeda_kms_add_private_objs(struct komeda_kms_dev *kms,
367 struct komeda_dev *mdev)
368{
369 struct komeda_pipeline *pipe;
370 int i, j, err;
371
372 for (i = 0; i < mdev->n_pipelines; i++) {
373 pipe = mdev->pipelines[i];
374
375 err = komeda_pipeline_obj_add(kms, pipe);
376 if (err)
377 return err;
378
379 for (j = 0; j < pipe->n_layers; j++) {
380 err = komeda_layer_obj_add(kms, pipe->layers[j]);
381 if (err)
382 return err;
383 }
384
385 if (pipe->wb_layer) {
386 err = komeda_layer_obj_add(kms, pipe->wb_layer);
387 if (err)
388 return err;
389 }
390
391 for (j = 0; j < pipe->n_scalers; j++) {
392 err = komeda_scaler_obj_add(kms, pipe->scalers[j]);
393 if (err)
394 return err;
395 }
396
397 err = komeda_compiz_obj_add(kms, pipe->compiz);
398 if (err)
399 return err;
400
401 if (pipe->splitter) {
402 err = komeda_splitter_obj_add(kms, pipe->splitter);
403 if (err)
404 return err;
405 }
406
407 if (pipe->merger) {
408 err = komeda_merger_obj_add(kms, pipe->merger);
409 if (err)
410 return err;
411 }
412
413 err = komeda_improc_obj_add(kms, pipe->improc);
414 if (err)
415 return err;
416
417 err = komeda_timing_ctrlr_obj_add(kms, pipe->ctrlr);
418 if (err)
419 return err;
420 }
421
422 return 0;
423}
424
425void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms)
426{
427 struct drm_mode_config *config = &kms->base.mode_config;
428 struct drm_private_obj *obj, *next;
429
430 list_for_each_entry_safe(obj, next, &config->privobj_list, head)
431 drm_atomic_private_obj_fini(obj);
432}
433