aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-04-03 02:30:24 -0400
committerDave Airlie <airlied@redhat.com>2017-04-03 02:30:24 -0400
commit320d8c3d38739fa8e31a076b86cbdafcf8897d5e (patch)
treeac43e4981ad56b9612cd0cfc0e075401da38f89f
parent7558ab66424e61819cbf3d778d9f780f3aa205e9 (diff)
parentb121b051d14cc6e4e799e96e9c06c55989f9e073 (diff)
Merge tag 'drm-misc-next-2017-03-31' of git://anongit.freedesktop.org/git/drm-misc into drm-next
drm-misc for 4.12: Core: - Removed some fb subsampling dimension checks from core (Ville) - Some MST slot cleanup (Dhinakaran) - Extracted drm_debugfs.h & drm_ioctl.h from drmP.h (Daniel) - Added drm_atomic_helper_shutdown() to compliment suspend/resume counterparts (Daniel) - Pipe context through legacy modeset to remove legacy_backoff nasties (Daniel) - Cleanups around vblank as well as allowing lockless counter reads (Chris W.) - VGA Switcheroo added to MAINTAINERS with Lukas Wunner as reviewer (Lukas) Drivers: - Enhancements to rockchip driver probe (Jeffy) and dsi (Chris Z.) - Thunderbolt external GPU awareness added (Lukas) * tag 'drm-misc-next-2017-03-31' of git://anongit.freedesktop.org/git/drm-misc: (63 commits) apple-gmux: Don't switch external DP port on 2011+ MacBook Pros drm/nouveau: Don't register Thunderbolt eGPU with vga_switcheroo drm/amdgpu: Don't register Thunderbolt eGPU with vga_switcheroo drm/radeon: Don't register Thunderbolt eGPU with vga_switcheroo PCI: Recognize Thunderbolt devices MAINTAINERS: Add Lukas Wunner as reviewer for vga_switcheroo drm: Fix locking gotcha in page_flip ioctl drm: Clarify the role of plane_state argument to drm_simple update(). drm: Clear e after kfree in drm_mode_page_flip_ioctl drm: Convert cmpxchg(bool) back to a two step operation drm/bridge: ti-tfp410: support hpd via gpio drm: use .hword to represent 16-bit numbers Revert unrelated part of "drm: simplify the locking in the GETCRTC ioctl" drm: Fixup failure paths in drm_atomic_helper_set_config drm: Peek at the current counter/timestamp for vblank queries drm: Refactor vblank sequence number comparison drm: vblank cannot be enabled if dev->irq_enabled is false drm: Mark up accesses of vblank->enabled outside of its spinlock drm: Make the decision to keep vblank irq enabled earlier drm/atomic-helper: Remove the backoff hack from set_config ...
-rw-r--r--Documentation/EDID/edid.S6
-rw-r--r--Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt2
-rw-r--r--Documentation/gpu/drm-uapi.rst12
-rw-r--r--Documentation/gpu/introduction.rst25
-rw-r--r--Documentation/gpu/kms-properties.csv5
-rw-r--r--Documentation/gpu/todo.rst96
-rw-r--r--Documentation/process/index.rst1
-rw-r--r--MAINTAINERS10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h6
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c3
-rw-r--r--drivers/gpu/drm/armada/armada_overlay.c6
-rw-r--r--drivers/gpu/drm/bochs/bochs_fbdev.c4
-rw-r--r--drivers/gpu/drm/bochs/bochs_kms.c3
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c2
-rw-r--r--drivers/gpu/drm/bridge/ti-tfp410.c72
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c171
-rw-r--r--drivers/gpu/drm/drm_crtc.c73
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c4
-rw-r--r--drivers/gpu/drm/drm_debugfs.c56
-rw-r--r--drivers/gpu/drm/drm_debugfs_crc.c17
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c35
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c2
-rw-r--r--drivers/gpu/drm/drm_fourcc.c25
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c45
-rw-r--r--drivers/gpu/drm/drm_internal.h2
-rw-r--r--drivers/gpu/drm/drm_ioctl.c1
-rw-r--r--drivers/gpu/drm/drm_irq.c90
-rw-r--r--drivers/gpu/drm/drm_modeset_helper.c2
-rw-r--r--drivers/gpu/drm/drm_plane.c91
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c11
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c4
-rw-r--r--drivers/gpu/drm/gma500/gma_display.c7
-rw-r--r--drivers/gpu/drm/gma500/gma_display.h3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c20
-rw-r--r--drivers/gpu/drm/i915/intel_display.c5
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c4
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c7
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/overlay.c18
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_vga.c10
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_dp_mst.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c3
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig10
-rw-r--r--drivers/gpu/drm/rockchip/Makefile16
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c9
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c8
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi.c50
-rw-r--r--drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c10
-rw-r--r--drivers/gpu/drm/rockchip/inno_hdmi.c10
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c141
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.h6
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c8
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_crtc.c3
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_plane.c8
-rw-r--r--drivers/gpu/drm/tegra/dc.c8
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c12
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-core.c19
-rw-r--r--drivers/gpu/drm/tinydrm/mi0283qt.c3
-rw-r--r--drivers/gpu/drm/udl/udl_modeset.c3
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c5
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h3
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c5
-rw-r--r--drivers/gpu/drm/zte/zx_hdmi.c1
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c21
-rw-r--r--drivers/platform/x86/apple-gmux.c31
-rw-r--r--include/drm/drmP.h106
-rw-r--r--include/drm/drm_atomic.h159
-rw-r--r--include/drm/drm_atomic_helper.h16
-rw-r--r--include/drm/drm_connector.h17
-rw-r--r--include/drm/drm_crtc.h28
-rw-r--r--include/drm/drm_crtc_helper.h39
-rw-r--r--include/drm/drm_debugfs.h101
-rw-r--r--include/drm/drm_dp_mst_helper.h15
-rw-r--r--include/drm/drm_drv.h4
-rw-r--r--include/drm/drm_fourcc.h6
-rw-r--r--include/drm/drm_global.h8
-rw-r--r--include/drm/drm_hashtab.h20
-rw-r--r--include/drm/drm_ioctl.h102
-rw-r--r--include/drm/drm_mode_config.h154
-rw-r--r--include/drm/drm_of.h24
-rw-r--r--include/drm/drm_pci.h22
-rw-r--r--include/drm/drm_plane.h43
-rw-r--r--include/drm/drm_plane_helper.h6
-rw-r--r--include/drm/drm_prime.h30
-rw-r--r--include/drm/drm_scdc_helper.h2
-rw-r--r--include/drm/drm_simple_kms_helper.h2
-rw-r--r--include/drm/drm_sysfs.h4
-rw-r--r--include/drm/tinydrm/tinydrm.h4
-rw-r--r--include/linux/pci.h23
101 files changed, 1596 insertions, 769 deletions
diff --git a/Documentation/EDID/edid.S b/Documentation/EDID/edid.S
index 7ac03276d7a2..ef082dcc6084 100644
--- a/Documentation/EDID/edid.S
+++ b/Documentation/EDID/edid.S
@@ -59,9 +59,9 @@
59/* Fixed header pattern */ 59/* Fixed header pattern */
60header: .byte 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00 60header: .byte 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00
61 61
62mfg_id: .word swap16(mfgname2id(MFG_LNX1, MFG_LNX2, MFG_LNX3)) 62mfg_id: .hword swap16(mfgname2id(MFG_LNX1, MFG_LNX2, MFG_LNX3))
63 63
64prod_code: .word 0 64prod_code: .hword 0
65 65
66/* Serial number. 32 bits, little endian. */ 66/* Serial number. 32 bits, little endian. */
67serial_number: .long SERIAL 67serial_number: .long SERIAL
@@ -177,7 +177,7 @@ std_vres: .byte (XY_RATIO<<6)+VFREQ-60
177 177
178descriptor1: 178descriptor1:
179/* Pixel clock in 10 kHz units. (0.-655.35 MHz, little-endian) */ 179/* Pixel clock in 10 kHz units. (0.-655.35 MHz, little-endian) */
180clock: .word CLOCK/10 180clock: .hword CLOCK/10
181 181
182/* Horizontal active pixels 8 lsbits (0-4095) */ 182/* Horizontal active pixels 8 lsbits (0-4095) */
183x_act_lsb: .byte XPIX&0xff 183x_act_lsb: .byte XPIX&0xff
diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 188f6f7403e6..1d722f5055ab 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -10,7 +10,7 @@ Required properties:
10- interrupts: Represent the controller's interrupt to the CPU(s). 10- interrupts: Represent the controller's interrupt to the CPU(s).
11- clocks, clock-names: Phandles to the controller's pll reference 11- clocks, clock-names: Phandles to the controller's pll reference
12 clock(ref) and APB clock(pclk). For RK3399, a phy config clock 12 clock(ref) and APB clock(pclk). For RK3399, a phy config clock
13 (phy_cfg) is additional required. As described in [1]. 13 (phy_cfg) and a grf clock(grf) are required. As described in [1].
14- rockchip,grf: this soc should set GRF regs to mux vopl/vopb. 14- rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
15- ports: contain a port node with endpoint definitions as defined in [2]. 15- ports: contain a port node with endpoint definitions as defined in [2].
16 For vopb,set the reg = <0> and set the reg = <1> for vopl. 16 For vopb,set the reg = <0> and set the reg = <1> for vopl.
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
index 352652810dab..76356c86e358 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -207,6 +207,18 @@ Display CRC Support
207.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c 207.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
208 :doc: CRC ABI 208 :doc: CRC ABI
209 209
210.. kernel-doc:: drivers/gpu/drm/drm_debugfs_crc.c
211 :export:
212
213Debugfs Support
214---------------
215
216.. kernel-doc:: include/drm/drm_debugfs.h
217 :internal:
218
219.. kernel-doc:: drivers/gpu/drm/drm_debugfs.c
220 :export:
221
210VBlank event handling 222VBlank event handling
211===================== 223=====================
212 224
diff --git a/Documentation/gpu/introduction.rst b/Documentation/gpu/introduction.rst
index 1f8bd5ef5f9d..05a82bdfbca4 100644
--- a/Documentation/gpu/introduction.rst
+++ b/Documentation/gpu/introduction.rst
@@ -60,3 +60,28 @@ checkpatch or sparse. We welcome such contributions.
60 60
61Anyone looking to kick it up a notch can find a list of janitorial tasks on 61Anyone looking to kick it up a notch can find a list of janitorial tasks on
62the :ref:`TODO list <todo>`. 62the :ref:`TODO list <todo>`.
63
64Contribution Process
65====================
66
67Mostly the DRM subsystem works like any other kernel subsystem, see :ref:`the
68main process guidelines and documentation <process_index>` for how things work.
69Here we just document some of the specialities of the GPU subsystem.
70
71Feature Merge Deadlines
72-----------------------
73
74All feature work must be in the linux-next tree by the -rc6 release of the
75current release cycle, otherwise they must be postponed and can't reach the next
76merge window. All patches must have landed in the drm-next tree by latest -rc7,
77but if your branch is not in linux-next then this must have happened by -rc6
78already.
79
80After that point only bugfixes (like after the upstream merge window has closed
81with the -rc1 release) are allowed. No new platform enabling or new drivers are
82allowed.
83
84This means that there's a blackout-period of about one month where feature work
85can't be merged. The recommended way to deal with that is having a -next tree
86that's always open, but making sure to not feed it into linux-next during the
87blackout period. As an example, drm-misc works like that.
diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
index 981873a05d14..927b65e14219 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -1,10 +1,5 @@
1Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,Description/Restrictions 1Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,Description/Restrictions
2,,“scaling mode”,ENUM,"{ ""None"", ""Full"", ""Center"", ""Full aspect"" }",Connector,"Supported by: amdgpu, gma500, i915, nouveau and radeon." 2,,“scaling mode”,ENUM,"{ ""None"", ""Full"", ""Center"", ""Full aspect"" }",Connector,"Supported by: amdgpu, gma500, i915, nouveau and radeon."
3,Connector,“EDID”,BLOB | IMMUTABLE,0,Connector,Contains id of edid blob ptr object.
4,,“DPMS”,ENUM,"{ “On”, “Standby”, “Suspend”, “Off” }",Connector,Contains DPMS operation mode value.
5,,“PATH”,BLOB | IMMUTABLE,0,Connector,Contains topology path to a connector.
6,,“TILE”,BLOB | IMMUTABLE,0,Connector,Contains tiling information for a connector.
7,,“CRTC_ID”,OBJECT,DRM_MODE_OBJECT_CRTC,Connector,CRTC that connector is attached to (atomic)
8,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD 3,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD
9,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD 4,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD
10,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD 5,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 64e9d16170ce..e255b36b34a3 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -99,6 +99,30 @@ events for atomic commits correctly. But fixing these bugs is good anyway.
99 99
100Contact: Daniel Vetter, respective driver maintainers 100Contact: Daniel Vetter, respective driver maintainers
101 101
102Better manual-upload support for atomic
103---------------------------------------
104
105This would be especially useful for tinydrm:
106
107- Add a struct drm_rect dirty_clip to drm_crtc_state. When duplicating the
108 crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in
109 __drm_atomic_helper_crtc_duplicate_state().
110
111- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_
112 prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this
113 is a function useful to implement the fb->dirty function.
114
115- Create a new drm_fb_dirty function which does essentially what e.g.
116 mipi_dbi_fb_dirty does. You can use e.g. drm_atomic_helper_update_plane as the
117 template. But instead of doing a simple full-screen plane update, this new
118 helper also sets crtc_state->dirty_clip to the right coordinates. And of
119 course it needs to check whether the fb is actually active (and maybe where),
120 so there's some book-keeping involved. There's also some good fun involved in
121 scaling things appropriately. For that case we might simply give up and
122 declare the entire area covered by the plane as dirty.
123
124Contact: Noralf Trønnes, Daniel Vetter
125
102Fallout from atomic KMS 126Fallout from atomic KMS
103----------------------- 127-----------------------
104 128
@@ -272,6 +296,32 @@ This is a really varied tasks with lots of little bits and pieces:
272 296
273Contact: Daniel Vetter 297Contact: Daniel Vetter
274 298
299Clean up the debugfs support
300----------------------------
301
302There's a bunch of issues with it:
303
304- The drm_info_list ->show() function doesn't even bother to cast to the drm
305 structure for you. This is lazy.
306
307- We probably want to have some support for debugfs files on crtc/connectors and
308 maybe other kms objects directly in core. There's even drm_print support in
309 the funcs for these objects to dump kms state, so it's all there. And then the
310 ->show() functions should obviously give you a pointer to the right object.
311
312- The drm_info_list stuff is centered on drm_minor instead of drm_device. For
313 anything we want to print drm_device (or maybe drm_file) is the right thing.
314
315- The drm_driver->debugfs_init hooks we have is just an artifact of the old
316 midlayered load sequence. DRM debugfs should work more like sysfs, where you
317 can create properties/files for an object anytime you want, and the core
318 takes care of publishing/unpuplishing all the files at register/unregister
319 time. Drivers shouldn't need to worry about these technicalities, and fixing
320 this (together with the drm_minor->drm_device move) would allow us to remove
321 debugfs_init.
322
323Contact: Daniel Vetter
324
275Better Testing 325Better Testing
276============== 326==============
277 327
@@ -310,6 +360,52 @@ Contact: Daniel Vetter
310Driver Specific 360Driver Specific
311=============== 361===============
312 362
363tinydrm
364-------
365
366Tinydrm is the helper driver for really simple fb drivers. The goal is to make
367those drivers as simple as possible, so lots of room for refactoring:
368
369- backlight helpers, probably best to put them into a new drm_backlight.c.
370 This is because drivers/video is de-facto unmaintained. We could also
371 move drivers/video/backlight to drivers/gpu/backlight and take it all
372 over within drm-misc, but that's more work.
373
374- spi helpers, probably best put into spi core/helper code. Thierry said
375 the spi maintainer is fast&reactive, so shouldn't be a big issue.
376
377- extract the mipi-dbi helper (well, the non-tinydrm specific parts at
378 least) into a separate helper, like we have for mipi-dsi already. Or follow
379 one of the ideas for having a shared dsi/dbi helper, abstracting away the
380 transport details more.
381
382- tinydrm_lastclose could be drm_fb_helper_lastclose. Only thing we need
383 for that is to store the drm_fb_helper pointer somewhere in
384 drm_device->mode_config. And then we could roll that out to all the
385 drivers.
386
387- tinydrm_gem_cma_prime_import_sg_table should probably go into the cma
388 helpers, as a _vmapped variant (since not every driver needs the vmap).
389 And tinydrm_gem_cma_free_object could the be merged into
390 drm_gem_cma_free_object().
391
392- tinydrm_fb_create we could move into drm_simple_pipe, only need to add
393 the fb_create hook to drm_simple_pipe_funcs, which would again simplify a
394 bunch of things (since it gives you a one-stop vfunc for simple drivers).
395
396- Quick aside: The unregister devm stuff is kinda getting the lifetimes of
397 a drm_device wrong. Doesn't matter, since everyone else gets it wrong
398 too :-)
399
400- With the fbdev pointer in dev->mode_config we could also make
401 suspend/resume helpers entirely generic, at least if we add a
402 dev->mode_config.suspend_state. We could even provide a generic pm_ops
403 structure with those.
404
405- also rework the drm_framebuffer_funcs->dirty hook wire-up, see above.
406
407Contact: Noralf Trønnes, Daniel Vetter
408
313Outside DRM 409Outside DRM
314=========== 410===========
315 411
diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst
index 10aa6920709a..82fc399fcd33 100644
--- a/Documentation/process/index.rst
+++ b/Documentation/process/index.rst
@@ -3,6 +3,7 @@
3 \renewcommand\thesection* 3 \renewcommand\thesection*
4 \renewcommand\thesubsection* 4 \renewcommand\thesubsection*
5 5
6.. _process_index:
6 7
7Working with the kernel development community 8Working with the kernel development community
8============================================= 9=============================================
diff --git a/MAINTAINERS b/MAINTAINERS
index be86eee3353f..fa8479e1799a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4145,6 +4145,7 @@ F: Documentation/devicetree/bindings/video/
4145F: Documentation/gpu/ 4145F: Documentation/gpu/
4146F: include/drm/ 4146F: include/drm/
4147F: include/uapi/drm/ 4147F: include/uapi/drm/
4148F: include/linux/vga*
4148 4149
4149DRM DRIVERS AND MISC GPU PATCHES 4150DRM DRIVERS AND MISC GPU PATCHES
4150M: Daniel Vetter <daniel.vetter@intel.com> 4151M: Daniel Vetter <daniel.vetter@intel.com>
@@ -4158,6 +4159,7 @@ F: drivers/gpu/vga/
4158F: drivers/gpu/drm/* 4159F: drivers/gpu/drm/*
4159F: include/drm/drm* 4160F: include/drm/drm*
4160F: include/uapi/drm/drm* 4161F: include/uapi/drm/drm*
4162F: include/linux/vga*
4161 4163
4162DRM DRIVER FOR AST SERVER GRAPHICS CHIPS 4164DRM DRIVER FOR AST SERVER GRAPHICS CHIPS
4163M: Dave Airlie <airlied@redhat.com> 4165M: Dave Airlie <airlied@redhat.com>
@@ -13257,6 +13259,14 @@ L: kvm@vger.kernel.org
13257S: Maintained 13259S: Maintained
13258F: drivers/vfio/platform/ 13260F: drivers/vfio/platform/
13259 13261
13262VGA_SWITCHEROO
13263R: Lukas Wunner <lukas@wunner.de>
13264S: Maintained
13265F: Documentation/gpu/vga-switcheroo.rst
13266F: drivers/gpu/vga/vga_switcheroo.c
13267F: include/linux/vga_switcheroo.h
13268T: git git://anongit.freedesktop.org/drm/drm-misc
13269
13260VIDEOBUF2 FRAMEWORK 13270VIDEOBUF2 FRAMEWORK
13261M: Pawel Osciak <pawel@osciak.com> 13271M: Pawel Osciak <pawel@osciak.com>
13262M: Marek Szyprowski <m.szyprowski@samsung.com> 13272M: Marek Szyprowski <m.szyprowski@samsung.com>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 93061a439dbc..83dda05325b8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1929,7 +1929,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
1929 runtime = true; 1929 runtime = true;
1930 if (amdgpu_device_is_px(ddev)) 1930 if (amdgpu_device_is_px(ddev))
1931 runtime = true; 1931 runtime = true;
1932 vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime); 1932 if (!pci_is_thunderbolt_attached(adev->pdev))
1933 vga_switcheroo_register_client(adev->pdev,
1934 &amdgpu_switcheroo_ops, runtime);
1933 if (runtime) 1935 if (runtime)
1934 vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain); 1936 vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
1935 1937
@@ -2084,7 +2086,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
2084 amdgpu_atombios_fini(adev); 2086 amdgpu_atombios_fini(adev);
2085 kfree(adev->bios); 2087 kfree(adev->bios);
2086 adev->bios = NULL; 2088 adev->bios = NULL;
2087 vga_switcheroo_unregister_client(adev->pdev); 2089 if (!pci_is_thunderbolt_attached(adev->pdev))
2090 vga_switcheroo_unregister_client(adev->pdev);
2088 if (adev->flags & AMD_IS_PX) 2091 if (adev->flags & AMD_IS_PX)
2089 vga_switcheroo_fini_domain_pm_ops(adev->dev); 2092 vga_switcheroo_fini_domain_pm_ops(adev->dev);
2090 vga_client_register(adev->pdev, NULL, NULL, NULL); 2093 vga_client_register(adev->pdev, NULL, NULL, NULL);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 39fc388f222a..ce15721cadda 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -311,7 +311,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
311 struct drm_framebuffer *fb, 311 struct drm_framebuffer *fb,
312 struct drm_pending_vblank_event *event, 312 struct drm_pending_vblank_event *event,
313 uint32_t page_flip_flags, 313 uint32_t page_flip_flags,
314 uint32_t target) 314 uint32_t target,
315 struct drm_modeset_acquire_ctx *ctx)
315{ 316{
316 struct amdgpu_bo *new_abo; 317 struct amdgpu_bo *new_abo;
317 struct amdgpu_flip_work *work; 318 struct amdgpu_flip_work *work;
@@ -332,7 +333,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
332 return 0; 333 return 0;
333} 334}
334 335
335int amdgpu_crtc_set_config(struct drm_mode_set *set) 336int amdgpu_crtc_set_config(struct drm_mode_set *set,
337 struct drm_modeset_acquire_ctx *ctx)
336{ 338{
337 struct drm_device *dev; 339 struct drm_device *dev;
338 struct amdgpu_device *adev; 340 struct amdgpu_device *adev;
@@ -349,7 +351,7 @@ int amdgpu_crtc_set_config(struct drm_mode_set *set)
349 if (ret < 0) 351 if (ret < 0)
350 return ret; 352 return ret;
351 353
352 ret = drm_crtc_helper_set_config(set); 354 ret = drm_crtc_helper_set_config(set, ctx);
353 355
354 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 356 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
355 if (crtc->enabled) 357 if (crtc->enabled)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 5ded370a4b35..dfb029ab3448 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -103,7 +103,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
103 amdgpu_has_atpx() && 103 amdgpu_has_atpx() &&
104 (amdgpu_is_atpx_hybrid() || 104 (amdgpu_is_atpx_hybrid() ||
105 amdgpu_has_atpx_dgpu_power_cntl()) && 105 amdgpu_has_atpx_dgpu_power_cntl()) &&
106 ((flags & AMD_IS_APU) == 0)) 106 ((flags & AMD_IS_APU) == 0) &&
107 !pci_is_thunderbolt_attached(dev->pdev))
107 flags |= AMD_IS_PX; 108 flags |= AMD_IS_PX;
108 109
109 /* amdgpu_device_init should report only fatal error 110 /* amdgpu_device_init should report only fatal error
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index c12497bd3889..db8f8dda209c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -590,11 +590,13 @@ int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tile
590/* amdgpu_display.c */ 590/* amdgpu_display.c */
591void amdgpu_print_display_setup(struct drm_device *dev); 591void amdgpu_print_display_setup(struct drm_device *dev);
592int amdgpu_modeset_create_props(struct amdgpu_device *adev); 592int amdgpu_modeset_create_props(struct amdgpu_device *adev);
593int amdgpu_crtc_set_config(struct drm_mode_set *set); 593int amdgpu_crtc_set_config(struct drm_mode_set *set,
594 struct drm_modeset_acquire_ctx *ctx);
594int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, 595int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
595 struct drm_framebuffer *fb, 596 struct drm_framebuffer *fb,
596 struct drm_pending_vblank_event *event, 597 struct drm_pending_vblank_event *event,
597 uint32_t page_flip_flags, uint32_t target); 598 uint32_t page_flip_flags, uint32_t target,
599 struct drm_modeset_acquire_ctx *ctx);
598void amdgpu_crtc_cleanup_flip_ctx(struct amdgpu_flip_work *work, 600void amdgpu_crtc_cleanup_flip_ctx(struct amdgpu_flip_work *work,
599 struct amdgpu_bo *new_abo); 601 struct amdgpu_bo *new_abo);
600int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc, 602int amdgpu_crtc_prepare_flip(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 1341e0b9368a..4fe19fde84f9 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1027,7 +1027,8 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
1027 * and a mode_set. 1027 * and a mode_set.
1028 */ 1028 */
1029static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, 1029static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
1030 struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t page_flip_flags) 1030 struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t page_flip_flags,
1031 struct drm_modeset_acquire_ctx *ctx)
1031{ 1032{
1032 struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); 1033 struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
1033 struct armada_frame_work *work; 1034 struct armada_frame_work *work;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 34cb73d0db77..424e465ff407 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -94,7 +94,8 @@ static int
94armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, 94armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
95 struct drm_framebuffer *fb, 95 struct drm_framebuffer *fb,
96 int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h, 96 int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
97 uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) 97 uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
98 struct drm_modeset_acquire_ctx *ctx)
98{ 99{
99 struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane); 100 struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
100 struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); 101 struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
@@ -257,7 +258,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
257 return 0; 258 return 0;
258} 259}
259 260
260static int armada_ovl_plane_disable(struct drm_plane *plane) 261static int armada_ovl_plane_disable(struct drm_plane *plane,
262 struct drm_modeset_acquire_ctx *ctx)
261{ 263{
262 struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane); 264 struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
263 struct drm_framebuffer *fb; 265 struct drm_framebuffer *fb;
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c
index 471bd588550b..c38deffa14de 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -192,6 +192,8 @@ void bochs_fbdev_fini(struct bochs_device *bochs)
192 if (bochs->fb.initialized) 192 if (bochs->fb.initialized)
193 bochs_fbdev_destroy(bochs); 193 bochs_fbdev_destroy(bochs);
194 194
195 drm_fb_helper_fini(&bochs->fb.helper); 195 if (bochs->fb.helper.fbdev)
196 drm_fb_helper_fini(&bochs->fb.helper);
197
196 bochs->fb.initialized = false; 198 bochs->fb.initialized = false;
197} 199}
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index d5e63eff357b..6a91e62da2f4 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -96,7 +96,8 @@ static void bochs_crtc_commit(struct drm_crtc *crtc)
96static int bochs_crtc_page_flip(struct drm_crtc *crtc, 96static int bochs_crtc_page_flip(struct drm_crtc *crtc,
97 struct drm_framebuffer *fb, 97 struct drm_framebuffer *fb,
98 struct drm_pending_vblank_event *event, 98 struct drm_pending_vblank_event *event,
99 uint32_t page_flip_flags) 99 uint32_t page_flip_flags,
100 struct drm_modeset_acquire_ctx *ctx)
100{ 101{
101 struct bochs_device *bochs = 102 struct bochs_device *bochs =
102 container_of(crtc, struct bochs_device, crtc); 103 container_of(crtc, struct bochs_device, crtc);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index af93f7a20697..32f02e92e0b9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1916,7 +1916,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
1916 if (intr_stat & 1916 if (intr_stat &
1917 (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) { 1917 (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
1918 mutex_lock(&hdmi->mutex); 1918 mutex_lock(&hdmi->mutex);
1919 if (!hdmi->disabled && !hdmi->force) { 1919 if (!hdmi->force) {
1920 /* 1920 /*
1921 * If the RX sense status indicates we're disconnected, 1921 * If the RX sense status indicates we're disconnected,
1922 * clear the software rxsense status. 1922 * clear the software rxsense status.
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
index b379d046991b..7d519b46aee4 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -8,6 +8,10 @@
8 * 8 *
9 */ 9 */
10 10
11#include <linux/delay.h>
12#include <linux/fwnode.h>
13#include <linux/gpio/consumer.h>
14#include <linux/irq.h>
11#include <linux/module.h> 15#include <linux/module.h>
12#include <linux/of_graph.h> 16#include <linux/of_graph.h>
13#include <linux/platform_device.h> 17#include <linux/platform_device.h>
@@ -18,11 +22,15 @@
18#include <drm/drm_crtc.h> 22#include <drm/drm_crtc.h>
19#include <drm/drm_crtc_helper.h> 23#include <drm/drm_crtc_helper.h>
20 24
25#define HOTPLUG_DEBOUNCE_MS 1100
26
21struct tfp410 { 27struct tfp410 {
22 struct drm_bridge bridge; 28 struct drm_bridge bridge;
23 struct drm_connector connector; 29 struct drm_connector connector;
24 30
25 struct i2c_adapter *ddc; 31 struct i2c_adapter *ddc;
32 struct gpio_desc *hpd;
33 struct delayed_work hpd_work;
26 34
27 struct device *dev; 35 struct device *dev;
28}; 36};
@@ -76,6 +84,13 @@ tfp410_connector_detect(struct drm_connector *connector, bool force)
76{ 84{
77 struct tfp410 *dvi = drm_connector_to_tfp410(connector); 85 struct tfp410 *dvi = drm_connector_to_tfp410(connector);
78 86
87 if (dvi->hpd) {
88 if (gpiod_get_value_cansleep(dvi->hpd))
89 return connector_status_connected;
90 else
91 return connector_status_disconnected;
92 }
93
79 if (dvi->ddc) { 94 if (dvi->ddc) {
80 if (drm_probe_ddc(dvi->ddc)) 95 if (drm_probe_ddc(dvi->ddc))
81 return connector_status_connected; 96 return connector_status_connected;
@@ -106,6 +121,9 @@ static int tfp410_attach(struct drm_bridge *bridge)
106 return -ENODEV; 121 return -ENODEV;
107 } 122 }
108 123
124 if (dvi->hpd)
125 dvi->connector.polled = DRM_CONNECTOR_POLL_HPD;
126
109 drm_connector_helper_add(&dvi->connector, 127 drm_connector_helper_add(&dvi->connector,
110 &tfp410_con_helper_funcs); 128 &tfp410_con_helper_funcs);
111 ret = drm_connector_init(bridge->dev, &dvi->connector, 129 ret = drm_connector_init(bridge->dev, &dvi->connector,
@@ -125,7 +143,27 @@ static const struct drm_bridge_funcs tfp410_bridge_funcs = {
125 .attach = tfp410_attach, 143 .attach = tfp410_attach,
126}; 144};
127 145
128static int tfp410_get_connector_ddc(struct tfp410 *dvi) 146static void tfp410_hpd_work_func(struct work_struct *work)
147{
148 struct tfp410 *dvi;
149
150 dvi = container_of(work, struct tfp410, hpd_work.work);
151
152 if (dvi->bridge.dev)
153 drm_helper_hpd_irq_event(dvi->bridge.dev);
154}
155
156static irqreturn_t tfp410_hpd_irq_thread(int irq, void *arg)
157{
158 struct tfp410 *dvi = arg;
159
160 mod_delayed_work(system_wq, &dvi->hpd_work,
161 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
162
163 return IRQ_HANDLED;
164}
165
166static int tfp410_get_connector_properties(struct tfp410 *dvi)
129{ 167{
130 struct device_node *ep = NULL, *connector_node = NULL; 168 struct device_node *ep = NULL, *connector_node = NULL;
131 struct device_node *ddc_phandle = NULL; 169 struct device_node *ddc_phandle = NULL;
@@ -140,6 +178,17 @@ static int tfp410_get_connector_ddc(struct tfp410 *dvi)
140 if (!connector_node) 178 if (!connector_node)
141 goto fail; 179 goto fail;
142 180
181 dvi->hpd = fwnode_get_named_gpiod(&connector_node->fwnode,
182 "hpd-gpios", 0, GPIOD_IN, "hpd");
183 if (IS_ERR(dvi->hpd)) {
184 ret = PTR_ERR(dvi->hpd);
185 dvi->hpd = NULL;
186 if (ret == -ENOENT)
187 ret = 0;
188 else
189 goto fail;
190 }
191
143 ddc_phandle = of_parse_phandle(connector_node, "ddc-i2c-bus", 0); 192 ddc_phandle = of_parse_phandle(connector_node, "ddc-i2c-bus", 0);
144 if (!ddc_phandle) 193 if (!ddc_phandle)
145 goto fail; 194 goto fail;
@@ -176,10 +225,23 @@ static int tfp410_init(struct device *dev)
176 dvi->bridge.of_node = dev->of_node; 225 dvi->bridge.of_node = dev->of_node;
177 dvi->dev = dev; 226 dvi->dev = dev;
178 227
179 ret = tfp410_get_connector_ddc(dvi); 228 ret = tfp410_get_connector_properties(dvi);
180 if (ret) 229 if (ret)
181 goto fail; 230 goto fail;
182 231
232 if (dvi->hpd) {
233 INIT_DELAYED_WORK(&dvi->hpd_work, tfp410_hpd_work_func);
234
235 ret = devm_request_threaded_irq(dev, gpiod_to_irq(dvi->hpd),
236 NULL, tfp410_hpd_irq_thread, IRQF_TRIGGER_RISING |
237 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
238 "hdmi-hpd", dvi);
239 if (ret) {
240 DRM_ERROR("failed to register hpd interrupt\n");
241 goto fail;
242 }
243 }
244
183 ret = drm_bridge_add(&dvi->bridge); 245 ret = drm_bridge_add(&dvi->bridge);
184 if (ret) { 246 if (ret) {
185 dev_err(dev, "drm_bridge_add() failed: %d\n", ret); 247 dev_err(dev, "drm_bridge_add() failed: %d\n", ret);
@@ -189,6 +251,8 @@ static int tfp410_init(struct device *dev)
189 return 0; 251 return 0;
190fail: 252fail:
191 i2c_put_adapter(dvi->ddc); 253 i2c_put_adapter(dvi->ddc);
254 if (dvi->hpd)
255 gpiod_put(dvi->hpd);
192 return ret; 256 return ret;
193} 257}
194 258
@@ -196,10 +260,14 @@ static int tfp410_fini(struct device *dev)
196{ 260{
197 struct tfp410 *dvi = dev_get_drvdata(dev); 261 struct tfp410 *dvi = dev_get_drvdata(dev);
198 262
263 cancel_delayed_work_sync(&dvi->hpd_work);
264
199 drm_bridge_remove(&dvi->bridge); 265 drm_bridge_remove(&dvi->bridge);
200 266
201 if (dvi->ddc) 267 if (dvi->ddc)
202 i2c_put_adapter(dvi->ddc); 268 i2c_put_adapter(dvi->ddc);
269 if (dvi->hpd)
270 gpiod_put(dvi->hpd);
203 271
204 return 0; 272 return 0;
205} 273}
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 4e26b73bb0d5..c3994b4d5f32 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2077,6 +2077,7 @@ EXPORT_SYMBOL(drm_atomic_helper_swap_state);
2077 * @src_y: y offset of @fb for panning 2077 * @src_y: y offset of @fb for panning
2078 * @src_w: width of source rectangle in @fb 2078 * @src_w: width of source rectangle in @fb
2079 * @src_h: height of source rectangle in @fb 2079 * @src_h: height of source rectangle in @fb
2080 * @ctx: lock acquire context
2080 * 2081 *
2081 * Provides a default plane update handler using the atomic driver interface. 2082 * Provides a default plane update handler using the atomic driver interface.
2082 * 2083 *
@@ -2089,7 +2090,8 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane,
2089 int crtc_x, int crtc_y, 2090 int crtc_x, int crtc_y,
2090 unsigned int crtc_w, unsigned int crtc_h, 2091 unsigned int crtc_w, unsigned int crtc_h,
2091 uint32_t src_x, uint32_t src_y, 2092 uint32_t src_x, uint32_t src_y,
2092 uint32_t src_w, uint32_t src_h) 2093 uint32_t src_w, uint32_t src_h,
2094 struct drm_modeset_acquire_ctx *ctx)
2093{ 2095{
2094 struct drm_atomic_state *state; 2096 struct drm_atomic_state *state;
2095 struct drm_plane_state *plane_state; 2097 struct drm_plane_state *plane_state;
@@ -2099,8 +2101,7 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane,
2099 if (!state) 2101 if (!state)
2100 return -ENOMEM; 2102 return -ENOMEM;
2101 2103
2102 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); 2104 state->acquire_ctx = ctx;
2103retry:
2104 plane_state = drm_atomic_get_plane_state(state, plane); 2105 plane_state = drm_atomic_get_plane_state(state, plane);
2105 if (IS_ERR(plane_state)) { 2106 if (IS_ERR(plane_state)) {
2106 ret = PTR_ERR(plane_state); 2107 ret = PTR_ERR(plane_state);
@@ -2125,59 +2126,33 @@ retry:
2125 2126
2126 ret = drm_atomic_commit(state); 2127 ret = drm_atomic_commit(state);
2127fail: 2128fail:
2128 if (ret == -EDEADLK)
2129 goto backoff;
2130
2131 drm_atomic_state_put(state); 2129 drm_atomic_state_put(state);
2132 return ret; 2130 return ret;
2133
2134backoff:
2135 drm_atomic_state_clear(state);
2136 drm_atomic_legacy_backoff(state);
2137
2138 /*
2139 * Someone might have exchanged the framebuffer while we dropped locks
2140 * in the backoff code. We need to fix up the fb refcount tracking the
2141 * core does for us.
2142 */
2143 plane->old_fb = plane->fb;
2144
2145 goto retry;
2146} 2131}
2147EXPORT_SYMBOL(drm_atomic_helper_update_plane); 2132EXPORT_SYMBOL(drm_atomic_helper_update_plane);
2148 2133
2149/** 2134/**
2150 * drm_atomic_helper_disable_plane - Helper for primary plane disable using * atomic 2135 * drm_atomic_helper_disable_plane - Helper for primary plane disable using * atomic
2151 * @plane: plane to disable 2136 * @plane: plane to disable
2137 * @ctx: lock acquire context
2152 * 2138 *
2153 * Provides a default plane disable handler using the atomic driver interface. 2139 * Provides a default plane disable handler using the atomic driver interface.
2154 * 2140 *
2155 * RETURNS: 2141 * RETURNS:
2156 * Zero on success, error code on failure 2142 * Zero on success, error code on failure
2157 */ 2143 */
2158int drm_atomic_helper_disable_plane(struct drm_plane *plane) 2144int drm_atomic_helper_disable_plane(struct drm_plane *plane,
2145 struct drm_modeset_acquire_ctx *ctx)
2159{ 2146{
2160 struct drm_atomic_state *state; 2147 struct drm_atomic_state *state;
2161 struct drm_plane_state *plane_state; 2148 struct drm_plane_state *plane_state;
2162 int ret = 0; 2149 int ret = 0;
2163 2150
2164 /*
2165 * FIXME: Without plane->crtc set we can't get at the implicit legacy
2166 * acquire context. The real fix will be to wire the acquire ctx through
2167 * everywhere we need it, but meanwhile prevent chaos by just skipping
2168 * this noop. The critical case is the cursor ioctls which a) only grab
2169 * crtc/cursor-plane locks (so we need the crtc to get at the right
2170 * acquire context) and b) can try to disable the plane multiple times.
2171 */
2172 if (!plane->crtc)
2173 return 0;
2174
2175 state = drm_atomic_state_alloc(plane->dev); 2151 state = drm_atomic_state_alloc(plane->dev);
2176 if (!state) 2152 if (!state)
2177 return -ENOMEM; 2153 return -ENOMEM;
2178 2154
2179 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(plane->crtc); 2155 state->acquire_ctx = ctx;
2180retry:
2181 plane_state = drm_atomic_get_plane_state(state, plane); 2156 plane_state = drm_atomic_get_plane_state(state, plane);
2182 if (IS_ERR(plane_state)) { 2157 if (IS_ERR(plane_state)) {
2183 ret = PTR_ERR(plane_state); 2158 ret = PTR_ERR(plane_state);
@@ -2193,24 +2168,8 @@ retry:
2193 2168
2194 ret = drm_atomic_commit(state); 2169 ret = drm_atomic_commit(state);
2195fail: 2170fail:
2196 if (ret == -EDEADLK)
2197 goto backoff;
2198
2199 drm_atomic_state_put(state); 2171 drm_atomic_state_put(state);
2200 return ret; 2172 return ret;
2201
2202backoff:
2203 drm_atomic_state_clear(state);
2204 drm_atomic_legacy_backoff(state);
2205
2206 /*
2207 * Someone might have exchanged the framebuffer while we dropped locks
2208 * in the backoff code. We need to fix up the fb refcount tracking the
2209 * core does for us.
2210 */
2211 plane->old_fb = plane->fb;
2212
2213 goto retry;
2214} 2173}
2215EXPORT_SYMBOL(drm_atomic_helper_disable_plane); 2174EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
2216 2175
@@ -2306,6 +2265,7 @@ static int update_output_state(struct drm_atomic_state *state,
2306/** 2265/**
2307 * drm_atomic_helper_set_config - set a new config from userspace 2266 * drm_atomic_helper_set_config - set a new config from userspace
2308 * @set: mode set configuration 2267 * @set: mode set configuration
2268 * @ctx: lock acquisition context
2309 * 2269 *
2310 * Provides a default crtc set_config handler using the atomic driver interface. 2270 * Provides a default crtc set_config handler using the atomic driver interface.
2311 * 2271 *
@@ -2318,7 +2278,8 @@ static int update_output_state(struct drm_atomic_state *state,
2318 * Returns: 2278 * Returns:
2319 * Returns 0 on success, negative errno numbers on failure. 2279 * Returns 0 on success, negative errno numbers on failure.
2320 */ 2280 */
2321int drm_atomic_helper_set_config(struct drm_mode_set *set) 2281int drm_atomic_helper_set_config(struct drm_mode_set *set,
2282 struct drm_modeset_acquire_ctx *ctx)
2322{ 2283{
2323 struct drm_atomic_state *state; 2284 struct drm_atomic_state *state;
2324 struct drm_crtc *crtc = set->crtc; 2285 struct drm_crtc *crtc = set->crtc;
@@ -2329,32 +2290,16 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set)
2329 return -ENOMEM; 2290 return -ENOMEM;
2330 2291
2331 state->legacy_set_config = true; 2292 state->legacy_set_config = true;
2332 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); 2293 state->acquire_ctx = ctx;
2333retry:
2334 ret = __drm_atomic_helper_set_config(set, state); 2294 ret = __drm_atomic_helper_set_config(set, state);
2335 if (ret != 0) 2295 if (ret != 0)
2336 goto fail; 2296 goto fail;
2337 2297
2338 ret = drm_atomic_commit(state); 2298 ret = drm_atomic_commit(state);
2339fail:
2340 if (ret == -EDEADLK)
2341 goto backoff;
2342 2299
2300fail:
2343 drm_atomic_state_put(state); 2301 drm_atomic_state_put(state);
2344 return ret; 2302 return ret;
2345
2346backoff:
2347 drm_atomic_state_clear(state);
2348 drm_atomic_legacy_backoff(state);
2349
2350 /*
2351 * Someone might have exchanged the framebuffer while we dropped locks
2352 * in the backoff code. We need to fix up the fb refcount tracking the
2353 * core does for us.
2354 */
2355 crtc->primary->old_fb = crtc->primary->fb;
2356
2357 goto retry;
2358} 2303}
2359EXPORT_SYMBOL(drm_atomic_helper_set_config); 2304EXPORT_SYMBOL(drm_atomic_helper_set_config);
2360 2305
@@ -2443,7 +2388,8 @@ commit:
2443 * that they are connected to. 2388 * that they are connected to.
2444 * 2389 *
2445 * This is used for example in suspend/resume to disable all currently active 2390 * This is used for example in suspend/resume to disable all currently active
2446 * functions when suspending. 2391 * functions when suspending. If you just want to shut down everything at e.g.
2392 * driver unload, look at drm_atomic_helper_shutdown().
2447 * 2393 *
2448 * Note that if callers haven't already acquired all modeset locks this might 2394 * Note that if callers haven't already acquired all modeset locks this might
2449 * return -EDEADLK, which must be handled by calling drm_modeset_backoff(). 2395 * return -EDEADLK, which must be handled by calling drm_modeset_backoff().
@@ -2452,7 +2398,8 @@ commit:
2452 * 0 on success or a negative error code on failure. 2398 * 0 on success or a negative error code on failure.
2453 * 2399 *
2454 * See also: 2400 * See also:
2455 * drm_atomic_helper_suspend(), drm_atomic_helper_resume() 2401 * drm_atomic_helper_suspend(), drm_atomic_helper_resume() and
2402 * drm_atomic_helper_shutdown().
2456 */ 2403 */
2457int drm_atomic_helper_disable_all(struct drm_device *dev, 2404int drm_atomic_helper_disable_all(struct drm_device *dev,
2458 struct drm_modeset_acquire_ctx *ctx) 2405 struct drm_modeset_acquire_ctx *ctx)
@@ -2517,6 +2464,42 @@ free:
2517EXPORT_SYMBOL(drm_atomic_helper_disable_all); 2464EXPORT_SYMBOL(drm_atomic_helper_disable_all);
2518 2465
2519/** 2466/**
2467 * drm_atomic_helper_shutdown - shutdown all CRTC
2468 * @dev: DRM device
2469 *
2470 * This shuts down all CRTC, which is useful for driver unloading. Shutdown on
2471 * suspend should instead be handled with drm_atomic_helper_suspend(), since
2472 * that also takes a snapshot of the modeset state to be restored on resume.
2473 *
2474 * This is just a convenience wrapper around drm_atomic_helper_disable_all(),
2475 * and it is the atomic version of drm_crtc_force_disable_all().
2476 */
2477void drm_atomic_helper_shutdown(struct drm_device *dev)
2478{
2479 struct drm_modeset_acquire_ctx ctx;
2480 int ret;
2481
2482 drm_modeset_acquire_init(&ctx, 0);
2483 while (1) {
2484 ret = drm_modeset_lock_all_ctx(dev, &ctx);
2485 if (!ret)
2486 ret = drm_atomic_helper_disable_all(dev, &ctx);
2487
2488 if (ret != -EDEADLK)
2489 break;
2490
2491 drm_modeset_backoff(&ctx);
2492 }
2493
2494 if (ret)
2495 DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
2496
2497 drm_modeset_drop_locks(&ctx);
2498 drm_modeset_acquire_fini(&ctx);
2499}
2500EXPORT_SYMBOL(drm_atomic_helper_shutdown);
2501
2502/**
2520 * drm_atomic_helper_suspend - subsystem-level suspend helper 2503 * drm_atomic_helper_suspend - subsystem-level suspend helper
2521 * @dev: DRM device 2504 * @dev: DRM device
2522 * 2505 *
@@ -2862,6 +2845,7 @@ static int page_flip_common(
2862 * @fb: DRM framebuffer 2845 * @fb: DRM framebuffer
2863 * @event: optional DRM event to signal upon completion 2846 * @event: optional DRM event to signal upon completion
2864 * @flags: flip flags for non-vblank sync'ed updates 2847 * @flags: flip flags for non-vblank sync'ed updates
2848 * @ctx: lock acquisition context
2865 * 2849 *
2866 * Provides a default &drm_crtc_funcs.page_flip implementation 2850 * Provides a default &drm_crtc_funcs.page_flip implementation
2867 * using the atomic driver interface. 2851 * using the atomic driver interface.
@@ -2875,7 +2859,8 @@ static int page_flip_common(
2875int drm_atomic_helper_page_flip(struct drm_crtc *crtc, 2859int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
2876 struct drm_framebuffer *fb, 2860 struct drm_framebuffer *fb,
2877 struct drm_pending_vblank_event *event, 2861 struct drm_pending_vblank_event *event,
2878 uint32_t flags) 2862 uint32_t flags,
2863 struct drm_modeset_acquire_ctx *ctx)
2879{ 2864{
2880 struct drm_plane *plane = crtc->primary; 2865 struct drm_plane *plane = crtc->primary;
2881 struct drm_atomic_state *state; 2866 struct drm_atomic_state *state;
@@ -2885,34 +2870,16 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
2885 if (!state) 2870 if (!state)
2886 return -ENOMEM; 2871 return -ENOMEM;
2887 2872
2888 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); 2873 state->acquire_ctx = ctx;
2889 2874
2890retry:
2891 ret = page_flip_common(state, crtc, fb, event, flags); 2875 ret = page_flip_common(state, crtc, fb, event, flags);
2892 if (ret != 0) 2876 if (ret != 0)
2893 goto fail; 2877 goto fail;
2894 2878
2895 ret = drm_atomic_nonblocking_commit(state); 2879 ret = drm_atomic_nonblocking_commit(state);
2896
2897fail: 2880fail:
2898 if (ret == -EDEADLK)
2899 goto backoff;
2900
2901 drm_atomic_state_put(state); 2881 drm_atomic_state_put(state);
2902 return ret; 2882 return ret;
2903
2904backoff:
2905 drm_atomic_state_clear(state);
2906 drm_atomic_legacy_backoff(state);
2907
2908 /*
2909 * Someone might have exchanged the framebuffer while we dropped locks
2910 * in the backoff code. We need to fix up the fb refcount tracking the
2911 * core does for us.
2912 */
2913 plane->old_fb = plane->fb;
2914
2915 goto retry;
2916} 2883}
2917EXPORT_SYMBOL(drm_atomic_helper_page_flip); 2884EXPORT_SYMBOL(drm_atomic_helper_page_flip);
2918 2885
@@ -2923,6 +2890,7 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
2923 * @event: optional DRM event to signal upon completion 2890 * @event: optional DRM event to signal upon completion
2924 * @flags: flip flags for non-vblank sync'ed updates 2891 * @flags: flip flags for non-vblank sync'ed updates
2925 * @target: specifying the target vblank period when the flip to take effect 2892 * @target: specifying the target vblank period when the flip to take effect
2893 * @ctx: lock acquisition context
2926 * 2894 *
2927 * Provides a default &drm_crtc_funcs.page_flip_target implementation. 2895 * Provides a default &drm_crtc_funcs.page_flip_target implementation.
2928 * Similar to drm_atomic_helper_page_flip() with extra parameter to specify 2896 * Similar to drm_atomic_helper_page_flip() with extra parameter to specify
@@ -2936,7 +2904,8 @@ int drm_atomic_helper_page_flip_target(
2936 struct drm_framebuffer *fb, 2904 struct drm_framebuffer *fb,
2937 struct drm_pending_vblank_event *event, 2905 struct drm_pending_vblank_event *event,
2938 uint32_t flags, 2906 uint32_t flags,
2939 uint32_t target) 2907 uint32_t target,
2908 struct drm_modeset_acquire_ctx *ctx)
2940{ 2909{
2941 struct drm_plane *plane = crtc->primary; 2910 struct drm_plane *plane = crtc->primary;
2942 struct drm_atomic_state *state; 2911 struct drm_atomic_state *state;
@@ -2947,9 +2916,8 @@ int drm_atomic_helper_page_flip_target(
2947 if (!state) 2916 if (!state)
2948 return -ENOMEM; 2917 return -ENOMEM;
2949 2918
2950 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); 2919 state->acquire_ctx = ctx;
2951 2920
2952retry:
2953 ret = page_flip_common(state, crtc, fb, event, flags); 2921 ret = page_flip_common(state, crtc, fb, event, flags);
2954 if (ret != 0) 2922 if (ret != 0)
2955 goto fail; 2923 goto fail;
@@ -2962,26 +2930,9 @@ retry:
2962 crtc_state->target_vblank = target; 2930 crtc_state->target_vblank = target;
2963 2931
2964 ret = drm_atomic_nonblocking_commit(state); 2932 ret = drm_atomic_nonblocking_commit(state);
2965
2966fail: 2933fail:
2967 if (ret == -EDEADLK)
2968 goto backoff;
2969
2970 drm_atomic_state_put(state); 2934 drm_atomic_state_put(state);
2971 return ret; 2935 return ret;
2972
2973backoff:
2974 drm_atomic_state_clear(state);
2975 drm_atomic_legacy_backoff(state);
2976
2977 /*
2978 * Someone might have exchanged the framebuffer while we dropped locks
2979 * in the backoff code. We need to fix up the fb refcount tracking the
2980 * core does for us.
2981 */
2982 plane->old_fb = plane->fb;
2983
2984 goto retry;
2985} 2936}
2986EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); 2937EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
2987 2938
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e2974d3c92e7..d69e180fc563 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -94,6 +94,8 @@ EXPORT_SYMBOL(drm_crtc_from_index);
94 * drm_crtc_force_disable - Forcibly turn off a CRTC 94 * drm_crtc_force_disable - Forcibly turn off a CRTC
95 * @crtc: CRTC to turn off 95 * @crtc: CRTC to turn off
96 * 96 *
97 * Note: This should only be used by non-atomic legacy drivers.
98 *
97 * Returns: 99 * Returns:
98 * Zero on success, error code on failure. 100 * Zero on success, error code on failure.
99 */ 101 */
@@ -103,6 +105,8 @@ int drm_crtc_force_disable(struct drm_crtc *crtc)
103 .crtc = crtc, 105 .crtc = crtc,
104 }; 106 };
105 107
108 WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
109
106 return drm_mode_set_config_internal(&set); 110 return drm_mode_set_config_internal(&set);
107} 111}
108EXPORT_SYMBOL(drm_crtc_force_disable); 112EXPORT_SYMBOL(drm_crtc_force_disable);
@@ -114,6 +118,9 @@ EXPORT_SYMBOL(drm_crtc_force_disable);
114 * Drivers may want to call this on unload to ensure that all displays are 118 * Drivers may want to call this on unload to ensure that all displays are
115 * unlit and the GPU is in a consistent, low power state. Takes modeset locks. 119 * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
116 * 120 *
121 * Note: This should only be used by non-atomic legacy drivers. For an atomic
122 * version look at drm_atomic_helper_shutdown().
123 *
117 * Returns: 124 * Returns:
118 * Zero on success, error code on failure. 125 * Zero on success, error code on failure.
119 */ 126 */
@@ -399,9 +406,9 @@ int drm_mode_getcrtc(struct drm_device *dev,
399 if (!crtc) 406 if (!crtc)
400 return -ENOENT; 407 return -ENOENT;
401 408
402 drm_modeset_lock_crtc(crtc, crtc->primary);
403 crtc_resp->gamma_size = crtc->gamma_size; 409 crtc_resp->gamma_size = crtc->gamma_size;
404 410
411 drm_modeset_lock(&crtc->primary->mutex, NULL);
405 if (crtc->primary->state && crtc->primary->state->fb) 412 if (crtc->primary->state && crtc->primary->state->fb)
406 crtc_resp->fb_id = crtc->primary->state->fb->base.id; 413 crtc_resp->fb_id = crtc->primary->state->fb->base.id;
407 else if (!crtc->primary->state && crtc->primary->fb) 414 else if (!crtc->primary->state && crtc->primary->fb)
@@ -409,9 +416,14 @@ int drm_mode_getcrtc(struct drm_device *dev,
409 else 416 else
410 crtc_resp->fb_id = 0; 417 crtc_resp->fb_id = 0;
411 418
412 if (crtc->state) { 419 if (crtc->primary->state) {
413 crtc_resp->x = crtc->primary->state->src_x >> 16; 420 crtc_resp->x = crtc->primary->state->src_x >> 16;
414 crtc_resp->y = crtc->primary->state->src_y >> 16; 421 crtc_resp->y = crtc->primary->state->src_y >> 16;
422 }
423 drm_modeset_unlock(&crtc->primary->mutex);
424
425 drm_modeset_lock(&crtc->mutex, NULL);
426 if (crtc->state) {
415 if (crtc->state->enable) { 427 if (crtc->state->enable) {
416 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode); 428 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
417 crtc_resp->mode_valid = 1; 429 crtc_resp->mode_valid = 1;
@@ -430,23 +442,13 @@ int drm_mode_getcrtc(struct drm_device *dev,
430 crtc_resp->mode_valid = 0; 442 crtc_resp->mode_valid = 0;
431 } 443 }
432 } 444 }
433 drm_modeset_unlock_crtc(crtc); 445 drm_modeset_unlock(&crtc->mutex);
434 446
435 return 0; 447 return 0;
436} 448}
437 449
438/** 450static int __drm_mode_set_config_internal(struct drm_mode_set *set,
439 * drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config 451 struct drm_modeset_acquire_ctx *ctx)
440 * @set: modeset config to set
441 *
442 * This is a little helper to wrap internal calls to the
443 * &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
444 * correct refcounting dance.
445 *
446 * Returns:
447 * Zero on success, negative errno on failure.
448 */
449int drm_mode_set_config_internal(struct drm_mode_set *set)
450{ 452{
451 struct drm_crtc *crtc = set->crtc; 453 struct drm_crtc *crtc = set->crtc;
452 struct drm_framebuffer *fb; 454 struct drm_framebuffer *fb;
@@ -463,7 +465,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
463 465
464 fb = set->fb; 466 fb = set->fb;
465 467
466 ret = crtc->funcs->set_config(set); 468 ret = crtc->funcs->set_config(set, ctx);
467 if (ret == 0) { 469 if (ret == 0) {
468 crtc->primary->crtc = crtc; 470 crtc->primary->crtc = crtc;
469 crtc->primary->fb = fb; 471 crtc->primary->fb = fb;
@@ -479,6 +481,25 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
479 481
480 return ret; 482 return ret;
481} 483}
484/**
485 * drm_mode_set_config_internal - helper to call &drm_mode_config_funcs.set_config
486 * @set: modeset config to set
487 *
488 * This is a little helper to wrap internal calls to the
489 * &drm_mode_config_funcs.set_config driver interface. The only thing it adds is
490 * correct refcounting dance.
491 *
492 * This should only be used by non-atomic legacy drivers.
493 *
494 * Returns:
495 * Zero on success, negative errno on failure.
496 */
497int drm_mode_set_config_internal(struct drm_mode_set *set)
498{
499 WARN_ON(drm_drv_uses_atomic_modeset(set->crtc->dev));
500
501 return __drm_mode_set_config_internal(set, NULL);
502}
482EXPORT_SYMBOL(drm_mode_set_config_internal); 503EXPORT_SYMBOL(drm_mode_set_config_internal);
483 504
484/** 505/**
@@ -534,6 +555,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
534 struct drm_display_mode *mode = NULL; 555 struct drm_display_mode *mode = NULL;
535 struct drm_mode_set set; 556 struct drm_mode_set set;
536 uint32_t __user *set_connectors_ptr; 557 uint32_t __user *set_connectors_ptr;
558 struct drm_modeset_acquire_ctx ctx;
537 int ret; 559 int ret;
538 int i; 560 int i;
539 561
@@ -547,15 +569,18 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
547 if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000) 569 if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
548 return -ERANGE; 570 return -ERANGE;
549 571
550 drm_modeset_lock_all(dev);
551 crtc = drm_crtc_find(dev, crtc_req->crtc_id); 572 crtc = drm_crtc_find(dev, crtc_req->crtc_id);
552 if (!crtc) { 573 if (!crtc) {
553 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); 574 DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
554 ret = -ENOENT; 575 return -ENOENT;
555 goto out;
556 } 576 }
557 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); 577 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
558 578
579 drm_modeset_acquire_init(&ctx, 0);
580retry:
581 ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
582 if (ret)
583 goto out;
559 if (crtc_req->mode_valid) { 584 if (crtc_req->mode_valid) {
560 /* If we have a mode we need a framebuffer. */ 585 /* If we have a mode we need a framebuffer. */
561 /* If we pass -1, set the mode with the currently bound fb */ 586 /* If we pass -1, set the mode with the currently bound fb */
@@ -676,7 +701,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
676 set.connectors = connector_set; 701 set.connectors = connector_set;
677 set.num_connectors = crtc_req->count_connectors; 702 set.num_connectors = crtc_req->count_connectors;
678 set.fb = fb; 703 set.fb = fb;
679 ret = drm_mode_set_config_internal(&set); 704 ret = __drm_mode_set_config_internal(&set, &ctx);
680 705
681out: 706out:
682 if (fb) 707 if (fb)
@@ -690,7 +715,13 @@ out:
690 } 715 }
691 kfree(connector_set); 716 kfree(connector_set);
692 drm_mode_destroy(dev, mode); 717 drm_mode_destroy(dev, mode);
693 drm_modeset_unlock_all(dev); 718 if (ret == -EDEADLK) {
719 drm_modeset_backoff(&ctx);
720 goto retry;
721 }
722 drm_modeset_drop_locks(&ctx);
723 drm_modeset_acquire_fini(&ctx);
724
694 return ret; 725 return ret;
695} 726}
696 727
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 8aa8c1084121..4afdf7902eda 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -476,6 +476,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
476/** 476/**
477 * drm_crtc_helper_set_config - set a new config from userspace 477 * drm_crtc_helper_set_config - set a new config from userspace
478 * @set: mode set configuration 478 * @set: mode set configuration
479 * @ctx: lock acquire context, not used here
479 * 480 *
480 * The drm_crtc_helper_set_config() helper function implements the of 481 * The drm_crtc_helper_set_config() helper function implements the of
481 * &drm_crtc_funcs.set_config callback for drivers using the legacy CRTC 482 * &drm_crtc_funcs.set_config callback for drivers using the legacy CRTC
@@ -510,7 +511,8 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
510 * Returns: 511 * Returns:
511 * Returns 0 on success, negative errno numbers on failure. 512 * Returns 0 on success, negative errno numbers on failure.
512 */ 513 */
513int drm_crtc_helper_set_config(struct drm_mode_set *set) 514int drm_crtc_helper_set_config(struct drm_mode_set *set,
515 struct drm_modeset_acquire_ctx *ctx)
514{ 516{
515 struct drm_device *dev; 517 struct drm_device *dev;
516 struct drm_crtc **save_encoder_crtcs, *new_crtc; 518 struct drm_crtc **save_encoder_crtcs, *new_crtc;
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 1d2d18d82d2e..c1807d5754b2 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -1,10 +1,3 @@
1/**
2 * \file drm_debugfs.c
3 * debugfs support for DRM
4 *
5 * \author Ben Gamari <bgamari@gmail.com>
6 */
7
8/* 1/*
9 * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com 2 * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com
10 * 3 *
@@ -34,9 +27,12 @@
34#include <linux/seq_file.h> 27#include <linux/seq_file.h>
35#include <linux/slab.h> 28#include <linux/slab.h>
36#include <linux/export.h> 29#include <linux/export.h>
37#include <drm/drmP.h> 30
31#include <drm/drm_debugfs.h>
38#include <drm/drm_edid.h> 32#include <drm/drm_edid.h>
39#include <drm/drm_atomic.h> 33#include <drm/drm_atomic.h>
34#include <drm/drmP.h>
35
40#include "drm_internal.h" 36#include "drm_internal.h"
41#include "drm_crtc_internal.h" 37#include "drm_crtc_internal.h"
42 38
@@ -72,16 +68,15 @@ static const struct file_operations drm_debugfs_fops = {
72 68
73 69
74/** 70/**
75 * Initialize a given set of debugfs files for a device 71 * drm_debugfs_create_files - Initialize a given set of debugfs files for DRM
76 * 72 * minor
77 * \param files The array of files to create 73 * @files: The array of files to create
78 * \param count The number of files given 74 * @count: The number of files given
79 * \param root DRI debugfs dir entry. 75 * @root: DRI debugfs dir entry.
80 * \param minor device minor number 76 * @minor: device minor number
81 * \return Zero on success, non-zero on failure
82 * 77 *
83 * Create a given set of debugfs files represented by an array of 78 * Create a given set of debugfs files represented by an array of
84 * &drm_info_list in the given root directory. These files will be removed 79 * &struct drm_info_list in the given root directory. These files will be removed
85 * automatically on drm_debugfs_cleanup(). 80 * automatically on drm_debugfs_cleanup().
86 */ 81 */
87int drm_debugfs_create_files(const struct drm_info_list *files, int count, 82int drm_debugfs_create_files(const struct drm_info_list *files, int count,
@@ -130,17 +125,6 @@ fail:
130} 125}
131EXPORT_SYMBOL(drm_debugfs_create_files); 126EXPORT_SYMBOL(drm_debugfs_create_files);
132 127
133/**
134 * Initialize the DRI debugfs filesystem for a device
135 *
136 * \param dev DRM device
137 * \param minor device minor number
138 * \param root DRI debugfs dir entry.
139 *
140 * Create the DRI debugfs root entry "/sys/kernel/debug/dri", the device debugfs root entry
141 * "/sys/kernel/debug/dri/%minor%/", and each entry in debugfs_list as
142 * "/sys/kernel/debug/dri/%minor%/%name%".
143 */
144int drm_debugfs_init(struct drm_minor *minor, int minor_id, 128int drm_debugfs_init(struct drm_minor *minor, int minor_id,
145 struct dentry *root) 129 struct dentry *root)
146{ 130{
@@ -186,16 +170,6 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
186} 170}
187 171
188 172
189/**
190 * Remove a list of debugfs files
191 *
192 * \param files The list of files
193 * \param count The number of files
194 * \param minor The minor of which we should remove the files
195 * \return always zero.
196 *
197 * Remove all debugfs entries created by debugfs_init().
198 */
199int drm_debugfs_remove_files(const struct drm_info_list *files, int count, 173int drm_debugfs_remove_files(const struct drm_info_list *files, int count,
200 struct drm_minor *minor) 174 struct drm_minor *minor)
201{ 175{
@@ -232,14 +206,6 @@ static void drm_debugfs_remove_all_files(struct drm_minor *minor)
232 mutex_unlock(&minor->debugfs_lock); 206 mutex_unlock(&minor->debugfs_lock);
233} 207}
234 208
235/**
236 * Cleanup the debugfs filesystem resources.
237 *
238 * \param minor device minor number.
239 * \return always zero.
240 *
241 * Remove all debugfs entries created by debugfs_init().
242 */
243int drm_debugfs_cleanup(struct drm_minor *minor) 209int drm_debugfs_cleanup(struct drm_minor *minor)
244{ 210{
245 if (!minor->debugfs_root) 211 if (!minor->debugfs_root)
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c
index 96891c4a6e23..1722d8f21449 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -36,7 +36,7 @@
36 * DOC: CRC ABI 36 * DOC: CRC ABI
37 * 37 *
38 * DRM device drivers can provide to userspace CRC information of each frame as 38 * DRM device drivers can provide to userspace CRC information of each frame as
39 * it reached a given hardware component (a "source"). 39 * it reached a given hardware component (a CRC sampling "source").
40 * 40 *
41 * Userspace can control generation of CRCs in a given CRTC by writing to the 41 * Userspace can control generation of CRCs in a given CRTC by writing to the
42 * file dri/0/crtc-N/crc/control in debugfs, with N being the index of the CRTC. 42 * file dri/0/crtc-N/crc/control in debugfs, with N being the index of the CRTC.
@@ -57,6 +57,11 @@
57 * rely on being able to generate matching CRC values for the frame contents that 57 * rely on being able to generate matching CRC values for the frame contents that
58 * it submits. In this general case, the maximum userspace can do is to compare 58 * it submits. In this general case, the maximum userspace can do is to compare
59 * the reported CRCs of frames that should have the same contents. 59 * the reported CRCs of frames that should have the same contents.
60 *
61 * On the driver side the implementation effort is minimal, drivers only need to
62 * implement &drm_crtc_funcs.set_crc_source. The debugfs files are automatically
63 * set up if that vfunc is set. CRC samples need to be captured in the driver by
64 * calling drm_crtc_add_crc_entry().
60 */ 65 */
61 66
62static int crc_control_show(struct seq_file *m, void *data) 67static int crc_control_show(struct seq_file *m, void *data)
@@ -280,16 +285,6 @@ static const struct file_operations drm_crtc_crc_data_fops = {
280 .release = crtc_crc_release, 285 .release = crtc_crc_release,
281}; 286};
282 287
283/**
284 * drm_debugfs_crtc_crc_add - Add files to debugfs for capture of frame CRCs
285 * @crtc: CRTC to whom the frames will belong
286 *
287 * Adds files to debugfs directory that allows userspace to control the
288 * generation of frame CRCs and to read them.
289 *
290 * Returns:
291 * Zero on success, error code on failure.
292 */
293int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc) 288int drm_debugfs_crtc_crc_add(struct drm_crtc *crtc)
294{ 289{
295 struct dentry *crc_ent, *ent; 290 struct dentry *crc_ent, *ent;
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index f2cc375907d0..d3fc7e4e85b7 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2042,10 +2042,6 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
2042 goto out_unlock; 2042 goto out_unlock;
2043 } 2043 }
2044 2044
2045 mgr->total_pbn = 2560;
2046 mgr->total_slots = DIV_ROUND_UP(mgr->total_pbn, mgr->pbn_div);
2047 mgr->avail_slots = mgr->total_slots;
2048
2049 /* add initial branch device at LCT 1 */ 2045 /* add initial branch device at LCT 1 */
2050 mstb = drm_dp_add_mst_branch_device(1, NULL); 2046 mstb = drm_dp_add_mst_branch_device(1, NULL);
2051 if (mstb == NULL) { 2047 if (mstb == NULL) {
@@ -2475,26 +2471,25 @@ int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
2475 2471
2476 num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div); 2472 num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
2477 2473
2478 if (num_slots > mgr->avail_slots) 2474 /* max. time slots - one slot for MTP header */
2475 if (num_slots > 63)
2479 return -ENOSPC; 2476 return -ENOSPC;
2480 return num_slots; 2477 return num_slots;
2481} 2478}
2482EXPORT_SYMBOL(drm_dp_find_vcpi_slots); 2479EXPORT_SYMBOL(drm_dp_find_vcpi_slots);
2483 2480
2484static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr, 2481static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
2485 struct drm_dp_vcpi *vcpi, int pbn) 2482 struct drm_dp_vcpi *vcpi, int pbn, int slots)
2486{ 2483{
2487 int num_slots;
2488 int ret; 2484 int ret;
2489 2485
2490 num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div); 2486 /* max. time slots - one slot for MTP header */
2491 2487 if (slots > 63)
2492 if (num_slots > mgr->avail_slots)
2493 return -ENOSPC; 2488 return -ENOSPC;
2494 2489
2495 vcpi->pbn = pbn; 2490 vcpi->pbn = pbn;
2496 vcpi->aligned_pbn = num_slots * mgr->pbn_div; 2491 vcpi->aligned_pbn = slots * mgr->pbn_div;
2497 vcpi->num_slots = num_slots; 2492 vcpi->num_slots = slots;
2498 2493
2499 ret = drm_dp_mst_assign_payload_id(mgr, vcpi); 2494 ret = drm_dp_mst_assign_payload_id(mgr, vcpi);
2500 if (ret < 0) 2495 if (ret < 0)
@@ -2509,7 +2504,8 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
2509 * @pbn: payload bandwidth number to request 2504 * @pbn: payload bandwidth number to request
2510 * @slots: returned number of slots for this PBN. 2505 * @slots: returned number of slots for this PBN.
2511 */ 2506 */
2512bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int *slots) 2507bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
2508 struct drm_dp_mst_port *port, int pbn, int slots)
2513{ 2509{
2514 int ret; 2510 int ret;
2515 2511
@@ -2517,22 +2513,25 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp
2517 if (!port) 2513 if (!port)
2518 return false; 2514 return false;
2519 2515
2516 if (slots < 0)
2517 return false;
2518
2520 if (port->vcpi.vcpi > 0) { 2519 if (port->vcpi.vcpi > 0) {
2521 DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n", port->vcpi.vcpi, port->vcpi.pbn, pbn); 2520 DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n", port->vcpi.vcpi, port->vcpi.pbn, pbn);
2522 if (pbn == port->vcpi.pbn) { 2521 if (pbn == port->vcpi.pbn) {
2523 *slots = port->vcpi.num_slots;
2524 drm_dp_put_port(port); 2522 drm_dp_put_port(port);
2525 return true; 2523 return true;
2526 } 2524 }
2527 } 2525 }
2528 2526
2529 ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn); 2527 ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
2530 if (ret) { 2528 if (ret) {
2531 DRM_DEBUG_KMS("failed to init vcpi %d %d %d\n", DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->avail_slots, ret); 2529 DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
2530 DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
2532 goto out; 2531 goto out;
2533 } 2532 }
2534 DRM_DEBUG_KMS("initing vcpi for %d %d\n", pbn, port->vcpi.num_slots); 2533 DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n",
2535 *slots = port->vcpi.num_slots; 2534 pbn, port->vcpi.num_slots);
2536 2535
2537 drm_dp_put_port(port); 2536 drm_dp_put_port(port);
2538 return true; 2537 return true;
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 74cd393a6407..50abd1faf38f 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -177,7 +177,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
177 int ret; 177 int ret;
178 int i; 178 int i;
179 179
180 info = drm_format_info(mode_cmd->pixel_format); 180 info = drm_get_format_info(dev, mode_cmd);
181 if (!info) 181 if (!info)
182 return ERR_PTR(-EINVAL); 182 return ERR_PTR(-EINVAL);
183 183
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 92bf3306d4b3..9c0152df45ad 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -207,6 +207,31 @@ const struct drm_format_info *drm_format_info(u32 format)
207EXPORT_SYMBOL(drm_format_info); 207EXPORT_SYMBOL(drm_format_info);
208 208
209/** 209/**
210 * drm_get_format_info - query information for a given framebuffer configuration
211 * @dev: DRM device
212 * @mode_cmd: metadata from the userspace fb creation request
213 *
214 * Returns:
215 * The instance of struct drm_format_info that describes the pixel format, or
216 * NULL if the format is unsupported.
217 */
218const struct drm_format_info *
219drm_get_format_info(struct drm_device *dev,
220 const struct drm_mode_fb_cmd2 *mode_cmd)
221{
222 const struct drm_format_info *info = NULL;
223
224 if (dev->mode_config.funcs->get_format_info)
225 info = dev->mode_config.funcs->get_format_info(mode_cmd);
226
227 if (!info)
228 info = drm_format_info(mode_cmd->pixel_format);
229
230 return info;
231}
232EXPORT_SYMBOL(drm_get_format_info);
233
234/**
210 * drm_format_num_planes - get the number of planes for format 235 * drm_format_num_planes - get the number of planes for format
211 * @format: pixel format (DRM_FORMAT_*) 236 * @format: pixel format (DRM_FORMAT_*)
212 * 237 *
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index e4909aef75d7..e8f9c13a0afd 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -126,11 +126,31 @@ int drm_mode_addfb(struct drm_device *dev,
126 return 0; 126 return 0;
127} 127}
128 128
129static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) 129static int fb_plane_width(int width,
130 const struct drm_format_info *format, int plane)
131{
132 if (plane == 0)
133 return width;
134
135 return DIV_ROUND_UP(width, format->hsub);
136}
137
138static int fb_plane_height(int height,
139 const struct drm_format_info *format, int plane)
140{
141 if (plane == 0)
142 return height;
143
144 return DIV_ROUND_UP(height, format->vsub);
145}
146
147static int framebuffer_check(struct drm_device *dev,
148 const struct drm_mode_fb_cmd2 *r)
130{ 149{
131 const struct drm_format_info *info; 150 const struct drm_format_info *info;
132 int i; 151 int i;
133 152
153 /* check if the format is supported at all */
134 info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN); 154 info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
135 if (!info) { 155 if (!info) {
136 struct drm_format_name_buf format_name; 156 struct drm_format_name_buf format_name;
@@ -140,19 +160,22 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
140 return -EINVAL; 160 return -EINVAL;
141 } 161 }
142 162
143 if (r->width == 0 || r->width % info->hsub) { 163 /* now let the driver pick its own format info */
164 info = drm_get_format_info(dev, r);
165
166 if (r->width == 0) {
144 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width); 167 DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
145 return -EINVAL; 168 return -EINVAL;
146 } 169 }
147 170
148 if (r->height == 0 || r->height % info->vsub) { 171 if (r->height == 0) {
149 DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height); 172 DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);
150 return -EINVAL; 173 return -EINVAL;
151 } 174 }
152 175
153 for (i = 0; i < info->num_planes; i++) { 176 for (i = 0; i < info->num_planes; i++) {
154 unsigned int width = r->width / (i != 0 ? info->hsub : 1); 177 unsigned int width = fb_plane_width(r->width, info, i);
155 unsigned int height = r->height / (i != 0 ? info->vsub : 1); 178 unsigned int height = fb_plane_height(r->height, info, i);
156 unsigned int cpp = info->cpp[i]; 179 unsigned int cpp = info->cpp[i];
157 180
158 if (!r->handles[i]) { 181 if (!r->handles[i]) {
@@ -263,7 +286,7 @@ drm_internal_framebuffer_create(struct drm_device *dev,
263 return ERR_PTR(-EINVAL); 286 return ERR_PTR(-EINVAL);
264 } 287 }
265 288
266 ret = framebuffer_check(r); 289 ret = framebuffer_check(dev, r);
267 if (ret) 290 if (ret)
268 return ERR_PTR(ret); 291 return ERR_PTR(ret);
269 292
@@ -816,10 +839,7 @@ int drm_framebuffer_plane_width(int width,
816 if (plane >= fb->format->num_planes) 839 if (plane >= fb->format->num_planes)
817 return 0; 840 return 0;
818 841
819 if (plane == 0) 842 return fb_plane_width(width, fb->format, plane);
820 return width;
821
822 return width / fb->format->hsub;
823} 843}
824EXPORT_SYMBOL(drm_framebuffer_plane_width); 844EXPORT_SYMBOL(drm_framebuffer_plane_width);
825 845
@@ -838,9 +858,6 @@ int drm_framebuffer_plane_height(int height,
838 if (plane >= fb->format->num_planes) 858 if (plane >= fb->format->num_planes)
839 return 0; 859 return 0;
840 860
841 if (plane == 0) 861 return fb_plane_height(height, fb->format, plane);
842 return height;
843
844 return height / fb->format->vsub;
845} 862}
846EXPORT_SYMBOL(drm_framebuffer_plane_height); 863EXPORT_SYMBOL(drm_framebuffer_plane_height);
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 92ff4b9393b1..3d8e8f878924 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -100,7 +100,7 @@ int drm_gem_open_ioctl(struct drm_device *dev, void *data,
100void drm_gem_open(struct drm_device *dev, struct drm_file *file_private); 100void drm_gem_open(struct drm_device *dev, struct drm_file *file_private);
101void drm_gem_release(struct drm_device *dev, struct drm_file *file_private); 101void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
102 102
103/* drm_debugfs.c */ 103/* drm_debugfs.c drm_debugfs_crc.c */
104#if defined(CONFIG_DEBUG_FS) 104#if defined(CONFIG_DEBUG_FS)
105int drm_debugfs_init(struct drm_minor *minor, int minor_id, 105int drm_debugfs_init(struct drm_minor *minor, int minor_id,
106 struct dentry *root); 106 struct dentry *root);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index a7c61c23685a..7d6deaa91281 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -28,6 +28,7 @@
28 * OTHER DEALINGS IN THE SOFTWARE. 28 * OTHER DEALINGS IN THE SOFTWARE.
29 */ 29 */
30 30
31#include <drm/drm_ioctl.h>
31#include <drm/drmP.h> 32#include <drm/drmP.h>
32#include <drm/drm_auth.h> 33#include <drm/drm_auth.h>
33#include "drm_legacy.h" 34#include "drm_legacy.h"
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 53a526c7b24d..dac1b2593cb1 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -325,6 +325,8 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
325 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 325 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
326 unsigned long irqflags; 326 unsigned long irqflags;
327 327
328 assert_spin_locked(&dev->vbl_lock);
329
328 /* Prevent vblank irq processing while disabling vblank irqs, 330 /* Prevent vblank irq processing while disabling vblank irqs,
329 * so no updates of timestamps or count can happen after we've 331 * so no updates of timestamps or count can happen after we've
330 * disabled. Needed to prevent races in case of delayed irq's. 332 * disabled. Needed to prevent races in case of delayed irq's.
@@ -384,7 +386,7 @@ void drm_vblank_cleanup(struct drm_device *dev)
384 for (pipe = 0; pipe < dev->num_crtcs; pipe++) { 386 for (pipe = 0; pipe < dev->num_crtcs; pipe++) {
385 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 387 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
386 388
387 WARN_ON(vblank->enabled && 389 WARN_ON(READ_ONCE(vblank->enabled) &&
388 drm_core_check_feature(dev, DRIVER_MODESET)); 390 drm_core_check_feature(dev, DRIVER_MODESET));
389 391
390 del_timer_sync(&vblank->disable_timer); 392 del_timer_sync(&vblank->disable_timer);
@@ -810,14 +812,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
810 /* Return upper bound of timestamp precision error. */ 812 /* Return upper bound of timestamp precision error. */
811 *max_error = duration_ns; 813 *max_error = duration_ns;
812 814
813 /* Check if in vblank area:
814 * vpos is >=0 in video scanout area, but negative
815 * within vblank area, counting down the number of lines until
816 * start of scanout.
817 */
818 if (vbl_status & DRM_SCANOUTPOS_IN_VBLANK)
819 ret |= DRM_VBLANKTIME_IN_VBLANK;
820
821 /* Convert scanout position into elapsed time at raw_time query 815 /* Convert scanout position into elapsed time at raw_time query
822 * since start of scanout at first display scanline. delta_ns 816 * since start of scanout at first display scanline. delta_ns
823 * can be negative if start of scanout hasn't happened yet. 817 * can be negative if start of scanout hasn't happened yet.
@@ -1105,11 +1099,16 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
1105 */ 1099 */
1106 ret = __enable_vblank(dev, pipe); 1100 ret = __enable_vblank(dev, pipe);
1107 DRM_DEBUG("enabling vblank on crtc %u, ret: %d\n", pipe, ret); 1101 DRM_DEBUG("enabling vblank on crtc %u, ret: %d\n", pipe, ret);
1108 if (ret) 1102 if (ret) {
1109 atomic_dec(&vblank->refcount); 1103 atomic_dec(&vblank->refcount);
1110 else { 1104 } else {
1111 vblank->enabled = true;
1112 drm_update_vblank_count(dev, pipe, 0); 1105 drm_update_vblank_count(dev, pipe, 0);
1106 /* drm_update_vblank_count() includes a wmb so we just
1107 * need to ensure that the compiler emits the write
1108 * to mark the vblank as enabled after the call
1109 * to drm_update_vblank_count().
1110 */
1111 WRITE_ONCE(vblank->enabled, true);
1113 } 1112 }
1114 } 1113 }
1115 1114
@@ -1487,6 +1486,11 @@ int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
1487 return 0; 1486 return 0;
1488} 1487}
1489 1488
1489static inline bool vblank_passed(u32 seq, u32 ref)
1490{
1491 return (seq - ref) <= (1 << 23);
1492}
1493
1490static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, 1494static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
1491 union drm_wait_vblank *vblwait, 1495 union drm_wait_vblank *vblwait,
1492 struct drm_file *file_priv) 1496 struct drm_file *file_priv)
@@ -1517,7 +1521,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
1517 * vblank disable, so no need for further locking. The reference from 1521 * vblank disable, so no need for further locking. The reference from
1518 * drm_vblank_get() protects against vblank disable from another source. 1522 * drm_vblank_get() protects against vblank disable from another source.
1519 */ 1523 */
1520 if (!vblank->enabled) { 1524 if (!READ_ONCE(vblank->enabled)) {
1521 ret = -EINVAL; 1525 ret = -EINVAL;
1522 goto err_unlock; 1526 goto err_unlock;
1523 } 1527 }
@@ -1537,7 +1541,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
1537 vblwait->request.sequence); 1541 vblwait->request.sequence);
1538 1542
1539 e->event.sequence = vblwait->request.sequence; 1543 e->event.sequence = vblwait->request.sequence;
1540 if ((seq - vblwait->request.sequence) <= (1 << 23)) { 1544 if (vblank_passed(seq, vblwait->request.sequence)) {
1541 drm_vblank_put(dev, pipe); 1545 drm_vblank_put(dev, pipe);
1542 send_vblank_event(dev, e, seq, &now); 1546 send_vblank_event(dev, e, seq, &now);
1543 vblwait->reply.sequence = seq; 1547 vblwait->reply.sequence = seq;
@@ -1559,6 +1563,17 @@ err_put:
1559 return ret; 1563 return ret;
1560} 1564}
1561 1565
1566static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait)
1567{
1568 if (vblwait->request.sequence)
1569 return false;
1570
1571 return _DRM_VBLANK_RELATIVE ==
1572 (vblwait->request.type & (_DRM_VBLANK_TYPES_MASK |
1573 _DRM_VBLANK_EVENT |
1574 _DRM_VBLANK_NEXTONMISS));
1575}
1576
1562/* 1577/*
1563 * Wait for VBLANK. 1578 * Wait for VBLANK.
1564 * 1579 *
@@ -1608,6 +1623,21 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1608 1623
1609 vblank = &dev->vblank[pipe]; 1624 vblank = &dev->vblank[pipe];
1610 1625
1626 /* If the counter is currently enabled and accurate, short-circuit
1627 * queries to return the cached timestamp of the last vblank.
1628 */
1629 if (dev->vblank_disable_immediate &&
1630 drm_wait_vblank_is_query(vblwait) &&
1631 READ_ONCE(vblank->enabled)) {
1632 struct timeval now;
1633
1634 vblwait->reply.sequence =
1635 drm_vblank_count_and_time(dev, pipe, &now);
1636 vblwait->reply.tval_sec = now.tv_sec;
1637 vblwait->reply.tval_usec = now.tv_usec;
1638 return 0;
1639 }
1640
1611 ret = drm_vblank_get(dev, pipe); 1641 ret = drm_vblank_get(dev, pipe);
1612 if (ret) { 1642 if (ret) {
1613 DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret); 1643 DRM_DEBUG("crtc %d failed to acquire vblank counter, %d\n", pipe, ret);
@@ -1627,9 +1657,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1627 } 1657 }
1628 1658
1629 if ((flags & _DRM_VBLANK_NEXTONMISS) && 1659 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
1630 (seq - vblwait->request.sequence) <= (1 << 23)) { 1660 vblank_passed(seq, vblwait->request.sequence))
1631 vblwait->request.sequence = seq + 1; 1661 vblwait->request.sequence = seq + 1;
1632 }
1633 1662
1634 if (flags & _DRM_VBLANK_EVENT) { 1663 if (flags & _DRM_VBLANK_EVENT) {
1635 /* must hold on to the vblank ref until the event fires 1664 /* must hold on to the vblank ref until the event fires
@@ -1642,10 +1671,9 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1642 DRM_DEBUG("waiting on vblank count %u, crtc %u\n", 1671 DRM_DEBUG("waiting on vblank count %u, crtc %u\n",
1643 vblwait->request.sequence, pipe); 1672 vblwait->request.sequence, pipe);
1644 DRM_WAIT_ON(ret, vblank->queue, 3 * HZ, 1673 DRM_WAIT_ON(ret, vblank->queue, 3 * HZ,
1645 (((drm_vblank_count(dev, pipe) - 1674 vblank_passed(drm_vblank_count(dev, pipe),
1646 vblwait->request.sequence) <= (1 << 23)) || 1675 vblwait->request.sequence) ||
1647 !vblank->enabled || 1676 !READ_ONCE(vblank->enabled));
1648 !dev->irq_enabled));
1649 } 1677 }
1650 1678
1651 if (ret != -EINTR) { 1679 if (ret != -EINTR) {
@@ -1679,7 +1707,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
1679 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { 1707 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
1680 if (e->pipe != pipe) 1708 if (e->pipe != pipe)
1681 continue; 1709 continue;
1682 if ((seq - e->event.sequence) > (1<<23)) 1710 if (!vblank_passed(seq, e->event.sequence))
1683 continue; 1711 continue;
1684 1712
1685 DRM_DEBUG("vblank event on %u, current %u\n", 1713 DRM_DEBUG("vblank event on %u, current %u\n",
@@ -1707,6 +1735,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
1707{ 1735{
1708 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 1736 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1709 unsigned long irqflags; 1737 unsigned long irqflags;
1738 bool disable_irq;
1710 1739
1711 if (WARN_ON_ONCE(!dev->num_crtcs)) 1740 if (WARN_ON_ONCE(!dev->num_crtcs))
1712 return false; 1741 return false;
@@ -1734,20 +1763,23 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
1734 spin_unlock(&dev->vblank_time_lock); 1763 spin_unlock(&dev->vblank_time_lock);
1735 1764
1736 wake_up(&vblank->queue); 1765 wake_up(&vblank->queue);
1737 drm_handle_vblank_events(dev, pipe);
1738 1766
1739 /* With instant-off, we defer disabling the interrupt until after 1767 /* With instant-off, we defer disabling the interrupt until after
1740 * we finish processing the following vblank. The disable has to 1768 * we finish processing the following vblank after all events have
1741 * be last (after drm_handle_vblank_events) so that the timestamp 1769 * been signaled. The disable has to be last (after
1742 * is always accurate. 1770 * drm_handle_vblank_events) so that the timestamp is always accurate.
1743 */ 1771 */
1744 if (dev->vblank_disable_immediate && 1772 disable_irq = (dev->vblank_disable_immediate &&
1745 drm_vblank_offdelay > 0 && 1773 drm_vblank_offdelay > 0 &&
1746 !atomic_read(&vblank->refcount)) 1774 !atomic_read(&vblank->refcount));
1747 vblank_disable_fn((unsigned long)vblank); 1775
1776 drm_handle_vblank_events(dev, pipe);
1748 1777
1749 spin_unlock_irqrestore(&dev->event_lock, irqflags); 1778 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1750 1779
1780 if (disable_irq)
1781 vblank_disable_fn((unsigned long)vblank);
1782
1751 return true; 1783 return true;
1752} 1784}
1753EXPORT_SYMBOL(drm_handle_vblank); 1785EXPORT_SYMBOL(drm_handle_vblank);
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index cc44a9a4b004..2b33825f2f93 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -78,7 +78,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_device *dev,
78 int i; 78 int i;
79 79
80 fb->dev = dev; 80 fb->dev = dev;
81 fb->format = drm_format_info(mode_cmd->pixel_format); 81 fb->format = drm_get_format_info(dev, mode_cmd);
82 fb->width = mode_cmd->width; 82 fb->width = mode_cmd->width;
83 fb->height = mode_cmd->height; 83 fb->height = mode_cmd->height;
84 for (i = 0; i < 4; i++) { 84 for (i = 0; i < 4; i++) {
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index a22e76837065..bc71aa2b7872 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -277,6 +277,12 @@ EXPORT_SYMBOL(drm_plane_from_index);
277 * 277 *
278 * Used when the plane's current framebuffer is destroyed, 278 * Used when the plane's current framebuffer is destroyed,
279 * and when restoring fbdev mode. 279 * and when restoring fbdev mode.
280 *
281 * Note that this function is not suitable for atomic drivers, since it doesn't
282 * wire through the lock acquisition context properly and hence can't handle
283 * retries or driver private locks. You probably want to use
284 * drm_atomic_helper_disable_plane() or
285 * drm_atomic_helper_disable_planes_on_crtc() instead.
280 */ 286 */
281void drm_plane_force_disable(struct drm_plane *plane) 287void drm_plane_force_disable(struct drm_plane *plane)
282{ 288{
@@ -285,8 +291,10 @@ void drm_plane_force_disable(struct drm_plane *plane)
285 if (!plane->fb) 291 if (!plane->fb)
286 return; 292 return;
287 293
294 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
295
288 plane->old_fb = plane->fb; 296 plane->old_fb = plane->fb;
289 ret = plane->funcs->disable_plane(plane); 297 ret = plane->funcs->disable_plane(plane, NULL);
290 if (ret) { 298 if (ret) {
291 DRM_ERROR("failed to disable plane with busy fb\n"); 299 DRM_ERROR("failed to disable plane with busy fb\n");
292 plane->old_fb = NULL; 300 plane->old_fb = NULL;
@@ -457,14 +465,15 @@ static int __setplane_internal(struct drm_plane *plane,
457 uint32_t crtc_w, uint32_t crtc_h, 465 uint32_t crtc_w, uint32_t crtc_h,
458 /* src_{x,y,w,h} values are 16.16 fixed point */ 466 /* src_{x,y,w,h} values are 16.16 fixed point */
459 uint32_t src_x, uint32_t src_y, 467 uint32_t src_x, uint32_t src_y,
460 uint32_t src_w, uint32_t src_h) 468 uint32_t src_w, uint32_t src_h,
469 struct drm_modeset_acquire_ctx *ctx)
461{ 470{
462 int ret = 0; 471 int ret = 0;
463 472
464 /* No fb means shut it down */ 473 /* No fb means shut it down */
465 if (!fb) { 474 if (!fb) {
466 plane->old_fb = plane->fb; 475 plane->old_fb = plane->fb;
467 ret = plane->funcs->disable_plane(plane); 476 ret = plane->funcs->disable_plane(plane, ctx);
468 if (!ret) { 477 if (!ret) {
469 plane->crtc = NULL; 478 plane->crtc = NULL;
470 plane->fb = NULL; 479 plane->fb = NULL;
@@ -509,7 +518,7 @@ static int __setplane_internal(struct drm_plane *plane,
509 plane->old_fb = plane->fb; 518 plane->old_fb = plane->fb;
510 ret = plane->funcs->update_plane(plane, crtc, fb, 519 ret = plane->funcs->update_plane(plane, crtc, fb,
511 crtc_x, crtc_y, crtc_w, crtc_h, 520 crtc_x, crtc_y, crtc_w, crtc_h,
512 src_x, src_y, src_w, src_h); 521 src_x, src_y, src_w, src_h, ctx);
513 if (!ret) { 522 if (!ret) {
514 plane->crtc = crtc; 523 plane->crtc = crtc;
515 plane->fb = fb; 524 plane->fb = fb;
@@ -537,13 +546,25 @@ static int setplane_internal(struct drm_plane *plane,
537 uint32_t src_x, uint32_t src_y, 546 uint32_t src_x, uint32_t src_y,
538 uint32_t src_w, uint32_t src_h) 547 uint32_t src_w, uint32_t src_h)
539{ 548{
549 struct drm_modeset_acquire_ctx ctx;
540 int ret; 550 int ret;
541 551
542 drm_modeset_lock_all(plane->dev); 552 drm_modeset_acquire_init(&ctx, 0);
553retry:
554 ret = drm_modeset_lock_all_ctx(plane->dev, &ctx);
555 if (ret)
556 goto fail;
543 ret = __setplane_internal(plane, crtc, fb, 557 ret = __setplane_internal(plane, crtc, fb,
544 crtc_x, crtc_y, crtc_w, crtc_h, 558 crtc_x, crtc_y, crtc_w, crtc_h,
545 src_x, src_y, src_w, src_h); 559 src_x, src_y, src_w, src_h, &ctx);
546 drm_modeset_unlock_all(plane->dev); 560
561fail:
562 if (ret == -EDEADLK) {
563 drm_modeset_backoff(&ctx);
564 goto retry;
565 }
566 drm_modeset_drop_locks(&ctx);
567 drm_modeset_acquire_fini(&ctx);
547 568
548 return ret; 569 return ret;
549} 570}
@@ -613,11 +634,21 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
613 int32_t crtc_x, crtc_y; 634 int32_t crtc_x, crtc_y;
614 uint32_t crtc_w = 0, crtc_h = 0; 635 uint32_t crtc_w = 0, crtc_h = 0;
615 uint32_t src_w = 0, src_h = 0; 636 uint32_t src_w = 0, src_h = 0;
637 struct drm_modeset_acquire_ctx ctx;
616 int ret = 0; 638 int ret = 0;
617 639
618 BUG_ON(!crtc->cursor); 640 BUG_ON(!crtc->cursor);
619 WARN_ON(crtc->cursor->crtc != crtc && crtc->cursor->crtc != NULL); 641 WARN_ON(crtc->cursor->crtc != crtc && crtc->cursor->crtc != NULL);
620 642
643 drm_modeset_acquire_init(&ctx, 0);
644retry:
645 ret = drm_modeset_lock(&crtc->mutex, &ctx);
646 if (ret)
647 goto fail;
648 ret = drm_modeset_lock(&crtc->cursor->mutex, &ctx);
649 if (ret)
650 goto fail;
651
621 /* 652 /*
622 * Obtain fb we'll be using (either new or existing) and take an extra 653 * Obtain fb we'll be using (either new or existing) and take an extra
623 * reference to it if fb != null. setplane will take care of dropping 654 * reference to it if fb != null. setplane will take care of dropping
@@ -662,7 +693,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
662 */ 693 */
663 ret = __setplane_internal(crtc->cursor, crtc, fb, 694 ret = __setplane_internal(crtc->cursor, crtc, fb,
664 crtc_x, crtc_y, crtc_w, crtc_h, 695 crtc_x, crtc_y, crtc_w, crtc_h,
665 0, 0, src_w, src_h); 696 0, 0, src_w, src_h, &ctx);
666 697
667 /* Update successful; save new cursor position, if necessary */ 698 /* Update successful; save new cursor position, if necessary */
668 if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) { 699 if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) {
@@ -670,6 +701,15 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
670 crtc->cursor_y = req->y; 701 crtc->cursor_y = req->y;
671 } 702 }
672 703
704fail:
705 if (ret == -EDEADLK) {
706 drm_modeset_backoff(&ctx);
707 goto retry;
708 }
709
710 drm_modeset_drop_locks(&ctx);
711 drm_modeset_acquire_fini(&ctx);
712
673 return ret; 713 return ret;
674} 714}
675 715
@@ -696,12 +736,10 @@ static int drm_mode_cursor_common(struct drm_device *dev,
696 * If this crtc has a universal cursor plane, call that plane's update 736 * If this crtc has a universal cursor plane, call that plane's update
697 * handler rather than using legacy cursor handlers. 737 * handler rather than using legacy cursor handlers.
698 */ 738 */
699 drm_modeset_lock_crtc(crtc, crtc->cursor); 739 if (crtc->cursor)
700 if (crtc->cursor) { 740 return drm_mode_cursor_universal(crtc, req, file_priv);
701 ret = drm_mode_cursor_universal(crtc, req, file_priv);
702 goto out;
703 }
704 741
742 drm_modeset_lock_crtc(crtc, crtc->cursor);
705 if (req->flags & DRM_MODE_CURSOR_BO) { 743 if (req->flags & DRM_MODE_CURSOR_BO) {
706 if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) { 744 if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
707 ret = -ENXIO; 745 ret = -ENXIO;
@@ -765,6 +803,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
765 struct drm_framebuffer *fb = NULL; 803 struct drm_framebuffer *fb = NULL;
766 struct drm_pending_vblank_event *e = NULL; 804 struct drm_pending_vblank_event *e = NULL;
767 u32 target_vblank = page_flip->sequence; 805 u32 target_vblank = page_flip->sequence;
806 struct drm_modeset_acquire_ctx ctx;
768 int ret = -EINVAL; 807 int ret = -EINVAL;
769 808
770 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 809 if (!drm_core_check_feature(dev, DRIVER_MODESET))
@@ -828,7 +867,15 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
828 return -EINVAL; 867 return -EINVAL;
829 } 868 }
830 869
831 drm_modeset_lock_crtc(crtc, crtc->primary); 870 drm_modeset_acquire_init(&ctx, 0);
871retry:
872 ret = drm_modeset_lock(&crtc->mutex, &ctx);
873 if (ret)
874 goto out;
875 ret = drm_modeset_lock(&crtc->primary->mutex, &ctx);
876 if (ret)
877 goto out;
878
832 if (crtc->primary->fb == NULL) { 879 if (crtc->primary->fb == NULL) {
833 /* The framebuffer is currently unbound, presumably 880 /* The framebuffer is currently unbound, presumably
834 * due to a hotplug event, that userspace has not 881 * due to a hotplug event, that userspace has not
@@ -876,6 +923,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
876 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); 923 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
877 if (ret) { 924 if (ret) {
878 kfree(e); 925 kfree(e);
926 e = NULL;
879 goto out; 927 goto out;
880 } 928 }
881 } 929 }
@@ -884,9 +932,11 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
884 if (crtc->funcs->page_flip_target) 932 if (crtc->funcs->page_flip_target)
885 ret = crtc->funcs->page_flip_target(crtc, fb, e, 933 ret = crtc->funcs->page_flip_target(crtc, fb, e,
886 page_flip->flags, 934 page_flip->flags,
887 target_vblank); 935 target_vblank,
936 &ctx);
888 else 937 else
889 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); 938 ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags,
939 &ctx);
890 if (ret) { 940 if (ret) {
891 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) 941 if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
892 drm_event_cancel_free(dev, &e->base); 942 drm_event_cancel_free(dev, &e->base);
@@ -906,7 +956,14 @@ out:
906 if (crtc->primary->old_fb) 956 if (crtc->primary->old_fb)
907 drm_framebuffer_put(crtc->primary->old_fb); 957 drm_framebuffer_put(crtc->primary->old_fb);
908 crtc->primary->old_fb = NULL; 958 crtc->primary->old_fb = NULL;
909 drm_modeset_unlock_crtc(crtc); 959
960 if (ret == -EDEADLK) {
961 drm_modeset_backoff(&ctx);
962 goto retry;
963 }
964
965 drm_modeset_drop_locks(&ctx);
966 drm_modeset_acquire_fini(&ctx);
910 967
911 return ret; 968 return ret;
912} 969}
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index de1ac5e08f4d..b84a295230fc 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -275,6 +275,7 @@ EXPORT_SYMBOL(drm_plane_helper_check_update);
275 * @src_y: y offset of @fb for panning 275 * @src_y: y offset of @fb for panning
276 * @src_w: width of source rectangle in @fb 276 * @src_w: width of source rectangle in @fb
277 * @src_h: height of source rectangle in @fb 277 * @src_h: height of source rectangle in @fb
278 * @ctx: lock acquire context, not used here
278 * 279 *
279 * Provides a default plane update handler for primary planes. This is handler 280 * Provides a default plane update handler for primary planes. This is handler
280 * is called in response to a userspace SetPlane operation on the plane with a 281 * is called in response to a userspace SetPlane operation on the plane with a
@@ -303,7 +304,8 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
303 int crtc_x, int crtc_y, 304 int crtc_x, int crtc_y,
304 unsigned int crtc_w, unsigned int crtc_h, 305 unsigned int crtc_w, unsigned int crtc_h,
305 uint32_t src_x, uint32_t src_y, 306 uint32_t src_x, uint32_t src_y,
306 uint32_t src_w, uint32_t src_h) 307 uint32_t src_w, uint32_t src_h,
308 struct drm_modeset_acquire_ctx *ctx)
307{ 309{
308 struct drm_mode_set set = { 310 struct drm_mode_set set = {
309 .crtc = crtc, 311 .crtc = crtc,
@@ -347,7 +349,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
347 * provides their own disable function, this will just 349 * provides their own disable function, this will just
348 * wind up returning -EINVAL to userspace. 350 * wind up returning -EINVAL to userspace.
349 */ 351 */
350 return plane->funcs->disable_plane(plane); 352 return plane->funcs->disable_plane(plane, ctx);
351 353
352 /* Find current connectors for CRTC */ 354 /* Find current connectors for CRTC */
353 num_connectors = get_connectors_for_crtc(crtc, NULL, 0); 355 num_connectors = get_connectors_for_crtc(crtc, NULL, 0);
@@ -369,7 +371,7 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
369 * drm_mode_setplane() already handles the basic refcounting for the 371 * drm_mode_setplane() already handles the basic refcounting for the
370 * framebuffers involved in this operation. 372 * framebuffers involved in this operation.
371 */ 373 */
372 ret = crtc->funcs->set_config(&set); 374 ret = crtc->funcs->set_config(&set, ctx);
373 375
374 kfree(connector_list); 376 kfree(connector_list);
375 return ret; 377 return ret;
@@ -396,7 +398,8 @@ EXPORT_SYMBOL(drm_primary_helper_update);
396 * RETURNS: 398 * RETURNS:
397 * Unconditionally returns -EINVAL. 399 * Unconditionally returns -EINVAL.
398 */ 400 */
399int drm_primary_helper_disable(struct drm_plane *plane) 401int drm_primary_helper_disable(struct drm_plane *plane,
402 struct drm_modeset_acquire_ctx *ctx)
400{ 403{
401 return -EINVAL; 404 return -EINVAL;
402} 405}
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index 16789faa9291..e084f9f8ca66 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -114,7 +114,7 @@ static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
114} 114}
115 115
116static void drm_simple_kms_plane_atomic_update(struct drm_plane *plane, 116static void drm_simple_kms_plane_atomic_update(struct drm_plane *plane,
117 struct drm_plane_state *pstate) 117 struct drm_plane_state *old_pstate)
118{ 118{
119 struct drm_simple_display_pipe *pipe; 119 struct drm_simple_display_pipe *pipe;
120 120
@@ -122,7 +122,7 @@ static void drm_simple_kms_plane_atomic_update(struct drm_plane *plane,
122 if (!pipe->funcs || !pipe->funcs->update) 122 if (!pipe->funcs || !pipe->funcs->update)
123 return; 123 return;
124 124
125 pipe->funcs->update(pipe, pstate); 125 pipe->funcs->update(pipe, old_pstate);
126} 126}
127 127
128static int drm_simple_kms_plane_prepare_fb(struct drm_plane *plane, 128static int drm_simple_kms_plane_prepare_fb(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c
index d1c5642b1c1e..93ff46535c04 100644
--- a/drivers/gpu/drm/gma500/gma_display.c
+++ b/drivers/gpu/drm/gma500/gma_display.c
@@ -514,17 +514,18 @@ void gma_crtc_destroy(struct drm_crtc *crtc)
514 kfree(gma_crtc); 514 kfree(gma_crtc);
515} 515}
516 516
517int gma_crtc_set_config(struct drm_mode_set *set) 517int gma_crtc_set_config(struct drm_mode_set *set,
518 struct drm_modeset_acquire_ctx *ctx)
518{ 519{
519 struct drm_device *dev = set->crtc->dev; 520 struct drm_device *dev = set->crtc->dev;
520 struct drm_psb_private *dev_priv = dev->dev_private; 521 struct drm_psb_private *dev_priv = dev->dev_private;
521 int ret; 522 int ret;
522 523
523 if (!dev_priv->rpm_enabled) 524 if (!dev_priv->rpm_enabled)
524 return drm_crtc_helper_set_config(set); 525 return drm_crtc_helper_set_config(set, ctx);
525 526
526 pm_runtime_forbid(&dev->pdev->dev); 527 pm_runtime_forbid(&dev->pdev->dev);
527 ret = drm_crtc_helper_set_config(set); 528 ret = drm_crtc_helper_set_config(set, ctx);
528 pm_runtime_allow(&dev->pdev->dev); 529 pm_runtime_allow(&dev->pdev->dev);
529 530
530 return ret; 531 return ret;
diff --git a/drivers/gpu/drm/gma500/gma_display.h b/drivers/gpu/drm/gma500/gma_display.h
index e72dd08b701b..166e608923db 100644
--- a/drivers/gpu/drm/gma500/gma_display.h
+++ b/drivers/gpu/drm/gma500/gma_display.h
@@ -79,7 +79,8 @@ extern void gma_crtc_prepare(struct drm_crtc *crtc);
79extern void gma_crtc_commit(struct drm_crtc *crtc); 79extern void gma_crtc_commit(struct drm_crtc *crtc);
80extern void gma_crtc_disable(struct drm_crtc *crtc); 80extern void gma_crtc_disable(struct drm_crtc *crtc);
81extern void gma_crtc_destroy(struct drm_crtc *crtc); 81extern void gma_crtc_destroy(struct drm_crtc *crtc);
82extern int gma_crtc_set_config(struct drm_mode_set *set); 82extern int gma_crtc_set_config(struct drm_mode_set *set,
83 struct drm_modeset_acquire_ctx *ctx);
83 84
84extern void gma_crtc_save(struct drm_crtc *crtc); 85extern void gma_crtc_save(struct drm_crtc *crtc);
85extern void gma_crtc_restore(struct drm_crtc *crtc); 86extern void gma_crtc_restore(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 03d9e45694c9..98b17070a123 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1307,8 +1307,6 @@ void i915_driver_unload(struct drm_device *dev)
1307{ 1307{
1308 struct drm_i915_private *dev_priv = to_i915(dev); 1308 struct drm_i915_private *dev_priv = to_i915(dev);
1309 struct pci_dev *pdev = dev_priv->drm.pdev; 1309 struct pci_dev *pdev = dev_priv->drm.pdev;
1310 struct drm_modeset_acquire_ctx ctx;
1311 int ret;
1312 1310
1313 intel_fbdev_fini(dev); 1311 intel_fbdev_fini(dev);
1314 1312
@@ -1317,23 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
1317 1315
1318 intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); 1316 intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
1319 1317
1320 drm_modeset_acquire_init(&ctx, 0); 1318 drm_atomic_helper_shutdown(dev);
1321 while (1) {
1322 ret = drm_modeset_lock_all_ctx(dev, &ctx);
1323 if (!ret)
1324 ret = drm_atomic_helper_disable_all(dev, &ctx);
1325
1326 if (ret != -EDEADLK)
1327 break;
1328
1329 drm_modeset_backoff(&ctx);
1330 }
1331
1332 if (ret)
1333 DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
1334
1335 drm_modeset_drop_locks(&ctx);
1336 drm_modeset_acquire_fini(&ctx);
1337 1319
1338 intel_gvt_cleanup(dev_priv); 1320 intel_gvt_cleanup(dev_priv);
1339 1321
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 010e5ddb198a..e27ea89efd67 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13426,7 +13426,8 @@ intel_legacy_cursor_update(struct drm_plane *plane,
13426 int crtc_x, int crtc_y, 13426 int crtc_x, int crtc_y,
13427 unsigned int crtc_w, unsigned int crtc_h, 13427 unsigned int crtc_w, unsigned int crtc_h,
13428 uint32_t src_x, uint32_t src_y, 13428 uint32_t src_x, uint32_t src_y,
13429 uint32_t src_w, uint32_t src_h) 13429 uint32_t src_w, uint32_t src_h,
13430 struct drm_modeset_acquire_ctx *ctx)
13430{ 13431{
13431 struct drm_i915_private *dev_priv = to_i915(crtc->dev); 13432 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
13432 int ret; 13433 int ret;
@@ -13539,7 +13540,7 @@ out_free:
13539slow: 13540slow:
13540 return drm_atomic_helper_update_plane(plane, crtc, fb, 13541 return drm_atomic_helper_update_plane(plane, crtc, fb,
13541 crtc_x, crtc_y, crtc_w, crtc_h, 13542 crtc_x, crtc_y, crtc_w, crtc_h,
13542 src_x, src_y, src_w, src_h); 13543 src_x, src_y, src_w, src_h, ctx);
13543} 13544}
13544 13545
13545static const struct drm_plane_funcs intel_cursor_plane_funcs = { 13546static const struct drm_plane_funcs intel_cursor_plane_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 094cbdcbcd6d..c1f62eb07c07 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -149,7 +149,6 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
149 to_intel_connector(conn_state->connector); 149 to_intel_connector(conn_state->connector);
150 int ret; 150 int ret;
151 uint32_t temp; 151 uint32_t temp;
152 int slots;
153 152
154 /* MST encoders are bound to a crtc, not to a connector, 153 /* MST encoders are bound to a crtc, not to a connector,
155 * force the mapping here for get_hw_state. 154 * force the mapping here for get_hw_state.
@@ -165,7 +164,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
165 164
166 ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr, 165 ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
167 connector->port, 166 connector->port,
168 pipe_config->pbn, &slots); 167 pipe_config->pbn,
168 pipe_config->dp_m_n.tu);
169 if (ret == false) { 169 if (ret == false) {
170 DRM_ERROR("failed to allocate vcpi\n"); 170 DRM_ERROR("failed to allocate vcpi\n");
171 return; 171 return;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 0ffb8affef35..60a5451ae0b9 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -37,7 +37,8 @@ static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane,
37 int crtc_x, int crtc_y, 37 int crtc_x, int crtc_y,
38 unsigned int crtc_w, unsigned int crtc_h, 38 unsigned int crtc_w, unsigned int crtc_h,
39 uint32_t src_x, uint32_t src_y, 39 uint32_t src_x, uint32_t src_y,
40 uint32_t src_w, uint32_t src_h); 40 uint32_t src_w, uint32_t src_h,
41 struct drm_modeset_acquire_ctx *ctx);
41 42
42static void set_scanout_locked(struct drm_plane *plane, 43static void set_scanout_locked(struct drm_plane *plane,
43 struct drm_framebuffer *fb); 44 struct drm_framebuffer *fb);
@@ -886,7 +887,8 @@ static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane,
886 int crtc_x, int crtc_y, 887 int crtc_x, int crtc_y,
887 unsigned int crtc_w, unsigned int crtc_h, 888 unsigned int crtc_w, unsigned int crtc_h,
888 uint32_t src_x, uint32_t src_y, 889 uint32_t src_x, uint32_t src_y,
889 uint32_t src_w, uint32_t src_h) 890 uint32_t src_w, uint32_t src_h,
891 struct drm_modeset_acquire_ctx *ctx)
890{ 892{
891 struct drm_plane_state *plane_state, *new_plane_state; 893 struct drm_plane_state *plane_state, *new_plane_state;
892 struct mdp5_plane_state *mdp5_pstate; 894 struct mdp5_plane_state *mdp5_pstate;
@@ -954,7 +956,7 @@ slow_free:
954slow: 956slow:
955 return drm_atomic_helper_update_plane(plane, crtc, fb, 957 return drm_atomic_helper_update_plane(plane, crtc, fb,
956 crtc_x, crtc_y, crtc_w, crtc_h, 958 crtc_x, crtc_y, crtc_w, crtc_h,
957 src_x, src_y, src_w, src_h); 959 src_x, src_y, src_w, src_h, ctx);
958} 960}
959 961
960enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane) 962enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane)
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index ab7b69c11d40..43ab560de7f9 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -1031,8 +1031,9 @@ nv04_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
1031 return 0; 1031 return 0;
1032} 1032}
1033 1033
1034int 1034static int
1035nouveau_crtc_set_config(struct drm_mode_set *set) 1035nouveau_crtc_set_config(struct drm_mode_set *set,
1036 struct drm_modeset_acquire_ctx *ctx)
1036{ 1037{
1037 struct drm_device *dev; 1038 struct drm_device *dev;
1038 struct nouveau_drm *drm; 1039 struct nouveau_drm *drm;
@@ -1049,7 +1050,7 @@ nouveau_crtc_set_config(struct drm_mode_set *set)
1049 if (ret < 0 && ret != -EACCES) 1050 if (ret < 0 && ret != -EACCES)
1050 return ret; 1051 return ret;
1051 1052
1052 ret = drm_crtc_helper_set_config(set); 1053 ret = drm_crtc_helper_set_config(set, ctx);
1053 1054
1054 drm = nouveau_drm(dev); 1055 drm = nouveau_drm(dev);
1055 1056
diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
index 5319f2a7f24d..e54944d23268 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
@@ -94,7 +94,8 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
94 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 94 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
95 unsigned int crtc_w, unsigned int crtc_h, 95 unsigned int crtc_w, unsigned int crtc_h,
96 uint32_t src_x, uint32_t src_y, 96 uint32_t src_x, uint32_t src_y,
97 uint32_t src_w, uint32_t src_h) 97 uint32_t src_w, uint32_t src_h,
98 struct drm_modeset_acquire_ctx *ctx)
98{ 99{
99 struct nouveau_drm *drm = nouveau_drm(plane->dev); 100 struct nouveau_drm *drm = nouveau_drm(plane->dev);
100 struct nvif_object *dev = &drm->client.device.object; 101 struct nvif_object *dev = &drm->client.device.object;
@@ -172,7 +173,8 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
172} 173}
173 174
174static int 175static int
175nv10_disable_plane(struct drm_plane *plane) 176nv10_disable_plane(struct drm_plane *plane,
177 struct drm_modeset_acquire_ctx *ctx)
176{ 178{
177 struct nvif_object *dev = &nouveau_drm(plane->dev)->client.device.object; 179 struct nvif_object *dev = &nouveau_drm(plane->dev)->client.device.object;
178 struct nouveau_plane *nv_plane = 180 struct nouveau_plane *nv_plane =
@@ -190,7 +192,7 @@ nv10_disable_plane(struct drm_plane *plane)
190static void 192static void
191nv_destroy_plane(struct drm_plane *plane) 193nv_destroy_plane(struct drm_plane *plane)
192{ 194{
193 plane->funcs->disable_plane(plane); 195 drm_plane_force_disable(plane);
194 drm_plane_cleanup(plane); 196 drm_plane_cleanup(plane);
195 kfree(plane); 197 kfree(plane);
196} 198}
@@ -331,7 +333,7 @@ nv10_overlay_init(struct drm_device *device)
331 333
332 plane->set_params = nv10_set_params; 334 plane->set_params = nv10_set_params;
333 nv10_set_params(plane); 335 nv10_set_params(plane);
334 nv10_disable_plane(&plane->base); 336 drm_plane_force_disable(&plane->base);
335 return; 337 return;
336cleanup: 338cleanup:
337 drm_plane_cleanup(&plane->base); 339 drm_plane_cleanup(&plane->base);
@@ -345,7 +347,8 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
345 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 347 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
346 unsigned int crtc_w, unsigned int crtc_h, 348 unsigned int crtc_w, unsigned int crtc_h,
347 uint32_t src_x, uint32_t src_y, 349 uint32_t src_x, uint32_t src_y,
348 uint32_t src_w, uint32_t src_h) 350 uint32_t src_w, uint32_t src_h,
351 struct drm_modeset_acquire_ctx *ctx)
349{ 352{
350 struct nvif_object *dev = &nouveau_drm(plane->dev)->client.device.object; 353 struct nvif_object *dev = &nouveau_drm(plane->dev)->client.device.object;
351 struct nouveau_plane *nv_plane = 354 struct nouveau_plane *nv_plane =
@@ -425,7 +428,8 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
425} 428}
426 429
427static int 430static int
428nv04_disable_plane(struct drm_plane *plane) 431nv04_disable_plane(struct drm_plane *plane,
432 struct drm_modeset_acquire_ctx *ctx)
429{ 433{
430 struct nvif_object *dev = &nouveau_drm(plane->dev)->client.device.object; 434 struct nvif_object *dev = &nouveau_drm(plane->dev)->client.device.object;
431 struct nouveau_plane *nv_plane = 435 struct nouveau_plane *nv_plane =
@@ -483,7 +487,7 @@ nv04_overlay_init(struct drm_device *device)
483 drm_object_attach_property(&plane->base.base, 487 drm_object_attach_property(&plane->base.base,
484 plane->props.brightness, plane->brightness); 488 plane->props.brightness, plane->brightness);
485 489
486 nv04_disable_plane(&plane->base); 490 drm_plane_force_disable(&plane->base);
487 return; 491 return;
488cleanup: 492cleanup:
489 drm_plane_cleanup(&plane->base); 493 drm_plane_cleanup(&plane->base);
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 33269c7df30f..6104f61b00fc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -436,8 +436,12 @@ nouveau_display_fini(struct drm_device *dev, bool suspend)
436 struct drm_connector *connector; 436 struct drm_connector *connector;
437 struct drm_crtc *crtc; 437 struct drm_crtc *crtc;
438 438
439 if (!suspend) 439 if (!suspend) {
440 drm_crtc_force_disable_all(dev); 440 if (drm_drv_uses_atomic_modeset(dev))
441 drm_atomic_helper_shutdown(dev);
442 else
443 drm_crtc_force_disable_all(dev);
444 }
441 445
442 /* Make sure that drm and hw vblank irqs get properly disabled. */ 446 /* Make sure that drm and hw vblank irqs get properly disabled. */
443 drm_for_each_crtc(crtc, dev) 447 drm_for_each_crtc(crtc, dev)
@@ -788,7 +792,8 @@ fail:
788 792
789int 793int
790nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 794nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
791 struct drm_pending_vblank_event *event, u32 flags) 795 struct drm_pending_vblank_event *event, u32 flags,
796 struct drm_modeset_acquire_ctx *ctx)
792{ 797{
793 const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; 798 const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1;
794 struct drm_device *dev = crtc->dev; 799 struct drm_device *dev = crtc->dev;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h
index 4a75df06c139..e1d772d39488 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.h
+++ b/drivers/gpu/drm/nouveau/nouveau_display.h
@@ -76,7 +76,8 @@ int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
76 76
77int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 77int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
78 struct drm_pending_vblank_event *event, 78 struct drm_pending_vblank_event *event,
79 uint32_t page_flip_flags); 79 uint32_t page_flip_flags,
80 struct drm_modeset_acquire_ctx *ctx);
80int nouveau_finish_page_flip(struct nouveau_channel *, 81int nouveau_finish_page_flip(struct nouveau_channel *,
81 struct nouveau_page_flip_state *); 82 struct nouveau_page_flip_state *);
82 83
@@ -87,7 +88,6 @@ int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
87 88
88void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *); 89void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *);
89 90
90int nouveau_crtc_set_config(struct drm_mode_set *set);
91#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT 91#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
92extern int nouveau_backlight_init(struct drm_device *); 92extern int nouveau_backlight_init(struct drm_device *);
93extern void nouveau_backlight_exit(struct drm_device *); 93extern void nouveau_backlight_exit(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
index ccb597eac538..a4aacbc0cec8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -95,6 +95,10 @@ nouveau_vga_init(struct nouveau_drm *drm)
95 95
96 vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); 96 vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
97 97
98 /* don't register Thunderbolt eGPU with vga_switcheroo */
99 if (pci_is_thunderbolt_attached(dev->pdev))
100 return;
101
98 if (nouveau_runtime_pm == 1) 102 if (nouveau_runtime_pm == 1)
99 runtime = true; 103 runtime = true;
100 if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm())) 104 if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm()))
@@ -111,6 +115,11 @@ nouveau_vga_fini(struct nouveau_drm *drm)
111 struct drm_device *dev = drm->dev; 115 struct drm_device *dev = drm->dev;
112 bool runtime = false; 116 bool runtime = false;
113 117
118 vga_client_register(dev->pdev, NULL, NULL, NULL);
119
120 if (pci_is_thunderbolt_attached(dev->pdev))
121 return;
122
114 if (nouveau_runtime_pm == 1) 123 if (nouveau_runtime_pm == 1)
115 runtime = true; 124 runtime = true;
116 if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm())) 125 if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm()))
@@ -119,7 +128,6 @@ nouveau_vga_fini(struct nouveau_drm *drm)
119 vga_switcheroo_unregister_client(dev->pdev); 128 vga_switcheroo_unregister_client(dev->pdev);
120 if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus()) 129 if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus())
121 vga_switcheroo_fini_domain_pm_ops(drm->dev->dev); 130 vga_switcheroo_fini_domain_pm_ops(drm->dev->dev);
122 vga_client_register(dev->pdev, NULL, NULL, NULL);
123} 131}
124 132
125 133
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 7ad1ee580cf0..418872b493a3 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -2895,7 +2895,8 @@ nv50_msto_enable(struct drm_encoder *encoder)
2895 if (WARN_ON(!mstc)) 2895 if (WARN_ON(!mstc))
2896 return; 2896 return;
2897 2897
2898 r = drm_dp_mst_allocate_vcpi(&mstm->mgr, mstc->port, mstc->pbn, &slots); 2898 slots = drm_dp_find_vcpi_slots(&mstm->mgr, mstc->pbn);
2899 r = drm_dp_mst_allocate_vcpi(&mstm->mgr, mstc->port, mstc->pbn, slots);
2899 WARN_ON(!r); 2900 WARN_ON(!r);
2900 2901
2901 if (mstm->outp->dcb->sorconf.link & 1) 2902 if (mstm->outp->dcb->sorconf.link & 1)
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 64b02f3c7906..6ecf42783d4b 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1468,7 +1468,9 @@ int radeon_device_init(struct radeon_device *rdev,
1468 1468
1469 if (rdev->flags & RADEON_IS_PX) 1469 if (rdev->flags & RADEON_IS_PX)
1470 runtime = true; 1470 runtime = true;
1471 vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); 1471 if (!pci_is_thunderbolt_attached(rdev->pdev))
1472 vga_switcheroo_register_client(rdev->pdev,
1473 &radeon_switcheroo_ops, runtime);
1472 if (runtime) 1474 if (runtime)
1473 vga_switcheroo_init_domain_pm_ops(rdev->dev, &rdev->vga_pm_domain); 1475 vga_switcheroo_init_domain_pm_ops(rdev->dev, &rdev->vga_pm_domain);
1474 1476
@@ -1561,7 +1563,8 @@ void radeon_device_fini(struct radeon_device *rdev)
1561 /* evict vram memory */ 1563 /* evict vram memory */
1562 radeon_bo_evict_vram(rdev); 1564 radeon_bo_evict_vram(rdev);
1563 radeon_fini(rdev); 1565 radeon_fini(rdev);
1564 vga_switcheroo_unregister_client(rdev->pdev); 1566 if (!pci_is_thunderbolt_attached(rdev->pdev))
1567 vga_switcheroo_unregister_client(rdev->pdev);
1565 if (rdev->flags & RADEON_IS_PX) 1568 if (rdev->flags & RADEON_IS_PX)
1566 vga_switcheroo_fini_domain_pm_ops(rdev->dev); 1569 vga_switcheroo_fini_domain_pm_ops(rdev->dev);
1567 vga_client_register(rdev->pdev, NULL, NULL, NULL); 1570 vga_client_register(rdev->pdev, NULL, NULL, NULL);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index aea8b62835a4..146297a702ab 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -485,7 +485,8 @@ static int radeon_crtc_page_flip_target(struct drm_crtc *crtc,
485 struct drm_framebuffer *fb, 485 struct drm_framebuffer *fb,
486 struct drm_pending_vblank_event *event, 486 struct drm_pending_vblank_event *event,
487 uint32_t page_flip_flags, 487 uint32_t page_flip_flags,
488 uint32_t target) 488 uint32_t target,
489 struct drm_modeset_acquire_ctx *ctx)
489{ 490{
490 struct drm_device *dev = crtc->dev; 491 struct drm_device *dev = crtc->dev;
491 struct radeon_device *rdev = dev->dev_private; 492 struct radeon_device *rdev = dev->dev_private;
@@ -623,7 +624,8 @@ cleanup:
623} 624}
624 625
625static int 626static int
626radeon_crtc_set_config(struct drm_mode_set *set) 627radeon_crtc_set_config(struct drm_mode_set *set,
628 struct drm_modeset_acquire_ctx *ctx)
627{ 629{
628 struct drm_device *dev; 630 struct drm_device *dev;
629 struct radeon_device *rdev; 631 struct radeon_device *rdev;
@@ -640,7 +642,7 @@ radeon_crtc_set_config(struct drm_mode_set *set)
640 if (ret < 0) 642 if (ret < 0)
641 return ret; 643 return ret;
642 644
643 ret = drm_crtc_helper_set_config(set); 645 ret = drm_crtc_helper_set_config(set, ctx);
644 646
645 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) 647 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
646 if (crtc->enabled) 648 if (crtc->enabled)
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 7d5ada3980dc..6598306dca9b 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -453,9 +453,11 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
453 DRM_DEBUG_KMS("dig encoder is %d %d %d\n", dig_enc->dig_encoder, 453 DRM_DEBUG_KMS("dig encoder is %d %d %d\n", dig_enc->dig_encoder,
454 dig_enc->linkb, radeon_crtc->crtc_id); 454 dig_enc->linkb, radeon_crtc->crtc_id);
455 455
456 slots = drm_dp_find_vcpi_slots(&radeon_connector->mst_port->mst_mgr,
457 mst_enc->pbn);
456 ret = drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr, 458 ret = drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
457 radeon_connector->port, 459 radeon_connector->port,
458 mst_enc->pbn, &slots); 460 mst_enc->pbn, slots);
459 ret = drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr); 461 ret = drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
460 462
461 radeon_dp_mst_set_be_cntl(primary, mst_enc, 463 radeon_dp_mst_set_be_cntl(primary, mst_enc,
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index a32a62e03a44..e3e7cb1d10a2 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -115,7 +115,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
115 115
116 if ((radeon_runtime_pm != 0) && 116 if ((radeon_runtime_pm != 0) &&
117 radeon_has_atpx() && 117 radeon_has_atpx() &&
118 ((flags & RADEON_IS_IGP) == 0)) 118 ((flags & RADEON_IS_IGP) == 0) &&
119 !pci_is_thunderbolt_attached(rdev->pdev))
119 flags |= RADEON_IS_PX; 120 flags |= RADEON_IS_PX;
120 121
121 /* radeon_device_init should report only fatal error 122 /* radeon_device_init should report only fatal error
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 0e4eb845cbb0..50c41c0a50ef 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -13,7 +13,7 @@ config DRM_ROCKCHIP
13 IP found on the SoC. 13 IP found on the SoC.
14 14
15config ROCKCHIP_ANALOGIX_DP 15config ROCKCHIP_ANALOGIX_DP
16 tristate "Rockchip specific extensions for Analogix DP driver" 16 bool "Rockchip specific extensions for Analogix DP driver"
17 depends on DRM_ROCKCHIP 17 depends on DRM_ROCKCHIP
18 select DRM_ANALOGIX_DP 18 select DRM_ANALOGIX_DP
19 help 19 help
@@ -22,7 +22,7 @@ config ROCKCHIP_ANALOGIX_DP
22 on RK3288 based SoC, you should selet this option. 22 on RK3288 based SoC, you should selet this option.
23 23
24config ROCKCHIP_CDN_DP 24config ROCKCHIP_CDN_DP
25 tristate "Rockchip cdn DP" 25 bool "Rockchip cdn DP"
26 depends on DRM_ROCKCHIP 26 depends on DRM_ROCKCHIP
27 depends on EXTCON 27 depends on EXTCON
28 select SND_SOC_HDMI_CODEC if SND_SOC 28 select SND_SOC_HDMI_CODEC if SND_SOC
@@ -33,7 +33,7 @@ config ROCKCHIP_CDN_DP
33 option. 33 option.
34 34
35config ROCKCHIP_DW_HDMI 35config ROCKCHIP_DW_HDMI
36 tristate "Rockchip specific extensions for Synopsys DW HDMI" 36 bool "Rockchip specific extensions for Synopsys DW HDMI"
37 depends on DRM_ROCKCHIP 37 depends on DRM_ROCKCHIP
38 select DRM_DW_HDMI 38 select DRM_DW_HDMI
39 help 39 help
@@ -43,7 +43,7 @@ config ROCKCHIP_DW_HDMI
43 option. 43 option.
44 44
45config ROCKCHIP_DW_MIPI_DSI 45config ROCKCHIP_DW_MIPI_DSI
46 tristate "Rockchip specific extensions for Synopsys DW MIPI DSI" 46 bool "Rockchip specific extensions for Synopsys DW MIPI DSI"
47 depends on DRM_ROCKCHIP 47 depends on DRM_ROCKCHIP
48 select DRM_MIPI_DSI 48 select DRM_MIPI_DSI
49 help 49 help
@@ -53,7 +53,7 @@ config ROCKCHIP_DW_MIPI_DSI
53 option. 53 option.
54 54
55config ROCKCHIP_INNO_HDMI 55config ROCKCHIP_INNO_HDMI
56 tristate "Rockchip specific extensions for Innosilicon HDMI" 56 bool "Rockchip specific extensions for Innosilicon HDMI"
57 depends on DRM_ROCKCHIP 57 depends on DRM_ROCKCHIP
58 help 58 help
59 This selects support for Rockchip SoC specific extensions 59 This selects support for Rockchip SoC specific extensions
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index c931e2a7d8de..fa8dc9d9aac2 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -3,14 +3,14 @@
3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4 4
5rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \ 5rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
6 rockchip_drm_gem.o rockchip_drm_psr.o rockchip_drm_vop.o 6 rockchip_drm_gem.o rockchip_drm_psr.o \
7 rockchip_drm_vop.o rockchip_vop_reg.o
7rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o 8rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
8 9
9obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o 10rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
10obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp.o 11rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
11cdn-dp-objs := cdn-dp-core.o cdn-dp-reg.o 12rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
12obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o 13rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
13obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o 14rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
14obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
15 15
16obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_vop_reg.o 16obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 8548e8271639..91ebe5c2c7a0 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -507,7 +507,7 @@ static const struct of_device_id rockchip_dp_dt_ids[] = {
507}; 507};
508MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids); 508MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
509 509
510static struct platform_driver rockchip_dp_driver = { 510struct platform_driver rockchip_dp_driver = {
511 .probe = rockchip_dp_probe, 511 .probe = rockchip_dp_probe,
512 .remove = rockchip_dp_remove, 512 .remove = rockchip_dp_remove,
513 .driver = { 513 .driver = {
@@ -516,10 +516,3 @@ static struct platform_driver rockchip_dp_driver = {
516 .of_match_table = of_match_ptr(rockchip_dp_dt_ids), 516 .of_match_table = of_match_ptr(rockchip_dp_dt_ids),
517 }, 517 },
518}; 518};
519
520module_platform_driver(rockchip_dp_driver);
521
522MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
523MODULE_AUTHOR("Jeff chen <jeff.chen@rock-chips.com>");
524MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension");
525MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 9edb8dc1ea14..4e55d63c3ef3 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1244,7 +1244,7 @@ static const struct dev_pm_ops cdn_dp_pm_ops = {
1244 cdn_dp_resume) 1244 cdn_dp_resume)
1245}; 1245};
1246 1246
1247static struct platform_driver cdn_dp_driver = { 1247struct platform_driver cdn_dp_driver = {
1248 .probe = cdn_dp_probe, 1248 .probe = cdn_dp_probe,
1249 .remove = cdn_dp_remove, 1249 .remove = cdn_dp_remove,
1250 .shutdown = cdn_dp_shutdown, 1250 .shutdown = cdn_dp_shutdown,
@@ -1255,9 +1255,3 @@ static struct platform_driver cdn_dp_driver = {
1255 .pm = &cdn_dp_pm_ops, 1255 .pm = &cdn_dp_pm_ops,
1256 }, 1256 },
1257}; 1257};
1258
1259module_platform_driver(cdn_dp_driver);
1260
1261MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
1262MODULE_DESCRIPTION("cdn DP Driver");
1263MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index f84f9ae2fd35..21b9737662ae 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -34,7 +34,7 @@
34#define RK3288_DSI0_SEL_VOP_LIT BIT(6) 34#define RK3288_DSI0_SEL_VOP_LIT BIT(6)
35#define RK3288_DSI1_SEL_VOP_LIT BIT(9) 35#define RK3288_DSI1_SEL_VOP_LIT BIT(9)
36 36
37#define RK3399_GRF_SOC_CON19 0x6250 37#define RK3399_GRF_SOC_CON20 0x6250
38#define RK3399_DSI0_SEL_VOP_LIT BIT(0) 38#define RK3399_DSI0_SEL_VOP_LIT BIT(0)
39#define RK3399_DSI1_SEL_VOP_LIT BIT(4) 39#define RK3399_DSI1_SEL_VOP_LIT BIT(4)
40 40
@@ -251,6 +251,9 @@
251#define THS_PRE_PROGRAM_EN BIT(7) 251#define THS_PRE_PROGRAM_EN BIT(7)
252#define THS_ZERO_PROGRAM_EN BIT(6) 252#define THS_ZERO_PROGRAM_EN BIT(6)
253 253
254#define DW_MIPI_NEEDS_PHY_CFG_CLK BIT(0)
255#define DW_MIPI_NEEDS_GRF_CLK BIT(1)
256
254enum { 257enum {
255 BANDGAP_97_07, 258 BANDGAP_97_07,
256 BANDGAP_98_05, 259 BANDGAP_98_05,
@@ -279,6 +282,7 @@ struct dw_mipi_dsi_plat_data {
279 u32 grf_switch_reg; 282 u32 grf_switch_reg;
280 u32 grf_dsi0_mode; 283 u32 grf_dsi0_mode;
281 u32 grf_dsi0_mode_reg; 284 u32 grf_dsi0_mode_reg;
285 unsigned int flags;
282 unsigned int max_data_lanes; 286 unsigned int max_data_lanes;
283}; 287};
284 288
@@ -291,6 +295,7 @@ struct dw_mipi_dsi {
291 struct regmap *grf_regmap; 295 struct regmap *grf_regmap;
292 void __iomem *base; 296 void __iomem *base;
293 297
298 struct clk *grf_clk;
294 struct clk *pllref_clk; 299 struct clk *pllref_clk;
295 struct clk *pclk; 300 struct clk *pclk;
296 struct clk *phy_cfg_clk; 301 struct clk *phy_cfg_clk;
@@ -979,6 +984,17 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
979 dw_mipi_dsi_dphy_interface_config(dsi); 984 dw_mipi_dsi_dphy_interface_config(dsi);
980 dw_mipi_dsi_clear_err(dsi); 985 dw_mipi_dsi_clear_err(dsi);
981 986
987 /*
988 * For the RK3399, the clk of grf must be enabled before writing grf
989 * register. And for RK3288 or other soc, this grf_clk must be NULL,
990 * the clk_prepare_enable return true directly.
991 */
992 ret = clk_prepare_enable(dsi->grf_clk);
993 if (ret) {
994 dev_err(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
995 return;
996 }
997
982 if (pdata->grf_dsi0_mode_reg) 998 if (pdata->grf_dsi0_mode_reg)
983 regmap_write(dsi->grf_regmap, pdata->grf_dsi0_mode_reg, 999 regmap_write(dsi->grf_regmap, pdata->grf_dsi0_mode_reg,
984 pdata->grf_dsi0_mode); 1000 pdata->grf_dsi0_mode);
@@ -1003,6 +1019,8 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
1003 regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val); 1019 regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val);
1004 dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG"); 1020 dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
1005 dsi->dpms_mode = DRM_MODE_DPMS_ON; 1021 dsi->dpms_mode = DRM_MODE_DPMS_ON;
1022
1023 clk_disable_unprepare(dsi->grf_clk);
1006} 1024}
1007 1025
1008static int 1026static int
@@ -1133,9 +1151,10 @@ static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
1133static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = { 1151static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
1134 .dsi0_en_bit = RK3399_DSI0_SEL_VOP_LIT, 1152 .dsi0_en_bit = RK3399_DSI0_SEL_VOP_LIT,
1135 .dsi1_en_bit = RK3399_DSI1_SEL_VOP_LIT, 1153 .dsi1_en_bit = RK3399_DSI1_SEL_VOP_LIT,
1136 .grf_switch_reg = RK3399_GRF_SOC_CON19, 1154 .grf_switch_reg = RK3399_GRF_SOC_CON20,
1137 .grf_dsi0_mode = RK3399_GRF_DSI_MODE, 1155 .grf_dsi0_mode = RK3399_GRF_DSI_MODE,
1138 .grf_dsi0_mode_reg = RK3399_GRF_SOC_CON22, 1156 .grf_dsi0_mode_reg = RK3399_GRF_SOC_CON22,
1157 .flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
1139 .max_data_lanes = 4, 1158 .max_data_lanes = 4,
1140}; 1159};
1141 1160
@@ -1227,15 +1246,22 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
1227 clk_disable_unprepare(dsi->pclk); 1246 clk_disable_unprepare(dsi->pclk);
1228 } 1247 }
1229 1248
1230 dsi->phy_cfg_clk = devm_clk_get(dev, "phy_cfg"); 1249 if (pdata->flags & DW_MIPI_NEEDS_PHY_CFG_CLK) {
1231 if (IS_ERR(dsi->phy_cfg_clk)) { 1250 dsi->phy_cfg_clk = devm_clk_get(dev, "phy_cfg");
1232 ret = PTR_ERR(dsi->phy_cfg_clk); 1251 if (IS_ERR(dsi->phy_cfg_clk)) {
1233 if (ret != -ENOENT) { 1252 ret = PTR_ERR(dsi->phy_cfg_clk);
1234 dev_err(dev, "Unable to get phy_cfg_clk: %d\n", ret); 1253 dev_err(dev, "Unable to get phy_cfg_clk: %d\n", ret);
1235 return ret; 1254 return ret;
1236 } 1255 }
1237 dsi->phy_cfg_clk = NULL; 1256 }
1238 dev_dbg(dev, "have not phy_cfg_clk\n"); 1257
1258 if (pdata->flags & DW_MIPI_NEEDS_GRF_CLK) {
1259 dsi->grf_clk = devm_clk_get(dev, "grf");
1260 if (IS_ERR(dsi->grf_clk)) {
1261 ret = PTR_ERR(dsi->grf_clk);
1262 dev_err(dev, "Unable to get grf_clk: %d\n", ret);
1263 return ret;
1264 }
1239 } 1265 }
1240 1266
1241 ret = clk_prepare_enable(dsi->pllref_clk); 1267 ret = clk_prepare_enable(dsi->pllref_clk);
@@ -1304,7 +1330,7 @@ static int dw_mipi_dsi_remove(struct platform_device *pdev)
1304 return 0; 1330 return 0;
1305} 1331}
1306 1332
1307static struct platform_driver dw_mipi_dsi_driver = { 1333struct platform_driver dw_mipi_dsi_driver = {
1308 .probe = dw_mipi_dsi_probe, 1334 .probe = dw_mipi_dsi_probe,
1309 .remove = dw_mipi_dsi_remove, 1335 .remove = dw_mipi_dsi_remove,
1310 .driver = { 1336 .driver = {
@@ -1312,9 +1338,3 @@ static struct platform_driver dw_mipi_dsi_driver = {
1312 .name = DRIVER_NAME, 1338 .name = DRIVER_NAME,
1313 }, 1339 },
1314}; 1340};
1315module_platform_driver(dw_mipi_dsi_driver);
1316
1317MODULE_DESCRIPTION("ROCKCHIP MIPI DSI host controller driver");
1318MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
1319MODULE_LICENSE("GPL");
1320MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index d53827413996..63dab6f1b191 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -325,7 +325,7 @@ static int dw_hdmi_rockchip_remove(struct platform_device *pdev)
325 return 0; 325 return 0;
326} 326}
327 327
328static struct platform_driver dw_hdmi_rockchip_pltfm_driver = { 328struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
329 .probe = dw_hdmi_rockchip_probe, 329 .probe = dw_hdmi_rockchip_probe,
330 .remove = dw_hdmi_rockchip_remove, 330 .remove = dw_hdmi_rockchip_remove,
331 .driver = { 331 .driver = {
@@ -333,11 +333,3 @@ static struct platform_driver dw_hdmi_rockchip_pltfm_driver = {
333 .of_match_table = dw_hdmi_rockchip_dt_ids, 333 .of_match_table = dw_hdmi_rockchip_dt_ids,
334 }, 334 },
335}; 335};
336
337module_platform_driver(dw_hdmi_rockchip_pltfm_driver);
338
339MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
340MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
341MODULE_DESCRIPTION("Rockchip Specific DW-HDMI Driver Extension");
342MODULE_LICENSE("GPL");
343MODULE_ALIAS("platform:dwhdmi-rockchip");
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 006260de9dbd..7d9b75eb6c44 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -923,7 +923,7 @@ static const struct of_device_id inno_hdmi_dt_ids[] = {
923}; 923};
924MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids); 924MODULE_DEVICE_TABLE(of, inno_hdmi_dt_ids);
925 925
926static struct platform_driver inno_hdmi_driver = { 926struct platform_driver inno_hdmi_driver = {
927 .probe = inno_hdmi_probe, 927 .probe = inno_hdmi_probe,
928 .remove = inno_hdmi_remove, 928 .remove = inno_hdmi_remove,
929 .driver = { 929 .driver = {
@@ -931,11 +931,3 @@ static struct platform_driver inno_hdmi_driver = {
931 .of_match_table = inno_hdmi_dt_ids, 931 .of_match_table = inno_hdmi_dt_ids,
932 }, 932 },
933}; 933};
934
935module_platform_driver(inno_hdmi_driver);
936
937MODULE_AUTHOR("Zheng Yang <zhengyang@rock-chips.com>");
938MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
939MODULE_DESCRIPTION("Rockchip Specific INNO-HDMI Driver");
940MODULE_LICENSE("GPL v2");
941MODULE_ALIAS("platform:innohdmi-rockchip");
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ccf456938792..cd7d02e1f758 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -304,34 +304,37 @@ static const struct dev_pm_ops rockchip_drm_pm_ops = {
304 rockchip_drm_sys_resume) 304 rockchip_drm_sys_resume)
305}; 305};
306 306
307static int compare_of(struct device *dev, void *data) 307#define MAX_ROCKCHIP_SUB_DRIVERS 16
308{ 308static struct platform_driver *rockchip_sub_drivers[MAX_ROCKCHIP_SUB_DRIVERS];
309 struct device_node *np = data; 309static int num_rockchip_sub_drivers;
310 310
311 return dev->of_node == np; 311static int compare_dev(struct device *dev, void *data)
312{
313 return dev == (struct device *)data;
312} 314}
313 315
314static void rockchip_add_endpoints(struct device *dev, 316static struct component_match *rockchip_drm_match_add(struct device *dev)
315 struct component_match **match,
316 struct device_node *port)
317{ 317{
318 struct device_node *ep, *remote; 318 struct component_match *match = NULL;
319 int i;
319 320
320 for_each_child_of_node(port, ep) { 321 for (i = 0; i < num_rockchip_sub_drivers; i++) {
321 remote = of_graph_get_remote_port_parent(ep); 322 struct platform_driver *drv = rockchip_sub_drivers[i];
322 if (!remote || !of_device_is_available(remote)) { 323 struct device *p = NULL, *d;
323 of_node_put(remote); 324
324 continue; 325 do {
325 } else if (!of_device_is_available(remote->parent)) { 326 d = bus_find_device(&platform_bus_type, p, &drv->driver,
326 dev_warn(dev, "parent device of %s is not available\n", 327 (void *)platform_bus_type.match);
327 remote->full_name); 328 put_device(p);
328 of_node_put(remote); 329 p = d;
329 continue;
330 }
331 330
332 drm_of_component_match_add(dev, match, compare_of, remote); 331 if (!d)
333 of_node_put(remote); 332 break;
333 component_match_add(dev, &match, compare_dev, d);
334 } while (true);
334 } 335 }
336
337 return match ?: ERR_PTR(-ENODEV);
335} 338}
336 339
337static const struct component_master_ops rockchip_drm_ops = { 340static const struct component_master_ops rockchip_drm_ops = {
@@ -339,21 +342,16 @@ static const struct component_master_ops rockchip_drm_ops = {
339 .unbind = rockchip_drm_unbind, 342 .unbind = rockchip_drm_unbind,
340}; 343};
341 344
342static int rockchip_drm_platform_probe(struct platform_device *pdev) 345static int rockchip_drm_platform_of_probe(struct device *dev)
343{ 346{
344 struct device *dev = &pdev->dev;
345 struct component_match *match = NULL;
346 struct device_node *np = dev->of_node; 347 struct device_node *np = dev->of_node;
347 struct device_node *port; 348 struct device_node *port;
349 bool found = false;
348 int i; 350 int i;
349 351
350 if (!np) 352 if (!np)
351 return -ENODEV; 353 return -ENODEV;
352 /* 354
353 * Bind the crtc ports first, so that
354 * drm_of_find_possible_crtcs called from encoder .bind callbacks
355 * works as expected.
356 */
357 for (i = 0;; i++) { 355 for (i = 0;; i++) {
358 struct device_node *iommu; 356 struct device_node *iommu;
359 357
@@ -377,9 +375,9 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
377 is_support_iommu = false; 375 is_support_iommu = false;
378 } 376 }
379 377
378 found = true;
379
380 of_node_put(iommu); 380 of_node_put(iommu);
381 drm_of_component_match_add(dev, &match, compare_of,
382 port->parent);
383 of_node_put(port); 381 of_node_put(port);
384 } 382 }
385 383
@@ -388,27 +386,27 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
388 return -ENODEV; 386 return -ENODEV;
389 } 387 }
390 388
391 if (!match) { 389 if (!found) {
392 dev_err(dev, "No available vop found for display-subsystem.\n"); 390 dev_err(dev, "No available vop found for display-subsystem.\n");
393 return -ENODEV; 391 return -ENODEV;
394 } 392 }
395 /*
396 * For each bound crtc, bind the encoders attached to its
397 * remote endpoint.
398 */
399 for (i = 0;; i++) {
400 port = of_parse_phandle(np, "ports", i);
401 if (!port)
402 break;
403 393
404 if (!of_device_is_available(port->parent)) { 394 return 0;
405 of_node_put(port); 395}
406 continue;
407 }
408 396
409 rockchip_add_endpoints(dev, &match, port); 397static int rockchip_drm_platform_probe(struct platform_device *pdev)
410 of_node_put(port); 398{
411 } 399 struct device *dev = &pdev->dev;
400 struct component_match *match = NULL;
401 int ret;
402
403 ret = rockchip_drm_platform_of_probe(dev);
404 if (ret)
405 return ret;
406
407 match = rockchip_drm_match_add(dev);
408 if (IS_ERR(match))
409 return PTR_ERR(match);
412 410
413 return component_master_add_with_match(dev, &rockchip_drm_ops, match); 411 return component_master_add_with_match(dev, &rockchip_drm_ops, match);
414} 412}
@@ -436,7 +434,54 @@ static struct platform_driver rockchip_drm_platform_driver = {
436 }, 434 },
437}; 435};
438 436
439module_platform_driver(rockchip_drm_platform_driver); 437#define ADD_ROCKCHIP_SUB_DRIVER(drv, cond) { \
438 if (IS_ENABLED(cond) && \
439 !WARN_ON(num_rockchip_sub_drivers >= MAX_ROCKCHIP_SUB_DRIVERS)) \
440 rockchip_sub_drivers[num_rockchip_sub_drivers++] = &drv; \
441}
442
443static int __init rockchip_drm_init(void)
444{
445 int ret;
446
447 num_rockchip_sub_drivers = 0;
448 ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP);
449 ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver,
450 CONFIG_ROCKCHIP_ANALOGIX_DP);
451 ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP);
452 ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_rockchip_pltfm_driver,
453 CONFIG_ROCKCHIP_DW_HDMI);
454 ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_driver,
455 CONFIG_ROCKCHIP_DW_MIPI_DSI);
456 ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI);
457
458 ret = platform_register_drivers(rockchip_sub_drivers,
459 num_rockchip_sub_drivers);
460 if (ret)
461 return ret;
462
463 ret = platform_driver_register(&rockchip_drm_platform_driver);
464 if (ret)
465 goto err_unreg_drivers;
466
467 return 0;
468
469err_unreg_drivers:
470 platform_unregister_drivers(rockchip_sub_drivers,
471 num_rockchip_sub_drivers);
472 return ret;
473}
474
475static void __exit rockchip_drm_fini(void)
476{
477 platform_driver_unregister(&rockchip_drm_platform_driver);
478
479 platform_unregister_drivers(rockchip_sub_drivers,
480 num_rockchip_sub_drivers);
481}
482
483module_init(rockchip_drm_init);
484module_exit(rockchip_drm_fini);
440 485
441MODULE_AUTHOR("Mark Yao <mark.yao@rock-chips.com>"); 486MODULE_AUTHOR("Mark Yao <mark.yao@rock-chips.com>");
442MODULE_DESCRIPTION("ROCKCHIP DRM Driver"); 487MODULE_DESCRIPTION("ROCKCHIP DRM Driver");
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 8aca219ec4c8..a48fcce3f5f6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -65,4 +65,10 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
65int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, 65int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
66 unsigned int mstimeout); 66 unsigned int mstimeout);
67 67
68extern struct platform_driver cdn_dp_driver;
69extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
70extern struct platform_driver dw_mipi_dsi_driver;
71extern struct platform_driver inno_hdmi_driver;
72extern struct platform_driver rockchip_dp_driver;
73extern struct platform_driver vop_platform_driver;
68#endif /* _ROCKCHIP_DRM_DRV_H_ */ 74#endif /* _ROCKCHIP_DRM_DRV_H_ */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 91fbc7b52147..0da44442aab0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -404,7 +404,7 @@ static int vop_remove(struct platform_device *pdev)
404 return 0; 404 return 0;
405} 405}
406 406
407static struct platform_driver vop_platform_driver = { 407struct platform_driver vop_platform_driver = {
408 .probe = vop_probe, 408 .probe = vop_probe,
409 .remove = vop_remove, 409 .remove = vop_remove,
410 .driver = { 410 .driver = {
@@ -412,9 +412,3 @@ static struct platform_driver vop_platform_driver = {
412 .of_match_table = of_match_ptr(vop_driver_dt_match), 412 .of_match_table = of_match_ptr(vop_driver_dt_match),
413 }, 413 },
414}; 414};
415
416module_platform_driver(vop_platform_driver);
417
418MODULE_AUTHOR("Mark Yao <mark.yao@rock-chips.com>");
419MODULE_DESCRIPTION("ROCKCHIP VOP Driver");
420MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
index 5fcabc04f307..e7738939a86d 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -449,7 +449,8 @@ void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
449static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc, 449static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
450 struct drm_framebuffer *fb, 450 struct drm_framebuffer *fb,
451 struct drm_pending_vblank_event *event, 451 struct drm_pending_vblank_event *event,
452 uint32_t page_flip_flags) 452 uint32_t page_flip_flags,
453 struct drm_modeset_acquire_ctx *ctx)
453{ 454{
454 struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); 455 struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
455 struct drm_device *dev = scrtc->crtc.dev; 456 struct drm_device *dev = scrtc->crtc.dev;
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/shmobile/shmob_drm_plane.c
index 2023a93cee2b..97f6e4a3eb0d 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_plane.c
@@ -177,7 +177,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
177 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 177 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
178 unsigned int crtc_w, unsigned int crtc_h, 178 unsigned int crtc_w, unsigned int crtc_h,
179 uint32_t src_x, uint32_t src_y, 179 uint32_t src_x, uint32_t src_y,
180 uint32_t src_w, uint32_t src_h) 180 uint32_t src_w, uint32_t src_h,
181 struct drm_modeset_acquire_ctx *ctx)
181{ 182{
182 struct shmob_drm_plane *splane = to_shmob_plane(plane); 183 struct shmob_drm_plane *splane = to_shmob_plane(plane);
183 struct shmob_drm_device *sdev = plane->dev->dev_private; 184 struct shmob_drm_device *sdev = plane->dev->dev_private;
@@ -208,7 +209,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
208 return 0; 209 return 0;
209} 210}
210 211
211static int shmob_drm_plane_disable(struct drm_plane *plane) 212static int shmob_drm_plane_disable(struct drm_plane *plane,
213 struct drm_modeset_acquire_ctx *ctx)
212{ 214{
213 struct shmob_drm_plane *splane = to_shmob_plane(plane); 215 struct shmob_drm_plane *splane = to_shmob_plane(plane);
214 struct shmob_drm_device *sdev = plane->dev->dev_private; 216 struct shmob_drm_device *sdev = plane->dev->dev_private;
@@ -221,7 +223,7 @@ static int shmob_drm_plane_disable(struct drm_plane *plane)
221 223
222static void shmob_drm_plane_destroy(struct drm_plane *plane) 224static void shmob_drm_plane_destroy(struct drm_plane *plane)
223{ 225{
224 shmob_drm_plane_disable(plane); 226 drm_plane_force_disable(plane);
225 drm_plane_cleanup(plane); 227 drm_plane_cleanup(plane);
226} 228}
227 229
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 0db5d5a8d3b9..95b373f739f2 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1382,7 +1382,7 @@ static int tegra_dc_show_regs(struct seq_file *s, void *data)
1382 struct tegra_dc *dc = node->info_ent->data; 1382 struct tegra_dc *dc = node->info_ent->data;
1383 int err = 0; 1383 int err = 0;
1384 1384
1385 drm_modeset_lock_crtc(&dc->base, NULL); 1385 drm_modeset_lock(&dc->base.mutex, NULL);
1386 1386
1387 if (!dc->base.state->active) { 1387 if (!dc->base.state->active) {
1388 err = -EBUSY; 1388 err = -EBUSY;
@@ -1609,7 +1609,7 @@ static int tegra_dc_show_regs(struct seq_file *s, void *data)
1609#undef DUMP_REG 1609#undef DUMP_REG
1610 1610
1611unlock: 1611unlock:
1612 drm_modeset_unlock_crtc(&dc->base); 1612 drm_modeset_unlock(&dc->base.mutex);
1613 return err; 1613 return err;
1614} 1614}
1615 1615
@@ -1620,7 +1620,7 @@ static int tegra_dc_show_crc(struct seq_file *s, void *data)
1620 int err = 0; 1620 int err = 0;
1621 u32 value; 1621 u32 value;
1622 1622
1623 drm_modeset_lock_crtc(&dc->base, NULL); 1623 drm_modeset_lock(&dc->base.mutex, NULL);
1624 1624
1625 if (!dc->base.state->active) { 1625 if (!dc->base.state->active) {
1626 err = -EBUSY; 1626 err = -EBUSY;
@@ -1640,7 +1640,7 @@ static int tegra_dc_show_crc(struct seq_file *s, void *data)
1640 tegra_dc_writel(dc, 0, DC_COM_CRC_CONTROL); 1640 tegra_dc_writel(dc, 0, DC_COM_CRC_CONTROL);
1641 1641
1642unlock: 1642unlock:
1643 drm_modeset_unlock_crtc(&dc->base); 1643 drm_modeset_unlock(&dc->base.mutex);
1644 return err; 1644 return err;
1645} 1645}
1646 1646
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index c92faa8f7560..afd2a7b2aff7 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -579,7 +579,7 @@ static void tilcdc_crtc_recover_work(struct work_struct *work)
579 579
580 dev_info(crtc->dev->dev, "%s: Reset CRTC", __func__); 580 dev_info(crtc->dev->dev, "%s: Reset CRTC", __func__);
581 581
582 drm_modeset_lock_crtc(crtc, NULL); 582 drm_modeset_lock(&crtc->mutex, NULL);
583 583
584 if (!tilcdc_crtc_is_on(crtc)) 584 if (!tilcdc_crtc_is_on(crtc))
585 goto out; 585 goto out;
@@ -587,7 +587,7 @@ static void tilcdc_crtc_recover_work(struct work_struct *work)
587 tilcdc_crtc_disable(crtc); 587 tilcdc_crtc_disable(crtc);
588 tilcdc_crtc_enable(crtc); 588 tilcdc_crtc_enable(crtc);
589out: 589out:
590 drm_modeset_unlock_crtc(crtc); 590 drm_modeset_unlock(&crtc->mutex);
591} 591}
592 592
593static void tilcdc_crtc_destroy(struct drm_crtc *crtc) 593static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
@@ -595,9 +595,9 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
595 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 595 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
596 struct tilcdc_drm_private *priv = crtc->dev->dev_private; 596 struct tilcdc_drm_private *priv = crtc->dev->dev_private;
597 597
598 drm_modeset_lock_crtc(crtc, NULL); 598 drm_modeset_lock(&crtc->mutex, NULL);
599 tilcdc_crtc_disable(crtc); 599 tilcdc_crtc_disable(crtc);
600 drm_modeset_unlock_crtc(crtc); 600 drm_modeset_unlock(&crtc->mutex);
601 601
602 flush_workqueue(priv->wq); 602 flush_workqueue(priv->wq);
603 603
@@ -856,7 +856,7 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
856 struct tilcdc_drm_private *priv = dev->dev_private; 856 struct tilcdc_drm_private *priv = dev->dev_private;
857 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 857 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
858 858
859 drm_modeset_lock_crtc(crtc, NULL); 859 drm_modeset_lock(&crtc->mutex, NULL);
860 if (tilcdc_crtc->lcd_fck_rate != clk_get_rate(priv->clk)) { 860 if (tilcdc_crtc->lcd_fck_rate != clk_get_rate(priv->clk)) {
861 if (tilcdc_crtc_is_on(crtc)) { 861 if (tilcdc_crtc_is_on(crtc)) {
862 pm_runtime_get_sync(dev->dev); 862 pm_runtime_get_sync(dev->dev);
@@ -868,7 +868,7 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc)
868 pm_runtime_put_sync(dev->dev); 868 pm_runtime_put_sync(dev->dev);
869 } 869 }
870 } 870 }
871 drm_modeset_unlock_crtc(crtc); 871 drm_modeset_unlock(&crtc->mutex);
872} 872}
873 873
874#define SYNC_LOST_COUNT_LIMIT 50 874#define SYNC_LOST_COUNT_LIMIT 50
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-core.c b/drivers/gpu/drm/tinydrm/core/tinydrm-core.c
index 6a257dd08ee0..551709e6b114 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-core.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-core.c
@@ -122,21 +122,6 @@ void tinydrm_gem_cma_free_object(struct drm_gem_object *gem_obj)
122} 122}
123EXPORT_SYMBOL_GPL(tinydrm_gem_cma_free_object); 123EXPORT_SYMBOL_GPL(tinydrm_gem_cma_free_object);
124 124
125const struct file_operations tinydrm_fops = {
126 .owner = THIS_MODULE,
127 .open = drm_open,
128 .release = drm_release,
129 .unlocked_ioctl = drm_ioctl,
130#ifdef CONFIG_COMPAT
131 .compat_ioctl = drm_compat_ioctl,
132#endif
133 .poll = drm_poll,
134 .read = drm_read,
135 .llseek = no_llseek,
136 .mmap = drm_gem_cma_mmap,
137};
138EXPORT_SYMBOL(tinydrm_fops);
139
140static struct drm_framebuffer * 125static struct drm_framebuffer *
141tinydrm_fb_create(struct drm_device *drm, struct drm_file *file_priv, 126tinydrm_fb_create(struct drm_device *drm, struct drm_file *file_priv,
142 const struct drm_mode_fb_cmd2 *mode_cmd) 127 const struct drm_mode_fb_cmd2 *mode_cmd)
@@ -251,7 +236,7 @@ static void tinydrm_unregister(struct tinydrm_device *tdev)
251{ 236{
252 struct drm_fbdev_cma *fbdev_cma = tdev->fbdev_cma; 237 struct drm_fbdev_cma *fbdev_cma = tdev->fbdev_cma;
253 238
254 drm_crtc_force_disable_all(tdev->drm); 239 drm_atomic_helper_shutdown(tdev->drm);
255 /* don't restore fbdev in lastclose, keep pipeline disabled */ 240 /* don't restore fbdev in lastclose, keep pipeline disabled */
256 tdev->fbdev_cma = NULL; 241 tdev->fbdev_cma = NULL;
257 drm_dev_unregister(tdev->drm); 242 drm_dev_unregister(tdev->drm);
@@ -302,7 +287,7 @@ EXPORT_SYMBOL(devm_tinydrm_register);
302 */ 287 */
303void tinydrm_shutdown(struct tinydrm_device *tdev) 288void tinydrm_shutdown(struct tinydrm_device *tdev)
304{ 289{
305 drm_crtc_force_disable_all(tdev->drm); 290 drm_atomic_helper_shutdown(tdev->drm);
306} 291}
307EXPORT_SYMBOL(tinydrm_shutdown); 292EXPORT_SYMBOL(tinydrm_shutdown);
308 293
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index b29fe86158f7..482ff1c3db61 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -132,9 +132,12 @@ static const struct drm_display_mode mi0283qt_mode = {
132 TINYDRM_MODE(320, 240, 58, 43), 132 TINYDRM_MODE(320, 240, 58, 43),
133}; 133};
134 134
135DEFINE_DRM_GEM_CMA_FOPS(mi0283qt_fops);
136
135static struct drm_driver mi0283qt_driver = { 137static struct drm_driver mi0283qt_driver = {
136 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | 138 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
137 DRIVER_ATOMIC, 139 DRIVER_ATOMIC,
140 .fops = &mi0283qt_fops,
138 TINYDRM_GEM_DRIVER_OPS, 141 TINYDRM_GEM_DRIVER_OPS,
139 .lastclose = tinydrm_lastclose, 142 .lastclose = tinydrm_lastclose,
140 .debugfs_init = mipi_dbi_debugfs_init, 143 .debugfs_init = mipi_dbi_debugfs_init,
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index f2b2481cad52..5bcae7649795 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -361,7 +361,8 @@ static void udl_crtc_destroy(struct drm_crtc *crtc)
361static int udl_crtc_page_flip(struct drm_crtc *crtc, 361static int udl_crtc_page_flip(struct drm_crtc *crtc,
362 struct drm_framebuffer *fb, 362 struct drm_framebuffer *fb,
363 struct drm_pending_vblank_event *event, 363 struct drm_pending_vblank_event *event,
364 uint32_t page_flip_flags) 364 uint32_t page_flip_flags,
365 struct drm_modeset_acquire_ctx *ctx)
365{ 366{
366 struct udl_framebuffer *ufb = to_udl_fb(fb); 367 struct udl_framebuffer *ufb = to_udl_fb(fb);
367 struct drm_device *dev = crtc->dev; 368 struct drm_device *dev = crtc->dev;
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 24edd0c22cc9..865e9f494bcc 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -807,12 +807,13 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
807static int vc4_page_flip(struct drm_crtc *crtc, 807static int vc4_page_flip(struct drm_crtc *crtc,
808 struct drm_framebuffer *fb, 808 struct drm_framebuffer *fb,
809 struct drm_pending_vblank_event *event, 809 struct drm_pending_vblank_event *event,
810 uint32_t flags) 810 uint32_t flags,
811 struct drm_modeset_acquire_ctx *ctx)
811{ 812{
812 if (flags & DRM_MODE_PAGE_FLIP_ASYNC) 813 if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
813 return vc4_async_page_flip(crtc, fb, event, flags); 814 return vc4_async_page_flip(crtc, fb, event, flags);
814 else 815 else
815 return drm_atomic_helper_page_flip(crtc, fb, event, flags); 816 return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx);
816} 817}
817 818
818static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) 819static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 0f4564beb017..d34cd5393a9b 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -756,7 +756,8 @@ vc4_update_plane(struct drm_plane *plane,
756 int crtc_x, int crtc_y, 756 int crtc_x, int crtc_y,
757 unsigned int crtc_w, unsigned int crtc_h, 757 unsigned int crtc_w, unsigned int crtc_h,
758 uint32_t src_x, uint32_t src_y, 758 uint32_t src_x, uint32_t src_y,
759 uint32_t src_w, uint32_t src_h) 759 uint32_t src_w, uint32_t src_h,
760 struct drm_modeset_acquire_ctx *ctx)
760{ 761{
761 struct drm_plane_state *plane_state; 762 struct drm_plane_state *plane_state;
762 struct vc4_plane_state *vc4_state; 763 struct vc4_plane_state *vc4_state;
@@ -817,7 +818,8 @@ out:
817 crtc_x, crtc_y, 818 crtc_x, crtc_y,
818 crtc_w, crtc_h, 819 crtc_w, crtc_h,
819 src_x, src_y, 820 src_x, src_y,
820 src_w, src_h); 821 src_w, src_h,
822 ctx);
821} 823}
822 824
823static const struct drm_plane_funcs vc4_plane_funcs = { 825static const struct drm_plane_funcs vc4_plane_funcs = {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index c18c81f63ac3..6078654d033b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -2947,10 +2947,11 @@ vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv,
2947 * the vmwgfx modesetting. So explicitly clear that member before calling 2947 * the vmwgfx modesetting. So explicitly clear that member before calling
2948 * into drm_atomic_helper_set_config. 2948 * into drm_atomic_helper_set_config.
2949 */ 2949 */
2950int vmw_kms_set_config(struct drm_mode_set *set) 2950int vmw_kms_set_config(struct drm_mode_set *set,
2951 struct drm_modeset_acquire_ctx *ctx)
2951{ 2952{
2952 if (set && set->mode) 2953 if (set && set->mode)
2953 set->mode->type = 0; 2954 set->mode->type = 0;
2954 2955
2955 return drm_atomic_helper_set_config(set); 2956 return drm_atomic_helper_set_config(set, ctx);
2956} 2957}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 9c161d29aaeb..0c226b2adea5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -453,6 +453,7 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
453 bool to_surface, 453 bool to_surface,
454 bool interruptible); 454 bool interruptible);
455 455
456int vmw_kms_set_config(struct drm_mode_set *set); 456int vmw_kms_set_config(struct drm_mode_set *set,
457 struct drm_modeset_acquire_ctx *ctx);
457 458
458#endif 459#endif
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 2664e4c16750..8d7dc9def7c2 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -310,7 +310,8 @@ static void vmw_sou_crtc_helper_disable(struct drm_crtc *crtc)
310static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, 310static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
311 struct drm_framebuffer *new_fb, 311 struct drm_framebuffer *new_fb,
312 struct drm_pending_vblank_event *event, 312 struct drm_pending_vblank_event *event,
313 uint32_t flags) 313 uint32_t flags,
314 struct drm_modeset_acquire_ctx *ctx)
314{ 315{
315 struct vmw_private *dev_priv = vmw_priv(crtc->dev); 316 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
316 struct drm_framebuffer *old_fb = crtc->primary->fb; 317 struct drm_framebuffer *old_fb = crtc->primary->fb;
@@ -323,7 +324,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
323 return -EINVAL; 324 return -EINVAL;
324 325
325 flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; 326 flags &= ~DRM_MODE_PAGE_FLIP_ASYNC;
326 ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); 327 ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx);
327 if (ret) { 328 if (ret) {
328 DRM_ERROR("Page flip error %d.\n", ret); 329 DRM_ERROR("Page flip error %d.\n", ret);
329 return ret; 330 return ret;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index e872ffe5f0db..bad31bdf09b6 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -481,7 +481,8 @@ static void vmw_stdu_crtc_helper_disable(struct drm_crtc *crtc)
481static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc, 481static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc,
482 struct drm_framebuffer *new_fb, 482 struct drm_framebuffer *new_fb,
483 struct drm_pending_vblank_event *event, 483 struct drm_pending_vblank_event *event,
484 uint32_t flags) 484 uint32_t flags,
485 struct drm_modeset_acquire_ctx *ctx)
485 486
486{ 487{
487 struct vmw_private *dev_priv = vmw_priv(crtc->dev); 488 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
@@ -504,7 +505,7 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc,
504 * don't hand it to the helper. 505 * don't hand it to the helper.
505 */ 506 */
506 flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; 507 flags &= ~DRM_MODE_PAGE_FLIP_ASYNC;
507 ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); 508 ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx);
508 if (ret) { 509 if (ret) {
509 DRM_ERROR("Page flip error %d.\n", ret); 510 DRM_ERROR("Page flip error %d.\n", ret);
510 return ret; 511 return ret;
diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c
index c47b9cbfe270..0df7366e594b 100644
--- a/drivers/gpu/drm/zte/zx_hdmi.c
+++ b/drivers/gpu/drm/zte/zx_hdmi.c
@@ -50,7 +50,6 @@ struct zx_hdmi {
50 struct clk *xclk; 50 struct clk *xclk;
51 bool sink_is_hdmi; 51 bool sink_is_hdmi;
52 bool sink_has_audio; 52 bool sink_has_audio;
53 const struct vou_inf *inf;
54 struct platform_device *audio_pdev; 53 struct platform_device *audio_pdev;
55}; 54};
56 55
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 8dd38e69d6f2..4dbf9f96ae5b 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -3,6 +3,8 @@
3 3
4#define PCI_FIND_CAP_TTL 48 4#define PCI_FIND_CAP_TTL 48
5 5
6#define PCI_VSEC_ID_INTEL_TBT 0x1234 /* Thunderbolt */
7
6extern const unsigned char pcie_link_speed[]; 8extern const unsigned char pcie_link_speed[];
7 9
8bool pcie_cap_has_lnkctl(const struct pci_dev *dev); 10bool pcie_cap_has_lnkctl(const struct pci_dev *dev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dfc9a2794141..90592d424e9b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1208,6 +1208,24 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)
1208 pdev->is_hotplug_bridge = 1; 1208 pdev->is_hotplug_bridge = 1;
1209} 1209}
1210 1210
1211static void set_pcie_thunderbolt(struct pci_dev *dev)
1212{
1213 int vsec = 0;
1214 u32 header;
1215
1216 while ((vsec = pci_find_next_ext_capability(dev, vsec,
1217 PCI_EXT_CAP_ID_VNDR))) {
1218 pci_read_config_dword(dev, vsec + PCI_VNDR_HEADER, &header);
1219
1220 /* Is the device part of a Thunderbolt controller? */
1221 if (dev->vendor == PCI_VENDOR_ID_INTEL &&
1222 PCI_VNDR_HEADER_ID(header) == PCI_VSEC_ID_INTEL_TBT) {
1223 dev->is_thunderbolt = 1;
1224 return;
1225 }
1226 }
1227}
1228
1211/** 1229/**
1212 * pci_ext_cfg_is_aliased - is ext config space just an alias of std config? 1230 * pci_ext_cfg_is_aliased - is ext config space just an alias of std config?
1213 * @dev: PCI device 1231 * @dev: PCI device
@@ -1360,6 +1378,9 @@ int pci_setup_device(struct pci_dev *dev)
1360 /* need to have dev->class ready */ 1378 /* need to have dev->class ready */
1361 dev->cfg_size = pci_cfg_space_size(dev); 1379 dev->cfg_size = pci_cfg_space_size(dev);
1362 1380
1381 /* need to have dev->cfg_size ready */
1382 set_pcie_thunderbolt(dev);
1383
1363 /* "Unknown power state" */ 1384 /* "Unknown power state" */
1364 dev->current_state = PCI_UNKNOWN; 1385 dev->current_state = PCI_UNKNOWN;
1365 1386
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
index a66be137324c..623d322447a2 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -60,6 +60,7 @@ struct apple_gmux_data {
60 /* switcheroo data */ 60 /* switcheroo data */
61 acpi_handle dhandle; 61 acpi_handle dhandle;
62 int gpe; 62 int gpe;
63 bool external_switchable;
63 enum vga_switcheroo_client_id switch_state_display; 64 enum vga_switcheroo_client_id switch_state_display;
64 enum vga_switcheroo_client_id switch_state_ddc; 65 enum vga_switcheroo_client_id switch_state_ddc;
65 enum vga_switcheroo_client_id switch_state_external; 66 enum vga_switcheroo_client_id switch_state_external;
@@ -358,6 +359,19 @@ static const struct backlight_ops gmux_bl_ops = {
358 * ports while the discrete GPU is asleep, but currently we do not make use 359 * ports while the discrete GPU is asleep, but currently we do not make use
359 * of this feature. 360 * of this feature.
360 * 361 *
362 * Our switching policy for the external port is that on those generations
363 * which are able to switch it fully, the port is switched together with the
364 * panel when IGD / DIS commands are issued to vga_switcheroo. It is thus
365 * possible to drive e.g. a beamer on battery power with the integrated GPU.
366 * The user may manually switch to the discrete GPU if more performance is
367 * needed.
368 *
369 * On all newer generations, the external port can only be driven by the
370 * discrete GPU. If a display is plugged in while the panel is switched to
371 * the integrated GPU, *both* GPUs will be in use for maximum performance.
372 * To decrease power consumption, the user may manually switch to the
373 * discrete GPU, thereby suspending the integrated GPU.
374 *
361 * gmux' initial switch state on bootup is user configurable via the EFI 375 * gmux' initial switch state on bootup is user configurable via the EFI
362 * variable ``gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9`` (5th byte, 376 * variable ``gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9`` (5th byte,
363 * 1 = IGD, 0 = DIS). Based on this setting, the EFI firmware tells gmux to 377 * 1 = IGD, 0 = DIS). Based on this setting, the EFI firmware tells gmux to
@@ -414,7 +428,8 @@ static int gmux_switchto(enum vga_switcheroo_client_id id)
414{ 428{
415 apple_gmux_data->switch_state_ddc = id; 429 apple_gmux_data->switch_state_ddc = id;
416 apple_gmux_data->switch_state_display = id; 430 apple_gmux_data->switch_state_display = id;
417 apple_gmux_data->switch_state_external = id; 431 if (apple_gmux_data->external_switchable)
432 apple_gmux_data->switch_state_external = id;
418 433
419 gmux_write_switch_state(apple_gmux_data); 434 gmux_write_switch_state(apple_gmux_data);
420 435
@@ -601,6 +616,11 @@ static struct pci_dev *gmux_get_io_pdev(void)
601 return NULL; 616 return NULL;
602} 617}
603 618
619static int is_thunderbolt(struct device *dev, void *data)
620{
621 return to_pci_dev(dev)->is_thunderbolt;
622}
623
604static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) 624static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
605{ 625{
606 struct apple_gmux_data *gmux_data; 626 struct apple_gmux_data *gmux_data;
@@ -755,6 +775,15 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
755 gmux_data->gpe = -1; 775 gmux_data->gpe = -1;
756 } 776 }
757 777
778 /*
779 * If Thunderbolt is present, the external DP port is not fully
780 * switchable. Force its AUX channel to the discrete GPU.
781 */
782 gmux_data->external_switchable =
783 !bus_for_each_dev(&pci_bus_type, NULL, NULL, is_thunderbolt);
784 if (!gmux_data->external_switchable)
785 gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
786
758 apple_gmux_data = gmux_data; 787 apple_gmux_data = gmux_data;
759 init_completion(&gmux_data->powerchange_done); 788 init_completion(&gmux_data->powerchange_done);
760 gmux_enable_interrupts(gmux_data); 789 gmux_enable_interrupts(gmux_data);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 0e383438f793..3bfafcdb8710 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -78,6 +78,8 @@
78#include <drm/drm_prime.h> 78#include <drm/drm_prime.h>
79#include <drm/drm_pci.h> 79#include <drm/drm_pci.h>
80#include <drm/drm_file.h> 80#include <drm/drm_file.h>
81#include <drm/drm_debugfs.h>
82#include <drm/drm_ioctl.h>
81 83
82struct module; 84struct module;
83 85
@@ -316,54 +318,10 @@ struct pci_controller;
316 318
317#define DRM_IF_VERSION(maj, min) (maj << 16 | min) 319#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
318 320
319/**
320 * Ioctl function type.
321 *
322 * \param inode device inode.
323 * \param file_priv DRM file private pointer.
324 * \param cmd command.
325 * \param arg argument.
326 */
327typedef int drm_ioctl_t(struct drm_device *dev, void *data,
328 struct drm_file *file_priv);
329
330typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
331 unsigned long arg);
332
333#define DRM_IOCTL_NR(n) _IOC_NR(n)
334#define DRM_MAJOR 226
335
336#define DRM_AUTH 0x1
337#define DRM_MASTER 0x2
338#define DRM_ROOT_ONLY 0x4
339#define DRM_CONTROL_ALLOW 0x8
340#define DRM_UNLOCKED 0x10
341#define DRM_RENDER_ALLOW 0x20
342
343struct drm_ioctl_desc {
344 unsigned int cmd;
345 int flags;
346 drm_ioctl_t *func;
347 const char *name;
348};
349
350/**
351 * Creates a driver or general drm_ioctl_desc array entry for the given
352 * ioctl, for use by drm_ioctl().
353 */
354
355#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
356 [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \
357 .cmd = DRM_IOCTL_##ioctl, \
358 .func = _func, \
359 .flags = _flags, \
360 .name = #ioctl \
361 }
362 321
363/* Flags and return codes for get_vblank_timestamp() driver function. */ 322/* Flags and return codes for get_vblank_timestamp() driver function. */
364#define DRM_CALLED_FROM_VBLIRQ 1 323#define DRM_CALLED_FROM_VBLIRQ 1
365#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) 324#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
366#define DRM_VBLANKTIME_IN_VBLANK (1 << 1)
367 325
368/* get_scanout_position() return flags */ 326/* get_scanout_position() return flags */
369#define DRM_SCANOUTPOS_VALID (1 << 0) 327#define DRM_SCANOUTPOS_VALID (1 << 0)
@@ -371,27 +329,6 @@ struct drm_ioctl_desc {
371#define DRM_SCANOUTPOS_ACCURATE (1 << 2) 329#define DRM_SCANOUTPOS_ACCURATE (1 << 2)
372 330
373/** 331/**
374 * Info file list entry. This structure represents a debugfs or proc file to
375 * be created by the drm core
376 */
377struct drm_info_list {
378 const char *name; /** file name */
379 int (*show)(struct seq_file*, void*); /** show callback */
380 u32 driver_features; /**< Required driver features for this entry */
381 void *data;
382};
383
384/**
385 * debugfs node structure. This structure represents a debugfs file.
386 */
387struct drm_info_node {
388 struct list_head list;
389 struct drm_minor *minor;
390 const struct drm_info_list *info_ent;
391 struct dentry *dent;
392};
393
394/**
395 * DRM device structure. This structure represent a complete card that 332 * DRM device structure. This structure represent a complete card that
396 * may contain multiple heads. 333 * may contain multiple heads.
397 */ 334 */
@@ -569,51 +506,12 @@ static inline int drm_device_is_unplugged(struct drm_device *dev)
569/*@{*/ 506/*@{*/
570 507
571 /* Driver support (drm_drv.h) */ 508 /* Driver support (drm_drv.h) */
572extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv);
573extern long drm_ioctl(struct file *filp,
574 unsigned int cmd, unsigned long arg);
575#ifdef CONFIG_COMPAT
576extern long drm_compat_ioctl(struct file *filp,
577 unsigned int cmd, unsigned long arg);
578#else
579/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */
580#define drm_compat_ioctl NULL
581#endif
582extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
583
584/* Misc. IOCTL support (drm_ioctl.c) */
585int drm_noop(struct drm_device *dev, void *data,
586 struct drm_file *file_priv);
587int drm_invalid_op(struct drm_device *dev, void *data,
588 struct drm_file *file_priv);
589 509
590/* 510/*
591 * These are exported to drivers so that they can implement fencing using 511 * These are exported to drivers so that they can implement fencing using
592 * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. 512 * DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
593 */ 513 */
594 514
595 /* Debugfs support */
596#if defined(CONFIG_DEBUG_FS)
597extern int drm_debugfs_create_files(const struct drm_info_list *files,
598 int count, struct dentry *root,
599 struct drm_minor *minor);
600extern int drm_debugfs_remove_files(const struct drm_info_list *files,
601 int count, struct drm_minor *minor);
602#else
603static inline int drm_debugfs_create_files(const struct drm_info_list *files,
604 int count, struct dentry *root,
605 struct drm_minor *minor)
606{
607 return 0;
608}
609
610static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
611 int count, struct drm_minor *minor)
612{
613 return 0;
614}
615#endif
616
617 /* sysfs support (drm_sysfs.c) */ 515 /* sysfs support (drm_sysfs.c) */
618extern void drm_sysfs_hotplug_event(struct drm_device *dev); 516extern void drm_sysfs_hotplug_event(struct drm_device *dev);
619 517
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 0147a047878d..fd33ed5eaeb4 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -498,6 +498,23 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
498 498
499void drm_state_dump(struct drm_device *dev, struct drm_printer *p); 499void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
500 500
501/**
502 * for_each_connector_in_state - iterate over all connectors in an atomic update
503 * @__state: &struct drm_atomic_state pointer
504 * @connector: &struct drm_connector iteration cursor
505 * @connector_state: &struct drm_connector_state iteration cursor
506 * @__i: int iteration cursor, for macro-internal use
507 *
508 * This iterates over all connectors in an atomic update. Note that before the
509 * software state is committed (by calling drm_atomic_helper_swap_state(), this
510 * points to the new state, while afterwards it points to the old state. Due to
511 * this tricky confusion this macro is deprecated.
512 *
513 * FIXME:
514 *
515 * Replace all usage of this with one of the explicit iterators below and then
516 * remove this macro.
517 */
501#define for_each_connector_in_state(__state, connector, connector_state, __i) \ 518#define for_each_connector_in_state(__state, connector, connector_state, __i) \
502 for ((__i) = 0; \ 519 for ((__i) = 0; \
503 (__i) < (__state)->num_connector && \ 520 (__i) < (__state)->num_connector && \
@@ -506,6 +523,20 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
506 (__i)++) \ 523 (__i)++) \
507 for_each_if (connector) 524 for_each_if (connector)
508 525
526/**
527 * for_each_oldnew_connector_in_state - iterate over all connectors in an atomic update
528 * @__state: &struct drm_atomic_state pointer
529 * @connector: &struct drm_connector iteration cursor
530 * @old_connector_state: &struct drm_connector_state iteration cursor for the
531 * old state
532 * @new_connector_state: &struct drm_connector_state iteration cursor for the
533 * new state
534 * @__i: int iteration cursor, for macro-internal use
535 *
536 * This iterates over all connectors in an atomic update, tracking both old and
537 * new state. This is useful in places where the state delta needs to be
538 * considered, for example in atomic check functions.
539 */
509#define for_each_oldnew_connector_in_state(__state, connector, old_connector_state, new_connector_state, __i) \ 540#define for_each_oldnew_connector_in_state(__state, connector, old_connector_state, new_connector_state, __i) \
510 for ((__i) = 0; \ 541 for ((__i) = 0; \
511 (__i) < (__state)->num_connector && \ 542 (__i) < (__state)->num_connector && \
@@ -515,6 +546,18 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
515 (__i)++) \ 546 (__i)++) \
516 for_each_if (connector) 547 for_each_if (connector)
517 548
549/**
550 * for_each_old_connector_in_state - iterate over all connectors in an atomic update
551 * @__state: &struct drm_atomic_state pointer
552 * @connector: &struct drm_connector iteration cursor
553 * @old_connector_state: &struct drm_connector_state iteration cursor for the
554 * old state
555 * @__i: int iteration cursor, for macro-internal use
556 *
557 * This iterates over all connectors in an atomic update, tracking only the old
558 * state. This is useful in disable functions, where we need the old state the
559 * hardware is still in.
560 */
518#define for_each_old_connector_in_state(__state, connector, old_connector_state, __i) \ 561#define for_each_old_connector_in_state(__state, connector, old_connector_state, __i) \
519 for ((__i) = 0; \ 562 for ((__i) = 0; \
520 (__i) < (__state)->num_connector && \ 563 (__i) < (__state)->num_connector && \
@@ -523,6 +566,18 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
523 (__i)++) \ 566 (__i)++) \
524 for_each_if (connector) 567 for_each_if (connector)
525 568
569/**
570 * for_each_new_connector_in_state - iterate over all connectors in an atomic update
571 * @__state: &struct drm_atomic_state pointer
572 * @connector: &struct drm_connector iteration cursor
573 * @new_connector_state: &struct drm_connector_state iteration cursor for the
574 * new state
575 * @__i: int iteration cursor, for macro-internal use
576 *
577 * This iterates over all connectors in an atomic update, tracking only the new
578 * state. This is useful in enable functions, where we need the new state the
579 * hardware should be in when the atomic commit operation has completed.
580 */
526#define for_each_new_connector_in_state(__state, connector, new_connector_state, __i) \ 581#define for_each_new_connector_in_state(__state, connector, new_connector_state, __i) \
527 for ((__i) = 0; \ 582 for ((__i) = 0; \
528 (__i) < (__state)->num_connector && \ 583 (__i) < (__state)->num_connector && \
@@ -531,6 +586,23 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
531 (__i)++) \ 586 (__i)++) \
532 for_each_if (connector) 587 for_each_if (connector)
533 588
589/**
590 * for_each_crtc_in_state - iterate over all connectors in an atomic update
591 * @__state: &struct drm_atomic_state pointer
592 * @crtc: &struct drm_crtc iteration cursor
593 * @crtc_state: &struct drm_crtc_state iteration cursor
594 * @__i: int iteration cursor, for macro-internal use
595 *
596 * This iterates over all CRTCs in an atomic update. Note that before the
597 * software state is committed (by calling drm_atomic_helper_swap_state(), this
598 * points to the new state, while afterwards it points to the old state. Due to
599 * this tricky confusion this macro is deprecated.
600 *
601 * FIXME:
602 *
603 * Replace all usage of this with one of the explicit iterators below and then
604 * remove this macro.
605 */
534#define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \ 606#define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \
535 for ((__i) = 0; \ 607 for ((__i) = 0; \
536 (__i) < (__state)->dev->mode_config.num_crtc && \ 608 (__i) < (__state)->dev->mode_config.num_crtc && \
@@ -539,6 +611,18 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
539 (__i)++) \ 611 (__i)++) \
540 for_each_if (crtc_state) 612 for_each_if (crtc_state)
541 613
614/**
615 * for_each_oldnew_crtc_in_state - iterate over all CRTCs in an atomic update
616 * @__state: &struct drm_atomic_state pointer
617 * @crtc: &struct drm_crtc iteration cursor
618 * @old_crtc_state: &struct drm_crtc_state iteration cursor for the old state
619 * @new_crtc_state: &struct drm_crtc_state iteration cursor for the new state
620 * @__i: int iteration cursor, for macro-internal use
621 *
622 * This iterates over all CRTCs in an atomic update, tracking both old and
623 * new state. This is useful in places where the state delta needs to be
624 * considered, for example in atomic check functions.
625 */
542#define for_each_oldnew_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \ 626#define for_each_oldnew_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \
543 for ((__i) = 0; \ 627 for ((__i) = 0; \
544 (__i) < (__state)->dev->mode_config.num_crtc && \ 628 (__i) < (__state)->dev->mode_config.num_crtc && \
@@ -548,6 +632,17 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
548 (__i)++) \ 632 (__i)++) \
549 for_each_if (crtc) 633 for_each_if (crtc)
550 634
635/**
636 * for_each_old_crtc_in_state - iterate over all CRTCs in an atomic update
637 * @__state: &struct drm_atomic_state pointer
638 * @crtc: &struct drm_crtc iteration cursor
639 * @old_crtc_state: &struct drm_crtc_state iteration cursor for the old state
640 * @__i: int iteration cursor, for macro-internal use
641 *
642 * This iterates over all CRTCs in an atomic update, tracking only the old
643 * state. This is useful in disable functions, where we need the old state the
644 * hardware is still in.
645 */
551#define for_each_old_crtc_in_state(__state, crtc, old_crtc_state, __i) \ 646#define for_each_old_crtc_in_state(__state, crtc, old_crtc_state, __i) \
552 for ((__i) = 0; \ 647 for ((__i) = 0; \
553 (__i) < (__state)->dev->mode_config.num_crtc && \ 648 (__i) < (__state)->dev->mode_config.num_crtc && \
@@ -556,6 +651,17 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
556 (__i)++) \ 651 (__i)++) \
557 for_each_if (crtc) 652 for_each_if (crtc)
558 653
654/**
655 * for_each_new_crtc_in_state - iterate over all CRTCs in an atomic update
656 * @__state: &struct drm_atomic_state pointer
657 * @crtc: &struct drm_crtc iteration cursor
658 * @new_crtc_state: &struct drm_crtc_state iteration cursor for the new state
659 * @__i: int iteration cursor, for macro-internal use
660 *
661 * This iterates over all CRTCs in an atomic update, tracking only the new
662 * state. This is useful in enable functions, where we need the new state the
663 * hardware should be in when the atomic commit operation has completed.
664 */
559#define for_each_new_crtc_in_state(__state, crtc, new_crtc_state, __i) \ 665#define for_each_new_crtc_in_state(__state, crtc, new_crtc_state, __i) \
560 for ((__i) = 0; \ 666 for ((__i) = 0; \
561 (__i) < (__state)->dev->mode_config.num_crtc && \ 667 (__i) < (__state)->dev->mode_config.num_crtc && \
@@ -564,6 +670,23 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
564 (__i)++) \ 670 (__i)++) \
565 for_each_if (crtc) 671 for_each_if (crtc)
566 672
673/**
674 * for_each_plane_in_state - iterate over all planes in an atomic update
675 * @__state: &struct drm_atomic_state pointer
676 * @plane: &struct drm_plane iteration cursor
677 * @plane_state: &struct drm_plane_state iteration cursor
678 * @__i: int iteration cursor, for macro-internal use
679 *
680 * This iterates over all planes in an atomic update. Note that before the
681 * software state is committed (by calling drm_atomic_helper_swap_state(), this
682 * points to the new state, while afterwards it points to the old state. Due to
683 * this tricky confusion this macro is deprecated.
684 *
685 * FIXME:
686 *
687 * Replace all usage of this with one of the explicit iterators below and then
688 * remove this macro.
689 */
567#define for_each_plane_in_state(__state, plane, plane_state, __i) \ 690#define for_each_plane_in_state(__state, plane, plane_state, __i) \
568 for ((__i) = 0; \ 691 for ((__i) = 0; \
569 (__i) < (__state)->dev->mode_config.num_total_plane && \ 692 (__i) < (__state)->dev->mode_config.num_total_plane && \
@@ -572,6 +695,18 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
572 (__i)++) \ 695 (__i)++) \
573 for_each_if (plane_state) 696 for_each_if (plane_state)
574 697
698/**
699 * for_each_oldnew_plane_in_state - iterate over all planes in an atomic update
700 * @__state: &struct drm_atomic_state pointer
701 * @plane: &struct drm_plane iteration cursor
702 * @old_plane_state: &struct drm_plane_state iteration cursor for the old state
703 * @new_plane_state: &struct drm_plane_state iteration cursor for the new state
704 * @__i: int iteration cursor, for macro-internal use
705 *
706 * This iterates over all planes in an atomic update, tracking both old and
707 * new state. This is useful in places where the state delta needs to be
708 * considered, for example in atomic check functions.
709 */
575#define for_each_oldnew_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \ 710#define for_each_oldnew_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \
576 for ((__i) = 0; \ 711 for ((__i) = 0; \
577 (__i) < (__state)->dev->mode_config.num_total_plane && \ 712 (__i) < (__state)->dev->mode_config.num_total_plane && \
@@ -581,6 +716,17 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
581 (__i)++) \ 716 (__i)++) \
582 for_each_if (plane) 717 for_each_if (plane)
583 718
719/**
720 * for_each_old_plane_in_state - iterate over all planes in an atomic update
721 * @__state: &struct drm_atomic_state pointer
722 * @plane: &struct drm_plane iteration cursor
723 * @old_plane_state: &struct drm_plane_state iteration cursor for the old state
724 * @__i: int iteration cursor, for macro-internal use
725 *
726 * This iterates over all planes in an atomic update, tracking only the old
727 * state. This is useful in disable functions, where we need the old state the
728 * hardware is still in.
729 */
584#define for_each_old_plane_in_state(__state, plane, old_plane_state, __i) \ 730#define for_each_old_plane_in_state(__state, plane, old_plane_state, __i) \
585 for ((__i) = 0; \ 731 for ((__i) = 0; \
586 (__i) < (__state)->dev->mode_config.num_total_plane && \ 732 (__i) < (__state)->dev->mode_config.num_total_plane && \
@@ -589,6 +735,17 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
589 (__i)++) \ 735 (__i)++) \
590 for_each_if (plane) 736 for_each_if (plane)
591 737
738/**
739 * for_each_new_plane_in_state - iterate over all planes in an atomic update
740 * @__state: &struct drm_atomic_state pointer
741 * @plane: &struct drm_plane iteration cursor
742 * @new_plane_state: &struct drm_plane_state iteration cursor for the new state
743 * @__i: int iteration cursor, for macro-internal use
744 *
745 * This iterates over all planes in an atomic update, tracking only the new
746 * state. This is useful in enable functions, where we need the new state the
747 * hardware should be in when the atomic commit operation has completed.
748 */
592#define for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \ 749#define for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \
593 for ((__i) = 0; \ 750 for ((__i) = 0; \
594 (__i) < (__state)->dev->mode_config.num_total_plane && \ 751 (__i) < (__state)->dev->mode_config.num_total_plane && \
@@ -603,7 +760,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
603 * 760 *
604 * To give drivers flexibility &struct drm_crtc_state has 3 booleans to track 761 * To give drivers flexibility &struct drm_crtc_state has 3 booleans to track
605 * whether the state CRTC changed enough to need a full modeset cycle: 762 * whether the state CRTC changed enough to need a full modeset cycle:
606 * connectors_changed, mode_changed and active_changed. This helper simply 763 * planes_changed, mode_changed and active_changed. This helper simply
607 * combines these three to compute the overall need for a modeset for @state. 764 * combines these three to compute the overall need for a modeset for @state.
608 * 765 *
609 * The atomic helper code sets these booleans, but drivers can and should 766 * The atomic helper code sets these booleans, but drivers can and should
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index dc16274987c7..fd395dc050ee 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -94,16 +94,20 @@ int drm_atomic_helper_update_plane(struct drm_plane *plane,
94 int crtc_x, int crtc_y, 94 int crtc_x, int crtc_y,
95 unsigned int crtc_w, unsigned int crtc_h, 95 unsigned int crtc_w, unsigned int crtc_h,
96 uint32_t src_x, uint32_t src_y, 96 uint32_t src_x, uint32_t src_y,
97 uint32_t src_w, uint32_t src_h); 97 uint32_t src_w, uint32_t src_h,
98int drm_atomic_helper_disable_plane(struct drm_plane *plane); 98 struct drm_modeset_acquire_ctx *ctx);
99int drm_atomic_helper_disable_plane(struct drm_plane *plane,
100 struct drm_modeset_acquire_ctx *ctx);
99int __drm_atomic_helper_disable_plane(struct drm_plane *plane, 101int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
100 struct drm_plane_state *plane_state); 102 struct drm_plane_state *plane_state);
101int drm_atomic_helper_set_config(struct drm_mode_set *set); 103int drm_atomic_helper_set_config(struct drm_mode_set *set,
104 struct drm_modeset_acquire_ctx *ctx);
102int __drm_atomic_helper_set_config(struct drm_mode_set *set, 105int __drm_atomic_helper_set_config(struct drm_mode_set *set,
103 struct drm_atomic_state *state); 106 struct drm_atomic_state *state);
104 107
105int drm_atomic_helper_disable_all(struct drm_device *dev, 108int drm_atomic_helper_disable_all(struct drm_device *dev,
106 struct drm_modeset_acquire_ctx *ctx); 109 struct drm_modeset_acquire_ctx *ctx);
110void drm_atomic_helper_shutdown(struct drm_device *dev);
107struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev); 111struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev);
108int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state, 112int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
109 struct drm_modeset_acquire_ctx *ctx); 113 struct drm_modeset_acquire_ctx *ctx);
@@ -122,13 +126,15 @@ int drm_atomic_helper_connector_set_property(struct drm_connector *connector,
122int drm_atomic_helper_page_flip(struct drm_crtc *crtc, 126int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
123 struct drm_framebuffer *fb, 127 struct drm_framebuffer *fb,
124 struct drm_pending_vblank_event *event, 128 struct drm_pending_vblank_event *event,
125 uint32_t flags); 129 uint32_t flags,
130 struct drm_modeset_acquire_ctx *ctx);
126int drm_atomic_helper_page_flip_target( 131int drm_atomic_helper_page_flip_target(
127 struct drm_crtc *crtc, 132 struct drm_crtc *crtc,
128 struct drm_framebuffer *fb, 133 struct drm_framebuffer *fb,
129 struct drm_pending_vblank_event *event, 134 struct drm_pending_vblank_event *event,
130 uint32_t flags, 135 uint32_t flags,
131 uint32_t target); 136 uint32_t target,
137 struct drm_modeset_acquire_ctx *ctx);
132int drm_atomic_helper_connector_dpms(struct drm_connector *connector, 138int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
133 int mode); 139 int mode);
134struct drm_encoder * 140struct drm_encoder *
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index f8b766d70a46..941f57f311aa 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -133,6 +133,7 @@ struct drm_scdc {
133 * This information is available in CEA-861-F extension blocks (like HF-VSDB). 133 * This information is available in CEA-861-F extension blocks (like HF-VSDB).
134 */ 134 */
135struct drm_hdmi_info { 135struct drm_hdmi_info {
136 /** @scdc: sink's scdc support and capabilities */
136 struct drm_scdc scdc; 137 struct drm_scdc scdc;
137}; 138};
138 139
@@ -655,7 +656,6 @@ struct drm_cmdline_mode {
655 * @bad_edid_counter: track sinks that give us an EDID with invalid checksum 656 * @bad_edid_counter: track sinks that give us an EDID with invalid checksum
656 * @edid_corrupt: indicates whether the last read EDID was corrupt 657 * @edid_corrupt: indicates whether the last read EDID was corrupt
657 * @debugfs_entry: debugfs directory for this connector 658 * @debugfs_entry: debugfs directory for this connector
658 * @state: current atomic state for this connector
659 * @has_tile: is this connector connected to a tiled monitor 659 * @has_tile: is this connector connected to a tiled monitor
660 * @tile_group: tile group for the connected monitor 660 * @tile_group: tile group for the connected monitor
661 * @tile_is_single_monitor: whether the tile is one monitor housing 661 * @tile_is_single_monitor: whether the tile is one monitor housing
@@ -823,6 +823,21 @@ struct drm_connector {
823 823
824 struct dentry *debugfs_entry; 824 struct dentry *debugfs_entry;
825 825
826 /**
827 * @state:
828 *
829 * Current atomic state for this connector.
830 *
831 * This is protected by @drm_mode_config.connection_mutex. Note that
832 * nonblocking atomic commits access the current connector state without
833 * taking locks. Either by going through the &struct drm_atomic_state
834 * pointers, see for_each_connector_in_state(),
835 * for_each_oldnew_connector_in_state(),
836 * for_each_old_connector_in_state() and
837 * for_each_new_connector_in_state(). Or through careful ordering of
838 * atomic commit operations as implemented in the atomic helpers, see
839 * &struct drm_crtc_commit.
840 */
826 struct drm_connector_state *state; 841 struct drm_connector_state *state;
827 842
828 /* DisplayID bits */ 843 /* DisplayID bits */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 6ef59da3fd8e..2be2192b1373 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -347,7 +347,8 @@ struct drm_crtc_funcs {
347 * 347 *
348 * 0 on success or a negative error code on failure. 348 * 0 on success or a negative error code on failure.
349 */ 349 */
350 int (*set_config)(struct drm_mode_set *set); 350 int (*set_config)(struct drm_mode_set *set,
351 struct drm_modeset_acquire_ctx *ctx);
351 352
352 /** 353 /**
353 * @page_flip: 354 * @page_flip:
@@ -405,7 +406,8 @@ struct drm_crtc_funcs {
405 int (*page_flip)(struct drm_crtc *crtc, 406 int (*page_flip)(struct drm_crtc *crtc,
406 struct drm_framebuffer *fb, 407 struct drm_framebuffer *fb,
407 struct drm_pending_vblank_event *event, 408 struct drm_pending_vblank_event *event,
408 uint32_t flags); 409 uint32_t flags,
410 struct drm_modeset_acquire_ctx *ctx);
409 411
410 /** 412 /**
411 * @page_flip_target: 413 * @page_flip_target:
@@ -423,7 +425,8 @@ struct drm_crtc_funcs {
423 int (*page_flip_target)(struct drm_crtc *crtc, 425 int (*page_flip_target)(struct drm_crtc *crtc,
424 struct drm_framebuffer *fb, 426 struct drm_framebuffer *fb,
425 struct drm_pending_vblank_event *event, 427 struct drm_pending_vblank_event *event,
426 uint32_t flags, uint32_t target); 428 uint32_t flags, uint32_t target,
429 struct drm_modeset_acquire_ctx *ctx);
427 430
428 /** 431 /**
429 * @set_property: 432 * @set_property:
@@ -590,9 +593,12 @@ struct drm_crtc_funcs {
590 * When CRC generation is enabled, the driver should call 593 * When CRC generation is enabled, the driver should call
591 * drm_crtc_add_crc_entry() at each frame, providing any information 594 * drm_crtc_add_crc_entry() at each frame, providing any information
592 * that characterizes the frame contents in the crcN arguments, as 595 * that characterizes the frame contents in the crcN arguments, as
593 * provided from the configured source. Drivers must accept a "auto" 596 * provided from the configured source. Drivers must accept an "auto"
594 * source name that will select a default source for this CRTC. 597 * source name that will select a default source for this CRTC.
595 * 598 *
599 * Note that "auto" can depend upon the current modeset configuration,
600 * e.g. it could pick an encoder or output specific CRC sampling point.
601 *
596 * This callback is optional if the driver does not support any CRC 602 * This callback is optional if the driver does not support any CRC
597 * generation functionality. 603 * generation functionality.
598 * 604 *
@@ -696,10 +702,12 @@ struct drm_crtc {
696 /** 702 /**
697 * @mutex: 703 * @mutex:
698 * 704 *
699 * This provides a read lock for the overall crtc state (mode, dpms 705 * This provides a read lock for the overall CRTC state (mode, dpms
700 * state, ...) and a write lock for everything which can be update 706 * state, ...) and a write lock for everything which can be update
701 * without a full modeset (fb, cursor data, crtc properties ...). A full 707 * without a full modeset (fb, cursor data, CRTC properties ...). A full
702 * modeset also need to grab &drm_mode_config.connection_mutex. 708 * modeset also need to grab &drm_mode_config.connection_mutex.
709 *
710 * For atomic drivers specifically this protects @state.
703 */ 711 */
704 struct drm_modeset_lock mutex; 712 struct drm_modeset_lock mutex;
705 713
@@ -745,6 +753,14 @@ struct drm_crtc {
745 * @state: 753 * @state:
746 * 754 *
747 * Current atomic state for this CRTC. 755 * Current atomic state for this CRTC.
756 *
757 * This is protected by @mutex. Note that nonblocking atomic commits
758 * access the current CRTC state without taking locks. Either by going
759 * through the &struct drm_atomic_state pointers, see
760 * for_each_crtc_in_state(), for_each_oldnew_crtc_in_state(),
761 * for_each_old_crtc_in_state() and for_each_new_crtc_in_state(). Or
762 * through careful ordering of atomic commit operations as implemented
763 * in the atomic helpers, see &struct drm_crtc_commit.
748 */ 764 */
749 struct drm_crtc_state *state; 765 struct drm_crtc_state *state;
750 766
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index d026f5017c33..43505c7b2b3f 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -43,18 +43,19 @@
43#include <drm/drm_modeset_helper_vtables.h> 43#include <drm/drm_modeset_helper_vtables.h>
44#include <drm/drm_modeset_helper.h> 44#include <drm/drm_modeset_helper.h>
45 45
46extern void drm_helper_disable_unused_functions(struct drm_device *dev); 46void drm_helper_disable_unused_functions(struct drm_device *dev);
47extern int drm_crtc_helper_set_config(struct drm_mode_set *set); 47int drm_crtc_helper_set_config(struct drm_mode_set *set,
48extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, 48 struct drm_modeset_acquire_ctx *ctx);
49 struct drm_display_mode *mode, 49bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
50 int x, int y, 50 struct drm_display_mode *mode,
51 struct drm_framebuffer *old_fb); 51 int x, int y,
52extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); 52 struct drm_framebuffer *old_fb);
53extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder); 53bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
54bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
54 55
55extern int drm_helper_connector_dpms(struct drm_connector *connector, int mode); 56int drm_helper_connector_dpms(struct drm_connector *connector, int mode);
56 57
57extern void drm_helper_resume_force_mode(struct drm_device *dev); 58void drm_helper_resume_force_mode(struct drm_device *dev);
58 59
59int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, 60int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
60 struct drm_display_mode *adjusted_mode, int x, int y, 61 struct drm_display_mode *adjusted_mode, int x, int y,
@@ -63,15 +64,15 @@ int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
63 struct drm_framebuffer *old_fb); 64 struct drm_framebuffer *old_fb);
64 65
65/* drm_probe_helper.c */ 66/* drm_probe_helper.c */
66extern int drm_helper_probe_single_connector_modes(struct drm_connector 67int drm_helper_probe_single_connector_modes(struct drm_connector
67 *connector, uint32_t maxX, 68 *connector, uint32_t maxX,
68 uint32_t maxY); 69 uint32_t maxY);
69extern void drm_kms_helper_poll_init(struct drm_device *dev); 70void drm_kms_helper_poll_init(struct drm_device *dev);
70extern void drm_kms_helper_poll_fini(struct drm_device *dev); 71void drm_kms_helper_poll_fini(struct drm_device *dev);
71extern bool drm_helper_hpd_irq_event(struct drm_device *dev); 72bool drm_helper_hpd_irq_event(struct drm_device *dev);
72extern void drm_kms_helper_hotplug_event(struct drm_device *dev); 73void drm_kms_helper_hotplug_event(struct drm_device *dev);
73 74
74extern void drm_kms_helper_poll_disable(struct drm_device *dev); 75void drm_kms_helper_poll_disable(struct drm_device *dev);
75extern void drm_kms_helper_poll_enable(struct drm_device *dev); 76void drm_kms_helper_poll_enable(struct drm_device *dev);
76 77
77#endif 78#endif
diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h
new file mode 100644
index 000000000000..ac0f75df1ac9
--- /dev/null
+++ b/include/drm/drm_debugfs.h
@@ -0,0 +1,101 @@
1/*
2 * Internal Header for the Direct Rendering Manager
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * Copyright (c) 2009-2010, Code Aurora Forum.
7 * All rights reserved.
8 *
9 * Author: Rickard E. (Rik) Faith <faith@valinux.com>
10 * Author: Gareth Hughes <gareth@valinux.com>
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice (including the next
20 * paragraph) shall be included in all copies or substantial portions of the
21 * Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 * OTHER DEALINGS IN THE SOFTWARE.
30 */
31
32#ifndef _DRM_DEBUGFS_H_
33#define _DRM_DEBUGFS_H_
34
35/**
36 * struct drm_info_list - debugfs info list entry
37 *
38 * This structure represents a debugfs file to be created by the drm
39 * core.
40 */
41struct drm_info_list {
42 /** @name: file name */
43 const char *name;
44 /**
45 * @show:
46 *
47 * Show callback. &seq_file->private will be set to the &struct
48 * drm_info_node corresponding to the instance of this info on a given
49 * &struct drm_minor.
50 */
51 int (*show)(struct seq_file*, void*);
52 /** @driver_features: Required driver features for this entry */
53 u32 driver_features;
54 /** @data: Driver-private data, should not be device-specific. */
55 void *data;
56};
57
58/**
59 * struct drm_info_node - Per-minor debugfs node structure
60 *
61 * This structure represents a debugfs file, as an instantiation of a &struct
62 * drm_info_list on a &struct drm_minor.
63 *
64 * FIXME:
65 *
66 * No it doesn't make a hole lot of sense that we duplicate debugfs entries for
67 * both the render and the primary nodes, but that's how this has organically
68 * grown. It should probably be fixed, with a compatibility link, if needed.
69 */
70struct drm_info_node {
71 /** @minor: &struct drm_minor for this node. */
72 struct drm_minor *minor;
73 /** @info_ent: template for this node. */
74 const struct drm_info_list *info_ent;
75 /* private: */
76 struct list_head list;
77 struct dentry *dent;
78};
79
80#if defined(CONFIG_DEBUG_FS)
81int drm_debugfs_create_files(const struct drm_info_list *files,
82 int count, struct dentry *root,
83 struct drm_minor *minor);
84int drm_debugfs_remove_files(const struct drm_info_list *files,
85 int count, struct drm_minor *minor);
86#else
87static inline int drm_debugfs_create_files(const struct drm_info_list *files,
88 int count, struct dentry *root,
89 struct drm_minor *minor)
90{
91 return 0;
92}
93
94static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
95 int count, struct drm_minor *minor)
96{
97 return 0;
98}
99#endif
100
101#endif /* _DRM_DEBUGFS_H_ */
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index f4b4d154b98e..5b024764666c 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -479,18 +479,6 @@ struct drm_dp_mst_topology_mgr {
479 * @pbn_div: PBN to slots divisor. 479 * @pbn_div: PBN to slots divisor.
480 */ 480 */
481 int pbn_div; 481 int pbn_div;
482 /**
483 * @total_slots: Total slots that can be allocated.
484 */
485 int total_slots;
486 /**
487 * @avail_slots: Still available slots that can be allocated.
488 */
489 int avail_slots;
490 /**
491 * @total_pbn: Total PBN count.
492 */
493 int total_pbn;
494 482
495 /** 483 /**
496 * @qlock: protects @tx_msg_downq, the &drm_dp_mst_branch.txslost and 484 * @qlock: protects @tx_msg_downq, the &drm_dp_mst_branch.txslost and
@@ -579,7 +567,8 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
579int drm_dp_calc_pbn_mode(int clock, int bpp); 567int drm_dp_calc_pbn_mode(int clock, int bpp);
580 568
581 569
582bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int *slots); 570bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
571 struct drm_dp_mst_port *port, int pbn, int slots);
583 572
584int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port); 573int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port);
585 574
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 8f900fb30275..53b98321df9b 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -522,11 +522,11 @@ struct drm_driver {
522 int dev_priv_size; 522 int dev_priv_size;
523}; 523};
524 524
525extern __printf(6, 7) 525__printf(6, 7)
526void drm_dev_printk(const struct device *dev, const char *level, 526void drm_dev_printk(const struct device *dev, const char *level,
527 unsigned int category, const char *function_name, 527 unsigned int category, const char *function_name,
528 const char *prefix, const char *format, ...); 528 const char *prefix, const char *format, ...);
529extern __printf(3, 4) 529__printf(3, 4)
530void drm_printk(const char *level, unsigned int category, 530void drm_printk(const char *level, unsigned int category,
531 const char *format, ...); 531 const char *format, ...);
532extern unsigned int drm_debug; 532extern unsigned int drm_debug;
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index fcc08da850c8..6942e84b6edd 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -25,6 +25,9 @@
25#include <linux/types.h> 25#include <linux/types.h>
26#include <uapi/drm/drm_fourcc.h> 26#include <uapi/drm/drm_fourcc.h>
27 27
28struct drm_device;
29struct drm_mode_fb_cmd2;
30
28/** 31/**
29 * struct drm_format_info - information about a DRM format 32 * struct drm_format_info - information about a DRM format
30 * @format: 4CC format identifier (DRM_FORMAT_*) 33 * @format: 4CC format identifier (DRM_FORMAT_*)
@@ -55,6 +58,9 @@ struct drm_format_name_buf {
55 58
56const struct drm_format_info *__drm_format_info(u32 format); 59const struct drm_format_info *__drm_format_info(u32 format);
57const struct drm_format_info *drm_format_info(u32 format); 60const struct drm_format_info *drm_format_info(u32 format);
61const struct drm_format_info *
62drm_get_format_info(struct drm_device *dev,
63 const struct drm_mode_fb_cmd2 *mode_cmd);
58uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth); 64uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
59int drm_format_num_planes(uint32_t format); 65int drm_format_num_planes(uint32_t format);
60int drm_format_plane_cpp(uint32_t format, int plane); 66int drm_format_plane_cpp(uint32_t format, int plane);
diff --git a/include/drm/drm_global.h b/include/drm/drm_global.h
index a06805eaf649..3a830602a2e4 100644
--- a/include/drm/drm_global.h
+++ b/include/drm/drm_global.h
@@ -45,9 +45,9 @@ struct drm_global_reference {
45 void (*release) (struct drm_global_reference *); 45 void (*release) (struct drm_global_reference *);
46}; 46};
47 47
48extern void drm_global_init(void); 48void drm_global_init(void);
49extern void drm_global_release(void); 49void drm_global_release(void);
50extern int drm_global_item_ref(struct drm_global_reference *ref); 50int drm_global_item_ref(struct drm_global_reference *ref);
51extern void drm_global_item_unref(struct drm_global_reference *ref); 51void drm_global_item_unref(struct drm_global_reference *ref);
52 52
53#endif 53#endif
diff --git a/include/drm/drm_hashtab.h b/include/drm/drm_hashtab.h
index fce2ef3fdfff..bb95ff011baf 100644
--- a/include/drm/drm_hashtab.h
+++ b/include/drm/drm_hashtab.h
@@ -49,17 +49,17 @@ struct drm_open_hash {
49 u8 order; 49 u8 order;
50}; 50};
51 51
52extern int drm_ht_create(struct drm_open_hash *ht, unsigned int order); 52int drm_ht_create(struct drm_open_hash *ht, unsigned int order);
53extern int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item); 53int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item);
54extern int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item, 54int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item,
55 unsigned long seed, int bits, int shift, 55 unsigned long seed, int bits, int shift,
56 unsigned long add); 56 unsigned long add);
57extern int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, struct drm_hash_item **item); 57int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, struct drm_hash_item **item);
58 58
59extern void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key); 59void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key);
60extern int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key); 60int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key);
61extern int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item); 61int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item);
62extern void drm_ht_remove(struct drm_open_hash *ht); 62void drm_ht_remove(struct drm_open_hash *ht);
63 63
64/* 64/*
65 * RCU-safe interface 65 * RCU-safe interface
diff --git a/include/drm/drm_ioctl.h b/include/drm/drm_ioctl.h
new file mode 100644
index 000000000000..f17ee077f649
--- /dev/null
+++ b/include/drm/drm_ioctl.h
@@ -0,0 +1,102 @@
1/*
2 * Internal Header for the Direct Rendering Manager
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * Copyright (c) 2009-2010, Code Aurora Forum.
7 * All rights reserved.
8 *
9 * Author: Rickard E. (Rik) Faith <faith@valinux.com>
10 * Author: Gareth Hughes <gareth@valinux.com>
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice (including the next
20 * paragraph) shall be included in all copies or substantial portions of the
21 * Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 * OTHER DEALINGS IN THE SOFTWARE.
30 */
31
32#ifndef _DRM_IOCTL_H_
33#define _DRM_IOCTL_H_
34
35#include <linux/types.h>
36
37#include <asm/ioctl.h>
38
39struct drm_device;
40struct drm_file;
41struct file;
42
43/**
44 * Ioctl function type.
45 *
46 * \param inode device inode.
47 * \param file_priv DRM file private pointer.
48 * \param cmd command.
49 * \param arg argument.
50 */
51typedef int drm_ioctl_t(struct drm_device *dev, void *data,
52 struct drm_file *file_priv);
53
54typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
55 unsigned long arg);
56
57#define DRM_IOCTL_NR(n) _IOC_NR(n)
58#define DRM_MAJOR 226
59
60#define DRM_AUTH 0x1
61#define DRM_MASTER 0x2
62#define DRM_ROOT_ONLY 0x4
63#define DRM_CONTROL_ALLOW 0x8
64#define DRM_UNLOCKED 0x10
65#define DRM_RENDER_ALLOW 0x20
66
67struct drm_ioctl_desc {
68 unsigned int cmd;
69 int flags;
70 drm_ioctl_t *func;
71 const char *name;
72};
73
74/**
75 * Creates a driver or general drm_ioctl_desc array entry for the given
76 * ioctl, for use by drm_ioctl().
77 */
78
79#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \
80 [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = { \
81 .cmd = DRM_IOCTL_##ioctl, \
82 .func = _func, \
83 .flags = _flags, \
84 .name = #ioctl \
85 }
86
87int drm_ioctl_permit(u32 flags, struct drm_file *file_priv);
88long drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
89#ifdef CONFIG_COMPAT
90long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
91#else
92/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */
93#define drm_compat_ioctl NULL
94#endif
95bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
96
97int drm_noop(struct drm_device *dev, void *data,
98 struct drm_file *file_priv);
99int drm_invalid_op(struct drm_device *dev, void *data,
100 struct drm_file *file_priv);
101
102#endif /* _DRM_IOCTL_H_ */
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index ea169a90b3c4..42981711189b 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -34,6 +34,7 @@ struct drm_file;
34struct drm_device; 34struct drm_device;
35struct drm_atomic_state; 35struct drm_atomic_state;
36struct drm_mode_fb_cmd2; 36struct drm_mode_fb_cmd2;
37struct drm_format_info;
37 38
38/** 39/**
39 * struct drm_mode_config_funcs - basic driver provided mode setting functions 40 * struct drm_mode_config_funcs - basic driver provided mode setting functions
@@ -70,6 +71,19 @@ struct drm_mode_config_funcs {
70 const struct drm_mode_fb_cmd2 *mode_cmd); 71 const struct drm_mode_fb_cmd2 *mode_cmd);
71 72
72 /** 73 /**
74 * @get_format_info:
75 *
76 * Allows a driver to return custom format information for special
77 * fb layouts (eg. ones with auxiliary compression control planes).
78 *
79 * RETURNS:
80 *
81 * The format information specific to the given fb metadata, or
82 * NULL if none is found.
83 */
84 const struct drm_format_info *(*get_format_info)(const struct drm_mode_fb_cmd2 *mode_cmd);
85
86 /**
73 * @output_poll_changed: 87 * @output_poll_changed:
74 * 88 *
75 * Callback used by helpers to inform the driver of output configuration 89 * Callback used by helpers to inform the driver of output configuration
@@ -293,21 +307,6 @@ struct drm_mode_config_funcs {
293 307
294/** 308/**
295 * struct drm_mode_config - Mode configuration control structure 309 * struct drm_mode_config - Mode configuration control structure
296 * @mutex: mutex protecting KMS related lists and structures
297 * @connection_mutex: ww mutex protecting connector state and routing
298 * @acquire_ctx: global implicit acquire context used by atomic drivers for
299 * legacy IOCTLs
300 * @fb_lock: mutex to protect fb state and lists
301 * @num_fb: number of fbs available
302 * @fb_list: list of framebuffers available
303 * @num_encoder: number of encoders on this device
304 * @encoder_list: list of encoder objects
305 * @num_overlay_plane: number of overlay planes on this device
306 * @num_total_plane: number of universal (i.e. with primary/curso) planes on this device
307 * @plane_list: list of plane objects
308 * @num_crtc: number of CRTCs on this device
309 * @crtc_list: list of CRTC objects
310 * @property_list: list of property objects
311 * @min_width: minimum pixel width on this device 310 * @min_width: minimum pixel width on this device
312 * @min_height: minimum pixel height on this device 311 * @min_height: minimum pixel height on this device
313 * @max_width: maximum pixel width on this device 312 * @max_width: maximum pixel width on this device
@@ -318,9 +317,6 @@ struct drm_mode_config_funcs {
318 * @poll_running: track polling status for this device 317 * @poll_running: track polling status for this device
319 * @delayed_event: track delayed poll uevent deliver for this device 318 * @delayed_event: track delayed poll uevent deliver for this device
320 * @output_poll_work: delayed work for polling in process context 319 * @output_poll_work: delayed work for polling in process context
321 * @property_blob_list: list of all the blob property objects
322 * @blob_lock: mutex for blob property allocation and management
323 * @*_property: core property tracking
324 * @preferred_depth: preferred RBG pixel depth, used by fb helpers 320 * @preferred_depth: preferred RBG pixel depth, used by fb helpers
325 * @prefer_shadow: hint to userspace to prefer shadow-fb rendering 321 * @prefer_shadow: hint to userspace to prefer shadow-fb rendering
326 * @cursor_width: hint to userspace for max cursor width 322 * @cursor_width: hint to userspace for max cursor width
@@ -332,9 +328,37 @@ struct drm_mode_config_funcs {
332 * global restrictions are also here, e.g. dimension restrictions. 328 * global restrictions are also here, e.g. dimension restrictions.
333 */ 329 */
334struct drm_mode_config { 330struct drm_mode_config {
335 struct mutex mutex; /* protects configuration (mode lists etc.) */ 331 /**
336 struct drm_modeset_lock connection_mutex; /* protects connector->encoder and encoder->crtc links */ 332 * @mutex:
337 struct drm_modeset_acquire_ctx *acquire_ctx; /* for legacy _lock_all() / _unlock_all() */ 333 *
334 * This is the big scary modeset BKL which protects everything that
335 * isn't protect otherwise. Scope is unclear and fuzzy, try to remove
336 * anything from under it's protection and move it into more well-scoped
337 * locks.
338 *
339 * The one important thing this protects is the use of @acquire_ctx.
340 */
341 struct mutex mutex;
342
343 /**
344 * @connection_mutex:
345 *
346 * This protects connector state and the connector to encoder to CRTC
347 * routing chain.
348 *
349 * For atomic drivers specifically this protects &drm_connector.state.
350 */
351 struct drm_modeset_lock connection_mutex;
352
353 /**
354 * @acquire_ctx:
355 *
356 * Global implicit acquire context used by atomic drivers for legacy
357 * IOCTLs. Deprecated, since implicit locking contexts make it
358 * impossible to use driver-private &struct drm_modeset_lock. Users of
359 * this must hold @mutex.
360 */
361 struct drm_modeset_acquire_ctx *acquire_ctx;
338 362
339 /** 363 /**
340 * @idr_mutex: 364 * @idr_mutex:
@@ -360,8 +384,11 @@ struct drm_mode_config {
360 */ 384 */
361 struct idr tile_idr; 385 struct idr tile_idr;
362 386
363 struct mutex fb_lock; /* proctects global and per-file fb lists */ 387 /** @fb_lock: Mutex to protect fb the global @fb_list and @num_fb. */
388 struct mutex fb_lock;
389 /** @num_fb: Number of entries on @fb_list. */
364 int num_fb; 390 int num_fb;
391 /** @fb_list: List of all &struct drm_framebuffer. */
365 struct list_head fb_list; 392 struct list_head fb_list;
366 393
367 /** 394 /**
@@ -379,27 +406,80 @@ struct drm_mode_config {
379 */ 406 */
380 struct ida connector_ida; 407 struct ida connector_ida;
381 /** 408 /**
382 * @connector_list: List of connector objects. Protected by 409 * @connector_list:
383 * @connector_list_lock. Only use drm_for_each_connector_iter() and 410 *
411 * List of connector objects linked with &drm_connector.head. Protected
412 * by @connector_list_lock. Only use drm_for_each_connector_iter() and
384 * &struct drm_connector_list_iter to walk this list. 413 * &struct drm_connector_list_iter to walk this list.
385 */ 414 */
386 struct list_head connector_list; 415 struct list_head connector_list;
416 /**
417 * @num_encoder:
418 *
419 * Number of encoders on this device. This is invariant over the
420 * lifetime of a device and hence doesn't need any locks.
421 */
387 int num_encoder; 422 int num_encoder;
423 /**
424 * @encoder_list:
425 *
426 * List of encoder objects linked with &drm_encoder.head. This is
427 * invariant over the lifetime of a device and hence doesn't need any
428 * locks.
429 */
388 struct list_head encoder_list; 430 struct list_head encoder_list;
389 431
390 /* 432 /**
391 * Track # of overlay planes separately from # of total planes. By 433 * @num_overlay_plane:
392 * default we only advertise overlay planes to userspace; if userspace 434 *
393 * sets the "universal plane" capability bit, we'll go ahead and 435 * Number of overlay planes on this device, excluding primary and cursor
394 * expose all planes. 436 * planes.
437 *
438 * Track number of overlay planes separately from number of total
439 * planes. By default we only advertise overlay planes to userspace; if
440 * userspace sets the "universal plane" capability bit, we'll go ahead
441 * and expose all planes. This is invariant over the lifetime of a
442 * device and hence doesn't need any locks.
395 */ 443 */
396 int num_overlay_plane; 444 int num_overlay_plane;
445 /**
446 * @num_total_plane:
447 *
448 * Number of universal (i.e. with primary/curso) planes on this device.
449 * This is invariant over the lifetime of a device and hence doesn't
450 * need any locks.
451 */
397 int num_total_plane; 452 int num_total_plane;
453 /**
454 * @plane_list:
455 *
456 * List of plane objects linked with &drm_plane.head. This is invariant
457 * over the lifetime of a device and hence doesn't need any locks.
458 */
398 struct list_head plane_list; 459 struct list_head plane_list;
399 460
461 /**
462 * @num_crtc:
463 *
464 * Number of CRTCs on this device linked with &drm_crtc.head. This is invariant over the lifetime
465 * of a device and hence doesn't need any locks.
466 */
400 int num_crtc; 467 int num_crtc;
468 /**
469 * @crtc_list:
470 *
471 * List of CRTC objects linked with &drm_crtc.head. This is invariant
472 * over the lifetime of a device and hence doesn't need any locks.
473 */
401 struct list_head crtc_list; 474 struct list_head crtc_list;
402 475
476 /**
477 * @property_list:
478 *
479 * List of property type objects linked with &drm_property.head. This is
480 * invariant over the lifetime of a device and hence doesn't need any
481 * locks.
482 */
403 struct list_head property_list; 483 struct list_head property_list;
404 484
405 int min_width, min_height; 485 int min_width, min_height;
@@ -413,10 +493,24 @@ struct drm_mode_config {
413 bool delayed_event; 493 bool delayed_event;
414 struct delayed_work output_poll_work; 494 struct delayed_work output_poll_work;
415 495
496 /**
497 * @blob_lock:
498 *
499 * Mutex for blob property allocation and management, protects
500 * @property_blob_list and &drm_file.blobs.
501 */
416 struct mutex blob_lock; 502 struct mutex blob_lock;
417 503
418 /* pointers to standard properties */ 504 /**
505 * @property_blob_list:
506 *
507 * List of all the blob property objects linked with
508 * &drm_property_blob.head. Protected by @blob_lock.
509 */
419 struct list_head property_blob_list; 510 struct list_head property_blob_list;
511
512 /* pointers to standard properties */
513
420 /** 514 /**
421 * @edid_property: Default connector property to hold the EDID of the 515 * @edid_property: Default connector property to hold the EDID of the
422 * currently connected sink, if any. 516 * currently connected sink, if any.
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
index 26a64805cc15..d1fc563f068a 100644
--- a/include/drm/drm_of.h
+++ b/include/drm/drm_of.h
@@ -11,18 +11,18 @@ struct drm_encoder;
11struct device_node; 11struct device_node;
12 12
13#ifdef CONFIG_OF 13#ifdef CONFIG_OF
14extern uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, 14uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
15 struct device_node *port); 15 struct device_node *port);
16extern void drm_of_component_match_add(struct device *master, 16void drm_of_component_match_add(struct device *master,
17 struct component_match **matchptr, 17 struct component_match **matchptr,
18 int (*compare)(struct device *, void *), 18 int (*compare)(struct device *, void *),
19 struct device_node *node); 19 struct device_node *node);
20extern int drm_of_component_probe(struct device *dev, 20int drm_of_component_probe(struct device *dev,
21 int (*compare_of)(struct device *, void *), 21 int (*compare_of)(struct device *, void *),
22 const struct component_master_ops *m_ops); 22 const struct component_master_ops *m_ops);
23extern int drm_of_encoder_active_endpoint(struct device_node *node, 23int drm_of_encoder_active_endpoint(struct device_node *node,
24 struct drm_encoder *encoder, 24 struct drm_encoder *encoder,
25 struct of_endpoint *endpoint); 25 struct of_endpoint *endpoint);
26#else 26#else
27static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev, 27static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
28 struct device_node *port) 28 struct device_node *port)
diff --git a/include/drm/drm_pci.h b/include/drm/drm_pci.h
index f5ebfcaf69e0..4579fac1080c 100644
--- a/include/drm/drm_pci.h
+++ b/include/drm/drm_pci.h
@@ -39,17 +39,17 @@ struct drm_device;
39struct drm_driver; 39struct drm_driver;
40struct drm_master; 40struct drm_master;
41 41
42extern struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size, 42struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size,
43 size_t align); 43 size_t align);
44extern void drm_pci_free(struct drm_device *dev, struct drm_dma_handle * dmah); 44void drm_pci_free(struct drm_device *dev, struct drm_dma_handle * dmah);
45 45
46extern int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); 46int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
47extern void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); 47void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
48#ifdef CONFIG_PCI 48#ifdef CONFIG_PCI
49extern int drm_get_pci_dev(struct pci_dev *pdev, 49int drm_get_pci_dev(struct pci_dev *pdev,
50 const struct pci_device_id *ent, 50 const struct pci_device_id *ent,
51 struct drm_driver *driver); 51 struct drm_driver *driver);
52extern int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master); 52int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master);
53#else 53#else
54static inline int drm_get_pci_dev(struct pci_dev *pdev, 54static inline int drm_get_pci_dev(struct pci_dev *pdev,
55 const struct pci_device_id *ent, 55 const struct pci_device_id *ent,
@@ -69,7 +69,7 @@ static inline int drm_pci_set_busid(struct drm_device *dev,
69#define DRM_PCIE_SPEED_50 2 69#define DRM_PCIE_SPEED_50 2
70#define DRM_PCIE_SPEED_80 4 70#define DRM_PCIE_SPEED_80 4
71 71
72extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask); 72int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask);
73extern int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw); 73int drm_pcie_get_max_link_width(struct drm_device *dev, u32 *mlw);
74 74
75#endif /* _DRM_PCI_H_ */ 75#endif /* _DRM_PCI_H_ */
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 20867b4371ab..9ab3e7044812 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -29,6 +29,7 @@
29 29
30struct drm_crtc; 30struct drm_crtc;
31struct drm_printer; 31struct drm_printer;
32struct drm_modeset_acquire_ctx;
32 33
33/** 34/**
34 * struct drm_plane_state - mutable plane state 35 * struct drm_plane_state - mutable plane state
@@ -184,7 +185,8 @@ struct drm_plane_funcs {
184 int crtc_x, int crtc_y, 185 int crtc_x, int crtc_y,
185 unsigned int crtc_w, unsigned int crtc_h, 186 unsigned int crtc_w, unsigned int crtc_h,
186 uint32_t src_x, uint32_t src_y, 187 uint32_t src_x, uint32_t src_y,
187 uint32_t src_w, uint32_t src_h); 188 uint32_t src_w, uint32_t src_h,
189 struct drm_modeset_acquire_ctx *ctx);
188 190
189 /** 191 /**
190 * @disable_plane: 192 * @disable_plane:
@@ -201,7 +203,8 @@ struct drm_plane_funcs {
201 * 203 *
202 * 0 on success or a negative error code on failure. 204 * 0 on success or a negative error code on failure.
203 */ 205 */
204 int (*disable_plane)(struct drm_plane *plane); 206 int (*disable_plane)(struct drm_plane *plane,
207 struct drm_modeset_acquire_ctx *ctx);
205 208
206 /** 209 /**
207 * @destroy: 210 * @destroy:
@@ -456,7 +459,6 @@ enum drm_plane_type {
456 * @funcs: helper functions 459 * @funcs: helper functions
457 * @properties: property tracking for this plane 460 * @properties: property tracking for this plane
458 * @type: type of plane (overlay, primary, cursor) 461 * @type: type of plane (overlay, primary, cursor)
459 * @state: current atomic state for this plane
460 * @zpos_property: zpos property for this plane 462 * @zpos_property: zpos property for this plane
461 * @rotation_property: rotation property for this plane 463 * @rotation_property: rotation property for this plane
462 * @helper_private: mid-layer private data 464 * @helper_private: mid-layer private data
@@ -473,6 +475,8 @@ struct drm_plane {
473 * Protects modeset plane state, together with the &drm_crtc.mutex of 475 * Protects modeset plane state, together with the &drm_crtc.mutex of
474 * CRTC this plane is linked to (when active, getting activated or 476 * CRTC this plane is linked to (when active, getting activated or
475 * getting disabled). 477 * getting disabled).
478 *
479 * For atomic drivers specifically this protects @state.
476 */ 480 */
477 struct drm_modeset_lock mutex; 481 struct drm_modeset_lock mutex;
478 482
@@ -502,6 +506,19 @@ struct drm_plane {
502 506
503 const struct drm_plane_helper_funcs *helper_private; 507 const struct drm_plane_helper_funcs *helper_private;
504 508
509 /**
510 * @state:
511 *
512 * Current atomic state for this plane.
513 *
514 * This is protected by @mutex. Note that nonblocking atomic commits
515 * access the current plane state without taking locks. Either by going
516 * through the &struct drm_atomic_state pointers, see
517 * for_each_plane_in_state(), for_each_oldnew_plane_in_state(),
518 * for_each_old_plane_in_state() and for_each_new_plane_in_state(). Or
519 * through careful ordering of atomic commit operations as implemented
520 * in the atomic helpers, see &struct drm_crtc_commit.
521 */
505 struct drm_plane_state *state; 522 struct drm_plane_state *state;
506 523
507 struct drm_property *zpos_property; 524 struct drm_property *zpos_property;
@@ -510,7 +527,7 @@ struct drm_plane {
510 527
511#define obj_to_plane(x) container_of(x, struct drm_plane, base) 528#define obj_to_plane(x) container_of(x, struct drm_plane, base)
512 529
513extern __printf(8, 9) 530__printf(8, 9)
514int drm_universal_plane_init(struct drm_device *dev, 531int drm_universal_plane_init(struct drm_device *dev,
515 struct drm_plane *plane, 532 struct drm_plane *plane,
516 uint32_t possible_crtcs, 533 uint32_t possible_crtcs,
@@ -519,13 +536,13 @@ int drm_universal_plane_init(struct drm_device *dev,
519 unsigned int format_count, 536 unsigned int format_count,
520 enum drm_plane_type type, 537 enum drm_plane_type type,
521 const char *name, ...); 538 const char *name, ...);
522extern int drm_plane_init(struct drm_device *dev, 539int drm_plane_init(struct drm_device *dev,
523 struct drm_plane *plane, 540 struct drm_plane *plane,
524 uint32_t possible_crtcs, 541 uint32_t possible_crtcs,
525 const struct drm_plane_funcs *funcs, 542 const struct drm_plane_funcs *funcs,
526 const uint32_t *formats, unsigned int format_count, 543 const uint32_t *formats, unsigned int format_count,
527 bool is_primary); 544 bool is_primary);
528extern void drm_plane_cleanup(struct drm_plane *plane); 545void drm_plane_cleanup(struct drm_plane *plane);
529 546
530/** 547/**
531 * drm_plane_index - find the index of a registered plane 548 * drm_plane_index - find the index of a registered plane
@@ -538,8 +555,8 @@ static inline unsigned int drm_plane_index(struct drm_plane *plane)
538{ 555{
539 return plane->index; 556 return plane->index;
540} 557}
541extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); 558struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx);
542extern void drm_plane_force_disable(struct drm_plane *plane); 559void drm_plane_force_disable(struct drm_plane *plane);
543 560
544int drm_mode_plane_set_obj_prop(struct drm_plane *plane, 561int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
545 struct drm_property *property, 562 struct drm_property *property,
diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h
index c18959685c06..7c8a00ceadb7 100644
--- a/include/drm/drm_plane_helper.h
+++ b/include/drm/drm_plane_helper.h
@@ -61,8 +61,10 @@ int drm_primary_helper_update(struct drm_plane *plane,
61 int crtc_x, int crtc_y, 61 int crtc_x, int crtc_y,
62 unsigned int crtc_w, unsigned int crtc_h, 62 unsigned int crtc_w, unsigned int crtc_h,
63 uint32_t src_x, uint32_t src_y, 63 uint32_t src_x, uint32_t src_y,
64 uint32_t src_w, uint32_t src_h); 64 uint32_t src_w, uint32_t src_h,
65int drm_primary_helper_disable(struct drm_plane *plane); 65 struct drm_modeset_acquire_ctx *ctx);
66int drm_primary_helper_disable(struct drm_plane *plane,
67 struct drm_modeset_acquire_ctx *ctx);
66void drm_primary_helper_destroy(struct drm_plane *plane); 68void drm_primary_helper_destroy(struct drm_plane *plane);
67extern const struct drm_plane_funcs drm_primary_helper_funcs; 69extern const struct drm_plane_funcs drm_primary_helper_funcs;
68 70
diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
index d09563ecc4b7..0b2a235c4be0 100644
--- a/include/drm/drm_prime.h
+++ b/include/drm/drm_prime.h
@@ -57,24 +57,24 @@ struct drm_device;
57struct drm_gem_object; 57struct drm_gem_object;
58struct drm_file; 58struct drm_file;
59 59
60extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, 60struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
61 struct drm_gem_object *obj, 61 struct drm_gem_object *obj,
62 int flags); 62 int flags);
63extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, 63int drm_gem_prime_handle_to_fd(struct drm_device *dev,
64 struct drm_file *file_priv, uint32_t handle, uint32_t flags, 64 struct drm_file *file_priv, uint32_t handle, uint32_t flags,
65 int *prime_fd); 65 int *prime_fd);
66extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, 66struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
67 struct dma_buf *dma_buf); 67 struct dma_buf *dma_buf);
68extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, 68int drm_gem_prime_fd_to_handle(struct drm_device *dev,
69 struct drm_file *file_priv, int prime_fd, uint32_t *handle); 69 struct drm_file *file_priv, int prime_fd, uint32_t *handle);
70struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev, 70struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev,
71 struct dma_buf_export_info *exp_info); 71 struct dma_buf_export_info *exp_info);
72extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf); 72void drm_gem_dmabuf_release(struct dma_buf *dma_buf);
73 73
74extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, 74int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
75 dma_addr_t *addrs, int max_pages); 75 dma_addr_t *addrs, int max_pages);
76extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages); 76struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages);
77extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); 77void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg);
78 78
79 79
80#endif /* __DRM_PRIME_H__ */ 80#endif /* __DRM_PRIME_H__ */
diff --git a/include/drm/drm_scdc_helper.h b/include/drm/drm_scdc_helper.h
index ab6bcfbceba9..c25122bb490a 100644
--- a/include/drm/drm_scdc_helper.h
+++ b/include/drm/drm_scdc_helper.h
@@ -129,6 +129,8 @@ static inline int drm_scdc_writeb(struct i2c_adapter *adapter, u8 offset,
129 return drm_scdc_write(adapter, offset, &value, sizeof(value)); 129 return drm_scdc_write(adapter, offset, &value, sizeof(value));
130} 130}
131 131
132bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter);
133
132/** 134/**
133 * drm_scdc_set_scrambling - enable scrambling 135 * drm_scdc_set_scrambling - enable scrambling
134 * @adapter: I2C adapter for DDC channel 136 * @adapter: I2C adapter for DDC channel
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
index fffbb95a0915..2d36538e4a17 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -72,7 +72,7 @@ struct drm_simple_display_pipe_funcs {
72 * the hardware lacks vblank support entirely. 72 * the hardware lacks vblank support entirely.
73 */ 73 */
74 void (*update)(struct drm_simple_display_pipe *pipe, 74 void (*update)(struct drm_simple_display_pipe *pipe,
75 struct drm_plane_state *plane_state); 75 struct drm_plane_state *old_plane_state);
76 76
77 /** 77 /**
78 * @prepare_fb: 78 * @prepare_fb:
diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
index 1d8e033fde67..23418c1f10d1 100644
--- a/include/drm/drm_sysfs.h
+++ b/include/drm/drm_sysfs.h
@@ -6,7 +6,7 @@
6 * don't want to include the full drmP.h file. 6 * don't want to include the full drmP.h file.
7 */ 7 */
8 8
9extern int drm_class_device_register(struct device *dev); 9int drm_class_device_register(struct device *dev);
10extern void drm_class_device_unregister(struct device *dev); 10void drm_class_device_unregister(struct device *dev);
11 11
12#endif 12#endif
diff --git a/include/drm/tinydrm/tinydrm.h b/include/drm/tinydrm/tinydrm.h
index cf9ca207b8b1..00b800df4d1b 100644
--- a/include/drm/tinydrm/tinydrm.h
+++ b/include/drm/tinydrm/tinydrm.h
@@ -58,8 +58,7 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe)
58 .gem_prime_mmap = drm_gem_cma_prime_mmap, \ 58 .gem_prime_mmap = drm_gem_cma_prime_mmap, \
59 .dumb_create = drm_gem_cma_dumb_create, \ 59 .dumb_create = drm_gem_cma_dumb_create, \
60 .dumb_map_offset = drm_gem_cma_dumb_map_offset, \ 60 .dumb_map_offset = drm_gem_cma_dumb_map_offset, \
61 .dumb_destroy = drm_gem_dumb_destroy, \ 61 .dumb_destroy = drm_gem_dumb_destroy
62 .fops = &tinydrm_fops
63 62
64/** 63/**
65 * TINYDRM_MODE - tinydrm display mode 64 * TINYDRM_MODE - tinydrm display mode
@@ -84,7 +83,6 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe)
84 .type = DRM_MODE_TYPE_DRIVER, \ 83 .type = DRM_MODE_TYPE_DRIVER, \
85 .clock = 1 /* pass validation */ 84 .clock = 1 /* pass validation */
86 85
87extern const struct file_operations tinydrm_fops;
88void tinydrm_lastclose(struct drm_device *drm); 86void tinydrm_lastclose(struct drm_device *drm);
89void tinydrm_gem_cma_free_object(struct drm_gem_object *gem_obj); 87void tinydrm_gem_cma_free_object(struct drm_gem_object *gem_obj);
90struct drm_gem_object * 88struct drm_gem_object *
diff --git a/include/linux/pci.h b/include/linux/pci.h
index eb3da1a04e6c..5948cfdc984e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -358,6 +358,7 @@ struct pci_dev {
358 unsigned int is_virtfn:1; 358 unsigned int is_virtfn:1;
359 unsigned int reset_fn:1; 359 unsigned int reset_fn:1;
360 unsigned int is_hotplug_bridge:1; 360 unsigned int is_hotplug_bridge:1;
361 unsigned int is_thunderbolt:1; /* Thunderbolt controller */
361 unsigned int __aer_firmware_first_valid:1; 362 unsigned int __aer_firmware_first_valid:1;
362 unsigned int __aer_firmware_first:1; 363 unsigned int __aer_firmware_first:1;
363 unsigned int broken_intx_masking:1; 364 unsigned int broken_intx_masking:1;
@@ -2160,6 +2161,28 @@ static inline bool pci_ari_enabled(struct pci_bus *bus)
2160 return bus->self && bus->self->ari_enabled; 2161 return bus->self && bus->self->ari_enabled;
2161} 2162}
2162 2163
2164/**
2165 * pci_is_thunderbolt_attached - whether device is on a Thunderbolt daisy chain
2166 * @pdev: PCI device to check
2167 *
2168 * Walk upwards from @pdev and check for each encountered bridge if it's part
2169 * of a Thunderbolt controller. Reaching the host bridge means @pdev is not
2170 * Thunderbolt-attached. (But rather soldered to the mainboard usually.)
2171 */
2172static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev)
2173{
2174 struct pci_dev *parent = pdev;
2175
2176 if (pdev->is_thunderbolt)
2177 return true;
2178
2179 while ((parent = pci_upstream_bridge(parent)))
2180 if (parent->is_thunderbolt)
2181 return true;
2182
2183 return false;
2184}
2185
2163/* provide the legacy pci_dma_* API */ 2186/* provide the legacy pci_dma_* API */
2164#include <linux/pci-dma-compat.h> 2187#include <linux/pci-dma-compat.h>
2165 2188