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
27#include <drm/drm_atomic.h>
28#include <drm/drm_atomic_state_helper.h>
29#include <drm/drm_connector.h>
30#include <drm/drm_crtc.h>
31#include <drm/drm_device.h>
32#include <drm/drm_plane.h>
33#include <drm/drm_print.h>
34#include <drm/drm_writeback.h>
35
36#include <linux/slab.h>
37#include <linux/dma-fence.h>
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72void
73__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
74 struct drm_crtc_state *crtc_state)
75{
76 if (crtc_state)
77 crtc_state->crtc = crtc;
78
79 crtc->state = crtc_state;
80}
81EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
82
83
84
85
86
87
88
89
90void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
91{
92 struct drm_crtc_state *crtc_state =
93 kzalloc(sizeof(*crtc->state), GFP_KERNEL);
94
95 if (crtc->state)
96 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
97
98 __drm_atomic_helper_crtc_reset(crtc, crtc_state);
99}
100EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
101
102
103
104
105
106
107
108
109
110void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
111 struct drm_crtc_state *state)
112{
113 memcpy(state, crtc->state, sizeof(*state));
114
115 if (state->mode_blob)
116 drm_property_blob_get(state->mode_blob);
117 if (state->degamma_lut)
118 drm_property_blob_get(state->degamma_lut);
119 if (state->ctm)
120 drm_property_blob_get(state->ctm);
121 if (state->gamma_lut)
122 drm_property_blob_get(state->gamma_lut);
123 state->mode_changed = false;
124 state->active_changed = false;
125 state->planes_changed = false;
126 state->connectors_changed = false;
127 state->color_mgmt_changed = false;
128 state->zpos_changed = false;
129 state->commit = NULL;
130 state->event = NULL;
131 state->pageflip_flags = 0;
132
133
134 state->active = drm_atomic_crtc_effectively_active(state);
135 state->self_refresh_active = false;
136}
137EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
138
139
140
141
142
143
144
145
146struct drm_crtc_state *
147drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
148{
149 struct drm_crtc_state *state;
150
151 if (WARN_ON(!crtc->state))
152 return NULL;
153
154 state = kmalloc(sizeof(*state), GFP_KERNEL);
155 if (state)
156 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
157
158 return state;
159}
160EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
161
162
163
164
165
166
167
168
169
170void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
171{
172 if (state->commit) {
173
174
175
176
177
178
179
180
181
182 if (state->event && state->commit->abort_completion)
183 drm_crtc_commit_put(state->commit);
184
185 kfree(state->commit->event);
186 state->commit->event = NULL;
187
188 drm_crtc_commit_put(state->commit);
189 }
190
191 drm_property_blob_put(state->mode_blob);
192 drm_property_blob_put(state->degamma_lut);
193 drm_property_blob_put(state->ctm);
194 drm_property_blob_put(state->gamma_lut);
195}
196EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
197
198
199
200
201
202
203
204
205
206void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
207 struct drm_crtc_state *state)
208{
209 __drm_atomic_helper_crtc_destroy_state(state);
210 kfree(state);
211}
212EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
213
214
215
216
217
218
219
220
221
222void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
223 struct drm_plane_state *state)
224{
225 state->plane = plane;
226 state->rotation = DRM_MODE_ROTATE_0;
227
228 state->alpha = DRM_BLEND_ALPHA_OPAQUE;
229 state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
230
231 plane->state = state;
232}
233EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
234
235
236
237
238
239
240
241
242void drm_atomic_helper_plane_reset(struct drm_plane *plane)
243{
244 if (plane->state)
245 __drm_atomic_helper_plane_destroy_state(plane->state);
246
247 kfree(plane->state);
248 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
249 if (plane->state)
250 __drm_atomic_helper_plane_reset(plane, plane->state);
251}
252EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
253
254
255
256
257
258
259
260
261
262void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
263 struct drm_plane_state *state)
264{
265 memcpy(state, plane->state, sizeof(*state));
266
267 if (state->fb)
268 drm_framebuffer_get(state->fb);
269
270 state->fence = NULL;
271 state->commit = NULL;
272 state->fb_damage_clips = NULL;
273}
274EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
275
276
277
278
279
280
281
282
283struct drm_plane_state *
284drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
285{
286 struct drm_plane_state *state;
287
288 if (WARN_ON(!plane->state))
289 return NULL;
290
291 state = kmalloc(sizeof(*state), GFP_KERNEL);
292 if (state)
293 __drm_atomic_helper_plane_duplicate_state(plane, state);
294
295 return state;
296}
297EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
298
299
300
301
302
303
304
305
306
307void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
308{
309 if (state->fb)
310 drm_framebuffer_put(state->fb);
311
312 if (state->fence)
313 dma_fence_put(state->fence);
314
315 if (state->commit)
316 drm_crtc_commit_put(state->commit);
317
318 drm_property_blob_put(state->fb_damage_clips);
319}
320EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
321
322
323
324
325
326
327
328
329
330void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
331 struct drm_plane_state *state)
332{
333 __drm_atomic_helper_plane_destroy_state(state);
334 kfree(state);
335}
336EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
337
338
339
340
341
342
343
344
345
346
347
348
349
350void
351__drm_atomic_helper_connector_reset(struct drm_connector *connector,
352 struct drm_connector_state *conn_state)
353{
354 if (conn_state)
355 conn_state->connector = connector;
356
357 connector->state = conn_state;
358}
359EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
360
361
362
363
364
365
366
367
368
369void drm_atomic_helper_connector_reset(struct drm_connector *connector)
370{
371 struct drm_connector_state *conn_state =
372 kzalloc(sizeof(*conn_state), GFP_KERNEL);
373
374 if (connector->state)
375 __drm_atomic_helper_connector_destroy_state(connector->state);
376
377 kfree(connector->state);
378 __drm_atomic_helper_connector_reset(connector, conn_state);
379}
380EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
381
382
383
384
385
386
387
388void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
389{
390 struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
391 struct drm_connector_state *state = connector->state;
392
393 state->tv.margins.left = cmdline->tv_margins.left;
394 state->tv.margins.right = cmdline->tv_margins.right;
395 state->tv.margins.top = cmdline->tv_margins.top;
396 state->tv.margins.bottom = cmdline->tv_margins.bottom;
397}
398EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
399
400
401
402
403
404
405
406
407
408void
409__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
410 struct drm_connector_state *state)
411{
412 memcpy(state, connector->state, sizeof(*state));
413 if (state->crtc)
414 drm_connector_get(connector);
415 state->commit = NULL;
416
417 if (state->hdr_output_metadata)
418 drm_property_blob_get(state->hdr_output_metadata);
419
420
421 state->writeback_job = NULL;
422}
423EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
424
425
426
427
428
429
430
431
432struct drm_connector_state *
433drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
434{
435 struct drm_connector_state *state;
436
437 if (WARN_ON(!connector->state))
438 return NULL;
439
440 state = kmalloc(sizeof(*state), GFP_KERNEL);
441 if (state)
442 __drm_atomic_helper_connector_duplicate_state(connector, state);
443
444 return state;
445}
446EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
447
448
449
450
451
452
453
454
455
456void
457__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
458{
459 if (state->crtc)
460 drm_connector_put(state->connector);
461
462 if (state->commit)
463 drm_crtc_commit_put(state->commit);
464
465 if (state->writeback_job)
466 drm_writeback_cleanup_job(state->writeback_job);
467
468 drm_property_blob_put(state->hdr_output_metadata);
469}
470EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
471
472
473
474
475
476
477
478
479
480void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
481 struct drm_connector_state *state)
482{
483 __drm_atomic_helper_connector_destroy_state(state);
484 kfree(state);
485}
486EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
487
488
489
490
491
492
493
494
495
496void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
497 struct drm_private_state *state)
498{
499 memcpy(state, obj->state, sizeof(*state));
500}
501EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
502