Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
c2fcd27
Documentation
arch
block
crypto
drivers
accessibility
acpi
amba
ata
atm
auxdisplay
base
bcma
block
bluetooth
bus
cdrom
char
clk
clocksource
connector
cpufreq
cpuidle
crypto
dca
devfreq
dio
dma-buf
dma
edac
eisa
extcon
firewire
firmware
fmc
gpio
gpu
drm
armada
ast
bochs
bridge
cirrus
exynos
gma500
i2c
i810
i915
mga
mgag200
msm
nouveau
omapdrm
panel
qxl
r128
radeon
rcar-du
savage
shmobile
sis
sti
tdfx
tegra
tilcdc
ttm
udl
via
vmwgfx
Kconfig
Makefile
README.drm
ati_pcigart.c
drm_agpsupport.c
drm_atomic.c
drm_atomic_helper.c
drm_auth.c
drm_bufs.c
drm_cache.c
drm_context.c
drm_crtc.c
drm_crtc_helper.c
drm_crtc_internal.h
drm_debugfs.c
drm_dma.c
drm_dp_helper.c
drm_dp_mst_topology.c
drm_drv.c
drm_edid.c
drm_edid_load.c
drm_encoder_slave.c
drm_fb_cma_helper.c
drm_fb_helper.c
drm_flip_work.c
drm_fops.c
drm_gem.c
drm_gem_cma_helper.c
drm_global.c
drm_hashtab.c
drm_info.c
drm_internal.h
drm_ioc32.c
drm_ioctl.c
drm_irq.c
drm_legacy.h
drm_lock.c
drm_memory.c
drm_mipi_dsi.c
drm_mm.c
drm_modes.c
drm_modeset_lock.c
drm_of.c
drm_panel.c
drm_pci.c
drm_plane_helper.c
drm_platform.c
drm_prime.c
drm_probe_helper.c
drm_rect.c
drm_scatter.c
drm_sysfs.c
drm_trace.h
drm_trace_points.c
drm_vm.c
drm_vma_manager.c
host1x
ipu-v3
vga
Makefile
hid
hsi
hv
hwmon
hwspinlock
i2c
ide
idle
iio
infiniband
input
iommu
ipack
irqchip
isdn
leds
lguest
macintosh
mailbox
mcb
md
media
memory
memstick
message
mfd
misc
mmc
mtd
net
nfc
ntb
nubus
of
oprofile
parisc
parport
pci
pcmcia
phy
pinctrl
platform
pnp
power
powercap
pps
ps3
ptp
pwm
rapidio
ras
regulator
remoteproc
reset
rpmsg
rtc
s390
sbus
scsi
sfi
sh
sn
soc
spi
spmi
ssb
staging
target
tc
thermal
thunderbolt
tty
uio
usb
uwb
vfio
vhost
video
virt
virtio
vlynq
vme
w1
watchdog
xen
zorro
Kconfig
Makefile
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
usr
virt
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
drivers
/
gpu
/
drm
/
drm_atomic_helper.c
Blame
Blame
Latest commit
History
History
355 lines (288 loc) · 9.17 KB
Breadcrumbs
linux
/
drivers
/
gpu
/
drm
/
drm_atomic_helper.c
Top
File metadata and controls
Code
Blame
355 lines (288 loc) · 9.17 KB
Raw
/* * Copyright (C) 2014 Red Hat * Copyright (C) 2014 Intel Corp. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Rob Clark <robdclark@gmail.com> * Daniel Vetter <daniel.vetter@ffwll.ch> */ #include <drm/drmP.h> #include <drm/drm_atomic.h> #include <drm/drm_plane_helper.h> #include <drm/drm_crtc_helper.h> static void drm_atomic_helper_plane_changed(struct drm_atomic_state *state, struct drm_plane_state *plane_state, struct drm_plane *plane) { struct drm_crtc_state *crtc_state; if (plane->state->crtc) { crtc_state = state->crtc_states[drm_crtc_index(plane->crtc)]; if (WARN_ON(!crtc_state)) return; crtc_state->planes_changed = true; } if (plane_state->crtc) { crtc_state = state->crtc_states[drm_crtc_index(plane_state->crtc)]; if (WARN_ON(!crtc_state)) return; crtc_state->planes_changed = true; } } /** * drm_atomic_helper_check - validate state object * @dev: DRM device * @state: the driver state object * * Check the state object to see if the requested state is physically possible. * Only crtcs and planes have check callbacks, so for any additional (global) * checking that a driver needs it can simply wrap that around this function. * Drivers without such needs can directly use this as their ->atomic_check() * callback. * * RETURNS * Zero for success or -errno */ int drm_atomic_helper_check(struct drm_device *dev, struct drm_atomic_state *state) { int nplanes = dev->mode_config.num_total_plane; int ncrtcs = dev->mode_config.num_crtc; int i, ret = 0; for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = state->planes[i]; struct drm_plane_state *plane_state = state->plane_states[i]; if (!plane) continue; funcs = plane->helper_private; drm_atomic_helper_plane_changed(state, plane_state, plane); if (!funcs || !funcs->atomic_check) continue; ret = funcs->atomic_check(plane, plane_state); if (ret) { DRM_DEBUG_KMS("[PLANE:%d] atomic check failed\n", plane->base.id); return ret; } } for (i = 0; i < ncrtcs; i++) { struct drm_crtc_helper_funcs *funcs; struct drm_crtc *crtc = state->crtcs[i]; if (!crtc) continue; funcs = crtc->helper_private; if (!funcs || !funcs->atomic_check) continue; ret = funcs->atomic_check(crtc, state->crtc_states[i]); if (ret) { DRM_DEBUG_KMS("[CRTC:%d] atomic check failed\n", crtc->base.id); return ret; } } return ret; } EXPORT_SYMBOL(drm_atomic_helper_check); /** * drm_atomic_helper_prepare_planes - prepare plane resources after commit * @dev: DRM device * @state: atomic state object with old state structures * * This function prepares plane state, specifically framebuffers, for the new * configuration. If any failure is encountered this function will call * ->cleanup_fb on any already successfully prepared framebuffer. * * Returns: * 0 on success, negative error code on failure. */ int drm_atomic_helper_prepare_planes(struct drm_device *dev, struct drm_atomic_state *state) { int nplanes = dev->mode_config.num_total_plane; int ret, i; for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = state->planes[i]; struct drm_framebuffer *fb; if (!plane) continue; funcs = plane->helper_private; fb = state->plane_states[i]->fb; if (fb && funcs->prepare_fb) { ret = funcs->prepare_fb(plane, fb); if (ret) goto fail; } } return 0; fail: for (i--; i >= 0; i--) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = state->planes[i]; struct drm_framebuffer *fb; if (!plane) continue; funcs = plane->helper_private; fb = state->plane_states[i]->fb; if (fb && funcs->cleanup_fb) funcs->cleanup_fb(plane, fb); } return ret; } EXPORT_SYMBOL(drm_atomic_helper_prepare_planes); /** * drm_atomic_helper_commit_planes - commit plane state * @dev: DRM device * @state: atomic state * * This function commits the new plane state using the plane and atomic helper * functions for planes and crtcs. It assumes that the atomic state has already * been pushed into the relevant object state pointers, since this step can no * longer fail. * * It still requires the global state object @state to know which planes and * crtcs need to be updated though. */ void drm_atomic_helper_commit_planes(struct drm_device *dev, struct drm_atomic_state *state) { int nplanes = dev->mode_config.num_total_plane; int ncrtcs = dev->mode_config.num_crtc; int i; for (i = 0; i < ncrtcs; i++) { struct drm_crtc_helper_funcs *funcs; struct drm_crtc *crtc = state->crtcs[i]; if (!crtc) continue; funcs = crtc->helper_private; if (!funcs || !funcs->atomic_begin) continue; funcs->atomic_begin(crtc); } for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = state->planes[i]; if (!plane) continue; funcs = plane->helper_private; if (!funcs || !funcs->atomic_update) continue; funcs->atomic_update(plane); } for (i = 0; i < ncrtcs; i++) { struct drm_crtc_helper_funcs *funcs; struct drm_crtc *crtc = state->crtcs[i]; if (!crtc) continue; funcs = crtc->helper_private; if (!funcs || !funcs->atomic_flush) continue; funcs->atomic_flush(crtc); } } EXPORT_SYMBOL(drm_atomic_helper_commit_planes); /** * drm_atomic_helper_cleanup_planes - cleanup plane resources after commit * @dev: DRM device * @old_state: atomic state object with old state structures * * This function cleans up plane state, specifically framebuffers, from the old * configuration. Hence the old configuration must be perserved in @old_state to * be able to call this function. * * This function must also be called on the new state when the atomic update * fails at any point after calling drm_atomic_helper_prepare_planes(). */ void drm_atomic_helper_cleanup_planes(struct drm_device *dev, struct drm_atomic_state *old_state) { int nplanes = dev->mode_config.num_total_plane; int i; for (i = 0; i < nplanes; i++) { struct drm_plane_helper_funcs *funcs; struct drm_plane *plane = old_state->planes[i]; struct drm_framebuffer *old_fb; if (!plane) continue; funcs = plane->helper_private; old_fb = old_state->plane_states[i]->fb; if (old_fb && funcs->cleanup_fb) funcs->cleanup_fb(plane, old_fb); } } EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes); /** * drm_atomic_helper_swap_state - store atomic state into current sw state * @dev: DRM device * @state: atomic state * * This function stores the atomic state into the current state pointers in all * driver objects. It should be called after all failing steps have been done * and succeeded, but before the actual hardware state is committed. * * For cleanup and error recovery the current state for all changed objects will * be swaped into @state. * * With that sequence it fits perfectly into the plane prepare/cleanup sequence: * * 1. Call drm_atomic_helper_prepare_planes() with the staged atomic state. * * 2. Do any other steps that might fail. * * 3. Put the staged state into the current state pointers with this function. * * 4. Actually commit the hardware state. * * 5. Call drm_atomic_helper_cleanup_planes with @state, which since step 3 * contains the old state. Also do any other cleanup required with that state. */ void drm_atomic_helper_swap_state(struct drm_device *dev, struct drm_atomic_state *state) { int i; for (i = 0; i < dev->mode_config.num_connector; i++) { struct drm_connector *connector = state->connectors[i]; if (!connector) continue; connector->state->state = state; swap(state->connector_states[i], connector->state); connector->state->state = NULL; } for (i = 0; i < dev->mode_config.num_crtc; i++) { struct drm_crtc *crtc = state->crtcs[i]; if (!crtc) continue; crtc->state->state = state; swap(state->crtc_states[i], crtc->state); crtc->state->state = NULL; } for (i = 0; i < dev->mode_config.num_total_plane; i++) { struct drm_plane *plane = state->planes[i]; if (!plane) continue; plane->state->state = state; swap(state->plane_states[i], plane->state); plane->state->state = NULL; } } EXPORT_SYMBOL(drm_atomic_helper_swap_state);
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
28
29
30
31
32
33
34
35
36
37
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
You can’t perform that action at this time.