1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
5 *
6 */
7 #include "komeda_dev.h"
8 #include "komeda_kms.h"
9
10 static void
komeda_component_state_reset(struct komeda_component_state * st)11 komeda_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
19 static struct drm_private_state *
komeda_layer_atomic_duplicate_state(struct drm_private_obj * obj)20 komeda_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
34 static void
komeda_layer_atomic_destroy_state(struct drm_private_obj * obj,struct drm_private_state * state)35 komeda_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
43 static 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
komeda_layer_obj_add(struct komeda_kms_dev * kms,struct komeda_layer * layer)48 static 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
63 static struct drm_private_state *
komeda_scaler_atomic_duplicate_state(struct drm_private_obj * obj)64 komeda_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
78 static void
komeda_scaler_atomic_destroy_state(struct drm_private_obj * obj,struct drm_private_state * state)79 komeda_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
85 static 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
komeda_scaler_obj_add(struct komeda_kms_dev * kms,struct komeda_scaler * scaler)90 static 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
106 static struct drm_private_state *
komeda_compiz_atomic_duplicate_state(struct drm_private_obj * obj)107 komeda_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
121 static void
komeda_compiz_atomic_destroy_state(struct drm_private_obj * obj,struct drm_private_state * state)122 komeda_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
128 static 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
komeda_compiz_obj_add(struct komeda_kms_dev * kms,struct komeda_compiz * compiz)133 static 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
149 static struct drm_private_state *
komeda_splitter_atomic_duplicate_state(struct drm_private_obj * obj)150 komeda_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
164 static void
komeda_splitter_atomic_destroy_state(struct drm_private_obj * obj,struct drm_private_state * state)165 komeda_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
171 static 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
komeda_splitter_obj_add(struct komeda_kms_dev * kms,struct komeda_splitter * splitter)176 static 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
193 static struct drm_private_state *
komeda_merger_atomic_duplicate_state(struct drm_private_obj * obj)194 komeda_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
komeda_merger_atomic_destroy_state(struct drm_private_obj * obj,struct drm_private_state * state)208 static 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
214 static 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
komeda_merger_obj_add(struct komeda_kms_dev * kms,struct komeda_merger * merger)219 static 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
236 static struct drm_private_state *
komeda_improc_atomic_duplicate_state(struct drm_private_obj * obj)237 komeda_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
251 static void
komeda_improc_atomic_destroy_state(struct drm_private_obj * obj,struct drm_private_state * state)252 komeda_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
258 static 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
komeda_improc_obj_add(struct komeda_kms_dev * kms,struct komeda_improc * improc)263 static 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
279 static struct drm_private_state *
komeda_timing_ctrlr_atomic_duplicate_state(struct drm_private_obj * obj)280 komeda_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
294 static void
komeda_timing_ctrlr_atomic_destroy_state(struct drm_private_obj * obj,struct drm_private_state * state)295 komeda_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
301 static 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
komeda_timing_ctrlr_obj_add(struct komeda_kms_dev * kms,struct komeda_timing_ctrlr * ctrlr)306 static 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
322 static struct drm_private_state *
komeda_pipeline_atomic_duplicate_state(struct drm_private_obj * obj)323 komeda_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
338 static void
komeda_pipeline_atomic_destroy_state(struct drm_private_obj * obj,struct drm_private_state * state)339 komeda_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
345 static 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
komeda_pipeline_obj_add(struct komeda_kms_dev * kms,struct komeda_pipeline * pipe)350 static 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
komeda_kms_add_private_objs(struct komeda_kms_dev * kms,struct komeda_dev * mdev)366 int 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
komeda_kms_cleanup_private_objs(struct komeda_kms_dev * kms)425 void 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