aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-01-17 18:20:10 -0500
committerDave Airlie <airlied@redhat.com>2019-01-17 18:31:28 -0500
commitf164a94c2c87752caeb1a3cbe068c440e7f7921f (patch)
treee914296ef0ce1df83e506a12bf4306d5aa468b24
parentb122153c7198e35fcb981ca9efd63b0df8ef3eab (diff)
parent94520db52fc0e931327bb77fe79a952a0e9dd2b0 (diff)
Merge tag 'drm-misc-next-2019-01-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.1: UAPI Changes: - New fourcc identifier for ARM Framebuffer Compression v1.3 Cross-subsystem Changes: Core Changes: - Reorganisation of drm_device and drm_framebuffer headers - Cleanup of the drmP inclusion - Fix leaks in the fb-helpers - Allow for depth different from bpp in fb-helper fbdev emulation - Remove drm_mode_object from drm_display_mode Driver Changes: - Add reflection properties to rockchip - a bunch of fixes for virtio - a bunch of fixes for dp_mst and drivers using it, and introduction of a new refcounting scheme - Convertion of bochs to atomic and generic fbdev emulation - Allow meson to remove the firmware framebuffers [airlied: patch rcar-du to add drm_modes.h] Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime.ripard@bootlin.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190116200428.u2n4jbk4mzza7n6e@flea
-rw-r--r--Documentation/devicetree/bindings/display/panel/auo,g101evn010.txt (renamed from Documentation/devicetree/bindings/display/panel/auo,g101evn010)0
-rw-r--r--Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt1
-rw-r--r--Documentation/gpu/dp-mst/topology-figure-1.dot52
-rw-r--r--Documentation/gpu/dp-mst/topology-figure-2.dot56
-rw-r--r--Documentation/gpu/dp-mst/topology-figure-3.dot59
-rw-r--r--Documentation/gpu/drm-internals.rst12
-rw-r--r--Documentation/gpu/drm-kms-helpers.rst30
-rw-r--r--Documentation/gpu/todo.rst30
-rw-r--r--MAINTAINERS17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/atom.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v6_0.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c2
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c11
-rw-r--r--drivers/gpu/drm/arc/arcpgu_crtc.c2
-rw-r--r--drivers/gpu/drm/arc/arcpgu_drv.c6
-rw-r--r--drivers/gpu/drm/arc/arcpgu_sim.c1
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c8
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c4
-rw-r--r--drivers/gpu/drm/bochs/Makefile2
-rw-r--r--drivers/gpu/drm/bochs/bochs.h23
-rw-r--r--drivers/gpu/drm/bochs/bochs_drv.c35
-rw-r--r--drivers/gpu/drm/bochs/bochs_fbdev.c163
-rw-r--r--drivers/gpu/drm/bochs/bochs_hw.c19
-rw-r--r--drivers/gpu/drm/bochs/bochs_kms.c218
-rw-r--r--drivers/gpu/drm/bochs/bochs_mm.c68
-rw-r--r--drivers/gpu/drm/bridge/analogix-anx78xx.c5
-rw-r--r--drivers/gpu/drm/bridge/panel.c22
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c3
-rw-r--r--drivers/gpu/drm/bridge/sil-sii8620.c3
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c4
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c3
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c3
-rw-r--r--drivers/gpu/drm/drm_crtc.c41
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c58
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h1
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c3
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c946
-rw-r--r--drivers/gpu/drm/drm_drv.c23
-rw-r--r--drivers/gpu/drm/drm_edid.c101
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c155
-rw-r--r--drivers/gpu/drm/drm_flip_work.c1
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c1
-rw-r--r--drivers/gpu/drm/drm_gem.c36
-rw-r--r--drivers/gpu/drm/drm_modes.c9
-rw-r--r--drivers/gpu/drm/drm_of.c4
-rw-r--r--drivers/gpu/drm/drm_panel.c3
-rw-r--r--drivers/gpu/drm/drm_plane.c3
-rw-r--r--drivers/gpu/drm/drm_vblank.c45
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c3
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c38
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h4
-rw-r--r--drivers/gpu/drm/i2c/ch7006_drv.c6
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c4
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c9
-rw-r--r--drivers/gpu/drm/i915/icl_dsi.c8
-rw-r--r--drivers/gpu/drm/i915/intel_connector.c4
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c35
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c6
-rw-r--r--drivers/gpu/drm/i915/intel_display.c15
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c71
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c67
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h19
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c11
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c34
-rw-r--r--drivers/gpu/drm/i915/intel_lspcon.c16
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c12
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c44
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c8
-rw-r--r--drivers/gpu/drm/i915/vlv_dsi.c14
-rw-r--r--drivers/gpu/drm/mediatek/mtk_hdmi.c3
-rw-r--r--drivers/gpu/drm/meson/meson_drv.c20
-rw-r--r--drivers/gpu/drm/meson/meson_dw_hdmi.c12
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c1
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c10
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c9
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c9
-rw-r--r--drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c9
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c9
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c9
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c9
-rw-r--r--drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c1
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c9
-rw-r--r--drivers/gpu/drm/msm/edp/edp_bridge.c9
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_bridge.c3
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c26
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/tvnv17.c4
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c103
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c9
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c8
-rw-r--r--drivers/gpu/drm/omapdrm/omap_encoder.c4
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c1
-rw-r--r--drivers/gpu/drm/panel/Kconfig9
-rw-r--r--drivers/gpu/drm/panel/Makefile1
-rw-r--r--drivers/gpu/drm/panel/panel-tpo-tpg110.c496
-rw-r--r--drivers/gpu/drm/qxl/qxl_cmd.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c4
-rw-r--r--drivers/gpu/drm/radeon/atom.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c1
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c2
-rw-r--r--drivers/gpu/drm/rockchip/inno_hdmi.c4
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fb.c36
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_psr.c37
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_psr.h3
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c157
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.h15
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c180
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.h53
-rw-r--r--drivers/gpu/drm/sti/sti_crtc.c16
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c3
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c3
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c3
-rw-r--r--drivers/gpu/drm/tegra/sor.c3
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-core.c3
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c3
-rw-r--r--drivers/gpu/drm/tinydrm/hx8357d.c1
-rw-r--r--drivers/gpu/drm/tinydrm/ili9225.c2
-rw-r--r--drivers/gpu/drm/tinydrm/ili9341.c1
-rw-r--r--drivers/gpu/drm/tinydrm/mi0283qt.c1
-rw-r--r--drivers/gpu/drm/tinydrm/mipi-dbi.c3
-rw-r--r--drivers/gpu/drm/tinydrm/repaper.c1
-rw-r--r--drivers/gpu/drm/tinydrm/st7586.c1
-rw-r--r--drivers/gpu/drm/tinydrm/st7735r.c1
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h1
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c16
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c17
-rw-r--r--drivers/gpu/drm/virtio/Makefile2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c7
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drm_bus.c103
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c79
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h10
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_fence.c8
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ioctl.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_kms.c10
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c17
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_vq.c12
-rw-r--r--drivers/gpu/drm/zte/zx_hdmi.c4
-rw-r--r--drivers/staging/vboxvideo/vbox_fb.c5
-rw-r--r--include/drm/bridge/dw_hdmi.h6
-rw-r--r--include/drm/drmP.h24
-rw-r--r--include/drm/drm_atomic.h6
-rw-r--r--include/drm/drm_connector.h6
-rw-r--r--include/drm/drm_crtc.h3
-rw-r--r--include/drm/drm_crtc_helper.h1
-rw-r--r--include/drm/drm_device.h288
-rw-r--r--include/drm/drm_dp_mst_helper.h151
-rw-r--r--include/drm/drm_edid.h10
-rw-r--r--include/drm/drm_encoder_slave.h1
-rw-r--r--include/drm/drm_framebuffer.h10
-rw-r--r--include/drm/drm_gem_cma_helper.h5
-rw-r--r--include/drm/drm_modes.h21
-rw-r--r--include/drm/drm_util.h53
-rw-r--r--include/drm/drm_vblank.h22
-rw-r--r--include/uapi/drm/drm_fourcc.h23
160 files changed, 3490 insertions, 1507 deletions
diff --git a/Documentation/devicetree/bindings/display/panel/auo,g101evn010 b/Documentation/devicetree/bindings/display/panel/auo,g101evn010.txt
index bc6a0c858e23..bc6a0c858e23 100644
--- a/Documentation/devicetree/bindings/display/panel/auo,g101evn010
+++ b/Documentation/devicetree/bindings/display/panel/auo,g101evn010.txt
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
index b79e5769f0ae..4f58c5a2d195 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
@@ -10,6 +10,7 @@ Required properties:
10 "rockchip,rk3126-vop"; 10 "rockchip,rk3126-vop";
11 "rockchip,px30-vop-lit"; 11 "rockchip,px30-vop-lit";
12 "rockchip,px30-vop-big"; 12 "rockchip,px30-vop-big";
13 "rockchip,rk3066-vop";
13 "rockchip,rk3188-vop"; 14 "rockchip,rk3188-vop";
14 "rockchip,rk3288-vop"; 15 "rockchip,rk3288-vop";
15 "rockchip,rk3368-vop"; 16 "rockchip,rk3368-vop";
diff --git a/Documentation/gpu/dp-mst/topology-figure-1.dot b/Documentation/gpu/dp-mst/topology-figure-1.dot
new file mode 100644
index 000000000000..157e17c7e0b0
--- /dev/null
+++ b/Documentation/gpu/dp-mst/topology-figure-1.dot
@@ -0,0 +1,52 @@
1digraph T {
2 /* Make sure our payloads are always drawn below the driver node */
3 subgraph cluster_driver {
4 fillcolor = grey;
5 style = filled;
6 driver -> {payload1, payload2} [dir=none];
7 }
8
9 /* Driver malloc references */
10 edge [style=dashed];
11 driver -> port1;
12 driver -> port2;
13 driver -> port3:e;
14 driver -> port4;
15
16 payload1:s -> port1:e;
17 payload2:s -> port3:e;
18 edge [style=""];
19
20 subgraph cluster_topology {
21 label="Topology Manager";
22 labelloc=bottom;
23
24 /* Topology references */
25 mstb1 -> {port1, port2};
26 port1 -> mstb2;
27 port2 -> mstb3 -> {port3, port4};
28 port3 -> mstb4;
29
30 /* Malloc references */
31 edge [style=dashed;dir=back];
32 mstb1 -> {port1, port2};
33 port1 -> mstb2;
34 port2 -> mstb3 -> {port3, port4};
35 port3 -> mstb4;
36 }
37
38 driver [label="DRM driver";style=filled;shape=box;fillcolor=lightblue];
39
40 payload1 [label="Payload #1";style=filled;shape=box;fillcolor=lightblue];
41 payload2 [label="Payload #2";style=filled;shape=box;fillcolor=lightblue];
42
43 mstb1 [label="MSTB #1";style=filled;fillcolor=palegreen;shape=oval];
44 mstb2 [label="MSTB #2";style=filled;fillcolor=palegreen;shape=oval];
45 mstb3 [label="MSTB #3";style=filled;fillcolor=palegreen;shape=oval];
46 mstb4 [label="MSTB #4";style=filled;fillcolor=palegreen;shape=oval];
47
48 port1 [label="Port #1";shape=oval];
49 port2 [label="Port #2";shape=oval];
50 port3 [label="Port #3";shape=oval];
51 port4 [label="Port #4";shape=oval];
52}
diff --git a/Documentation/gpu/dp-mst/topology-figure-2.dot b/Documentation/gpu/dp-mst/topology-figure-2.dot
new file mode 100644
index 000000000000..4243dd1737cb
--- /dev/null
+++ b/Documentation/gpu/dp-mst/topology-figure-2.dot
@@ -0,0 +1,56 @@
1digraph T {
2 /* Make sure our payloads are always drawn below the driver node */
3 subgraph cluster_driver {
4 fillcolor = grey;
5 style = filled;
6 driver -> {payload1, payload2} [dir=none];
7 }
8
9 /* Driver malloc references */
10 edge [style=dashed];
11 driver -> port1;
12 driver -> port2;
13 driver -> port3:e;
14 driver -> port4 [color=red];
15
16 payload1:s -> port1:e;
17 payload2:s -> port3:e;
18 edge [style=""];
19
20 subgraph cluster_topology {
21 label="Topology Manager";
22 labelloc=bottom;
23
24 /* Topology references */
25 mstb1 -> {port1, port2};
26 port1 -> mstb2;
27 edge [color=red];
28 port2 -> mstb3 -> {port3, port4};
29 port3 -> mstb4;
30 edge [color=""];
31
32 /* Malloc references */
33 edge [style=dashed;dir=back];
34 mstb1 -> {port1, port2};
35 port1 -> mstb2;
36 port2 -> mstb3 -> port3;
37 edge [color=red];
38 mstb3 -> port4;
39 port3 -> mstb4;
40 }
41
42 mstb1 [label="MSTB #1";style=filled;fillcolor=palegreen];
43 mstb2 [label="MSTB #2";style=filled;fillcolor=palegreen];
44 mstb3 [label="MSTB #3";style=filled;fillcolor=palegreen];
45 mstb4 [label="MSTB #4";style=filled;fillcolor=grey];
46
47 port1 [label="Port #1"];
48 port2 [label="Port #2"];
49 port3 [label="Port #3"];
50 port4 [label="Port #4";style=filled;fillcolor=grey];
51
52 driver [label="DRM driver";style=filled;shape=box;fillcolor=lightblue];
53
54 payload1 [label="Payload #1";style=filled;shape=box;fillcolor=lightblue];
55 payload2 [label="Payload #2";style=filled;shape=box;fillcolor=lightblue];
56}
diff --git a/Documentation/gpu/dp-mst/topology-figure-3.dot b/Documentation/gpu/dp-mst/topology-figure-3.dot
new file mode 100644
index 000000000000..6cd78d06778b
--- /dev/null
+++ b/Documentation/gpu/dp-mst/topology-figure-3.dot
@@ -0,0 +1,59 @@
1digraph T {
2 /* Make sure our payloads are always drawn below the driver node */
3 subgraph cluster_driver {
4 fillcolor = grey;
5 style = filled;
6 edge [dir=none];
7 driver -> payload1;
8 driver -> payload2 [penwidth=3];
9 edge [dir=""];
10 }
11
12 /* Driver malloc references */
13 edge [style=dashed];
14 driver -> port1;
15 driver -> port2;
16 driver -> port3:e;
17 driver -> port4 [color=grey];
18 payload1:s -> port1:e;
19 payload2:s -> port3:e [penwidth=3];
20 edge [style=""];
21
22 subgraph cluster_topology {
23 label="Topology Manager";
24 labelloc=bottom;
25
26 /* Topology references */
27 mstb1 -> {port1, port2};
28 port1 -> mstb2;
29 edge [color=grey];
30 port2 -> mstb3 -> {port3, port4};
31 port3 -> mstb4;
32 edge [color=""];
33
34 /* Malloc references */
35 edge [style=dashed;dir=back];
36 mstb1 -> {port1, port2};
37 port1 -> mstb2;
38 port2 -> mstb3 [penwidth=3];
39 mstb3 -> port3 [penwidth=3];
40 edge [color=grey];
41 mstb3 -> port4;
42 port3 -> mstb4;
43 }
44
45 mstb1 [label="MSTB #1";style=filled;fillcolor=palegreen];
46 mstb2 [label="MSTB #2";style=filled;fillcolor=palegreen];
47 mstb3 [label="MSTB #3";style=filled;fillcolor=palegreen;penwidth=3];
48 mstb4 [label="MSTB #4";style=filled;fillcolor=grey];
49
50 port1 [label="Port #1"];
51 port2 [label="Port #2";penwidth=5];
52 port3 [label="Port #3";penwidth=3];
53 port4 [label="Port #4";style=filled;fillcolor=grey];
54
55 driver [label="DRM driver";style=filled;shape=box;fillcolor=lightblue];
56
57 payload1 [label="Payload #1";style=filled;shape=box;fillcolor=lightblue];
58 payload2 [label="Payload #2";style=filled;shape=box;fillcolor=lightblue;penwidth=3];
59}
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index 5ee9674fb9e9..2caf21effd28 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -143,6 +143,9 @@ Device Instance and Driver Handling
143.. kernel-doc:: drivers/gpu/drm/drm_drv.c 143.. kernel-doc:: drivers/gpu/drm/drm_drv.c
144 :doc: driver instance overview 144 :doc: driver instance overview
145 145
146.. kernel-doc:: include/drm/drm_device.h
147 :internal:
148
146.. kernel-doc:: include/drm/drm_drv.h 149.. kernel-doc:: include/drm/drm_drv.h
147 :internal: 150 :internal:
148 151
@@ -230,6 +233,15 @@ Printer
230.. kernel-doc:: drivers/gpu/drm/drm_print.c 233.. kernel-doc:: drivers/gpu/drm/drm_print.c
231 :export: 234 :export:
232 235
236Utilities
237---------
238
239.. kernel-doc:: include/drm/drm_util.h
240 :doc: drm utils
241
242.. kernel-doc:: include/drm/drm_util.h
243 :internal:
244
233 245
234Legacy Support Code 246Legacy Support Code
235=================== 247===================
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index b422eb8edf16..fbd11b2fe5b5 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -116,8 +116,6 @@ Framebuffer CMA Helper Functions Reference
116.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c 116.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c
117 :export: 117 :export:
118 118
119.. _drm_bridges:
120
121Framebuffer GEM Helper Reference 119Framebuffer GEM Helper Reference
122================================ 120================================
123 121
@@ -127,6 +125,8 @@ Framebuffer GEM Helper Reference
127.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c 125.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c
128 :export: 126 :export:
129 127
128.. _drm_bridges:
129
130Bridges 130Bridges
131======= 131=======
132 132
@@ -208,18 +208,40 @@ Display Port Dual Mode Adaptor Helper Functions Reference
208.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c 208.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c
209 :export: 209 :export:
210 210
211Display Port MST Helper Functions Reference 211Display Port MST Helpers
212=========================================== 212========================
213
214Overview
215--------
213 216
214.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c 217.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
215 :doc: dp mst helper 218 :doc: dp mst helper
216 219
220.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
221 :doc: Branch device and port refcounting
222
223Functions Reference
224-------------------
225
217.. kernel-doc:: include/drm/drm_dp_mst_helper.h 226.. kernel-doc:: include/drm/drm_dp_mst_helper.h
218 :internal: 227 :internal:
219 228
220.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c 229.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
221 :export: 230 :export:
222 231
232Topology Lifetime Internals
233---------------------------
234
235These functions aren't exported to drivers, but are documented here to help make
236the MST topology helpers easier to understand
237
238.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
239 :functions: drm_dp_mst_topology_try_get_mstb drm_dp_mst_topology_get_mstb
240 drm_dp_mst_topology_put_mstb
241 drm_dp_mst_topology_try_get_port drm_dp_mst_topology_get_port
242 drm_dp_mst_topology_put_port
243 drm_dp_mst_get_mstb_malloc drm_dp_mst_put_mstb_malloc
244
223MIPI DSI Helper Functions Reference 245MIPI DSI Helper Functions Reference
224=================================== 246===================================
225 247
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 41da7b06195c..0a85dad876ae 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -209,6 +209,36 @@ Would be great to refactor this all into a set of small common helpers.
209 209
210Contact: Daniel Vetter 210Contact: Daniel Vetter
211 211
212Generic fbdev defio support
213---------------------------
214
215The defio support code in the fbdev core has some very specific requirements,
216which means drivers need to have a special framebuffer for fbdev. Which prevents
217us from using the generic fbdev emulation code everywhere. The main issue is
218that it uses some fields in struct page itself, which breaks shmem gem objects
219(and other things).
220
221Possible solution would be to write our own defio mmap code in the drm fbdev
222emulation. It would need to fully wrap the existing mmap ops, forwarding
223everything after it has done the write-protect/mkwrite trickery:
224
225- In the drm_fbdev_fb_mmap helper, if we need defio, change the
226 default page prots to write-protected with something like this::
227
228 vma->vm_page_prot = pgprot_wrprotect(vma->vm_page_prot);
229
230- Set the mkwrite and fsync callbacks with similar implementions to the core
231 fbdev defio stuff. These should all work on plain ptes, they don't actually
232 require a struct page. uff. These should all work on plain ptes, they don't
233 actually require a struct page.
234
235- Track the dirty pages in a separate structure (bitfield with one bit per page
236 should work) to avoid clobbering struct page.
237
238Might be good to also have some igt testcases for this.
239
240Contact: Daniel Vetter, Noralf Tronnes
241
212Put a reservation_object into drm_gem_object 242Put a reservation_object into drm_gem_object
213-------------------------------------------- 243--------------------------------------------
214 244
diff --git a/MAINTAINERS b/MAINTAINERS
index 6b510ef800f6..6e1cef2f21d9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4910,6 +4910,13 @@ DRM DRIVER FOR TDFX VIDEO CARDS
4910S: Orphan / Obsolete 4910S: Orphan / Obsolete
4911F: drivers/gpu/drm/tdfx/ 4911F: drivers/gpu/drm/tdfx/
4912 4912
4913DRM DRIVER FOR TPO TPG110 PANELS
4914M: Linus Walleij <linus.walleij@linaro.org>
4915T: git git://anongit.freedesktop.org/drm/drm-misc
4916S: Maintained
4917F: drivers/gpu/drm/panel/panel-tpo-tpg110.c
4918F: Documentation/devicetree/bindings/display/panel/tpo,tpg110.txt
4919
4913DRM DRIVER FOR USB DISPLAYLINK VIDEO ADAPTERS 4920DRM DRIVER FOR USB DISPLAYLINK VIDEO ADAPTERS
4914M: Dave Airlie <airlied@redhat.com> 4921M: Dave Airlie <airlied@redhat.com>
4915R: Sean Paul <sean@poorly.run> 4922R: Sean Paul <sean@poorly.run>
@@ -4918,6 +4925,16 @@ S: Odd Fixes
4918F: drivers/gpu/drm/udl/ 4925F: drivers/gpu/drm/udl/
4919T: git git://anongit.freedesktop.org/drm/drm-misc 4926T: git git://anongit.freedesktop.org/drm/drm-misc
4920 4927
4928DRM DRIVER FOR VIRTUAL KERNEL MODESETTING (VKMS)
4929M: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
4930R: Haneen Mohammed <hamohammed.sa@gmail.com>
4931R: Daniel Vetter <daniel@ffwll.ch>
4932T: git git://anongit.freedesktop.org/drm/drm-misc
4933S: Maintained
4934L: dri-devel@lists.freedesktop.org
4935F: drivers/gpu/drm/vkms/
4936F: Documentation/gpu/vkms.rst
4937
4921DRM DRIVER FOR VMWARE VIRTUAL GPU 4938DRM DRIVER FOR VMWARE VIRTUAL GPU
4922M: "VMware Graphics" <linux-graphics-maintainer@vmware.com> 4939M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
4923M: Thomas Hellstrom <thellstrom@vmware.com> 4940M: Thomas Hellstrom <thellstrom@vmware.com>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 8a078f4ae73d..28bccceaa363 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2708,7 +2708,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
2708 amdgpu_irq_disable_all(adev); 2708 amdgpu_irq_disable_all(adev);
2709 if (adev->mode_info.mode_config_initialized){ 2709 if (adev->mode_info.mode_config_initialized){
2710 if (!amdgpu_device_has_dc_support(adev)) 2710 if (!amdgpu_device_has_dc_support(adev))
2711 drm_crtc_force_disable_all(adev->ddev); 2711 drm_helper_force_disable_all(adev->ddev);
2712 else 2712 else
2713 drm_atomic_helper_shutdown(adev->ddev); 2713 drm_atomic_helper_shutdown(adev->ddev);
2714 } 2714 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index e9934de1b9cf..dd30f4e61a8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -27,6 +27,8 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <asm/unaligned.h> 28#include <asm/unaligned.h>
29 29
30#include <drm/drm_util.h>
31
30#define ATOM_DEBUG 32#define ATOM_DEBUG
31 33
32#include "atom.h" 34#include "atom.h"
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 4cfecdce29a3..1f0426d2fc2a 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -1682,7 +1682,7 @@ static void dce_v10_0_afmt_setmode(struct drm_encoder *encoder,
1682 dce_v10_0_audio_write_sad_regs(encoder); 1682 dce_v10_0_audio_write_sad_regs(encoder);
1683 dce_v10_0_audio_write_latency_fields(encoder, mode); 1683 dce_v10_0_audio_write_latency_fields(encoder, mode);
1684 1684
1685 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 1685 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
1686 if (err < 0) { 1686 if (err < 0) {
1687 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); 1687 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
1688 return; 1688 return;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 7c868916d90f..2280b971d758 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -1724,7 +1724,7 @@ static void dce_v11_0_afmt_setmode(struct drm_encoder *encoder,
1724 dce_v11_0_audio_write_sad_regs(encoder); 1724 dce_v11_0_audio_write_sad_regs(encoder);
1725 dce_v11_0_audio_write_latency_fields(encoder, mode); 1725 dce_v11_0_audio_write_latency_fields(encoder, mode);
1726 1726
1727 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 1727 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
1728 if (err < 0) { 1728 if (err < 0) {
1729 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); 1729 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
1730 return; 1730 return;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 17eaaba36017..db443ec53d3a 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1423,6 +1423,7 @@ static void dce_v6_0_audio_set_avi_infoframe(struct drm_encoder *encoder,
1423 struct amdgpu_device *adev = dev->dev_private; 1423 struct amdgpu_device *adev = dev->dev_private;
1424 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder); 1424 struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
1425 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv; 1425 struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
1426 struct drm_connector *connector = amdgpu_get_connector_for_encoder(encoder);
1426 struct hdmi_avi_infoframe frame; 1427 struct hdmi_avi_infoframe frame;
1427 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; 1428 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
1428 uint8_t *payload = buffer + 3; 1429 uint8_t *payload = buffer + 3;
@@ -1430,7 +1431,7 @@ static void dce_v6_0_audio_set_avi_infoframe(struct drm_encoder *encoder,
1430 ssize_t err; 1431 ssize_t err;
1431 u32 tmp; 1432 u32 tmp;
1432 1433
1433 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 1434 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
1434 if (err < 0) { 1435 if (err < 0) {
1435 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); 1436 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
1436 return; 1437 return;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 8c0576978d36..13da915991dd 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1616,7 +1616,7 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,
1616 dce_v8_0_audio_write_sad_regs(encoder); 1616 dce_v8_0_audio_write_sad_regs(encoder);
1617 dce_v8_0_audio_write_latency_fields(encoder, mode); 1617 dce_v8_0_audio_write_latency_fields(encoder, mode);
1618 1618
1619 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 1619 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
1620 if (err < 0) { 1620 if (err < 0) {
1621 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); 1621 DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
1622 return; 1622 return;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 5e7ca1f3a8d1..24632727e127 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -191,6 +191,7 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
191 drm_encoder_cleanup(&amdgpu_encoder->base); 191 drm_encoder_cleanup(&amdgpu_encoder->base);
192 kfree(amdgpu_encoder); 192 kfree(amdgpu_encoder);
193 drm_connector_cleanup(connector); 193 drm_connector_cleanup(connector);
194 drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port);
194 kfree(amdgpu_dm_connector); 195 kfree(amdgpu_dm_connector);
195} 196}
196 197
@@ -363,7 +364,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
363 amdgpu_dm_connector_funcs_reset(connector); 364 amdgpu_dm_connector_funcs_reset(connector);
364 365
365 DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", 366 DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
366 aconnector, connector->base.id, aconnector->mst_port); 367 aconnector, connector->base.id, aconnector->mst_port);
368
369 drm_dp_mst_get_port_malloc(port);
367 370
368 DRM_DEBUG_KMS(":%d\n", connector->base.id); 371 DRM_DEBUG_KMS(":%d\n", connector->base.id);
369 372
@@ -379,12 +382,12 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
379 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 382 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
380 383
381 DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", 384 DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
382 aconnector, connector->base.id, aconnector->mst_port); 385 aconnector, connector->base.id, aconnector->mst_port);
383 386
384 aconnector->port = NULL;
385 if (aconnector->dc_sink) { 387 if (aconnector->dc_sink) {
386 amdgpu_dm_update_freesync_caps(connector, NULL); 388 amdgpu_dm_update_freesync_caps(connector, NULL);
387 dc_link_remove_remote_sink(aconnector->dc_link, aconnector->dc_sink); 389 dc_link_remove_remote_sink(aconnector->dc_link,
390 aconnector->dc_sink);
388 dc_sink_release(aconnector->dc_sink); 391 dc_sink_release(aconnector->dc_sink);
389 aconnector->dc_sink = NULL; 392 aconnector->dc_sink = NULL;
390 } 393 }
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 62f51f70606d..155ab177ce0b 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -16,8 +16,10 @@
16 16
17#include <drm/drm_atomic_helper.h> 17#include <drm/drm_atomic_helper.h>
18#include <drm/drm_crtc_helper.h> 18#include <drm/drm_crtc_helper.h>
19#include <drm/drm_device.h>
19#include <drm/drm_fb_cma_helper.h> 20#include <drm/drm_fb_cma_helper.h>
20#include <drm/drm_gem_cma_helper.h> 21#include <drm/drm_gem_cma_helper.h>
22#include <drm/drm_vblank.h>
21#include <drm/drm_plane_helper.h> 23#include <drm/drm_plane_helper.h>
22#include <linux/clk.h> 24#include <linux/clk.h>
23#include <linux/platform_data/simplefb.h> 25#include <linux/platform_data/simplefb.h>
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 206a76abf771..39a79f5718c4 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -16,12 +16,18 @@
16 16
17#include <linux/clk.h> 17#include <linux/clk.h>
18#include <drm/drm_crtc_helper.h> 18#include <drm/drm_crtc_helper.h>
19#include <drm/drm_device.h>
20#include <drm/drm_debugfs.h>
21#include <drm/drm_drv.h>
19#include <drm/drm_fb_cma_helper.h> 22#include <drm/drm_fb_cma_helper.h>
20#include <drm/drm_fb_helper.h> 23#include <drm/drm_fb_helper.h>
21#include <drm/drm_gem_cma_helper.h> 24#include <drm/drm_gem_cma_helper.h>
22#include <drm/drm_gem_framebuffer_helper.h> 25#include <drm/drm_gem_framebuffer_helper.h>
23#include <drm/drm_atomic_helper.h> 26#include <drm/drm_atomic_helper.h>
27#include <linux/dma-mapping.h>
28#include <linux/module.h>
24#include <linux/of_reserved_mem.h> 29#include <linux/of_reserved_mem.h>
30#include <linux/platform_device.h>
25 31
26#include "arcpgu.h" 32#include "arcpgu.h"
27#include "arcpgu_regs.h" 33#include "arcpgu_regs.h"
diff --git a/drivers/gpu/drm/arc/arcpgu_sim.c b/drivers/gpu/drm/arc/arcpgu_sim.c
index 68629e614990..6530d88f7293 100644
--- a/drivers/gpu/drm/arc/arcpgu_sim.c
+++ b/drivers/gpu/drm/arc/arcpgu_sim.c
@@ -51,7 +51,6 @@ arcpgu_drm_connector_helper_funcs = {
51}; 51};
52 52
53static const struct drm_connector_funcs arcpgu_drm_connector_funcs = { 53static const struct drm_connector_funcs arcpgu_drm_connector_funcs = {
54 .dpms = drm_helper_connector_dpms,
55 .reset = drm_atomic_helper_connector_reset, 54 .reset = drm_atomic_helper_connector_reset,
56 .fill_modes = drm_helper_probe_single_connector_modes, 55 .fill_modes = drm_helper_probe_single_connector_modes,
57 .destroy = arcpgu_drm_connector_destroy, 56 .destroy = arcpgu_drm_connector_destroy,
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index da9360688b55..20dfb29561c2 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -270,13 +270,7 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
270 tm = adj->crtc_vtotal - adj->crtc_vsync_end; 270 tm = adj->crtc_vtotal - adj->crtc_vsync_end;
271 271
272 DRM_DEBUG_KMS("[CRTC:%d:%s] mode " DRM_MODE_FMT "\n", 272 DRM_DEBUG_KMS("[CRTC:%d:%s] mode " DRM_MODE_FMT "\n",
273 crtc->base.id, crtc->name, 273 crtc->base.id, crtc->name, DRM_MODE_ARG(adj));
274 adj->base.id, adj->name, adj->vrefresh, adj->clock,
275 adj->crtc_hdisplay, adj->crtc_hsync_start,
276 adj->crtc_hsync_end, adj->crtc_htotal,
277 adj->crtc_vdisplay, adj->crtc_vsync_start,
278 adj->crtc_vsync_end, adj->crtc_vtotal,
279 adj->type, adj->flags);
280 DRM_DEBUG_KMS("lm %d rm %d tm %d bm %d\n", lm, rm, tm, bm); 274 DRM_DEBUG_KMS("lm %d rm %d tm %d bm %d\n", lm, rm, tm, bm);
281 275
282 /* Now compute the divider for real */ 276 /* Now compute the divider for real */
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index c2e41369adcf..2c9f8dd9733a 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -39,7 +39,9 @@
39#include <drm/drmP.h> 39#include <drm/drmP.h>
40#include <drm/drm_crtc.h> 40#include <drm/drm_crtc.h>
41#include <drm/drm_fb_helper.h> 41#include <drm/drm_fb_helper.h>
42#include <drm/drm_util.h>
42#include <drm/drm_crtc_helper.h> 43#include <drm/drm_crtc_helper.h>
44
43#include "ast_drv.h" 45#include "ast_drv.h"
44 46
45static void ast_dirty_update(struct ast_fbdev *afbdev, 47static void ast_dirty_update(struct ast_fbdev *afbdev,
@@ -261,7 +263,7 @@ static void ast_fbdev_destroy(struct drm_device *dev,
261{ 263{
262 struct ast_framebuffer *afb = &afbdev->afb; 264 struct ast_framebuffer *afb = &afbdev->afb;
263 265
264 drm_crtc_force_disable_all(dev); 266 drm_helper_force_disable_all(dev);
265 drm_fb_helper_unregister_fbi(&afbdev->helper); 267 drm_fb_helper_unregister_fbi(&afbdev->helper);
266 268
267 if (afb->obj) { 269 if (afb->obj) {
diff --git a/drivers/gpu/drm/bochs/Makefile b/drivers/gpu/drm/bochs/Makefile
index 98ef60a19e8f..e9e0f8f5eb5b 100644
--- a/drivers/gpu/drm/bochs/Makefile
+++ b/drivers/gpu/drm/bochs/Makefile
@@ -1,3 +1,3 @@
1bochs-drm-y := bochs_drv.o bochs_mm.o bochs_kms.o bochs_fbdev.o bochs_hw.o 1bochs-drm-y := bochs_drv.o bochs_mm.o bochs_kms.o bochs_hw.o
2 2
3obj-$(CONFIG_DRM_BOCHS) += bochs-drm.o 3obj-$(CONFIG_DRM_BOCHS) += bochs-drm.o
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index fb38c8b857b5..03711394f1ed 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -80,12 +80,6 @@ struct bochs_device {
80 struct ttm_bo_device bdev; 80 struct ttm_bo_device bdev;
81 bool initialized; 81 bool initialized;
82 } ttm; 82 } ttm;
83
84 /* fbdev */
85 struct {
86 struct drm_framebuffer *fb;
87 struct drm_fb_helper helper;
88 } fb;
89}; 83};
90 84
91struct bochs_bo { 85struct bochs_bo {
@@ -121,8 +115,9 @@ int bochs_hw_init(struct drm_device *dev);
121void bochs_hw_fini(struct drm_device *dev); 115void bochs_hw_fini(struct drm_device *dev);
122 116
123void bochs_hw_setmode(struct bochs_device *bochs, 117void bochs_hw_setmode(struct bochs_device *bochs,
124 struct drm_display_mode *mode, 118 struct drm_display_mode *mode);
125 const struct drm_format_info *format); 119void bochs_hw_setformat(struct bochs_device *bochs,
120 const struct drm_format_info *format);
126void bochs_hw_setbase(struct bochs_device *bochs, 121void bochs_hw_setbase(struct bochs_device *bochs,
127 int x, int y, u64 addr); 122 int x, int y, u64 addr);
128int bochs_hw_load_edid(struct bochs_device *bochs); 123int bochs_hw_load_edid(struct bochs_device *bochs);
@@ -141,15 +136,19 @@ int bochs_dumb_create(struct drm_file *file, struct drm_device *dev,
141int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, 136int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
142 uint32_t handle, uint64_t *offset); 137 uint32_t handle, uint64_t *offset);
143 138
144int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 *gpu_addr); 139int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag);
145int bochs_bo_unpin(struct bochs_bo *bo); 140int bochs_bo_unpin(struct bochs_bo *bo);
146 141
142int bochs_gem_prime_pin(struct drm_gem_object *obj);
143void bochs_gem_prime_unpin(struct drm_gem_object *obj);
144void *bochs_gem_prime_vmap(struct drm_gem_object *obj);
145void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
146int bochs_gem_prime_mmap(struct drm_gem_object *obj,
147 struct vm_area_struct *vma);
148
147/* bochs_kms.c */ 149/* bochs_kms.c */
148int bochs_kms_init(struct bochs_device *bochs); 150int bochs_kms_init(struct bochs_device *bochs);
149void bochs_kms_fini(struct bochs_device *bochs); 151void bochs_kms_fini(struct bochs_device *bochs);
150 152
151/* bochs_fbdev.c */ 153/* bochs_fbdev.c */
152int bochs_fbdev_init(struct bochs_device *bochs);
153void bochs_fbdev_fini(struct bochs_device *bochs);
154
155extern const struct drm_mode_config_funcs bochs_mode_funcs; 154extern const struct drm_mode_config_funcs bochs_mode_funcs;
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index f3dd66ae990a..cea42ac64d7e 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -16,10 +16,6 @@ static int bochs_modeset = -1;
16module_param_named(modeset, bochs_modeset, int, 0444); 16module_param_named(modeset, bochs_modeset, int, 0444);
17MODULE_PARM_DESC(modeset, "enable/disable kernel modesetting"); 17MODULE_PARM_DESC(modeset, "enable/disable kernel modesetting");
18 18
19static bool enable_fbdev = true;
20module_param_named(fbdev, enable_fbdev, bool, 0444);
21MODULE_PARM_DESC(fbdev, "register fbdev device");
22
23/* ---------------------------------------------------------------------- */ 19/* ---------------------------------------------------------------------- */
24/* drm interface */ 20/* drm interface */
25 21
@@ -27,7 +23,6 @@ static void bochs_unload(struct drm_device *dev)
27{ 23{
28 struct bochs_device *bochs = dev->dev_private; 24 struct bochs_device *bochs = dev->dev_private;
29 25
30 bochs_fbdev_fini(bochs);
31 bochs_kms_fini(bochs); 26 bochs_kms_fini(bochs);
32 bochs_mm_fini(bochs); 27 bochs_mm_fini(bochs);
33 bochs_hw_fini(dev); 28 bochs_hw_fini(dev);
@@ -58,9 +53,6 @@ static int bochs_load(struct drm_device *dev)
58 if (ret) 53 if (ret)
59 goto err; 54 goto err;
60 55
61 if (enable_fbdev)
62 bochs_fbdev_init(bochs);
63
64 return 0; 56 return 0;
65 57
66err: 58err:
@@ -81,7 +73,8 @@ static const struct file_operations bochs_fops = {
81}; 73};
82 74
83static struct drm_driver bochs_driver = { 75static struct drm_driver bochs_driver = {
84 .driver_features = DRIVER_GEM | DRIVER_MODESET, 76 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
77 DRIVER_PRIME,
85 .fops = &bochs_fops, 78 .fops = &bochs_fops,
86 .name = "bochs-drm", 79 .name = "bochs-drm",
87 .desc = "bochs dispi vga interface (qemu stdvga)", 80 .desc = "bochs dispi vga interface (qemu stdvga)",
@@ -91,6 +84,14 @@ static struct drm_driver bochs_driver = {
91 .gem_free_object_unlocked = bochs_gem_free_object, 84 .gem_free_object_unlocked = bochs_gem_free_object,
92 .dumb_create = bochs_dumb_create, 85 .dumb_create = bochs_dumb_create,
93 .dumb_map_offset = bochs_dumb_mmap_offset, 86 .dumb_map_offset = bochs_dumb_mmap_offset,
87
88 .gem_prime_export = drm_gem_prime_export,
89 .gem_prime_import = drm_gem_prime_import,
90 .gem_prime_pin = bochs_gem_prime_pin,
91 .gem_prime_unpin = bochs_gem_prime_unpin,
92 .gem_prime_vmap = bochs_gem_prime_vmap,
93 .gem_prime_vunmap = bochs_gem_prime_vunmap,
94 .gem_prime_mmap = bochs_gem_prime_mmap,
94}; 95};
95 96
96/* ---------------------------------------------------------------------- */ 97/* ---------------------------------------------------------------------- */
@@ -101,27 +102,16 @@ static int bochs_pm_suspend(struct device *dev)
101{ 102{
102 struct pci_dev *pdev = to_pci_dev(dev); 103 struct pci_dev *pdev = to_pci_dev(dev);
103 struct drm_device *drm_dev = pci_get_drvdata(pdev); 104 struct drm_device *drm_dev = pci_get_drvdata(pdev);
104 struct bochs_device *bochs = drm_dev->dev_private;
105
106 drm_kms_helper_poll_disable(drm_dev);
107
108 drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 1);
109 105
110 return 0; 106 return drm_mode_config_helper_suspend(drm_dev);
111} 107}
112 108
113static int bochs_pm_resume(struct device *dev) 109static int bochs_pm_resume(struct device *dev)
114{ 110{
115 struct pci_dev *pdev = to_pci_dev(dev); 111 struct pci_dev *pdev = to_pci_dev(dev);
116 struct drm_device *drm_dev = pci_get_drvdata(pdev); 112 struct drm_device *drm_dev = pci_get_drvdata(pdev);
117 struct bochs_device *bochs = drm_dev->dev_private;
118
119 drm_helper_resume_force_mode(drm_dev);
120 113
121 drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 0); 114 return drm_mode_config_helper_resume(drm_dev);
122
123 drm_kms_helper_poll_enable(drm_dev);
124 return 0;
125} 115}
126#endif 116#endif
127 117
@@ -165,6 +155,7 @@ static int bochs_pci_probe(struct pci_dev *pdev,
165 if (ret) 155 if (ret)
166 goto err_unload; 156 goto err_unload;
167 157
158 drm_fbdev_generic_setup(dev, 32);
168 return ret; 159 return ret;
169 160
170err_unload: 161err_unload:
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c
deleted file mode 100644
index dd3c7df267da..000000000000
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ /dev/null
@@ -1,163 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 */
7
8#include "bochs.h"
9#include <drm/drm_gem_framebuffer_helper.h>
10
11/* ---------------------------------------------------------------------- */
12
13static int bochsfb_mmap(struct fb_info *info,
14 struct vm_area_struct *vma)
15{
16 struct drm_fb_helper *fb_helper = info->par;
17 struct bochs_bo *bo = gem_to_bochs_bo(fb_helper->fb->obj[0]);
18
19 return ttm_fbdev_mmap(vma, &bo->bo);
20}
21
22static struct fb_ops bochsfb_ops = {
23 .owner = THIS_MODULE,
24 DRM_FB_HELPER_DEFAULT_OPS,
25 .fb_fillrect = drm_fb_helper_cfb_fillrect,
26 .fb_copyarea = drm_fb_helper_cfb_copyarea,
27 .fb_imageblit = drm_fb_helper_cfb_imageblit,
28 .fb_mmap = bochsfb_mmap,
29};
30
31static int bochsfb_create_object(struct bochs_device *bochs,
32 const struct drm_mode_fb_cmd2 *mode_cmd,
33 struct drm_gem_object **gobj_p)
34{
35 struct drm_device *dev = bochs->dev;
36 struct drm_gem_object *gobj;
37 u32 size;
38 int ret = 0;
39
40 size = mode_cmd->pitches[0] * mode_cmd->height;
41 ret = bochs_gem_create(dev, size, true, &gobj);
42 if (ret)
43 return ret;
44
45 *gobj_p = gobj;
46 return ret;
47}
48
49static int bochsfb_create(struct drm_fb_helper *helper,
50 struct drm_fb_helper_surface_size *sizes)
51{
52 struct bochs_device *bochs =
53 container_of(helper, struct bochs_device, fb.helper);
54 struct fb_info *info;
55 struct drm_framebuffer *fb;
56 struct drm_mode_fb_cmd2 mode_cmd;
57 struct drm_gem_object *gobj = NULL;
58 struct bochs_bo *bo = NULL;
59 int size, ret;
60
61 if (sizes->surface_bpp != 32)
62 return -EINVAL;
63
64 mode_cmd.width = sizes->surface_width;
65 mode_cmd.height = sizes->surface_height;
66 mode_cmd.pitches[0] = sizes->surface_width * 4;
67 mode_cmd.pixel_format = DRM_FORMAT_HOST_XRGB8888;
68 size = mode_cmd.pitches[0] * mode_cmd.height;
69
70 /* alloc, pin & map bo */
71 ret = bochsfb_create_object(bochs, &mode_cmd, &gobj);
72 if (ret) {
73 DRM_ERROR("failed to create fbcon backing object %d\n", ret);
74 return ret;
75 }
76
77 bo = gem_to_bochs_bo(gobj);
78
79 ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
80 if (ret)
81 return ret;
82
83 ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
84 if (ret) {
85 DRM_ERROR("failed to pin fbcon\n");
86 ttm_bo_unreserve(&bo->bo);
87 return ret;
88 }
89
90 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages,
91 &bo->kmap);
92 if (ret) {
93 DRM_ERROR("failed to kmap fbcon\n");
94 ttm_bo_unreserve(&bo->bo);
95 return ret;
96 }
97
98 ttm_bo_unreserve(&bo->bo);
99
100 /* init fb device */
101 info = drm_fb_helper_alloc_fbi(helper);
102 if (IS_ERR(info)) {
103 DRM_ERROR("Failed to allocate fbi: %ld\n", PTR_ERR(info));
104 return PTR_ERR(info);
105 }
106
107 info->par = &bochs->fb.helper;
108
109 fb = drm_gem_fbdev_fb_create(bochs->dev, sizes, 0, gobj, NULL);
110 if (IS_ERR(fb)) {
111 DRM_ERROR("Failed to create framebuffer: %ld\n", PTR_ERR(fb));
112 return PTR_ERR(fb);
113 }
114
115 /* setup helper */
116 bochs->fb.helper.fb = fb;
117
118 strcpy(info->fix.id, "bochsdrmfb");
119
120 info->fbops = &bochsfb_ops;
121
122 drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
123 drm_fb_helper_fill_var(info, &bochs->fb.helper, sizes->fb_width,
124 sizes->fb_height);
125
126 info->screen_base = bo->kmap.virtual;
127 info->screen_size = size;
128
129 drm_vma_offset_remove(&bo->bo.bdev->vma_manager, &bo->bo.vma_node);
130 info->fix.smem_start = 0;
131 info->fix.smem_len = size;
132 return 0;
133}
134
135static const struct drm_fb_helper_funcs bochs_fb_helper_funcs = {
136 .fb_probe = bochsfb_create,
137};
138
139static struct drm_framebuffer *
140bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file,
141 const struct drm_mode_fb_cmd2 *mode_cmd)
142{
143 if (mode_cmd->pixel_format != DRM_FORMAT_XRGB8888 &&
144 mode_cmd->pixel_format != DRM_FORMAT_BGRX8888)
145 return ERR_PTR(-EINVAL);
146
147 return drm_gem_fb_create(dev, file, mode_cmd);
148}
149
150const struct drm_mode_config_funcs bochs_mode_funcs = {
151 .fb_create = bochs_gem_fb_create,
152};
153
154int bochs_fbdev_init(struct bochs_device *bochs)
155{
156 return drm_fb_helper_fbdev_setup(bochs->dev, &bochs->fb.helper,
157 &bochs_fb_helper_funcs, 32, 1);
158}
159
160void bochs_fbdev_fini(struct bochs_device *bochs)
161{
162 drm_fb_helper_fbdev_teardown(bochs->dev);
163}
diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c
index d0b4e1cee83e..3e04b2f0ec08 100644
--- a/drivers/gpu/drm/bochs/bochs_hw.c
+++ b/drivers/gpu/drm/bochs/bochs_hw.c
@@ -204,8 +204,7 @@ void bochs_hw_fini(struct drm_device *dev)
204} 204}
205 205
206void bochs_hw_setmode(struct bochs_device *bochs, 206void bochs_hw_setmode(struct bochs_device *bochs,
207 struct drm_display_mode *mode, 207 struct drm_display_mode *mode)
208 const struct drm_format_info *format)
209{ 208{
210 bochs->xres = mode->hdisplay; 209 bochs->xres = mode->hdisplay;
211 bochs->yres = mode->vdisplay; 210 bochs->yres = mode->vdisplay;
@@ -213,12 +212,8 @@ void bochs_hw_setmode(struct bochs_device *bochs,
213 bochs->stride = mode->hdisplay * (bochs->bpp / 8); 212 bochs->stride = mode->hdisplay * (bochs->bpp / 8);
214 bochs->yres_virtual = bochs->fb_size / bochs->stride; 213 bochs->yres_virtual = bochs->fb_size / bochs->stride;
215 214
216 DRM_DEBUG_DRIVER("%dx%d @ %d bpp, format %c%c%c%c, vy %d\n", 215 DRM_DEBUG_DRIVER("%dx%d @ %d bpp, vy %d\n",
217 bochs->xres, bochs->yres, bochs->bpp, 216 bochs->xres, bochs->yres, bochs->bpp,
218 (format->format >> 0) & 0xff,
219 (format->format >> 8) & 0xff,
220 (format->format >> 16) & 0xff,
221 (format->format >> 24) & 0xff,
222 bochs->yres_virtual); 217 bochs->yres_virtual);
223 218
224 bochs_vga_writeb(bochs, 0x3c0, 0x20); /* unblank */ 219 bochs_vga_writeb(bochs, 0x3c0, 0x20); /* unblank */
@@ -236,6 +231,16 @@ void bochs_hw_setmode(struct bochs_device *bochs,
236 231
237 bochs_dispi_write(bochs, VBE_DISPI_INDEX_ENABLE, 232 bochs_dispi_write(bochs, VBE_DISPI_INDEX_ENABLE,
238 VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED); 233 VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
234}
235
236void bochs_hw_setformat(struct bochs_device *bochs,
237 const struct drm_format_info *format)
238{
239 DRM_DEBUG_DRIVER("format %c%c%c%c\n",
240 (format->format >> 0) & 0xff,
241 (format->format >> 8) & 0xff,
242 (format->format >> 16) & 0xff,
243 (format->format >> 24) & 0xff);
239 244
240 switch (format->format) { 245 switch (format->format) {
241 case DRM_FORMAT_XRGB8888: 246 case DRM_FORMAT_XRGB8888:
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index f87c284dd93d..e9d5dbc34676 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -6,7 +6,10 @@
6 */ 6 */
7 7
8#include "bochs.h" 8#include "bochs.h"
9#include <drm/drm_atomic_helper.h>
9#include <drm/drm_plane_helper.h> 10#include <drm/drm_plane_helper.h>
11#include <drm/drm_atomic_uapi.h>
12#include <drm/drm_gem_framebuffer_helper.h>
10 13
11static int defx = 1024; 14static int defx = 1024;
12static int defy = 768; 15static int defy = 768;
@@ -18,115 +21,51 @@ MODULE_PARM_DESC(defy, "default y resolution");
18 21
19/* ---------------------------------------------------------------------- */ 22/* ---------------------------------------------------------------------- */
20 23
21static void bochs_crtc_dpms(struct drm_crtc *crtc, int mode) 24static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc)
22{
23 switch (mode) {
24 case DRM_MODE_DPMS_ON:
25 case DRM_MODE_DPMS_STANDBY:
26 case DRM_MODE_DPMS_SUSPEND:
27 case DRM_MODE_DPMS_OFF:
28 default:
29 return;
30 }
31}
32
33static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
34 struct drm_framebuffer *old_fb)
35{
36 struct bochs_device *bochs =
37 container_of(crtc, struct bochs_device, crtc);
38 struct bochs_bo *bo;
39 u64 gpu_addr = 0;
40 int ret;
41
42 if (old_fb) {
43 bo = gem_to_bochs_bo(old_fb->obj[0]);
44 ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
45 if (ret) {
46 DRM_ERROR("failed to reserve old_fb bo\n");
47 } else {
48 bochs_bo_unpin(bo);
49 ttm_bo_unreserve(&bo->bo);
50 }
51 }
52
53 if (WARN_ON(crtc->primary->fb == NULL))
54 return -EINVAL;
55
56 bo = gem_to_bochs_bo(crtc->primary->fb->obj[0]);
57 ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
58 if (ret)
59 return ret;
60
61 ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
62 if (ret) {
63 ttm_bo_unreserve(&bo->bo);
64 return ret;
65 }
66
67 ttm_bo_unreserve(&bo->bo);
68 bochs_hw_setbase(bochs, x, y, gpu_addr);
69 return 0;
70}
71
72static int bochs_crtc_mode_set(struct drm_crtc *crtc,
73 struct drm_display_mode *mode,
74 struct drm_display_mode *adjusted_mode,
75 int x, int y, struct drm_framebuffer *old_fb)
76{ 25{
77 struct bochs_device *bochs = 26 struct bochs_device *bochs =
78 container_of(crtc, struct bochs_device, crtc); 27 container_of(crtc, struct bochs_device, crtc);
79 28
80 if (WARN_ON(crtc->primary->fb == NULL)) 29 bochs_hw_setmode(bochs, &crtc->mode);
81 return -EINVAL;
82
83 bochs_hw_setmode(bochs, mode, crtc->primary->fb->format);
84 bochs_crtc_mode_set_base(crtc, x, y, old_fb);
85 return 0;
86} 30}
87 31
88static void bochs_crtc_prepare(struct drm_crtc *crtc) 32static void bochs_crtc_atomic_enable(struct drm_crtc *crtc,
33 struct drm_crtc_state *old_crtc_state)
89{ 34{
90} 35}
91 36
92static void bochs_crtc_commit(struct drm_crtc *crtc) 37static void bochs_crtc_atomic_flush(struct drm_crtc *crtc,
38 struct drm_crtc_state *old_crtc_state)
93{ 39{
94} 40 struct drm_device *dev = crtc->dev;
41 struct drm_pending_vblank_event *event;
95 42
96static int bochs_crtc_page_flip(struct drm_crtc *crtc, 43 if (crtc->state && crtc->state->event) {
97 struct drm_framebuffer *fb, 44 unsigned long irqflags;
98 struct drm_pending_vblank_event *event,
99 uint32_t page_flip_flags,
100 struct drm_modeset_acquire_ctx *ctx)
101{
102 struct bochs_device *bochs =
103 container_of(crtc, struct bochs_device, crtc);
104 struct drm_framebuffer *old_fb = crtc->primary->fb;
105 unsigned long irqflags;
106 45
107 crtc->primary->fb = fb; 46 spin_lock_irqsave(&dev->event_lock, irqflags);
108 bochs_crtc_mode_set_base(crtc, 0, 0, old_fb); 47 event = crtc->state->event;
109 if (event) { 48 crtc->state->event = NULL;
110 spin_lock_irqsave(&bochs->dev->event_lock, irqflags);
111 drm_crtc_send_vblank_event(crtc, event); 49 drm_crtc_send_vblank_event(crtc, event);
112 spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags); 50 spin_unlock_irqrestore(&dev->event_lock, irqflags);
113 } 51 }
114 return 0;
115} 52}
116 53
54
117/* These provide the minimum set of functions required to handle a CRTC */ 55/* These provide the minimum set of functions required to handle a CRTC */
118static const struct drm_crtc_funcs bochs_crtc_funcs = { 56static const struct drm_crtc_funcs bochs_crtc_funcs = {
119 .set_config = drm_crtc_helper_set_config, 57 .set_config = drm_atomic_helper_set_config,
120 .destroy = drm_crtc_cleanup, 58 .destroy = drm_crtc_cleanup,
121 .page_flip = bochs_crtc_page_flip, 59 .page_flip = drm_atomic_helper_page_flip,
60 .reset = drm_atomic_helper_crtc_reset,
61 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
62 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
122}; 63};
123 64
124static const struct drm_crtc_helper_funcs bochs_helper_funcs = { 65static const struct drm_crtc_helper_funcs bochs_helper_funcs = {
125 .dpms = bochs_crtc_dpms, 66 .mode_set_nofb = bochs_crtc_mode_set_nofb,
126 .mode_set = bochs_crtc_mode_set, 67 .atomic_enable = bochs_crtc_atomic_enable,
127 .mode_set_base = bochs_crtc_mode_set_base, 68 .atomic_flush = bochs_crtc_atomic_flush,
128 .prepare = bochs_crtc_prepare,
129 .commit = bochs_crtc_commit,
130}; 69};
131 70
132static const uint32_t bochs_formats[] = { 71static const uint32_t bochs_formats[] = {
@@ -134,6 +73,59 @@ static const uint32_t bochs_formats[] = {
134 DRM_FORMAT_BGRX8888, 73 DRM_FORMAT_BGRX8888,
135}; 74};
136 75
76static void bochs_plane_atomic_update(struct drm_plane *plane,
77 struct drm_plane_state *old_state)
78{
79 struct bochs_device *bochs = plane->dev->dev_private;
80 struct bochs_bo *bo;
81
82 if (!plane->state->fb)
83 return;
84 bo = gem_to_bochs_bo(plane->state->fb->obj[0]);
85 bochs_hw_setbase(bochs,
86 plane->state->crtc_x,
87 plane->state->crtc_y,
88 bo->bo.offset);
89 bochs_hw_setformat(bochs, plane->state->fb->format);
90}
91
92static int bochs_plane_prepare_fb(struct drm_plane *plane,
93 struct drm_plane_state *new_state)
94{
95 struct bochs_bo *bo;
96
97 if (!new_state->fb)
98 return 0;
99 bo = gem_to_bochs_bo(new_state->fb->obj[0]);
100 return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
101}
102
103static void bochs_plane_cleanup_fb(struct drm_plane *plane,
104 struct drm_plane_state *old_state)
105{
106 struct bochs_bo *bo;
107
108 if (!old_state->fb)
109 return;
110 bo = gem_to_bochs_bo(old_state->fb->obj[0]);
111 bochs_bo_unpin(bo);
112}
113
114static const struct drm_plane_helper_funcs bochs_plane_helper_funcs = {
115 .atomic_update = bochs_plane_atomic_update,
116 .prepare_fb = bochs_plane_prepare_fb,
117 .cleanup_fb = bochs_plane_cleanup_fb,
118};
119
120static const struct drm_plane_funcs bochs_plane_funcs = {
121 .update_plane = drm_atomic_helper_update_plane,
122 .disable_plane = drm_atomic_helper_disable_plane,
123 .destroy = drm_primary_helper_destroy,
124 .reset = drm_atomic_helper_plane_reset,
125 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
126 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
127};
128
137static struct drm_plane *bochs_primary_plane(struct drm_device *dev) 129static struct drm_plane *bochs_primary_plane(struct drm_device *dev)
138{ 130{
139 struct drm_plane *primary; 131 struct drm_plane *primary;
@@ -146,16 +138,17 @@ static struct drm_plane *bochs_primary_plane(struct drm_device *dev)
146 } 138 }
147 139
148 ret = drm_universal_plane_init(dev, primary, 0, 140 ret = drm_universal_plane_init(dev, primary, 0,
149 &drm_primary_helper_funcs, 141 &bochs_plane_funcs,
150 bochs_formats, 142 bochs_formats,
151 ARRAY_SIZE(bochs_formats), 143 ARRAY_SIZE(bochs_formats),
152 NULL, 144 NULL,
153 DRM_PLANE_TYPE_PRIMARY, NULL); 145 DRM_PLANE_TYPE_PRIMARY, NULL);
154 if (ret) { 146 if (ret) {
155 kfree(primary); 147 kfree(primary);
156 primary = NULL; 148 return NULL;
157 } 149 }
158 150
151 drm_plane_helper_add(primary, &bochs_plane_helper_funcs);
159 return primary; 152 return primary;
160} 153}
161 154
@@ -170,31 +163,6 @@ static void bochs_crtc_init(struct drm_device *dev)
170 drm_crtc_helper_add(crtc, &bochs_helper_funcs); 163 drm_crtc_helper_add(crtc, &bochs_helper_funcs);
171} 164}
172 165
173static void bochs_encoder_mode_set(struct drm_encoder *encoder,
174 struct drm_display_mode *mode,
175 struct drm_display_mode *adjusted_mode)
176{
177}
178
179static void bochs_encoder_dpms(struct drm_encoder *encoder, int state)
180{
181}
182
183static void bochs_encoder_prepare(struct drm_encoder *encoder)
184{
185}
186
187static void bochs_encoder_commit(struct drm_encoder *encoder)
188{
189}
190
191static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = {
192 .dpms = bochs_encoder_dpms,
193 .mode_set = bochs_encoder_mode_set,
194 .prepare = bochs_encoder_prepare,
195 .commit = bochs_encoder_commit,
196};
197
198static const struct drm_encoder_funcs bochs_encoder_encoder_funcs = { 166static const struct drm_encoder_funcs bochs_encoder_encoder_funcs = {
199 .destroy = drm_encoder_cleanup, 167 .destroy = drm_encoder_cleanup,
200}; 168};
@@ -207,7 +175,6 @@ static void bochs_encoder_init(struct drm_device *dev)
207 encoder->possible_crtcs = 0x1; 175 encoder->possible_crtcs = 0x1;
208 drm_encoder_init(dev, encoder, &bochs_encoder_encoder_funcs, 176 drm_encoder_init(dev, encoder, &bochs_encoder_encoder_funcs,
209 DRM_MODE_ENCODER_DAC, NULL); 177 DRM_MODE_ENCODER_DAC, NULL);
210 drm_encoder_helper_add(encoder, &bochs_encoder_helper_funcs);
211} 178}
212 179
213 180
@@ -266,6 +233,9 @@ static const struct drm_connector_funcs bochs_connector_connector_funcs = {
266 .dpms = drm_helper_connector_dpms, 233 .dpms = drm_helper_connector_dpms,
267 .fill_modes = drm_helper_probe_single_connector_modes, 234 .fill_modes = drm_helper_probe_single_connector_modes,
268 .destroy = drm_connector_cleanup, 235 .destroy = drm_connector_cleanup,
236 .reset = drm_atomic_helper_connector_reset,
237 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
238 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
269}; 239};
270 240
271static void bochs_connector_init(struct drm_device *dev) 241static void bochs_connector_init(struct drm_device *dev)
@@ -287,6 +257,22 @@ static void bochs_connector_init(struct drm_device *dev)
287 } 257 }
288} 258}
289 259
260static struct drm_framebuffer *
261bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file,
262 const struct drm_mode_fb_cmd2 *mode_cmd)
263{
264 if (mode_cmd->pixel_format != DRM_FORMAT_XRGB8888 &&
265 mode_cmd->pixel_format != DRM_FORMAT_BGRX8888)
266 return ERR_PTR(-EINVAL);
267
268 return drm_gem_fb_create(dev, file, mode_cmd);
269}
270
271const struct drm_mode_config_funcs bochs_mode_funcs = {
272 .fb_create = bochs_gem_fb_create,
273 .atomic_check = drm_atomic_helper_check,
274 .atomic_commit = drm_atomic_helper_commit,
275};
290 276
291int bochs_kms_init(struct bochs_device *bochs) 277int bochs_kms_init(struct bochs_device *bochs)
292{ 278{
@@ -309,6 +295,8 @@ int bochs_kms_init(struct bochs_device *bochs)
309 drm_connector_attach_encoder(&bochs->connector, 295 drm_connector_attach_encoder(&bochs->connector,
310 &bochs->encoder); 296 &bochs->encoder);
311 297
298 drm_mode_config_reset(bochs->dev);
299
312 return 0; 300 return 0;
313} 301}
314 302
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c
index 0980411e41bf..641a33f134ee 100644
--- a/drivers/gpu/drm/bochs/bochs_mm.c
+++ b/drivers/gpu/drm/bochs/bochs_mm.c
@@ -210,33 +210,28 @@ static void bochs_ttm_placement(struct bochs_bo *bo, int domain)
210 bo->placement.num_busy_placement = c; 210 bo->placement.num_busy_placement = c;
211} 211}
212 212
213static inline u64 bochs_bo_gpu_offset(struct bochs_bo *bo) 213int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag)
214{
215 return bo->bo.offset;
216}
217
218int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 *gpu_addr)
219{ 214{
220 struct ttm_operation_ctx ctx = { false, false }; 215 struct ttm_operation_ctx ctx = { false, false };
221 int i, ret; 216 int i, ret;
222 217
223 if (bo->pin_count) { 218 if (bo->pin_count) {
224 bo->pin_count++; 219 bo->pin_count++;
225 if (gpu_addr)
226 *gpu_addr = bochs_bo_gpu_offset(bo);
227 return 0; 220 return 0;
228 } 221 }
229 222
230 bochs_ttm_placement(bo, pl_flag); 223 bochs_ttm_placement(bo, pl_flag);
231 for (i = 0; i < bo->placement.num_placement; i++) 224 for (i = 0; i < bo->placement.num_placement; i++)
232 bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; 225 bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
226 ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
227 if (ret)
228 return ret;
233 ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); 229 ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
230 ttm_bo_unreserve(&bo->bo);
234 if (ret) 231 if (ret)
235 return ret; 232 return ret;
236 233
237 bo->pin_count = 1; 234 bo->pin_count = 1;
238 if (gpu_addr)
239 *gpu_addr = bochs_bo_gpu_offset(bo);
240 return 0; 235 return 0;
241} 236}
242 237
@@ -256,7 +251,11 @@ int bochs_bo_unpin(struct bochs_bo *bo)
256 251
257 for (i = 0; i < bo->placement.num_placement; i++) 252 for (i = 0; i < bo->placement.num_placement; i++)
258 bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; 253 bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
254 ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
255 if (ret)
256 return ret;
259 ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); 257 ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
258 ttm_bo_unreserve(&bo->bo);
260 if (ret) 259 if (ret)
261 return ret; 260 return ret;
262 261
@@ -396,3 +395,52 @@ int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
396 drm_gem_object_put_unlocked(obj); 395 drm_gem_object_put_unlocked(obj);
397 return 0; 396 return 0;
398} 397}
398
399/* ---------------------------------------------------------------------- */
400
401int bochs_gem_prime_pin(struct drm_gem_object *obj)
402{
403 struct bochs_bo *bo = gem_to_bochs_bo(obj);
404
405 return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
406}
407
408void bochs_gem_prime_unpin(struct drm_gem_object *obj)
409{
410 struct bochs_bo *bo = gem_to_bochs_bo(obj);
411
412 bochs_bo_unpin(bo);
413}
414
415void *bochs_gem_prime_vmap(struct drm_gem_object *obj)
416{
417 struct bochs_bo *bo = gem_to_bochs_bo(obj);
418 bool is_iomem;
419 int ret;
420
421 ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
422 if (ret)
423 return NULL;
424 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
425 if (ret) {
426 bochs_bo_unpin(bo);
427 return NULL;
428 }
429 return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
430}
431
432void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
433{
434 struct bochs_bo *bo = gem_to_bochs_bo(obj);
435
436 ttm_bo_kunmap(&bo->kmap);
437 bochs_bo_unpin(bo);
438}
439
440int bochs_gem_prime_mmap(struct drm_gem_object *obj,
441 struct vm_area_struct *vma)
442{
443 struct bochs_bo *bo = gem_to_bochs_bo(obj);
444
445 return ttm_fbdev_mmap(vma, &bo->bo);
446}
diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c
index 705620e9f505..4cf7bc17ae14 100644
--- a/drivers/gpu/drm/bridge/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c
@@ -1094,8 +1094,9 @@ static void anx78xx_bridge_mode_set(struct drm_bridge *bridge,
1094 1094
1095 mutex_lock(&anx78xx->lock); 1095 mutex_lock(&anx78xx->lock);
1096 1096
1097 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, adjusted_mode, 1097 err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
1098 false); 1098 &anx78xx->connector,
1099 adjusted_mode);
1099 if (err) { 1100 if (err) {
1100 DRM_ERROR("Failed to setup AVI infoframe: %d\n", err); 1101 DRM_ERROR("Failed to setup AVI infoframe: %d\n", err);
1101 goto unlock; 1102 goto unlock;
diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 7cbaba213ef6..37baa79e95c3 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -134,8 +134,8 @@ static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
134}; 134};
135 135
136/** 136/**
137 * drm_panel_bridge_add - Creates a drm_bridge and drm_connector that 137 * drm_panel_bridge_add - Creates a &drm_bridge and &drm_connector that
138 * just calls the appropriate functions from drm_panel. 138 * just calls the appropriate functions from &drm_panel.
139 * 139 *
140 * @panel: The drm_panel being wrapped. Must be non-NULL. 140 * @panel: The drm_panel being wrapped. Must be non-NULL.
141 * @connector_type: The DRM_MODE_CONNECTOR_* for the connector to be 141 * @connector_type: The DRM_MODE_CONNECTOR_* for the connector to be
@@ -149,9 +149,12 @@ static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
149 * passed to drm_bridge_attach(). The drm_panel_prepare() and related 149 * passed to drm_bridge_attach(). The drm_panel_prepare() and related
150 * functions can be dropped from the encoder driver (they're now 150 * functions can be dropped from the encoder driver (they're now
151 * called by the KMS helpers before calling into the encoder), along 151 * called by the KMS helpers before calling into the encoder), along
152 * with connector creation. When done with the bridge, 152 * with connector creation. When done with the bridge (after
153 * drm_bridge_detach() should be called as normal, then 153 * drm_mode_config_cleanup() if the bridge has already been attached), then
154 * drm_panel_bridge_remove() to free it. 154 * drm_panel_bridge_remove() to free it.
155 *
156 * See devm_drm_panel_bridge_add() for an automatically manged version of this
157 * function.
155 */ 158 */
156struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel, 159struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
157 u32 connector_type) 160 u32 connector_type)
@@ -210,6 +213,17 @@ static void devm_drm_panel_bridge_release(struct device *dev, void *res)
210 drm_panel_bridge_remove(*bridge); 213 drm_panel_bridge_remove(*bridge);
211} 214}
212 215
216/**
217 * devm_drm_panel_bridge_add - Creates a managed &drm_bridge and &drm_connector
218 * that just calls the appropriate functions from &drm_panel.
219 * @dev: device to tie the bridge lifetime to
220 * @panel: The drm_panel being wrapped. Must be non-NULL.
221 * @connector_type: The DRM_MODE_CONNECTOR_* for the connector to be
222 * created.
223 *
224 * This is the managed version of drm_panel_bridge_add() which automatically
225 * calls drm_panel_bridge_remove() when @dev is unbound.
226 */
213struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, 227struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
214 struct drm_panel *panel, 228 struct drm_panel *panel,
215 u32 connector_type) 229 u32 connector_type)
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index a0b3a568dd9c..a5d58f7035c1 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -258,7 +258,8 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
258 if (ret) 258 if (ret)
259 return; 259 return;
260 260
261 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, adj, false); 261 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
262 &sii902x->connector, adj);
262 if (ret < 0) { 263 if (ret < 0) {
263 DRM_ERROR("couldn't fill AVI infoframe\n"); 264 DRM_ERROR("couldn't fill AVI infoframe\n");
264 return; 265 return;
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index a6e8f4591e63..0cc293a6ac24 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -1104,8 +1104,7 @@ static void sii8620_set_infoframes(struct sii8620 *ctx,
1104 int ret; 1104 int ret;
1105 1105
1106 ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi, 1106 ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
1107 mode, 1107 NULL, mode);
1108 true);
1109 if (ctx->use_packed_pixel) 1108 if (ctx->use_packed_pixel)
1110 frm.avi.colorspace = HDMI_COLORSPACE_YUV422; 1109 frm.avi.colorspace = HDMI_COLORSPACE_YUV422;
1111 1110
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 2228689d9a5e..5cbb71a866d5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -5,6 +5,10 @@
5 * Copyright (c) 2017 Renesas Solutions Corp. 5 * Copyright (c) 2017 Renesas Solutions Corp.
6 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 */ 7 */
8
9#include <linux/dma-mapping.h>
10#include <linux/module.h>
11
8#include <drm/bridge/dw_hdmi.h> 12#include <drm/bridge/dw_hdmi.h>
9 13
10#include <sound/hdmi-codec.h> 14#include <sound/hdmi-codec.h>
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 4fed3eda6ded..129f464cbeb1 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1344,7 +1344,8 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
1344 u8 val; 1344 u8 val;
1345 1345
1346 /* Initialise info frame from DRM mode */ 1346 /* Initialise info frame from DRM mode */
1347 drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 1347 drm_hdmi_avi_infoframe_from_display_mode(&frame,
1348 &hdmi->connector, mode);
1348 1349
1349 if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) 1350 if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
1350 frame.colorspace = HDMI_COLORSPACE_YUV444; 1351 frame.colorspace = HDMI_COLORSPACE_YUV444;
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 4dd499c7d1ba..39df62acac69 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -10,6 +10,7 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <drm/drmP.h> 12#include <drm/drmP.h>
13#include <drm/drm_util.h>
13#include <drm/drm_fb_helper.h> 14#include <drm/drm_fb_helper.h>
14#include <drm/drm_crtc_helper.h> 15#include <drm/drm_crtc_helper.h>
15 16
@@ -256,6 +257,8 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
256{ 257{
257 struct drm_framebuffer *gfb = gfbdev->gfb; 258 struct drm_framebuffer *gfb = gfbdev->gfb;
258 259
260 drm_helper_force_disable_all(dev);
261
259 drm_fb_helper_unregister_fbi(&gfbdev->helper); 262 drm_fb_helper_unregister_fbi(&gfbdev->helper);
260 263
261 vfree(gfbdev->sysram); 264 vfree(gfbdev->sysram);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1593dd6cdfb7..7dabbaf033a1 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -93,15 +93,6 @@ struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx)
93} 93}
94EXPORT_SYMBOL(drm_crtc_from_index); 94EXPORT_SYMBOL(drm_crtc_from_index);
95 95
96/**
97 * drm_crtc_force_disable - Forcibly turn off a CRTC
98 * @crtc: CRTC to turn off
99 *
100 * Note: This should only be used by non-atomic legacy drivers.
101 *
102 * Returns:
103 * Zero on success, error code on failure.
104 */
105int drm_crtc_force_disable(struct drm_crtc *crtc) 96int drm_crtc_force_disable(struct drm_crtc *crtc)
106{ 97{
107 struct drm_mode_set set = { 98 struct drm_mode_set set = {
@@ -112,38 +103,6 @@ int drm_crtc_force_disable(struct drm_crtc *crtc)
112 103
113 return drm_mode_set_config_internal(&set); 104 return drm_mode_set_config_internal(&set);
114} 105}
115EXPORT_SYMBOL(drm_crtc_force_disable);
116
117/**
118 * drm_crtc_force_disable_all - Forcibly turn off all enabled CRTCs
119 * @dev: DRM device whose CRTCs to turn off
120 *
121 * Drivers may want to call this on unload to ensure that all displays are
122 * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
123 *
124 * Note: This should only be used by non-atomic legacy drivers. For an atomic
125 * version look at drm_atomic_helper_shutdown().
126 *
127 * Returns:
128 * Zero on success, error code on failure.
129 */
130int drm_crtc_force_disable_all(struct drm_device *dev)
131{
132 struct drm_crtc *crtc;
133 int ret = 0;
134
135 drm_modeset_lock_all(dev);
136 drm_for_each_crtc(crtc, dev)
137 if (crtc->enabled) {
138 ret = drm_crtc_force_disable(crtc);
139 if (ret)
140 goto out;
141 }
142out:
143 drm_modeset_unlock_all(dev);
144 return ret;
145}
146EXPORT_SYMBOL(drm_crtc_force_disable_all);
147 106
148static unsigned int drm_num_crtcs(struct drm_device *dev) 107static unsigned int drm_num_crtcs(struct drm_device *dev)
149{ 108{
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index a3c81850e755..747661f63fbb 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -93,6 +93,8 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
93 struct drm_connector_list_iter conn_iter; 93 struct drm_connector_list_iter conn_iter;
94 struct drm_device *dev = encoder->dev; 94 struct drm_device *dev = encoder->dev;
95 95
96 WARN_ON(drm_drv_uses_atomic_modeset(dev));
97
96 /* 98 /*
97 * We can expect this mutex to be locked if we are not panicking. 99 * We can expect this mutex to be locked if we are not panicking.
98 * Locking is currently fubar in the panic handler. 100 * Locking is currently fubar in the panic handler.
@@ -131,6 +133,8 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
131 struct drm_encoder *encoder; 133 struct drm_encoder *encoder;
132 struct drm_device *dev = crtc->dev; 134 struct drm_device *dev = crtc->dev;
133 135
136 WARN_ON(drm_drv_uses_atomic_modeset(dev));
137
134 /* 138 /*
135 * We can expect this mutex to be locked if we are not panicking. 139 * We can expect this mutex to be locked if we are not panicking.
136 * Locking is currently fubar in the panic handler. 140 * Locking is currently fubar in the panic handler.
@@ -212,8 +216,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
212 */ 216 */
213void drm_helper_disable_unused_functions(struct drm_device *dev) 217void drm_helper_disable_unused_functions(struct drm_device *dev)
214{ 218{
215 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) 219 WARN_ON(drm_drv_uses_atomic_modeset(dev));
216 DRM_ERROR("Called for atomic driver, this is not what you want.\n");
217 220
218 drm_modeset_lock_all(dev); 221 drm_modeset_lock_all(dev);
219 __drm_helper_disable_unused_functions(dev); 222 __drm_helper_disable_unused_functions(dev);
@@ -281,6 +284,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
281 struct drm_encoder *encoder; 284 struct drm_encoder *encoder;
282 bool ret = true; 285 bool ret = true;
283 286
287 WARN_ON(drm_drv_uses_atomic_modeset(dev));
288
284 drm_warn_on_modeset_not_all_locked(dev); 289 drm_warn_on_modeset_not_all_locked(dev);
285 290
286 saved_enabled = crtc->enabled; 291 saved_enabled = crtc->enabled;
@@ -386,9 +391,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
386 if (!encoder_funcs) 391 if (!encoder_funcs)
387 continue; 392 continue;
388 393
389 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", 394 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%s]\n",
390 encoder->base.id, encoder->name, 395 encoder->base.id, encoder->name, mode->name);
391 mode->base.id, mode->name);
392 if (encoder_funcs->mode_set) 396 if (encoder_funcs->mode_set)
393 encoder_funcs->mode_set(encoder, mode, adjusted_mode); 397 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
394 398
@@ -540,6 +544,9 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set,
540 544
541 crtc_funcs = set->crtc->helper_private; 545 crtc_funcs = set->crtc->helper_private;
542 546
547 dev = set->crtc->dev;
548 WARN_ON(drm_drv_uses_atomic_modeset(dev));
549
543 if (!set->mode) 550 if (!set->mode)
544 set->fb = NULL; 551 set->fb = NULL;
545 552
@@ -555,8 +562,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set,
555 return 0; 562 return 0;
556 } 563 }
557 564
558 dev = set->crtc->dev;
559
560 drm_warn_on_modeset_not_all_locked(dev); 565 drm_warn_on_modeset_not_all_locked(dev);
561 566
562 /* 567 /*
@@ -875,6 +880,8 @@ int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
875 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; 880 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
876 int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF; 881 int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
877 882
883 WARN_ON(drm_drv_uses_atomic_modeset(connector->dev));
884
878 if (mode == connector->dpms) 885 if (mode == connector->dpms)
879 return 0; 886 return 0;
880 887
@@ -946,6 +953,8 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
946 int encoder_dpms; 953 int encoder_dpms;
947 bool ret; 954 bool ret;
948 955
956 WARN_ON(drm_drv_uses_atomic_modeset(dev));
957
949 drm_modeset_lock_all(dev); 958 drm_modeset_lock_all(dev);
950 drm_for_each_crtc(crtc, dev) { 959 drm_for_each_crtc(crtc, dev) {
951 960
@@ -984,3 +993,38 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
984 drm_modeset_unlock_all(dev); 993 drm_modeset_unlock_all(dev);
985} 994}
986EXPORT_SYMBOL(drm_helper_resume_force_mode); 995EXPORT_SYMBOL(drm_helper_resume_force_mode);
996
997/**
998 * drm_helper_force_disable_all - Forcibly turn off all enabled CRTCs
999 * @dev: DRM device whose CRTCs to turn off
1000 *
1001 * Drivers may want to call this on unload to ensure that all displays are
1002 * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
1003 *
1004 * Note: This should only be used by non-atomic legacy drivers. For an atomic
1005 * version look at drm_atomic_helper_shutdown().
1006 *
1007 * Returns:
1008 * Zero on success, error code on failure.
1009 */
1010int drm_helper_force_disable_all(struct drm_device *dev)
1011{
1012 struct drm_crtc *crtc;
1013 int ret = 0;
1014
1015 drm_modeset_lock_all(dev);
1016 drm_for_each_crtc(crtc, dev)
1017 if (crtc->enabled) {
1018 struct drm_mode_set set = {
1019 .crtc = crtc,
1020 };
1021
1022 ret = drm_mode_set_config_internal(&set);
1023 if (ret)
1024 goto out;
1025 }
1026out:
1027 drm_modeset_unlock_all(dev);
1028 return ret;
1029}
1030EXPORT_SYMBOL(drm_helper_force_disable_all);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 86893448f486..216f2a9ee3d4 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -50,6 +50,7 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
50 const struct drm_framebuffer *fb); 50 const struct drm_framebuffer *fb);
51int drm_crtc_register_all(struct drm_device *dev); 51int drm_crtc_register_all(struct drm_device *dev);
52void drm_crtc_unregister_all(struct drm_device *dev); 52void drm_crtc_unregister_all(struct drm_device *dev);
53int drm_crtc_force_disable(struct drm_crtc *crtc);
53 54
54struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc); 55struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
55 56
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 2d6c491a0542..f51a116543f7 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -154,6 +154,7 @@ u8 drm_dp_link_rate_to_bw_code(int link_rate)
154 default: 154 default:
155 WARN(1, "unknown DP link rate %d, using %x\n", link_rate, 155 WARN(1, "unknown DP link rate %d, using %x\n", link_rate,
156 DP_LINK_BW_1_62); 156 DP_LINK_BW_1_62);
157 /* fall through */
157 case 162000: 158 case 162000:
158 return DP_LINK_BW_1_62; 159 return DP_LINK_BW_1_62;
159 case 270000: 160 case 270000:
@@ -171,6 +172,7 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw)
171 switch (link_bw) { 172 switch (link_bw) {
172 default: 173 default:
173 WARN(1, "unknown DP link BW code %x, using 162000\n", link_bw); 174 WARN(1, "unknown DP link BW code %x, using 162000\n", link_bw);
175 /* fall through */
174 case DP_LINK_BW_1_62: 176 case DP_LINK_BW_1_62:
175 return 162000; 177 return 162000;
176 case DP_LINK_BW_2_7: 178 case DP_LINK_BW_2_7:
@@ -552,6 +554,7 @@ int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
552 case DP_DS_16BPC: 554 case DP_DS_16BPC:
553 return 16; 555 return 16;
554 } 556 }
557 /* fall through */
555 default: 558 default:
556 return 0; 559 return 0;
557 } 560 }
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 2ab16c9e6243..196ebba8af5f 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -46,7 +46,7 @@ static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
46 char *buf); 46 char *buf);
47static int test_calc_pbn_mode(void); 47static int test_calc_pbn_mode(void);
48 48
49static void drm_dp_put_port(struct drm_dp_mst_port *port); 49static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port);
50 50
51static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr, 51static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
52 int id, 52 int id,
@@ -850,46 +850,212 @@ static struct drm_dp_mst_branch *drm_dp_add_mst_branch_device(u8 lct, u8 *rad)
850 if (lct > 1) 850 if (lct > 1)
851 memcpy(mstb->rad, rad, lct / 2); 851 memcpy(mstb->rad, rad, lct / 2);
852 INIT_LIST_HEAD(&mstb->ports); 852 INIT_LIST_HEAD(&mstb->ports);
853 kref_init(&mstb->kref); 853 kref_init(&mstb->topology_kref);
854 kref_init(&mstb->malloc_kref);
854 return mstb; 855 return mstb;
855} 856}
856 857
857static void drm_dp_free_mst_port(struct kref *kref);
858
859static void drm_dp_free_mst_branch_device(struct kref *kref) 858static void drm_dp_free_mst_branch_device(struct kref *kref)
860{ 859{
861 struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref); 860 struct drm_dp_mst_branch *mstb =
862 if (mstb->port_parent) { 861 container_of(kref, struct drm_dp_mst_branch, malloc_kref);
863 if (list_empty(&mstb->port_parent->next)) 862
864 kref_put(&mstb->port_parent->kref, drm_dp_free_mst_port); 863 if (mstb->port_parent)
865 } 864 drm_dp_mst_put_port_malloc(mstb->port_parent);
865
866 kfree(mstb); 866 kfree(mstb);
867} 867}
868 868
869/**
870 * DOC: Branch device and port refcounting
871 *
872 * Topology refcount overview
873 * ~~~~~~~~~~~~~~~~~~~~~~~~~~
874 *
875 * The refcounting schemes for &struct drm_dp_mst_branch and &struct
876 * drm_dp_mst_port are somewhat unusual. Both ports and branch devices have
877 * two different kinds of refcounts: topology refcounts, and malloc refcounts.
878 *
879 * Topology refcounts are not exposed to drivers, and are handled internally
880 * by the DP MST helpers. The helpers use them in order to prevent the
881 * in-memory topology state from being changed in the middle of critical
882 * operations like changing the internal state of payload allocations. This
883 * means each branch and port will be considered to be connected to the rest
884 * of the topology until it's topology refcount reaches zero. Additionally,
885 * for ports this means that their associated &struct drm_connector will stay
886 * registered with userspace until the port's refcount reaches 0.
887 *
888 * Malloc refcount overview
889 * ~~~~~~~~~~~~~~~~~~~~~~~~
890 *
891 * Malloc references are used to keep a &struct drm_dp_mst_port or &struct
892 * drm_dp_mst_branch allocated even after all of its topology references have
893 * been dropped, so that the driver or MST helpers can safely access each
894 * branch's last known state before it was disconnected from the topology.
895 * When the malloc refcount of a port or branch reaches 0, the memory
896 * allocation containing the &struct drm_dp_mst_branch or &struct
897 * drm_dp_mst_port respectively will be freed.
898 *
899 * For &struct drm_dp_mst_branch, malloc refcounts are not currently exposed
900 * to drivers. As of writing this documentation, there are no drivers that
901 * have a usecase for accessing &struct drm_dp_mst_branch outside of the MST
902 * helpers. Exposing this API to drivers in a race-free manner would take more
903 * tweaking of the refcounting scheme, however patches are welcome provided
904 * there is a legitimate driver usecase for this.
905 *
906 * Refcount relationships in a topology
907 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
908 *
909 * Let's take a look at why the relationship between topology and malloc
910 * refcounts is designed the way it is.
911 *
912 * .. kernel-figure:: dp-mst/topology-figure-1.dot
913 *
914 * An example of topology and malloc refs in a DP MST topology with two
915 * active payloads. Topology refcount increments are indicated by solid
916 * lines, and malloc refcount increments are indicated by dashed lines.
917 * Each starts from the branch which incremented the refcount, and ends at
918 * the branch to which the refcount belongs to, i.e. the arrow points the
919 * same way as the C pointers used to reference a structure.
920 *
921 * As you can see in the above figure, every branch increments the topology
922 * refcount of it's children, and increments the malloc refcount of it's
923 * parent. Additionally, every payload increments the malloc refcount of it's
924 * assigned port by 1.
925 *
926 * So, what would happen if MSTB #3 from the above figure was unplugged from
927 * the system, but the driver hadn't yet removed payload #2 from port #3? The
928 * topology would start to look like the figure below.
929 *
930 * .. kernel-figure:: dp-mst/topology-figure-2.dot
931 *
932 * Ports and branch devices which have been released from memory are
933 * colored grey, and references which have been removed are colored red.
934 *
935 * Whenever a port or branch device's topology refcount reaches zero, it will
936 * decrement the topology refcounts of all its children, the malloc refcount
937 * of its parent, and finally its own malloc refcount. For MSTB #4 and port
938 * #4, this means they both have been disconnected from the topology and freed
939 * from memory. But, because payload #2 is still holding a reference to port
940 * #3, port #3 is removed from the topology but it's &struct drm_dp_mst_port
941 * is still accessible from memory. This also means port #3 has not yet
942 * decremented the malloc refcount of MSTB #3, so it's &struct
943 * drm_dp_mst_branch will also stay allocated in memory until port #3's
944 * malloc refcount reaches 0.
945 *
946 * This relationship is necessary because in order to release payload #2, we
947 * need to be able to figure out the last relative of port #3 that's still
948 * connected to the topology. In this case, we would travel up the topology as
949 * shown below.
950 *
951 * .. kernel-figure:: dp-mst/topology-figure-3.dot
952 *
953 * And finally, remove payload #2 by communicating with port #2 through
954 * sideband transactions.
955 */
956
957/**
958 * drm_dp_mst_get_mstb_malloc() - Increment the malloc refcount of a branch
959 * device
960 * @mstb: The &struct drm_dp_mst_branch to increment the malloc refcount of
961 *
962 * Increments &drm_dp_mst_branch.malloc_kref. When
963 * &drm_dp_mst_branch.malloc_kref reaches 0, the memory allocation for @mstb
964 * will be released and @mstb may no longer be used.
965 *
966 * See also: drm_dp_mst_put_mstb_malloc()
967 */
968static void
969drm_dp_mst_get_mstb_malloc(struct drm_dp_mst_branch *mstb)
970{
971 kref_get(&mstb->malloc_kref);
972 DRM_DEBUG("mstb %p (%d)\n", mstb, kref_read(&mstb->malloc_kref));
973}
974
975/**
976 * drm_dp_mst_put_mstb_malloc() - Decrement the malloc refcount of a branch
977 * device
978 * @mstb: The &struct drm_dp_mst_branch to decrement the malloc refcount of
979 *
980 * Decrements &drm_dp_mst_branch.malloc_kref. When
981 * &drm_dp_mst_branch.malloc_kref reaches 0, the memory allocation for @mstb
982 * will be released and @mstb may no longer be used.
983 *
984 * See also: drm_dp_mst_get_mstb_malloc()
985 */
986static void
987drm_dp_mst_put_mstb_malloc(struct drm_dp_mst_branch *mstb)
988{
989 DRM_DEBUG("mstb %p (%d)\n", mstb, kref_read(&mstb->malloc_kref) - 1);
990 kref_put(&mstb->malloc_kref, drm_dp_free_mst_branch_device);
991}
992
993static void drm_dp_free_mst_port(struct kref *kref)
994{
995 struct drm_dp_mst_port *port =
996 container_of(kref, struct drm_dp_mst_port, malloc_kref);
997
998 drm_dp_mst_put_mstb_malloc(port->parent);
999 kfree(port);
1000}
1001
1002/**
1003 * drm_dp_mst_get_port_malloc() - Increment the malloc refcount of an MST port
1004 * @port: The &struct drm_dp_mst_port to increment the malloc refcount of
1005 *
1006 * Increments &drm_dp_mst_port.malloc_kref. When &drm_dp_mst_port.malloc_kref
1007 * reaches 0, the memory allocation for @port will be released and @port may
1008 * no longer be used.
1009 *
1010 * Because @port could potentially be freed at any time by the DP MST helpers
1011 * if &drm_dp_mst_port.malloc_kref reaches 0, including during a call to this
1012 * function, drivers that which to make use of &struct drm_dp_mst_port should
1013 * ensure that they grab at least one main malloc reference to their MST ports
1014 * in &drm_dp_mst_topology_cbs.add_connector. This callback is called before
1015 * there is any chance for &drm_dp_mst_port.malloc_kref to reach 0.
1016 *
1017 * See also: drm_dp_mst_put_port_malloc()
1018 */
1019void
1020drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port)
1021{
1022 kref_get(&port->malloc_kref);
1023 DRM_DEBUG("port %p (%d)\n", port, kref_read(&port->malloc_kref));
1024}
1025EXPORT_SYMBOL(drm_dp_mst_get_port_malloc);
1026
1027/**
1028 * drm_dp_mst_put_port_malloc() - Decrement the malloc refcount of an MST port
1029 * @port: The &struct drm_dp_mst_port to decrement the malloc refcount of
1030 *
1031 * Decrements &drm_dp_mst_port.malloc_kref. When &drm_dp_mst_port.malloc_kref
1032 * reaches 0, the memory allocation for @port will be released and @port may
1033 * no longer be used.
1034 *
1035 * See also: drm_dp_mst_get_port_malloc()
1036 */
1037void
1038drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port)
1039{
1040 DRM_DEBUG("port %p (%d)\n", port, kref_read(&port->malloc_kref) - 1);
1041 kref_put(&port->malloc_kref, drm_dp_free_mst_port);
1042}
1043EXPORT_SYMBOL(drm_dp_mst_put_port_malloc);
1044
869static void drm_dp_destroy_mst_branch_device(struct kref *kref) 1045static void drm_dp_destroy_mst_branch_device(struct kref *kref)
870{ 1046{
871 struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref); 1047 struct drm_dp_mst_branch *mstb =
1048 container_of(kref, struct drm_dp_mst_branch, topology_kref);
1049 struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
872 struct drm_dp_mst_port *port, *tmp; 1050 struct drm_dp_mst_port *port, *tmp;
873 bool wake_tx = false; 1051 bool wake_tx = false;
874 1052
875 /* 1053 mutex_lock(&mgr->lock);
876 * init kref again to be used by ports to remove mst branch when it is
877 * not needed anymore
878 */
879 kref_init(kref);
880
881 if (mstb->port_parent && list_empty(&mstb->port_parent->next))
882 kref_get(&mstb->port_parent->kref);
883
884 /*
885 * destroy all ports - don't need lock
886 * as there are no more references to the mst branch
887 * device at this point.
888 */
889 list_for_each_entry_safe(port, tmp, &mstb->ports, next) { 1054 list_for_each_entry_safe(port, tmp, &mstb->ports, next) {
890 list_del(&port->next); 1055 list_del(&port->next);
891 drm_dp_put_port(port); 1056 drm_dp_mst_topology_put_port(port);
892 } 1057 }
1058 mutex_unlock(&mgr->lock);
893 1059
894 /* drop any tx slots msg */ 1060 /* drop any tx slots msg */
895 mutex_lock(&mstb->mgr->qlock); 1061 mutex_lock(&mstb->mgr->qlock);
@@ -908,14 +1074,83 @@ static void drm_dp_destroy_mst_branch_device(struct kref *kref)
908 if (wake_tx) 1074 if (wake_tx)
909 wake_up_all(&mstb->mgr->tx_waitq); 1075 wake_up_all(&mstb->mgr->tx_waitq);
910 1076
911 kref_put(kref, drm_dp_free_mst_branch_device); 1077 drm_dp_mst_put_mstb_malloc(mstb);
912} 1078}
913 1079
914static void drm_dp_put_mst_branch_device(struct drm_dp_mst_branch *mstb) 1080/**
1081 * drm_dp_mst_topology_try_get_mstb() - Increment the topology refcount of a
1082 * branch device unless its zero
1083 * @mstb: &struct drm_dp_mst_branch to increment the topology refcount of
1084 *
1085 * Attempts to grab a topology reference to @mstb, if it hasn't yet been
1086 * removed from the topology (e.g. &drm_dp_mst_branch.topology_kref has
1087 * reached 0). Holding a topology reference implies that a malloc reference
1088 * will be held to @mstb as long as the user holds the topology reference.
1089 *
1090 * Care should be taken to ensure that the user has at least one malloc
1091 * reference to @mstb. If you already have a topology reference to @mstb, you
1092 * should use drm_dp_mst_topology_get_mstb() instead.
1093 *
1094 * See also:
1095 * drm_dp_mst_topology_get_mstb()
1096 * drm_dp_mst_topology_put_mstb()
1097 *
1098 * Returns:
1099 * * 1: A topology reference was grabbed successfully
1100 * * 0: @port is no longer in the topology, no reference was grabbed
1101 */
1102static int __must_check
1103drm_dp_mst_topology_try_get_mstb(struct drm_dp_mst_branch *mstb)
915{ 1104{
916 kref_put(&mstb->kref, drm_dp_destroy_mst_branch_device); 1105 int ret = kref_get_unless_zero(&mstb->topology_kref);
1106
1107 if (ret)
1108 DRM_DEBUG("mstb %p (%d)\n", mstb,
1109 kref_read(&mstb->topology_kref));
1110
1111 return ret;
917} 1112}
918 1113
1114/**
1115 * drm_dp_mst_topology_get_mstb() - Increment the topology refcount of a
1116 * branch device
1117 * @mstb: The &struct drm_dp_mst_branch to increment the topology refcount of
1118 *
1119 * Increments &drm_dp_mst_branch.topology_refcount without checking whether or
1120 * not it's already reached 0. This is only valid to use in scenarios where
1121 * you are already guaranteed to have at least one active topology reference
1122 * to @mstb. Otherwise, drm_dp_mst_topology_try_get_mstb() must be used.
1123 *
1124 * See also:
1125 * drm_dp_mst_topology_try_get_mstb()
1126 * drm_dp_mst_topology_put_mstb()
1127 */
1128static void drm_dp_mst_topology_get_mstb(struct drm_dp_mst_branch *mstb)
1129{
1130 WARN_ON(kref_read(&mstb->topology_kref) == 0);
1131 kref_get(&mstb->topology_kref);
1132 DRM_DEBUG("mstb %p (%d)\n", mstb, kref_read(&mstb->topology_kref));
1133}
1134
1135/**
1136 * drm_dp_mst_topology_put_mstb() - release a topology reference to a branch
1137 * device
1138 * @mstb: The &struct drm_dp_mst_branch to release the topology reference from
1139 *
1140 * Releases a topology reference from @mstb by decrementing
1141 * &drm_dp_mst_branch.topology_kref.
1142 *
1143 * See also:
1144 * drm_dp_mst_topology_try_get_mstb()
1145 * drm_dp_mst_topology_get_mstb()
1146 */
1147static void
1148drm_dp_mst_topology_put_mstb(struct drm_dp_mst_branch *mstb)
1149{
1150 DRM_DEBUG("mstb %p (%d)\n",
1151 mstb, kref_read(&mstb->topology_kref) - 1);
1152 kref_put(&mstb->topology_kref, drm_dp_destroy_mst_branch_device);
1153}
919 1154
920static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt) 1155static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt)
921{ 1156{
@@ -930,19 +1165,18 @@ static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt)
930 case DP_PEER_DEVICE_MST_BRANCHING: 1165 case DP_PEER_DEVICE_MST_BRANCHING:
931 mstb = port->mstb; 1166 mstb = port->mstb;
932 port->mstb = NULL; 1167 port->mstb = NULL;
933 drm_dp_put_mst_branch_device(mstb); 1168 drm_dp_mst_topology_put_mstb(mstb);
934 break; 1169 break;
935 } 1170 }
936} 1171}
937 1172
938static void drm_dp_destroy_port(struct kref *kref) 1173static void drm_dp_destroy_port(struct kref *kref)
939{ 1174{
940 struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref); 1175 struct drm_dp_mst_port *port =
1176 container_of(kref, struct drm_dp_mst_port, topology_kref);
941 struct drm_dp_mst_topology_mgr *mgr = port->mgr; 1177 struct drm_dp_mst_topology_mgr *mgr = port->mgr;
942 1178
943 if (!port->input) { 1179 if (!port->input) {
944 port->vcpi.num_slots = 0;
945
946 kfree(port->cached_edid); 1180 kfree(port->cached_edid);
947 1181
948 /* 1182 /*
@@ -956,7 +1190,6 @@ static void drm_dp_destroy_port(struct kref *kref)
956 * from an EDID retrieval */ 1190 * from an EDID retrieval */
957 1191
958 mutex_lock(&mgr->destroy_connector_lock); 1192 mutex_lock(&mgr->destroy_connector_lock);
959 kref_get(&port->parent->kref);
960 list_add(&port->next, &mgr->destroy_connector_list); 1193 list_add(&port->next, &mgr->destroy_connector_list);
961 mutex_unlock(&mgr->destroy_connector_lock); 1194 mutex_unlock(&mgr->destroy_connector_lock);
962 schedule_work(&mgr->destroy_connector_work); 1195 schedule_work(&mgr->destroy_connector_work);
@@ -967,25 +1200,95 @@ static void drm_dp_destroy_port(struct kref *kref)
967 drm_dp_port_teardown_pdt(port, port->pdt); 1200 drm_dp_port_teardown_pdt(port, port->pdt);
968 port->pdt = DP_PEER_DEVICE_NONE; 1201 port->pdt = DP_PEER_DEVICE_NONE;
969 } 1202 }
970 kfree(port); 1203 drm_dp_mst_put_port_malloc(port);
971} 1204}
972 1205
973static void drm_dp_put_port(struct drm_dp_mst_port *port) 1206/**
1207 * drm_dp_mst_topology_try_get_port() - Increment the topology refcount of a
1208 * port unless its zero
1209 * @port: &struct drm_dp_mst_port to increment the topology refcount of
1210 *
1211 * Attempts to grab a topology reference to @port, if it hasn't yet been
1212 * removed from the topology (e.g. &drm_dp_mst_port.topology_kref has reached
1213 * 0). Holding a topology reference implies that a malloc reference will be
1214 * held to @port as long as the user holds the topology reference.
1215 *
1216 * Care should be taken to ensure that the user has at least one malloc
1217 * reference to @port. If you already have a topology reference to @port, you
1218 * should use drm_dp_mst_topology_get_port() instead.
1219 *
1220 * See also:
1221 * drm_dp_mst_topology_get_port()
1222 * drm_dp_mst_topology_put_port()
1223 *
1224 * Returns:
1225 * * 1: A topology reference was grabbed successfully
1226 * * 0: @port is no longer in the topology, no reference was grabbed
1227 */
1228static int __must_check
1229drm_dp_mst_topology_try_get_port(struct drm_dp_mst_port *port)
974{ 1230{
975 kref_put(&port->kref, drm_dp_destroy_port); 1231 int ret = kref_get_unless_zero(&port->topology_kref);
1232
1233 if (ret)
1234 DRM_DEBUG("port %p (%d)\n", port,
1235 kref_read(&port->topology_kref));
1236
1237 return ret;
976} 1238}
977 1239
978static struct drm_dp_mst_branch *drm_dp_mst_get_validated_mstb_ref_locked(struct drm_dp_mst_branch *mstb, struct drm_dp_mst_branch *to_find) 1240/**
1241 * drm_dp_mst_topology_get_port() - Increment the topology refcount of a port
1242 * @port: The &struct drm_dp_mst_port to increment the topology refcount of
1243 *
1244 * Increments &drm_dp_mst_port.topology_refcount without checking whether or
1245 * not it's already reached 0. This is only valid to use in scenarios where
1246 * you are already guaranteed to have at least one active topology reference
1247 * to @port. Otherwise, drm_dp_mst_topology_try_get_port() must be used.
1248 *
1249 * See also:
1250 * drm_dp_mst_topology_try_get_port()
1251 * drm_dp_mst_topology_put_port()
1252 */
1253static void drm_dp_mst_topology_get_port(struct drm_dp_mst_port *port)
1254{
1255 WARN_ON(kref_read(&port->topology_kref) == 0);
1256 kref_get(&port->topology_kref);
1257 DRM_DEBUG("port %p (%d)\n", port, kref_read(&port->topology_kref));
1258}
1259
1260/**
1261 * drm_dp_mst_topology_put_port() - release a topology reference to a port
1262 * @port: The &struct drm_dp_mst_port to release the topology reference from
1263 *
1264 * Releases a topology reference from @port by decrementing
1265 * &drm_dp_mst_port.topology_kref.
1266 *
1267 * See also:
1268 * drm_dp_mst_topology_try_get_port()
1269 * drm_dp_mst_topology_get_port()
1270 */
1271static void drm_dp_mst_topology_put_port(struct drm_dp_mst_port *port)
1272{
1273 DRM_DEBUG("port %p (%d)\n",
1274 port, kref_read(&port->topology_kref) - 1);
1275 kref_put(&port->topology_kref, drm_dp_destroy_port);
1276}
1277
1278static struct drm_dp_mst_branch *
1279drm_dp_mst_topology_get_mstb_validated_locked(struct drm_dp_mst_branch *mstb,
1280 struct drm_dp_mst_branch *to_find)
979{ 1281{
980 struct drm_dp_mst_port *port; 1282 struct drm_dp_mst_port *port;
981 struct drm_dp_mst_branch *rmstb; 1283 struct drm_dp_mst_branch *rmstb;
982 if (to_find == mstb) { 1284
983 kref_get(&mstb->kref); 1285 if (to_find == mstb)
984 return mstb; 1286 return mstb;
985 } 1287
986 list_for_each_entry(port, &mstb->ports, next) { 1288 list_for_each_entry(port, &mstb->ports, next) {
987 if (port->mstb) { 1289 if (port->mstb) {
988 rmstb = drm_dp_mst_get_validated_mstb_ref_locked(port->mstb, to_find); 1290 rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
1291 port->mstb, to_find);
989 if (rmstb) 1292 if (rmstb)
990 return rmstb; 1293 return rmstb;
991 } 1294 }
@@ -993,27 +1296,37 @@ static struct drm_dp_mst_branch *drm_dp_mst_get_validated_mstb_ref_locked(struct
993 return NULL; 1296 return NULL;
994} 1297}
995 1298
996static struct drm_dp_mst_branch *drm_dp_get_validated_mstb_ref(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb) 1299static struct drm_dp_mst_branch *
1300drm_dp_mst_topology_get_mstb_validated(struct drm_dp_mst_topology_mgr *mgr,
1301 struct drm_dp_mst_branch *mstb)
997{ 1302{
998 struct drm_dp_mst_branch *rmstb = NULL; 1303 struct drm_dp_mst_branch *rmstb = NULL;
1304
999 mutex_lock(&mgr->lock); 1305 mutex_lock(&mgr->lock);
1000 if (mgr->mst_primary) 1306 if (mgr->mst_primary) {
1001 rmstb = drm_dp_mst_get_validated_mstb_ref_locked(mgr->mst_primary, mstb); 1307 rmstb = drm_dp_mst_topology_get_mstb_validated_locked(
1308 mgr->mst_primary, mstb);
1309
1310 if (rmstb && !drm_dp_mst_topology_try_get_mstb(rmstb))
1311 rmstb = NULL;
1312 }
1002 mutex_unlock(&mgr->lock); 1313 mutex_unlock(&mgr->lock);
1003 return rmstb; 1314 return rmstb;
1004} 1315}
1005 1316
1006static struct drm_dp_mst_port *drm_dp_mst_get_port_ref_locked(struct drm_dp_mst_branch *mstb, struct drm_dp_mst_port *to_find) 1317static struct drm_dp_mst_port *
1318drm_dp_mst_topology_get_port_validated_locked(struct drm_dp_mst_branch *mstb,
1319 struct drm_dp_mst_port *to_find)
1007{ 1320{
1008 struct drm_dp_mst_port *port, *mport; 1321 struct drm_dp_mst_port *port, *mport;
1009 1322
1010 list_for_each_entry(port, &mstb->ports, next) { 1323 list_for_each_entry(port, &mstb->ports, next) {
1011 if (port == to_find) { 1324 if (port == to_find)
1012 kref_get(&port->kref);
1013 return port; 1325 return port;
1014 } 1326
1015 if (port->mstb) { 1327 if (port->mstb) {
1016 mport = drm_dp_mst_get_port_ref_locked(port->mstb, to_find); 1328 mport = drm_dp_mst_topology_get_port_validated_locked(
1329 port->mstb, to_find);
1017 if (mport) 1330 if (mport)
1018 return mport; 1331 return mport;
1019 } 1332 }
@@ -1021,12 +1334,20 @@ static struct drm_dp_mst_port *drm_dp_mst_get_port_ref_locked(struct drm_dp_mst_
1021 return NULL; 1334 return NULL;
1022} 1335}
1023 1336
1024static struct drm_dp_mst_port *drm_dp_get_validated_port_ref(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) 1337static struct drm_dp_mst_port *
1338drm_dp_mst_topology_get_port_validated(struct drm_dp_mst_topology_mgr *mgr,
1339 struct drm_dp_mst_port *port)
1025{ 1340{
1026 struct drm_dp_mst_port *rport = NULL; 1341 struct drm_dp_mst_port *rport = NULL;
1342
1027 mutex_lock(&mgr->lock); 1343 mutex_lock(&mgr->lock);
1028 if (mgr->mst_primary) 1344 if (mgr->mst_primary) {
1029 rport = drm_dp_mst_get_port_ref_locked(mgr->mst_primary, port); 1345 rport = drm_dp_mst_topology_get_port_validated_locked(
1346 mgr->mst_primary, port);
1347
1348 if (rport && !drm_dp_mst_topology_try_get_port(rport))
1349 rport = NULL;
1350 }
1030 mutex_unlock(&mgr->lock); 1351 mutex_unlock(&mgr->lock);
1031 return rport; 1352 return rport;
1032} 1353}
@@ -1034,11 +1355,12 @@ static struct drm_dp_mst_port *drm_dp_get_validated_port_ref(struct drm_dp_mst_t
1034static struct drm_dp_mst_port *drm_dp_get_port(struct drm_dp_mst_branch *mstb, u8 port_num) 1355static struct drm_dp_mst_port *drm_dp_get_port(struct drm_dp_mst_branch *mstb, u8 port_num)
1035{ 1356{
1036 struct drm_dp_mst_port *port; 1357 struct drm_dp_mst_port *port;
1358 int ret;
1037 1359
1038 list_for_each_entry(port, &mstb->ports, next) { 1360 list_for_each_entry(port, &mstb->ports, next) {
1039 if (port->port_num == port_num) { 1361 if (port->port_num == port_num) {
1040 kref_get(&port->kref); 1362 ret = drm_dp_mst_topology_try_get_port(port);
1041 return port; 1363 return ret ? port : NULL;
1042 } 1364 }
1043 } 1365 }
1044 1366
@@ -1087,6 +1409,11 @@ static bool drm_dp_port_setup_pdt(struct drm_dp_mst_port *port)
1087 if (port->mstb) { 1409 if (port->mstb) {
1088 port->mstb->mgr = port->mgr; 1410 port->mstb->mgr = port->mgr;
1089 port->mstb->port_parent = port; 1411 port->mstb->port_parent = port;
1412 /*
1413 * Make sure this port's memory allocation stays
1414 * around until it's child MSTB releases it
1415 */
1416 drm_dp_mst_get_port_malloc(port);
1090 1417
1091 send_link = true; 1418 send_link = true;
1092 } 1419 }
@@ -1147,17 +1474,26 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
1147 bool created = false; 1474 bool created = false;
1148 int old_pdt = 0; 1475 int old_pdt = 0;
1149 int old_ddps = 0; 1476 int old_ddps = 0;
1477
1150 port = drm_dp_get_port(mstb, port_msg->port_number); 1478 port = drm_dp_get_port(mstb, port_msg->port_number);
1151 if (!port) { 1479 if (!port) {
1152 port = kzalloc(sizeof(*port), GFP_KERNEL); 1480 port = kzalloc(sizeof(*port), GFP_KERNEL);
1153 if (!port) 1481 if (!port)
1154 return; 1482 return;
1155 kref_init(&port->kref); 1483 kref_init(&port->topology_kref);
1484 kref_init(&port->malloc_kref);
1156 port->parent = mstb; 1485 port->parent = mstb;
1157 port->port_num = port_msg->port_number; 1486 port->port_num = port_msg->port_number;
1158 port->mgr = mstb->mgr; 1487 port->mgr = mstb->mgr;
1159 port->aux.name = "DPMST"; 1488 port->aux.name = "DPMST";
1160 port->aux.dev = dev->dev; 1489 port->aux.dev = dev->dev;
1490
1491 /*
1492 * Make sure the memory allocation for our parent branch stays
1493 * around until our own memory allocation is released
1494 */
1495 drm_dp_mst_get_mstb_malloc(mstb);
1496
1161 created = true; 1497 created = true;
1162 } else { 1498 } else {
1163 old_pdt = port->pdt; 1499 old_pdt = port->pdt;
@@ -1177,18 +1513,20 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
1177 for this list */ 1513 for this list */
1178 if (created) { 1514 if (created) {
1179 mutex_lock(&mstb->mgr->lock); 1515 mutex_lock(&mstb->mgr->lock);
1180 kref_get(&port->kref); 1516 drm_dp_mst_topology_get_port(port);
1181 list_add(&port->next, &mstb->ports); 1517 list_add(&port->next, &mstb->ports);
1182 mutex_unlock(&mstb->mgr->lock); 1518 mutex_unlock(&mstb->mgr->lock);
1183 } 1519 }
1184 1520
1185 if (old_ddps != port->ddps) { 1521 if (old_ddps != port->ddps) {
1186 if (port->ddps) { 1522 if (port->ddps) {
1187 if (!port->input) 1523 if (!port->input) {
1188 drm_dp_send_enum_path_resources(mstb->mgr, mstb, port); 1524 drm_dp_send_enum_path_resources(mstb->mgr,
1525 mstb, port);
1526 }
1189 } else { 1527 } else {
1190 port->available_pbn = 0; 1528 port->available_pbn = 0;
1191 } 1529 }
1192 } 1530 }
1193 1531
1194 if (old_pdt != port->pdt && !port->input) { 1532 if (old_pdt != port->pdt && !port->input) {
@@ -1202,21 +1540,25 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
1202 if (created && !port->input) { 1540 if (created && !port->input) {
1203 char proppath[255]; 1541 char proppath[255];
1204 1542
1205 build_mst_prop_path(mstb, port->port_num, proppath, sizeof(proppath)); 1543 build_mst_prop_path(mstb, port->port_num, proppath,
1206 port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath); 1544 sizeof(proppath));
1545 port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr,
1546 port,
1547 proppath);
1207 if (!port->connector) { 1548 if (!port->connector) {
1208 /* remove it from the port list */ 1549 /* remove it from the port list */
1209 mutex_lock(&mstb->mgr->lock); 1550 mutex_lock(&mstb->mgr->lock);
1210 list_del(&port->next); 1551 list_del(&port->next);
1211 mutex_unlock(&mstb->mgr->lock); 1552 mutex_unlock(&mstb->mgr->lock);
1212 /* drop port list reference */ 1553 /* drop port list reference */
1213 drm_dp_put_port(port); 1554 drm_dp_mst_topology_put_port(port);
1214 goto out; 1555 goto out;
1215 } 1556 }
1216 if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV || 1557 if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
1217 port->pdt == DP_PEER_DEVICE_SST_SINK) && 1558 port->pdt == DP_PEER_DEVICE_SST_SINK) &&
1218 port->port_num >= DP_MST_LOGICAL_PORT_0) { 1559 port->port_num >= DP_MST_LOGICAL_PORT_0) {
1219 port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc); 1560 port->cached_edid = drm_get_edid(port->connector,
1561 &port->aux.ddc);
1220 drm_connector_set_tile_property(port->connector); 1562 drm_connector_set_tile_property(port->connector);
1221 } 1563 }
1222 (*mstb->mgr->cbs->register_connector)(port->connector); 1564 (*mstb->mgr->cbs->register_connector)(port->connector);
@@ -1224,7 +1566,7 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
1224 1566
1225out: 1567out:
1226 /* put reference to this port */ 1568 /* put reference to this port */
1227 drm_dp_put_port(port); 1569 drm_dp_mst_topology_put_port(port);
1228} 1570}
1229 1571
1230static void drm_dp_update_port(struct drm_dp_mst_branch *mstb, 1572static void drm_dp_update_port(struct drm_dp_mst_branch *mstb,
@@ -1259,7 +1601,7 @@ static void drm_dp_update_port(struct drm_dp_mst_branch *mstb,
1259 dowork = true; 1601 dowork = true;
1260 } 1602 }
1261 1603
1262 drm_dp_put_port(port); 1604 drm_dp_mst_topology_put_port(port);
1263 if (dowork) 1605 if (dowork)
1264 queue_work(system_long_wq, &mstb->mgr->work); 1606 queue_work(system_long_wq, &mstb->mgr->work);
1265 1607
@@ -1270,7 +1612,7 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_
1270{ 1612{
1271 struct drm_dp_mst_branch *mstb; 1613 struct drm_dp_mst_branch *mstb;
1272 struct drm_dp_mst_port *port; 1614 struct drm_dp_mst_port *port;
1273 int i; 1615 int i, ret;
1274 /* find the port by iterating down */ 1616 /* find the port by iterating down */
1275 1617
1276 mutex_lock(&mgr->lock); 1618 mutex_lock(&mgr->lock);
@@ -1295,7 +1637,9 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_
1295 } 1637 }
1296 } 1638 }
1297 } 1639 }
1298 kref_get(&mstb->kref); 1640 ret = drm_dp_mst_topology_try_get_mstb(mstb);
1641 if (!ret)
1642 mstb = NULL;
1299out: 1643out:
1300 mutex_unlock(&mgr->lock); 1644 mutex_unlock(&mgr->lock);
1301 return mstb; 1645 return mstb;
@@ -1325,19 +1669,22 @@ static struct drm_dp_mst_branch *get_mst_branch_device_by_guid_helper(
1325 return NULL; 1669 return NULL;
1326} 1670}
1327 1671
1328static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device_by_guid( 1672static struct drm_dp_mst_branch *
1329 struct drm_dp_mst_topology_mgr *mgr, 1673drm_dp_get_mst_branch_device_by_guid(struct drm_dp_mst_topology_mgr *mgr,
1330 uint8_t *guid) 1674 uint8_t *guid)
1331{ 1675{
1332 struct drm_dp_mst_branch *mstb; 1676 struct drm_dp_mst_branch *mstb;
1677 int ret;
1333 1678
1334 /* find the port by iterating down */ 1679 /* find the port by iterating down */
1335 mutex_lock(&mgr->lock); 1680 mutex_lock(&mgr->lock);
1336 1681
1337 mstb = get_mst_branch_device_by_guid_helper(mgr->mst_primary, guid); 1682 mstb = get_mst_branch_device_by_guid_helper(mgr->mst_primary, guid);
1338 1683 if (mstb) {
1339 if (mstb) 1684 ret = drm_dp_mst_topology_try_get_mstb(mstb);
1340 kref_get(&mstb->kref); 1685 if (!ret)
1686 mstb = NULL;
1687 }
1341 1688
1342 mutex_unlock(&mgr->lock); 1689 mutex_unlock(&mgr->lock);
1343 return mstb; 1690 return mstb;
@@ -1362,10 +1709,11 @@ static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *m
1362 drm_dp_send_enum_path_resources(mgr, mstb, port); 1709 drm_dp_send_enum_path_resources(mgr, mstb, port);
1363 1710
1364 if (port->mstb) { 1711 if (port->mstb) {
1365 mstb_child = drm_dp_get_validated_mstb_ref(mgr, port->mstb); 1712 mstb_child = drm_dp_mst_topology_get_mstb_validated(
1713 mgr, port->mstb);
1366 if (mstb_child) { 1714 if (mstb_child) {
1367 drm_dp_check_and_send_link_address(mgr, mstb_child); 1715 drm_dp_check_and_send_link_address(mgr, mstb_child);
1368 drm_dp_put_mst_branch_device(mstb_child); 1716 drm_dp_mst_topology_put_mstb(mstb_child);
1369 } 1717 }
1370 } 1718 }
1371 } 1719 }
@@ -1375,16 +1723,19 @@ static void drm_dp_mst_link_probe_work(struct work_struct *work)
1375{ 1723{
1376 struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, work); 1724 struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, work);
1377 struct drm_dp_mst_branch *mstb; 1725 struct drm_dp_mst_branch *mstb;
1726 int ret;
1378 1727
1379 mutex_lock(&mgr->lock); 1728 mutex_lock(&mgr->lock);
1380 mstb = mgr->mst_primary; 1729 mstb = mgr->mst_primary;
1381 if (mstb) { 1730 if (mstb) {
1382 kref_get(&mstb->kref); 1731 ret = drm_dp_mst_topology_try_get_mstb(mstb);
1732 if (!ret)
1733 mstb = NULL;
1383 } 1734 }
1384 mutex_unlock(&mgr->lock); 1735 mutex_unlock(&mgr->lock);
1385 if (mstb) { 1736 if (mstb) {
1386 drm_dp_check_and_send_link_address(mgr, mstb); 1737 drm_dp_check_and_send_link_address(mgr, mstb);
1387 drm_dp_put_mst_branch_device(mstb); 1738 drm_dp_mst_topology_put_mstb(mstb);
1388 } 1739 }
1389} 1740}
1390 1741
@@ -1695,22 +2046,40 @@ static struct drm_dp_mst_port *drm_dp_get_last_connected_port_to_mstb(struct drm
1695 return drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent); 2046 return drm_dp_get_last_connected_port_to_mstb(mstb->port_parent->parent);
1696} 2047}
1697 2048
1698static struct drm_dp_mst_branch *drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr, 2049/*
1699 struct drm_dp_mst_branch *mstb, 2050 * Searches upwards in the topology starting from mstb to try to find the
1700 int *port_num) 2051 * closest available parent of mstb that's still connected to the rest of the
2052 * topology. This can be used in order to perform operations like releasing
2053 * payloads, where the branch device which owned the payload may no longer be
2054 * around and thus would require that the payload on the last living relative
2055 * be freed instead.
2056 */
2057static struct drm_dp_mst_branch *
2058drm_dp_get_last_connected_port_and_mstb(struct drm_dp_mst_topology_mgr *mgr,
2059 struct drm_dp_mst_branch *mstb,
2060 int *port_num)
1701{ 2061{
1702 struct drm_dp_mst_branch *rmstb = NULL; 2062 struct drm_dp_mst_branch *rmstb = NULL;
1703 struct drm_dp_mst_port *found_port; 2063 struct drm_dp_mst_port *found_port;
2064
1704 mutex_lock(&mgr->lock); 2065 mutex_lock(&mgr->lock);
1705 if (mgr->mst_primary) { 2066 if (!mgr->mst_primary)
2067 goto out;
2068
2069 do {
1706 found_port = drm_dp_get_last_connected_port_to_mstb(mstb); 2070 found_port = drm_dp_get_last_connected_port_to_mstb(mstb);
2071 if (!found_port)
2072 break;
1707 2073
1708 if (found_port) { 2074 if (drm_dp_mst_topology_try_get_mstb(found_port->parent)) {
1709 rmstb = found_port->parent; 2075 rmstb = found_port->parent;
1710 kref_get(&rmstb->kref);
1711 *port_num = found_port->port_num; 2076 *port_num = found_port->port_num;
2077 } else {
2078 /* Search again, starting from this parent */
2079 mstb = found_port->parent;
1712 } 2080 }
1713 } 2081 } while (!rmstb);
2082out:
1714 mutex_unlock(&mgr->lock); 2083 mutex_unlock(&mgr->lock);
1715 return rmstb; 2084 return rmstb;
1716} 2085}
@@ -1726,19 +2095,15 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,
1726 u8 sinks[DRM_DP_MAX_SDP_STREAMS]; 2095 u8 sinks[DRM_DP_MAX_SDP_STREAMS];
1727 int i; 2096 int i;
1728 2097
1729 port = drm_dp_get_validated_port_ref(mgr, port);
1730 if (!port)
1731 return -EINVAL;
1732
1733 port_num = port->port_num; 2098 port_num = port->port_num;
1734 mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); 2099 mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
1735 if (!mstb) { 2100 if (!mstb) {
1736 mstb = drm_dp_get_last_connected_port_and_mstb(mgr, port->parent, &port_num); 2101 mstb = drm_dp_get_last_connected_port_and_mstb(mgr,
2102 port->parent,
2103 &port_num);
1737 2104
1738 if (!mstb) { 2105 if (!mstb)
1739 drm_dp_put_port(port);
1740 return -EINVAL; 2106 return -EINVAL;
1741 }
1742 } 2107 }
1743 2108
1744 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); 2109 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
@@ -1757,17 +2122,24 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,
1757 2122
1758 drm_dp_queue_down_tx(mgr, txmsg); 2123 drm_dp_queue_down_tx(mgr, txmsg);
1759 2124
2125 /*
2126 * FIXME: there is a small chance that between getting the last
2127 * connected mstb and sending the payload message, the last connected
2128 * mstb could also be removed from the topology. In the future, this
2129 * needs to be fixed by restarting the
2130 * drm_dp_get_last_connected_port_and_mstb() search in the event of a
2131 * timeout if the topology is still connected to the system.
2132 */
1760 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); 2133 ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
1761 if (ret > 0) { 2134 if (ret > 0) {
1762 if (txmsg->reply.reply_type == 1) { 2135 if (txmsg->reply.reply_type == 1)
1763 ret = -EINVAL; 2136 ret = -EINVAL;
1764 } else 2137 else
1765 ret = 0; 2138 ret = 0;
1766 } 2139 }
1767 kfree(txmsg); 2140 kfree(txmsg);
1768fail_put: 2141fail_put:
1769 drm_dp_put_mst_branch_device(mstb); 2142 drm_dp_mst_topology_put_mstb(mstb);
1770 drm_dp_put_port(port);
1771 return ret; 2143 return ret;
1772} 2144}
1773 2145
@@ -1777,13 +2149,13 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
1777 struct drm_dp_sideband_msg_tx *txmsg; 2149 struct drm_dp_sideband_msg_tx *txmsg;
1778 int len, ret; 2150 int len, ret;
1779 2151
1780 port = drm_dp_get_validated_port_ref(mgr, port); 2152 port = drm_dp_mst_topology_get_port_validated(mgr, port);
1781 if (!port) 2153 if (!port)
1782 return -EINVAL; 2154 return -EINVAL;
1783 2155
1784 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); 2156 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
1785 if (!txmsg) { 2157 if (!txmsg) {
1786 drm_dp_put_port(port); 2158 drm_dp_mst_topology_put_port(port);
1787 return -ENOMEM; 2159 return -ENOMEM;
1788 } 2160 }
1789 2161
@@ -1799,7 +2171,7 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
1799 ret = 0; 2171 ret = 0;
1800 } 2172 }
1801 kfree(txmsg); 2173 kfree(txmsg);
1802 drm_dp_put_port(port); 2174 drm_dp_mst_topology_put_port(port);
1803 2175
1804 return ret; 2176 return ret;
1805} 2177}
@@ -1872,15 +2244,16 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
1872 */ 2244 */
1873int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) 2245int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
1874{ 2246{
1875 int i, j;
1876 int cur_slots = 1;
1877 struct drm_dp_payload req_payload; 2247 struct drm_dp_payload req_payload;
1878 struct drm_dp_mst_port *port; 2248 struct drm_dp_mst_port *port;
2249 int i, j;
2250 int cur_slots = 1;
1879 2251
1880 mutex_lock(&mgr->payload_lock); 2252 mutex_lock(&mgr->payload_lock);
1881 for (i = 0; i < mgr->max_payloads; i++) { 2253 for (i = 0; i < mgr->max_payloads; i++) {
1882 struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i]; 2254 struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
1883 struct drm_dp_payload *payload = &mgr->payloads[i]; 2255 struct drm_dp_payload *payload = &mgr->payloads[i];
2256 bool put_port = false;
1884 2257
1885 /* solve the current payloads - compare to the hw ones 2258 /* solve the current payloads - compare to the hw ones
1886 - update the hw view */ 2259 - update the hw view */
@@ -1888,11 +2261,20 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
1888 if (vcpi) { 2261 if (vcpi) {
1889 port = container_of(vcpi, struct drm_dp_mst_port, 2262 port = container_of(vcpi, struct drm_dp_mst_port,
1890 vcpi); 2263 vcpi);
1891 port = drm_dp_get_validated_port_ref(mgr, port); 2264
1892 if (!port) { 2265 /* Validated ports don't matter if we're releasing
1893 mutex_unlock(&mgr->payload_lock); 2266 * VCPI
1894 return -EINVAL; 2267 */
2268 if (vcpi->num_slots) {
2269 port = drm_dp_mst_topology_get_port_validated(
2270 mgr, port);
2271 if (!port) {
2272 mutex_unlock(&mgr->payload_lock);
2273 return -EINVAL;
2274 }
2275 put_port = true;
1895 } 2276 }
2277
1896 req_payload.num_slots = vcpi->num_slots; 2278 req_payload.num_slots = vcpi->num_slots;
1897 req_payload.vcpi = vcpi->vcpi; 2279 req_payload.vcpi = vcpi->vcpi;
1898 } else { 2280 } else {
@@ -1924,8 +2306,8 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
1924 } 2306 }
1925 cur_slots += req_payload.num_slots; 2307 cur_slots += req_payload.num_slots;
1926 2308
1927 if (port) 2309 if (put_port)
1928 drm_dp_put_port(port); 2310 drm_dp_mst_topology_put_port(port);
1929 } 2311 }
1930 2312
1931 for (i = 0; i < mgr->max_payloads; i++) { 2313 for (i = 0; i < mgr->max_payloads; i++) {
@@ -2024,7 +2406,7 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
2024 struct drm_dp_sideband_msg_tx *txmsg; 2406 struct drm_dp_sideband_msg_tx *txmsg;
2025 struct drm_dp_mst_branch *mstb; 2407 struct drm_dp_mst_branch *mstb;
2026 2408
2027 mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); 2409 mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
2028 if (!mstb) 2410 if (!mstb)
2029 return -EINVAL; 2411 return -EINVAL;
2030 2412
@@ -2048,7 +2430,7 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
2048 } 2430 }
2049 kfree(txmsg); 2431 kfree(txmsg);
2050fail_put: 2432fail_put:
2051 drm_dp_put_mst_branch_device(mstb); 2433 drm_dp_mst_topology_put_mstb(mstb);
2052 return ret; 2434 return ret;
2053} 2435}
2054 2436
@@ -2158,7 +2540,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
2158 2540
2159 /* give this the main reference */ 2541 /* give this the main reference */
2160 mgr->mst_primary = mstb; 2542 mgr->mst_primary = mstb;
2161 kref_get(&mgr->mst_primary->kref); 2543 drm_dp_mst_topology_get_mstb(mgr->mst_primary);
2162 2544
2163 ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 2545 ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
2164 DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC); 2546 DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
@@ -2192,7 +2574,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
2192out_unlock: 2574out_unlock:
2193 mutex_unlock(&mgr->lock); 2575 mutex_unlock(&mgr->lock);
2194 if (mstb) 2576 if (mstb)
2195 drm_dp_put_mst_branch_device(mstb); 2577 drm_dp_mst_topology_put_mstb(mstb);
2196 return ret; 2578 return ret;
2197 2579
2198} 2580}
@@ -2357,7 +2739,7 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
2357 mgr->down_rep_recv.initial_hdr.lct, 2739 mgr->down_rep_recv.initial_hdr.lct,
2358 mgr->down_rep_recv.initial_hdr.rad[0], 2740 mgr->down_rep_recv.initial_hdr.rad[0],
2359 mgr->down_rep_recv.msg[0]); 2741 mgr->down_rep_recv.msg[0]);
2360 drm_dp_put_mst_branch_device(mstb); 2742 drm_dp_mst_topology_put_mstb(mstb);
2361 memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx)); 2743 memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
2362 return 0; 2744 return 0;
2363 } 2745 }
@@ -2368,7 +2750,7 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
2368 } 2750 }
2369 2751
2370 memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx)); 2752 memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
2371 drm_dp_put_mst_branch_device(mstb); 2753 drm_dp_mst_topology_put_mstb(mstb);
2372 2754
2373 mutex_lock(&mgr->qlock); 2755 mutex_lock(&mgr->qlock);
2374 txmsg->state = DRM_DP_SIDEBAND_TX_RX; 2756 txmsg->state = DRM_DP_SIDEBAND_TX_RX;
@@ -2441,7 +2823,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
2441 } 2823 }
2442 2824
2443 if (mstb) 2825 if (mstb)
2444 drm_dp_put_mst_branch_device(mstb); 2826 drm_dp_mst_topology_put_mstb(mstb);
2445 2827
2446 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx)); 2828 memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
2447 } 2829 }
@@ -2501,7 +2883,7 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector
2501 enum drm_connector_status status = connector_status_disconnected; 2883 enum drm_connector_status status = connector_status_disconnected;
2502 2884
2503 /* we need to search for the port in the mgr in case its gone */ 2885 /* we need to search for the port in the mgr in case its gone */
2504 port = drm_dp_get_validated_port_ref(mgr, port); 2886 port = drm_dp_mst_topology_get_port_validated(mgr, port);
2505 if (!port) 2887 if (!port)
2506 return connector_status_disconnected; 2888 return connector_status_disconnected;
2507 2889
@@ -2526,7 +2908,7 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector
2526 break; 2908 break;
2527 } 2909 }
2528out: 2910out:
2529 drm_dp_put_port(port); 2911 drm_dp_mst_topology_put_port(port);
2530 return status; 2912 return status;
2531} 2913}
2532EXPORT_SYMBOL(drm_dp_mst_detect_port); 2914EXPORT_SYMBOL(drm_dp_mst_detect_port);
@@ -2543,11 +2925,11 @@ bool drm_dp_mst_port_has_audio(struct drm_dp_mst_topology_mgr *mgr,
2543{ 2925{
2544 bool ret = false; 2926 bool ret = false;
2545 2927
2546 port = drm_dp_get_validated_port_ref(mgr, port); 2928 port = drm_dp_mst_topology_get_port_validated(mgr, port);
2547 if (!port) 2929 if (!port)
2548 return ret; 2930 return ret;
2549 ret = port->has_audio; 2931 ret = port->has_audio;
2550 drm_dp_put_port(port); 2932 drm_dp_mst_topology_put_port(port);
2551 return ret; 2933 return ret;
2552} 2934}
2553EXPORT_SYMBOL(drm_dp_mst_port_has_audio); 2935EXPORT_SYMBOL(drm_dp_mst_port_has_audio);
@@ -2567,7 +2949,7 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
2567 struct edid *edid = NULL; 2949 struct edid *edid = NULL;
2568 2950
2569 /* we need to search for the port in the mgr in case its gone */ 2951 /* we need to search for the port in the mgr in case its gone */
2570 port = drm_dp_get_validated_port_ref(mgr, port); 2952 port = drm_dp_mst_topology_get_port_validated(mgr, port);
2571 if (!port) 2953 if (!port)
2572 return NULL; 2954 return NULL;
2573 2955
@@ -2578,7 +2960,7 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_
2578 drm_connector_set_tile_property(connector); 2960 drm_connector_set_tile_property(connector);
2579 } 2961 }
2580 port->has_audio = drm_detect_monitor_audio(edid); 2962 port->has_audio = drm_detect_monitor_audio(edid);
2581 drm_dp_put_port(port); 2963 drm_dp_mst_topology_put_port(port);
2582 return edid; 2964 return edid;
2583} 2965}
2584EXPORT_SYMBOL(drm_dp_mst_get_edid); 2966EXPORT_SYMBOL(drm_dp_mst_get_edid);
@@ -2629,43 +3011,98 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
2629} 3011}
2630 3012
2631/** 3013/**
2632 * drm_dp_atomic_find_vcpi_slots() - Find and add vcpi slots to the state 3014 * drm_dp_atomic_find_vcpi_slots() - Find and add VCPI slots to the state
2633 * @state: global atomic state 3015 * @state: global atomic state
2634 * @mgr: MST topology manager for the port 3016 * @mgr: MST topology manager for the port
2635 * @port: port to find vcpi slots for 3017 * @port: port to find vcpi slots for
2636 * @pbn: bandwidth required for the mode in PBN 3018 * @pbn: bandwidth required for the mode in PBN
2637 * 3019 *
2638 * RETURNS: 3020 * Allocates VCPI slots to @port, replacing any previous VCPI allocations it
2639 * Total slots in the atomic state assigned for this port or error 3021 * may have had. Any atomic drivers which support MST must call this function
3022 * in their &drm_encoder_helper_funcs.atomic_check() callback to change the
3023 * current VCPI allocation for the new state, but only when
3024 * &drm_crtc_state.mode_changed or &drm_crtc_state.connectors_changed is set
3025 * to ensure compatibility with userspace applications that still use the
3026 * legacy modesetting UAPI.
3027 *
3028 * Allocations set by this function are not checked against the bandwidth
3029 * restraints of @mgr until the driver calls drm_dp_mst_atomic_check().
3030 *
3031 * Additionally, it is OK to call this function multiple times on the same
3032 * @port as needed. It is not OK however, to call this function and
3033 * drm_dp_atomic_release_vcpi_slots() in the same atomic check phase.
3034 *
3035 * See also:
3036 * drm_dp_atomic_release_vcpi_slots()
3037 * drm_dp_mst_atomic_check()
3038 *
3039 * Returns:
3040 * Total slots in the atomic state assigned for this port, or a negative error
3041 * code if the port no longer exists
2640 */ 3042 */
2641int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, 3043int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
2642 struct drm_dp_mst_topology_mgr *mgr, 3044 struct drm_dp_mst_topology_mgr *mgr,
2643 struct drm_dp_mst_port *port, int pbn) 3045 struct drm_dp_mst_port *port, int pbn)
2644{ 3046{
2645 struct drm_dp_mst_topology_state *topology_state; 3047 struct drm_dp_mst_topology_state *topology_state;
2646 int req_slots; 3048 struct drm_dp_vcpi_allocation *pos, *vcpi = NULL;
3049 int prev_slots, req_slots, ret;
2647 3050
2648 topology_state = drm_atomic_get_mst_topology_state(state, mgr); 3051 topology_state = drm_atomic_get_mst_topology_state(state, mgr);
2649 if (IS_ERR(topology_state)) 3052 if (IS_ERR(topology_state))
2650 return PTR_ERR(topology_state); 3053 return PTR_ERR(topology_state);
2651 3054
2652 port = drm_dp_get_validated_port_ref(mgr, port); 3055 port = drm_dp_mst_topology_get_port_validated(mgr, port);
2653 if (port == NULL) 3056 if (port == NULL)
2654 return -EINVAL; 3057 return -EINVAL;
2655 req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
2656 DRM_DEBUG_KMS("vcpi slots req=%d, avail=%d\n",
2657 req_slots, topology_state->avail_slots);
2658 3058
2659 if (req_slots > topology_state->avail_slots) { 3059 /* Find the current allocation for this port, if any */
2660 drm_dp_put_port(port); 3060 list_for_each_entry(pos, &topology_state->vcpis, next) {
2661 return -ENOSPC; 3061 if (pos->port == port) {
3062 vcpi = pos;
3063 prev_slots = vcpi->vcpi;
3064
3065 /*
3066 * This should never happen, unless the driver tries
3067 * releasing and allocating the same VCPI allocation,
3068 * which is an error
3069 */
3070 if (WARN_ON(!prev_slots)) {
3071 DRM_ERROR("cannot allocate and release VCPI on [MST PORT:%p] in the same state\n",
3072 port);
3073 return -EINVAL;
3074 }
3075
3076 break;
3077 }
2662 } 3078 }
3079 if (!vcpi)
3080 prev_slots = 0;
3081
3082 req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
2663 3083
2664 topology_state->avail_slots -= req_slots; 3084 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] [MST PORT:%p] VCPI %d -> %d\n",
2665 DRM_DEBUG_KMS("vcpi slots avail=%d", topology_state->avail_slots); 3085 port->connector->base.id, port->connector->name,
3086 port, prev_slots, req_slots);
3087
3088 /* Add the new allocation to the state */
3089 if (!vcpi) {
3090 vcpi = kzalloc(sizeof(*vcpi), GFP_KERNEL);
3091 if (!vcpi) {
3092 ret = -ENOMEM;
3093 goto out;
3094 }
3095
3096 drm_dp_mst_get_port_malloc(port);
3097 vcpi->port = port;
3098 list_add(&vcpi->next, &topology_state->vcpis);
3099 }
3100 vcpi->vcpi = req_slots;
2666 3101
2667 drm_dp_put_port(port); 3102 ret = req_slots;
2668 return req_slots; 3103out:
3104 drm_dp_mst_topology_put_port(port);
3105 return ret;
2669} 3106}
2670EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots); 3107EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots);
2671 3108
@@ -2673,31 +3110,57 @@ EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots);
2673 * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots 3110 * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots
2674 * @state: global atomic state 3111 * @state: global atomic state
2675 * @mgr: MST topology manager for the port 3112 * @mgr: MST topology manager for the port
2676 * @slots: number of vcpi slots to release 3113 * @port: The port to release the VCPI slots from
2677 * 3114 *
2678 * RETURNS: 3115 * Releases any VCPI slots that have been allocated to a port in the atomic
2679 * 0 if @slots were added back to &drm_dp_mst_topology_state->avail_slots or 3116 * state. Any atomic drivers which support MST must call this function in
2680 * negative error code 3117 * their &drm_connector_helper_funcs.atomic_check() callback when the
3118 * connector will no longer have VCPI allocated (e.g. because it's CRTC was
3119 * removed) when it had VCPI allocated in the previous atomic state.
3120 *
3121 * It is OK to call this even if @port has been removed from the system.
3122 * Additionally, it is OK to call this function multiple times on the same
3123 * @port as needed. It is not OK however, to call this function and
3124 * drm_dp_atomic_find_vcpi_slots() on the same @port in a single atomic check
3125 * phase.
3126 *
3127 * See also:
3128 * drm_dp_atomic_find_vcpi_slots()
3129 * drm_dp_mst_atomic_check()
3130 *
3131 * Returns:
3132 * 0 if all slots for this port were added back to
3133 * &drm_dp_mst_topology_state.avail_slots or negative error code
2681 */ 3134 */
2682int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, 3135int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
2683 struct drm_dp_mst_topology_mgr *mgr, 3136 struct drm_dp_mst_topology_mgr *mgr,
2684 int slots) 3137 struct drm_dp_mst_port *port)
2685{ 3138{
2686 struct drm_dp_mst_topology_state *topology_state; 3139 struct drm_dp_mst_topology_state *topology_state;
3140 struct drm_dp_vcpi_allocation *pos;
3141 bool found = false;
2687 3142
2688 topology_state = drm_atomic_get_mst_topology_state(state, mgr); 3143 topology_state = drm_atomic_get_mst_topology_state(state, mgr);
2689 if (IS_ERR(topology_state)) 3144 if (IS_ERR(topology_state))
2690 return PTR_ERR(topology_state); 3145 return PTR_ERR(topology_state);
2691 3146
2692 /* We cannot rely on port->vcpi.num_slots to update 3147 list_for_each_entry(pos, &topology_state->vcpis, next) {
2693 * topology_state->avail_slots as the port may not exist if the parent 3148 if (pos->port == port) {
2694 * branch device was unplugged. This should be fixed by tracking 3149 found = true;
2695 * per-port slot allocation in drm_dp_mst_topology_state instead of 3150 break;
2696 * depending on the caller to tell us how many slots to release. 3151 }
2697 */ 3152 }
2698 topology_state->avail_slots += slots; 3153 if (WARN_ON(!found)) {
2699 DRM_DEBUG_KMS("vcpi slots released=%d, avail=%d\n", 3154 DRM_ERROR("no VCPI for [MST PORT:%p] found in mst state %p\n",
2700 slots, topology_state->avail_slots); 3155 port, &topology_state->base);
3156 return -EINVAL;
3157 }
3158
3159 DRM_DEBUG_ATOMIC("[MST PORT:%p] VCPI %d -> 0\n", port, pos->vcpi);
3160 if (pos->vcpi) {
3161 drm_dp_mst_put_port_malloc(port);
3162 pos->vcpi = 0;
3163 }
2701 3164
2702 return 0; 3165 return 0;
2703} 3166}
@@ -2715,7 +3178,7 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
2715{ 3178{
2716 int ret; 3179 int ret;
2717 3180
2718 port = drm_dp_get_validated_port_ref(mgr, port); 3181 port = drm_dp_mst_topology_get_port_validated(mgr, port);
2719 if (!port) 3182 if (!port)
2720 return false; 3183 return false;
2721 3184
@@ -2723,9 +3186,10 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
2723 return false; 3186 return false;
2724 3187
2725 if (port->vcpi.vcpi > 0) { 3188 if (port->vcpi.vcpi > 0) {
2726 DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n", port->vcpi.vcpi, port->vcpi.pbn, pbn); 3189 DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n",
3190 port->vcpi.vcpi, port->vcpi.pbn, pbn);
2727 if (pbn == port->vcpi.pbn) { 3191 if (pbn == port->vcpi.pbn) {
2728 drm_dp_put_port(port); 3192 drm_dp_mst_topology_put_port(port);
2729 return true; 3193 return true;
2730 } 3194 }
2731 } 3195 }
@@ -2733,13 +3197,15 @@ bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
2733 ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots); 3197 ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn, slots);
2734 if (ret) { 3198 if (ret) {
2735 DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n", 3199 DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n",
2736 DIV_ROUND_UP(pbn, mgr->pbn_div), ret); 3200 DIV_ROUND_UP(pbn, mgr->pbn_div), ret);
2737 goto out; 3201 goto out;
2738 } 3202 }
2739 DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n", 3203 DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n",
2740 pbn, port->vcpi.num_slots); 3204 pbn, port->vcpi.num_slots);
2741 3205
2742 drm_dp_put_port(port); 3206 /* Keep port allocated until it's payload has been removed */
3207 drm_dp_mst_get_port_malloc(port);
3208 drm_dp_mst_topology_put_port(port);
2743 return true; 3209 return true;
2744out: 3210out:
2745 return false; 3211 return false;
@@ -2749,12 +3215,12 @@ EXPORT_SYMBOL(drm_dp_mst_allocate_vcpi);
2749int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) 3215int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
2750{ 3216{
2751 int slots = 0; 3217 int slots = 0;
2752 port = drm_dp_get_validated_port_ref(mgr, port); 3218 port = drm_dp_mst_topology_get_port_validated(mgr, port);
2753 if (!port) 3219 if (!port)
2754 return slots; 3220 return slots;
2755 3221
2756 slots = port->vcpi.num_slots; 3222 slots = port->vcpi.num_slots;
2757 drm_dp_put_port(port); 3223 drm_dp_mst_topology_put_port(port);
2758 return slots; 3224 return slots;
2759} 3225}
2760EXPORT_SYMBOL(drm_dp_mst_get_vcpi_slots); 3226EXPORT_SYMBOL(drm_dp_mst_get_vcpi_slots);
@@ -2768,11 +3234,12 @@ EXPORT_SYMBOL(drm_dp_mst_get_vcpi_slots);
2768 */ 3234 */
2769void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) 3235void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
2770{ 3236{
2771 port = drm_dp_get_validated_port_ref(mgr, port); 3237 /*
2772 if (!port) 3238 * A port with VCPI will remain allocated until it's VCPI is
2773 return; 3239 * released, no verified ref needed
3240 */
3241
2774 port->vcpi.num_slots = 0; 3242 port->vcpi.num_slots = 0;
2775 drm_dp_put_port(port);
2776} 3243}
2777EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots); 3244EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots);
2778 3245
@@ -2781,18 +3248,20 @@ EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots);
2781 * @mgr: manager for this port 3248 * @mgr: manager for this port
2782 * @port: unverified port to deallocate vcpi for 3249 * @port: unverified port to deallocate vcpi for
2783 */ 3250 */
2784void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) 3251void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
3252 struct drm_dp_mst_port *port)
2785{ 3253{
2786 port = drm_dp_get_validated_port_ref(mgr, port); 3254 /*
2787 if (!port) 3255 * A port with VCPI will remain allocated until it's VCPI is
2788 return; 3256 * released, no verified ref needed
3257 */
2789 3258
2790 drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); 3259 drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
2791 port->vcpi.num_slots = 0; 3260 port->vcpi.num_slots = 0;
2792 port->vcpi.pbn = 0; 3261 port->vcpi.pbn = 0;
2793 port->vcpi.aligned_pbn = 0; 3262 port->vcpi.aligned_pbn = 0;
2794 port->vcpi.vcpi = 0; 3263 port->vcpi.vcpi = 0;
2795 drm_dp_put_port(port); 3264 drm_dp_mst_put_port_malloc(port);
2796} 3265}
2797EXPORT_SYMBOL(drm_dp_mst_deallocate_vcpi); 3266EXPORT_SYMBOL(drm_dp_mst_deallocate_vcpi);
2798 3267
@@ -3076,13 +3545,6 @@ static void drm_dp_tx_work(struct work_struct *work)
3076 mutex_unlock(&mgr->qlock); 3545 mutex_unlock(&mgr->qlock);
3077} 3546}
3078 3547
3079static void drm_dp_free_mst_port(struct kref *kref)
3080{
3081 struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref);
3082 kref_put(&port->parent->kref, drm_dp_free_mst_branch_device);
3083 kfree(port);
3084}
3085
3086static void drm_dp_destroy_connector_work(struct work_struct *work) 3548static void drm_dp_destroy_connector_work(struct work_struct *work)
3087{ 3549{
3088 struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work); 3550 struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work);
@@ -3103,7 +3565,6 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
3103 list_del(&port->next); 3565 list_del(&port->next);
3104 mutex_unlock(&mgr->destroy_connector_lock); 3566 mutex_unlock(&mgr->destroy_connector_lock);
3105 3567
3106 kref_init(&port->kref);
3107 INIT_LIST_HEAD(&port->next); 3568 INIT_LIST_HEAD(&port->next);
3108 3569
3109 mgr->cbs->destroy_connector(mgr, port->connector); 3570 mgr->cbs->destroy_connector(mgr, port->connector);
@@ -3111,13 +3572,7 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
3111 drm_dp_port_teardown_pdt(port, port->pdt); 3572 drm_dp_port_teardown_pdt(port, port->pdt);
3112 port->pdt = DP_PEER_DEVICE_NONE; 3573 port->pdt = DP_PEER_DEVICE_NONE;
3113 3574
3114 if (!port->input && port->vcpi.vcpi > 0) { 3575 drm_dp_mst_put_port_malloc(port);
3115 drm_dp_mst_reset_vcpi_slots(mgr, port);
3116 drm_dp_update_payload_part1(mgr);
3117 drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
3118 }
3119
3120 kref_put(&port->kref, drm_dp_free_mst_port);
3121 send_hotplug = true; 3576 send_hotplug = true;
3122 } 3577 }
3123 if (send_hotplug) 3578 if (send_hotplug)
@@ -3127,15 +3582,41 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
3127static struct drm_private_state * 3582static struct drm_private_state *
3128drm_dp_mst_duplicate_state(struct drm_private_obj *obj) 3583drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
3129{ 3584{
3130 struct drm_dp_mst_topology_state *state; 3585 struct drm_dp_mst_topology_state *state, *old_state =
3586 to_dp_mst_topology_state(obj->state);
3587 struct drm_dp_vcpi_allocation *pos, *vcpi;
3131 3588
3132 state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); 3589 state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
3133 if (!state) 3590 if (!state)
3134 return NULL; 3591 return NULL;
3135 3592
3136 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); 3593 __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
3137 3594
3595 INIT_LIST_HEAD(&state->vcpis);
3596
3597 list_for_each_entry(pos, &old_state->vcpis, next) {
3598 /* Prune leftover freed VCPI allocations */
3599 if (!pos->vcpi)
3600 continue;
3601
3602 vcpi = kmemdup(pos, sizeof(*vcpi), GFP_KERNEL);
3603 if (!vcpi)
3604 goto fail;
3605
3606 drm_dp_mst_get_port_malloc(vcpi->port);
3607 list_add(&vcpi->next, &state->vcpis);
3608 }
3609
3138 return &state->base; 3610 return &state->base;
3611
3612fail:
3613 list_for_each_entry_safe(pos, vcpi, &state->vcpis, next) {
3614 drm_dp_mst_put_port_malloc(pos->port);
3615 kfree(pos);
3616 }
3617 kfree(state);
3618
3619 return NULL;
3139} 3620}
3140 3621
3141static void drm_dp_mst_destroy_state(struct drm_private_obj *obj, 3622static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
@@ -3143,14 +3624,99 @@ static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
3143{ 3624{
3144 struct drm_dp_mst_topology_state *mst_state = 3625 struct drm_dp_mst_topology_state *mst_state =
3145 to_dp_mst_topology_state(state); 3626 to_dp_mst_topology_state(state);
3627 struct drm_dp_vcpi_allocation *pos, *tmp;
3628
3629 list_for_each_entry_safe(pos, tmp, &mst_state->vcpis, next) {
3630 /* We only keep references to ports with non-zero VCPIs */
3631 if (pos->vcpi)
3632 drm_dp_mst_put_port_malloc(pos->port);
3633 kfree(pos);
3634 }
3146 3635
3147 kfree(mst_state); 3636 kfree(mst_state);
3148} 3637}
3149 3638
3150static const struct drm_private_state_funcs mst_state_funcs = { 3639static inline int
3640drm_dp_mst_atomic_check_topology_state(struct drm_dp_mst_topology_mgr *mgr,
3641 struct drm_dp_mst_topology_state *mst_state)
3642{
3643 struct drm_dp_vcpi_allocation *vcpi;
3644 int avail_slots = 63, payload_count = 0;
3645
3646 list_for_each_entry(vcpi, &mst_state->vcpis, next) {
3647 /* Releasing VCPI is always OK-even if the port is gone */
3648 if (!vcpi->vcpi) {
3649 DRM_DEBUG_ATOMIC("[MST PORT:%p] releases all VCPI slots\n",
3650 vcpi->port);
3651 continue;
3652 }
3653
3654 DRM_DEBUG_ATOMIC("[MST PORT:%p] requires %d vcpi slots\n",
3655 vcpi->port, vcpi->vcpi);
3656
3657 avail_slots -= vcpi->vcpi;
3658 if (avail_slots < 0) {
3659 DRM_DEBUG_ATOMIC("[MST PORT:%p] not enough VCPI slots in mst state %p (avail=%d)\n",
3660 vcpi->port, mst_state,
3661 avail_slots + vcpi->vcpi);
3662 return -ENOSPC;
3663 }
3664
3665 if (++payload_count > mgr->max_payloads) {
3666 DRM_DEBUG_ATOMIC("[MST MGR:%p] state %p has too many payloads (max=%d)\n",
3667 mgr, mst_state, mgr->max_payloads);
3668 return -EINVAL;
3669 }
3670 }
3671 DRM_DEBUG_ATOMIC("[MST MGR:%p] mst state %p VCPI avail=%d used=%d\n",
3672 mgr, mst_state, avail_slots,
3673 63 - avail_slots);
3674
3675 return 0;
3676}
3677
3678/**
3679 * drm_dp_mst_atomic_check - Check that the new state of an MST topology in an
3680 * atomic update is valid
3681 * @state: Pointer to the new &struct drm_dp_mst_topology_state
3682 *
3683 * Checks the given topology state for an atomic update to ensure that it's
3684 * valid. This includes checking whether there's enough bandwidth to support
3685 * the new VCPI allocations in the atomic update.
3686 *
3687 * Any atomic drivers supporting DP MST must make sure to call this after
3688 * checking the rest of their state in their
3689 * &drm_mode_config_funcs.atomic_check() callback.
3690 *
3691 * See also:
3692 * drm_dp_atomic_find_vcpi_slots()
3693 * drm_dp_atomic_release_vcpi_slots()
3694 *
3695 * Returns:
3696 *
3697 * 0 if the new state is valid, negative error code otherwise.
3698 */
3699int drm_dp_mst_atomic_check(struct drm_atomic_state *state)
3700{
3701 struct drm_dp_mst_topology_mgr *mgr;
3702 struct drm_dp_mst_topology_state *mst_state;
3703 int i, ret = 0;
3704
3705 for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) {
3706 ret = drm_dp_mst_atomic_check_topology_state(mgr, mst_state);
3707 if (ret)
3708 break;
3709 }
3710
3711 return ret;
3712}
3713EXPORT_SYMBOL(drm_dp_mst_atomic_check);
3714
3715const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs = {
3151 .atomic_duplicate_state = drm_dp_mst_duplicate_state, 3716 .atomic_duplicate_state = drm_dp_mst_duplicate_state,
3152 .atomic_destroy_state = drm_dp_mst_destroy_state, 3717 .atomic_destroy_state = drm_dp_mst_destroy_state,
3153}; 3718};
3719EXPORT_SYMBOL(drm_dp_mst_topology_state_funcs);
3154 3720
3155/** 3721/**
3156 * drm_atomic_get_mst_topology_state: get MST topology state 3722 * drm_atomic_get_mst_topology_state: get MST topology state
@@ -3228,13 +3794,11 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
3228 return -ENOMEM; 3794 return -ENOMEM;
3229 3795
3230 mst_state->mgr = mgr; 3796 mst_state->mgr = mgr;
3231 3797 INIT_LIST_HEAD(&mst_state->vcpis);
3232 /* max. time slots - one slot for MTP header */
3233 mst_state->avail_slots = 63;
3234 3798
3235 drm_atomic_private_obj_init(dev, &mgr->base, 3799 drm_atomic_private_obj_init(dev, &mgr->base,
3236 &mst_state->base, 3800 &mst_state->base,
3237 &mst_state_funcs); 3801 &drm_dp_mst_topology_state_funcs);
3238 3802
3239 return 0; 3803 return 0;
3240} 3804}
@@ -3292,7 +3856,7 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs
3292 struct drm_dp_sideband_msg_tx *txmsg = NULL; 3856 struct drm_dp_sideband_msg_tx *txmsg = NULL;
3293 int ret; 3857 int ret;
3294 3858
3295 mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); 3859 mstb = drm_dp_mst_topology_get_mstb_validated(mgr, port->parent);
3296 if (!mstb) 3860 if (!mstb)
3297 return -EREMOTEIO; 3861 return -EREMOTEIO;
3298 3862
@@ -3342,7 +3906,7 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs
3342 } 3906 }
3343out: 3907out:
3344 kfree(txmsg); 3908 kfree(txmsg);
3345 drm_dp_put_mst_branch_device(mstb); 3909 drm_dp_mst_topology_put_mstb(mstb);
3346 return ret; 3910 return ret;
3347} 3911}
3348 3912
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index a5fe91b8c3c9..381581b01d48 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -264,14 +264,13 @@ void drm_minor_release(struct drm_minor *minor)
264 * DOC: driver instance overview 264 * DOC: driver instance overview
265 * 265 *
266 * A device instance for a drm driver is represented by &struct drm_device. This 266 * A device instance for a drm driver is represented by &struct drm_device. This
267 * is allocated with drm_dev_alloc(), usually from bus-specific ->probe() 267 * is initialized with drm_dev_init(), usually from bus-specific ->probe()
268 * callbacks implemented by the driver. The driver then needs to initialize all 268 * callbacks implemented by the driver. The driver then needs to initialize all
269 * the various subsystems for the drm device like memory management, vblank 269 * the various subsystems for the drm device like memory management, vblank
270 * handling, modesetting support and intial output configuration plus obviously 270 * handling, modesetting support and intial output configuration plus obviously
271 * initialize all the corresponding hardware bits. An important part of this is 271 * initialize all the corresponding hardware bits. Finally when everything is up
272 * also calling drm_dev_set_unique() to set the userspace-visible unique name of 272 * and running and ready for userspace the device instance can be published
273 * this device instance. Finally when everything is up and running and ready for 273 * using drm_dev_register().
274 * userspace the device instance can be published using drm_dev_register().
275 * 274 *
276 * There is also deprecated support for initalizing device instances using 275 * There is also deprecated support for initalizing device instances using
277 * bus-specific helpers and the &drm_driver.load callback. But due to 276 * bus-specific helpers and the &drm_driver.load callback. But due to
@@ -287,9 +286,6 @@ void drm_minor_release(struct drm_minor *minor)
287 * Note that the lifetime rules for &drm_device instance has still a lot of 286 * Note that the lifetime rules for &drm_device instance has still a lot of
288 * historical baggage. Hence use the reference counting provided by 287 * historical baggage. Hence use the reference counting provided by
289 * drm_dev_get() and drm_dev_put() only carefully. 288 * drm_dev_get() and drm_dev_put() only carefully.
290 *
291 * It is recommended that drivers embed &struct drm_device into their own device
292 * structure, which is supported through drm_dev_init().
293 */ 289 */
294 290
295/** 291/**
@@ -475,6 +471,9 @@ static void drm_fs_inode_free(struct inode *inode)
475 * The initial ref-count of the object is 1. Use drm_dev_get() and 471 * The initial ref-count of the object is 1. Use drm_dev_get() and
476 * drm_dev_put() to take and drop further ref-counts. 472 * drm_dev_put() to take and drop further ref-counts.
477 * 473 *
474 * It is recommended that drivers embed &struct drm_device into their own device
475 * structure.
476 *
478 * Drivers that do not want to allocate their own device struct 477 * Drivers that do not want to allocate their own device struct
479 * embedding &struct drm_device can call drm_dev_alloc() instead. For drivers 478 * embedding &struct drm_device can call drm_dev_alloc() instead. For drivers
480 * that do embed &struct drm_device it must be placed first in the overall 479 * that do embed &struct drm_device it must be placed first in the overall
@@ -765,7 +764,7 @@ static void remove_compat_control_link(struct drm_device *dev)
765 * @flags: Flags passed to the driver's .load() function 764 * @flags: Flags passed to the driver's .load() function
766 * 765 *
767 * Register the DRM device @dev with the system, advertise device to user-space 766 * Register the DRM device @dev with the system, advertise device to user-space
768 * and start normal device operation. @dev must be allocated via drm_dev_alloc() 767 * and start normal device operation. @dev must be initialized via drm_dev_init()
769 * previously. 768 * previously.
770 * 769 *
771 * Never call this twice on any device! 770 * Never call this twice on any device!
@@ -877,9 +876,9 @@ EXPORT_SYMBOL(drm_dev_unregister);
877 * @dev: device of which to set the unique name 876 * @dev: device of which to set the unique name
878 * @name: unique name 877 * @name: unique name
879 * 878 *
880 * Sets the unique name of a DRM device using the specified string. Drivers 879 * Sets the unique name of a DRM device using the specified string. This is
881 * can use this at driver probe time if the unique name of the devices they 880 * already done by drm_dev_init(), drivers should only override the default
882 * drive is static. 881 * unique name for backwards compatibility reasons.
883 * 882 *
884 * Return: 0 on success or a negative error code on failure. 883 * Return: 0 on success or a negative error code on failure.
885 */ 884 */
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b506e3622b08..990b1909f9d7 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3641,6 +3641,20 @@ static bool cea_db_is_hdmi_forum_vsdb(const u8 *db)
3641 return oui == HDMI_FORUM_IEEE_OUI; 3641 return oui == HDMI_FORUM_IEEE_OUI;
3642} 3642}
3643 3643
3644static bool cea_db_is_vcdb(const u8 *db)
3645{
3646 if (cea_db_tag(db) != USE_EXTENDED_TAG)
3647 return false;
3648
3649 if (cea_db_payload_len(db) != 2)
3650 return false;
3651
3652 if (cea_db_extended_tag(db) != EXT_VIDEO_CAPABILITY_BLOCK)
3653 return false;
3654
3655 return true;
3656}
3657
3644static bool cea_db_is_y420cmdb(const u8 *db) 3658static bool cea_db_is_y420cmdb(const u8 *db)
3645{ 3659{
3646 if (cea_db_tag(db) != USE_EXTENDED_TAG) 3660 if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -4223,41 +4237,6 @@ end:
4223} 4237}
4224EXPORT_SYMBOL(drm_detect_monitor_audio); 4238EXPORT_SYMBOL(drm_detect_monitor_audio);
4225 4239
4226/**
4227 * drm_rgb_quant_range_selectable - is RGB quantization range selectable?
4228 * @edid: EDID block to scan
4229 *
4230 * Check whether the monitor reports the RGB quantization range selection
4231 * as supported. The AVI infoframe can then be used to inform the monitor
4232 * which quantization range (full or limited) is used.
4233 *
4234 * Return: True if the RGB quantization range is selectable, false otherwise.
4235 */
4236bool drm_rgb_quant_range_selectable(struct edid *edid)
4237{
4238 u8 *edid_ext;
4239 int i, start, end;
4240
4241 edid_ext = drm_find_cea_extension(edid);
4242 if (!edid_ext)
4243 return false;
4244
4245 if (cea_db_offsets(edid_ext, &start, &end))
4246 return false;
4247
4248 for_each_cea_db(edid_ext, i, start, end) {
4249 if (cea_db_tag(&edid_ext[i]) == USE_EXTENDED_TAG &&
4250 cea_db_payload_len(&edid_ext[i]) == 2 &&
4251 cea_db_extended_tag(&edid_ext[i]) ==
4252 EXT_VIDEO_CAPABILITY_BLOCK) {
4253 DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
4254 return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
4255 }
4256 }
4257
4258 return false;
4259}
4260EXPORT_SYMBOL(drm_rgb_quant_range_selectable);
4261 4240
4262/** 4241/**
4263 * drm_default_rgb_quant_range - default RGB quantization range 4242 * drm_default_rgb_quant_range - default RGB quantization range
@@ -4278,6 +4257,16 @@ drm_default_rgb_quant_range(const struct drm_display_mode *mode)
4278} 4257}
4279EXPORT_SYMBOL(drm_default_rgb_quant_range); 4258EXPORT_SYMBOL(drm_default_rgb_quant_range);
4280 4259
4260static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
4261{
4262 struct drm_display_info *info = &connector->display_info;
4263
4264 DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", db[2]);
4265
4266 if (db[2] & EDID_CEA_VCDB_QS)
4267 info->rgb_quant_range_selectable = true;
4268}
4269
4281static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector, 4270static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
4282 const u8 *db) 4271 const u8 *db)
4283{ 4272{
@@ -4452,6 +4441,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
4452 drm_parse_hdmi_forum_vsdb(connector, db); 4441 drm_parse_hdmi_forum_vsdb(connector, db);
4453 if (cea_db_is_y420cmdb(db)) 4442 if (cea_db_is_y420cmdb(db))
4454 drm_parse_y420cmdb_bitmap(connector, db); 4443 drm_parse_y420cmdb_bitmap(connector, db);
4444 if (cea_db_is_vcdb(db))
4445 drm_parse_vcdb(connector, db);
4455 } 4446 }
4456} 4447}
4457 4448
@@ -4472,6 +4463,7 @@ drm_reset_display_info(struct drm_connector *connector)
4472 info->max_tmds_clock = 0; 4463 info->max_tmds_clock = 0;
4473 info->dvi_dual = false; 4464 info->dvi_dual = false;
4474 info->has_hdmi_infoframe = false; 4465 info->has_hdmi_infoframe = false;
4466 info->rgb_quant_range_selectable = false;
4475 memset(&info->hdmi, 0, sizeof(info->hdmi)); 4467 memset(&info->hdmi, 0, sizeof(info->hdmi));
4476 4468
4477 info->non_desktop = 0; 4469 info->non_desktop = 0;
@@ -4830,19 +4822,32 @@ void drm_set_preferred_mode(struct drm_connector *connector,
4830} 4822}
4831EXPORT_SYMBOL(drm_set_preferred_mode); 4823EXPORT_SYMBOL(drm_set_preferred_mode);
4832 4824
4825static bool is_hdmi2_sink(struct drm_connector *connector)
4826{
4827 /*
4828 * FIXME: sil-sii8620 doesn't have a connector around when
4829 * we need one, so we have to be prepared for a NULL connector.
4830 */
4831 if (!connector)
4832 return true;
4833
4834 return connector->display_info.hdmi.scdc.supported ||
4835 connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB420;
4836}
4837
4833/** 4838/**
4834 * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with 4839 * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
4835 * data from a DRM display mode 4840 * data from a DRM display mode
4836 * @frame: HDMI AVI infoframe 4841 * @frame: HDMI AVI infoframe
4842 * @connector: the connector
4837 * @mode: DRM display mode 4843 * @mode: DRM display mode
4838 * @is_hdmi2_sink: Sink is HDMI 2.0 compliant
4839 * 4844 *
4840 * Return: 0 on success or a negative error code on failure. 4845 * Return: 0 on success or a negative error code on failure.
4841 */ 4846 */
4842int 4847int
4843drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, 4848drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
4844 const struct drm_display_mode *mode, 4849 struct drm_connector *connector,
4845 bool is_hdmi2_sink) 4850 const struct drm_display_mode *mode)
4846{ 4851{
4847 enum hdmi_picture_aspect picture_aspect; 4852 enum hdmi_picture_aspect picture_aspect;
4848 int err; 4853 int err;
@@ -4864,7 +4869,7 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
4864 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we 4869 * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we
4865 * have to make sure we dont break HDMI 1.4 sinks. 4870 * have to make sure we dont break HDMI 1.4 sinks.
4866 */ 4871 */
4867 if (!is_hdmi2_sink && frame->video_code > 64) 4872 if (!is_hdmi2_sink(connector) && frame->video_code > 64)
4868 frame->video_code = 0; 4873 frame->video_code = 0;
4869 4874
4870 /* 4875 /*
@@ -4923,22 +4928,18 @@ EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode);
4923 * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe 4928 * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe
4924 * quantization range information 4929 * quantization range information
4925 * @frame: HDMI AVI infoframe 4930 * @frame: HDMI AVI infoframe
4931 * @connector: the connector
4926 * @mode: DRM display mode 4932 * @mode: DRM display mode
4927 * @rgb_quant_range: RGB quantization range (Q) 4933 * @rgb_quant_range: RGB quantization range (Q)
4928 * @rgb_quant_range_selectable: Sink support selectable RGB quantization range (QS)
4929 * @is_hdmi2_sink: HDMI 2.0 sink, which has different default recommendations
4930 *
4931 * Note that @is_hdmi2_sink can be derived by looking at the
4932 * &drm_scdc.supported flag stored in &drm_hdmi_info.scdc,
4933 * &drm_display_info.hdmi, which can be found in &drm_connector.display_info.
4934 */ 4934 */
4935void 4935void
4936drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame, 4936drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
4937 struct drm_connector *connector,
4937 const struct drm_display_mode *mode, 4938 const struct drm_display_mode *mode,
4938 enum hdmi_quantization_range rgb_quant_range, 4939 enum hdmi_quantization_range rgb_quant_range)
4939 bool rgb_quant_range_selectable,
4940 bool is_hdmi2_sink)
4941{ 4940{
4941 const struct drm_display_info *info = &connector->display_info;
4942
4942 /* 4943 /*
4943 * CEA-861: 4944 * CEA-861:
4944 * "A Source shall not send a non-zero Q value that does not correspond 4945 * "A Source shall not send a non-zero Q value that does not correspond
@@ -4949,7 +4950,7 @@ drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
4949 * HDMI 2.0 recommends sending non-zero Q when it does match the 4950 * HDMI 2.0 recommends sending non-zero Q when it does match the
4950 * default RGB quantization range for the mode, even when QS=0. 4951 * default RGB quantization range for the mode, even when QS=0.
4951 */ 4952 */
4952 if (rgb_quant_range_selectable || 4953 if (info->rgb_quant_range_selectable ||
4953 rgb_quant_range == drm_default_rgb_quant_range(mode)) 4954 rgb_quant_range == drm_default_rgb_quant_range(mode))
4954 frame->quantization_range = rgb_quant_range; 4955 frame->quantization_range = rgb_quant_range;
4955 else 4956 else
@@ -4968,7 +4969,7 @@ drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
4968 * we limit non-zero YQ to HDMI 2.0 sinks only as HDMI 2.0 is based 4969 * we limit non-zero YQ to HDMI 2.0 sinks only as HDMI 2.0 is based
4969 * on on CEA-861-F. 4970 * on on CEA-861-F.
4970 */ 4971 */
4971 if (!is_hdmi2_sink || 4972 if (!is_hdmi2_sink(connector) ||
4972 rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED) 4973 rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED)
4973 frame->ycc_quantization_range = 4974 frame->ycc_quantization_range =
4974 HDMI_YCC_QUANTIZATION_RANGE_LIMITED; 4975 HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index d3af098b0922..ca706fb1d975 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1797,6 +1797,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
1797 int i; 1797 int i;
1798 struct drm_fb_helper_surface_size sizes; 1798 struct drm_fb_helper_surface_size sizes;
1799 int gamma_size = 0; 1799 int gamma_size = 0;
1800 int best_depth = 0;
1800 1801
1801 memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size)); 1802 memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size));
1802 sizes.surface_depth = 24; 1803 sizes.surface_depth = 24;
@@ -1804,7 +1805,10 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
1804 sizes.fb_width = (u32)-1; 1805 sizes.fb_width = (u32)-1;
1805 sizes.fb_height = (u32)-1; 1806 sizes.fb_height = (u32)-1;
1806 1807
1807 /* if driver picks 8 or 16 by default use that for both depth/bpp */ 1808 /*
1809 * If driver picks 8 or 16 by default use that for both depth/bpp
1810 * to begin with
1811 */
1808 if (preferred_bpp != sizes.surface_bpp) 1812 if (preferred_bpp != sizes.surface_bpp)
1809 sizes.surface_depth = sizes.surface_bpp = preferred_bpp; 1813 sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
1810 1814
@@ -1839,6 +1843,55 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
1839 } 1843 }
1840 } 1844 }
1841 1845
1846 /*
1847 * If we run into a situation where, for example, the primary plane
1848 * supports RGBA5551 (16 bpp, depth 15) but not RGB565 (16 bpp, depth
1849 * 16) we need to scale down the depth of the sizes we request.
1850 */
1851 for (i = 0; i < fb_helper->crtc_count; i++) {
1852 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
1853 struct drm_crtc *crtc = mode_set->crtc;
1854 struct drm_plane *plane = crtc->primary;
1855 int j;
1856
1857 DRM_DEBUG("test CRTC %d primary plane\n", i);
1858
1859 for (j = 0; j < plane->format_count; j++) {
1860 const struct drm_format_info *fmt;
1861
1862 fmt = drm_format_info(plane->format_types[j]);
1863
1864 /*
1865 * Do not consider YUV or other complicated formats
1866 * for framebuffers. This means only legacy formats
1867 * are supported (fmt->depth is a legacy field) but
1868 * the framebuffer emulation can only deal with such
1869 * formats, specifically RGB/BGA formats.
1870 */
1871 if (fmt->depth == 0)
1872 continue;
1873
1874 /* We found a perfect fit, great */
1875 if (fmt->depth == sizes.surface_depth) {
1876 best_depth = fmt->depth;
1877 break;
1878 }
1879
1880 /* Skip depths above what we're looking for */
1881 if (fmt->depth > sizes.surface_depth)
1882 continue;
1883
1884 /* Best depth found so far */
1885 if (fmt->depth > best_depth)
1886 best_depth = fmt->depth;
1887 }
1888 }
1889 if (sizes.surface_depth != best_depth) {
1890 DRM_INFO("requested bpp %d, scaled depth down to %d",
1891 sizes.surface_bpp, best_depth);
1892 sizes.surface_depth = best_depth;
1893 }
1894
1842 crtc_count = 0; 1895 crtc_count = 0;
1843 for (i = 0; i < fb_helper->crtc_count; i++) { 1896 for (i = 0; i < fb_helper->crtc_count; i++) {
1844 struct drm_display_mode *desired_mode; 1897 struct drm_display_mode *desired_mode;
@@ -2866,7 +2919,7 @@ int drm_fb_helper_fbdev_setup(struct drm_device *dev,
2866 return 0; 2919 return 0;
2867 2920
2868err_drm_fb_helper_fini: 2921err_drm_fb_helper_fini:
2869 drm_fb_helper_fini(fb_helper); 2922 drm_fb_helper_fbdev_teardown(dev);
2870 2923
2871 return ret; 2924 return ret;
2872} 2925}
@@ -2961,18 +3014,16 @@ static int drm_fbdev_fb_release(struct fb_info *info, int user)
2961 return 0; 3014 return 0;
2962} 3015}
2963 3016
2964/* 3017static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
2965 * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of
2966 * unregister_framebuffer() or fb_release().
2967 */
2968static void drm_fbdev_fb_destroy(struct fb_info *info)
2969{ 3018{
2970 struct drm_fb_helper *fb_helper = info->par;
2971 struct fb_info *fbi = fb_helper->fbdev; 3019 struct fb_info *fbi = fb_helper->fbdev;
2972 struct fb_ops *fbops = NULL; 3020 struct fb_ops *fbops = NULL;
2973 void *shadow = NULL; 3021 void *shadow = NULL;
2974 3022
2975 if (fbi->fbdefio) { 3023 if (!fb_helper->dev)
3024 return;
3025
3026 if (fbi && fbi->fbdefio) {
2976 fb_deferred_io_cleanup(fbi); 3027 fb_deferred_io_cleanup(fbi);
2977 shadow = fbi->screen_buffer; 3028 shadow = fbi->screen_buffer;
2978 fbops = fbi->fbops; 3029 fbops = fbi->fbops;
@@ -2986,6 +3037,12 @@ static void drm_fbdev_fb_destroy(struct fb_info *info)
2986 } 3037 }
2987 3038
2988 drm_client_framebuffer_delete(fb_helper->buffer); 3039 drm_client_framebuffer_delete(fb_helper->buffer);
3040}
3041
3042static void drm_fbdev_release(struct drm_fb_helper *fb_helper)
3043{
3044 drm_fbdev_cleanup(fb_helper);
3045
2989 /* 3046 /*
2990 * FIXME: 3047 * FIXME:
2991 * Remove conditional when all CMA drivers have been moved over to using 3048 * Remove conditional when all CMA drivers have been moved over to using
@@ -2997,6 +3054,15 @@ static void drm_fbdev_fb_destroy(struct fb_info *info)
2997 } 3054 }
2998} 3055}
2999 3056
3057/*
3058 * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of
3059 * unregister_framebuffer() or fb_release().
3060 */
3061static void drm_fbdev_fb_destroy(struct fb_info *info)
3062{
3063 drm_fbdev_release(info->par);
3064}
3065
3000static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 3066static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
3001{ 3067{
3002 struct drm_fb_helper *fb_helper = info->par; 3068 struct drm_fb_helper *fb_helper = info->par;
@@ -3047,7 +3113,6 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
3047 struct drm_framebuffer *fb; 3113 struct drm_framebuffer *fb;
3048 struct fb_info *fbi; 3114 struct fb_info *fbi;
3049 u32 format; 3115 u32 format;
3050 int ret;
3051 3116
3052 DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n", 3117 DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",
3053 sizes->surface_width, sizes->surface_height, 3118 sizes->surface_width, sizes->surface_height,
@@ -3064,10 +3129,8 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
3064 fb = buffer->fb; 3129 fb = buffer->fb;
3065 3130
3066 fbi = drm_fb_helper_alloc_fbi(fb_helper); 3131 fbi = drm_fb_helper_alloc_fbi(fb_helper);
3067 if (IS_ERR(fbi)) { 3132 if (IS_ERR(fbi))
3068 ret = PTR_ERR(fbi); 3133 return PTR_ERR(fbi);
3069 goto err_free_buffer;
3070 }
3071 3134
3072 fbi->par = fb_helper; 3135 fbi->par = fb_helper;
3073 fbi->fbops = &drm_fbdev_fb_ops; 3136 fbi->fbops = &drm_fbdev_fb_ops;
@@ -3098,8 +3161,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
3098 if (!fbops || !shadow) { 3161 if (!fbops || !shadow) {
3099 kfree(fbops); 3162 kfree(fbops);
3100 vfree(shadow); 3163 vfree(shadow);
3101 ret = -ENOMEM; 3164 return -ENOMEM;
3102 goto err_fb_info_destroy;
3103 } 3165 }
3104 3166
3105 *fbops = *fbi->fbops; 3167 *fbops = *fbi->fbops;
@@ -3111,13 +3173,6 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
3111 } 3173 }
3112 3174
3113 return 0; 3175 return 0;
3114
3115err_fb_info_destroy:
3116 drm_fb_helper_fini(fb_helper);
3117err_free_buffer:
3118 drm_client_framebuffer_delete(buffer);
3119
3120 return ret;
3121} 3176}
3122EXPORT_SYMBOL(drm_fb_helper_generic_probe); 3177EXPORT_SYMBOL(drm_fb_helper_generic_probe);
3123 3178
@@ -3129,18 +3184,11 @@ static void drm_fbdev_client_unregister(struct drm_client_dev *client)
3129{ 3184{
3130 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); 3185 struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
3131 3186
3132 if (fb_helper->fbdev) { 3187 if (fb_helper->fbdev)
3133 drm_fb_helper_unregister_fbi(fb_helper);
3134 /* drm_fbdev_fb_destroy() takes care of cleanup */ 3188 /* drm_fbdev_fb_destroy() takes care of cleanup */
3135 return; 3189 drm_fb_helper_unregister_fbi(fb_helper);
3136 } 3190 else
3137 3191 drm_fbdev_release(fb_helper);
3138 /* Did drm_fb_helper_fbdev_setup() run? */
3139 if (fb_helper->dev)
3140 drm_fb_helper_fini(fb_helper);
3141
3142 drm_client_release(client);
3143 kfree(fb_helper);
3144} 3192}
3145 3193
3146static int drm_fbdev_client_restore(struct drm_client_dev *client) 3194static int drm_fbdev_client_restore(struct drm_client_dev *client)
@@ -3158,7 +3206,7 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
3158 struct drm_device *dev = client->dev; 3206 struct drm_device *dev = client->dev;
3159 int ret; 3207 int ret;
3160 3208
3161 /* If drm_fb_helper_fbdev_setup() failed, we only try once */ 3209 /* Setup is not retried if it has failed */
3162 if (!fb_helper->dev && fb_helper->funcs) 3210 if (!fb_helper->dev && fb_helper->funcs)
3163 return 0; 3211 return 0;
3164 3212
@@ -3170,15 +3218,34 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
3170 return 0; 3218 return 0;
3171 } 3219 }
3172 3220
3173 ret = drm_fb_helper_fbdev_setup(dev, fb_helper, &drm_fb_helper_generic_funcs, 3221 drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs);
3174 fb_helper->preferred_bpp, 0); 3222
3175 if (ret) { 3223 ret = drm_fb_helper_init(dev, fb_helper, dev->mode_config.num_connector);
3176 fb_helper->dev = NULL; 3224 if (ret)
3177 fb_helper->fbdev = NULL; 3225 goto err;
3178 return ret; 3226
3179 } 3227 ret = drm_fb_helper_single_add_all_connectors(fb_helper);
3228 if (ret)
3229 goto err_cleanup;
3230
3231 if (!drm_drv_uses_atomic_modeset(dev))
3232 drm_helper_disable_unused_functions(dev);
3233
3234 ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp);
3235 if (ret)
3236 goto err_cleanup;
3180 3237
3181 return 0; 3238 return 0;
3239
3240err_cleanup:
3241 drm_fbdev_cleanup(fb_helper);
3242err:
3243 fb_helper->dev = NULL;
3244 fb_helper->fbdev = NULL;
3245
3246 DRM_DEV_ERROR(dev->dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret);
3247
3248 return ret;
3182} 3249}
3183 3250
3184static const struct drm_client_funcs drm_fbdev_client_funcs = { 3251static const struct drm_client_funcs drm_fbdev_client_funcs = {
@@ -3237,6 +3304,10 @@ int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
3237 3304
3238 drm_client_add(&fb_helper->client); 3305 drm_client_add(&fb_helper->client);
3239 3306
3307 if (!preferred_bpp)
3308 preferred_bpp = dev->mode_config.preferred_depth;
3309 if (!preferred_bpp)
3310 preferred_bpp = 32;
3240 fb_helper->preferred_bpp = preferred_bpp; 3311 fb_helper->preferred_bpp = preferred_bpp;
3241 3312
3242 ret = drm_fbdev_client_hotplug(&fb_helper->client); 3313 ret = drm_fbdev_client_hotplug(&fb_helper->client);
diff --git a/drivers/gpu/drm/drm_flip_work.c b/drivers/gpu/drm/drm_flip_work.c
index 12dea16f22a8..3da3bf5af405 100644
--- a/drivers/gpu/drm/drm_flip_work.c
+++ b/drivers/gpu/drm/drm_flip_work.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <drm/drmP.h> 24#include <drm/drmP.h>
25#include <drm/drm_util.h>
25#include <drm/drm_flip_work.h> 26#include <drm/drm_flip_work.h>
26 27
27/** 28/**
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index fcaea8f50513..7abcb265a108 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -27,6 +27,7 @@
27#include <drm/drm_atomic.h> 27#include <drm/drm_atomic.h>
28#include <drm/drm_atomic_uapi.h> 28#include <drm/drm_atomic_uapi.h>
29#include <drm/drm_print.h> 29#include <drm/drm_print.h>
30#include <drm/drm_util.h>
30 31
31#include "drm_internal.h" 32#include "drm_internal.h"
32#include "drm_crtc_internal.h" 33#include "drm_crtc_internal.h"
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 8b55ece97967..2896ff60552f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -37,6 +37,7 @@
37#include <linux/shmem_fs.h> 37#include <linux/shmem_fs.h>
38#include <linux/dma-buf.h> 38#include <linux/dma-buf.h>
39#include <linux/mem_encrypt.h> 39#include <linux/mem_encrypt.h>
40#include <linux/pagevec.h>
40#include <drm/drmP.h> 41#include <drm/drmP.h>
41#include <drm/drm_vma_manager.h> 42#include <drm/drm_vma_manager.h>
42#include <drm/drm_gem.h> 43#include <drm/drm_gem.h>
@@ -526,6 +527,17 @@ int drm_gem_create_mmap_offset(struct drm_gem_object *obj)
526} 527}
527EXPORT_SYMBOL(drm_gem_create_mmap_offset); 528EXPORT_SYMBOL(drm_gem_create_mmap_offset);
528 529
530/*
531 * Move pages to appropriate lru and release the pagevec, decrementing the
532 * ref count of those pages.
533 */
534static void drm_gem_check_release_pagevec(struct pagevec *pvec)
535{
536 check_move_unevictable_pages(pvec);
537 __pagevec_release(pvec);
538 cond_resched();
539}
540
529/** 541/**
530 * drm_gem_get_pages - helper to allocate backing pages for a GEM object 542 * drm_gem_get_pages - helper to allocate backing pages for a GEM object
531 * from shmem 543 * from shmem
@@ -551,6 +563,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj)
551{ 563{
552 struct address_space *mapping; 564 struct address_space *mapping;
553 struct page *p, **pages; 565 struct page *p, **pages;
566 struct pagevec pvec;
554 int i, npages; 567 int i, npages;
555 568
556 /* This is the shared memory object that backs the GEM resource */ 569 /* This is the shared memory object that backs the GEM resource */
@@ -568,6 +581,8 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj)
568 if (pages == NULL) 581 if (pages == NULL)
569 return ERR_PTR(-ENOMEM); 582 return ERR_PTR(-ENOMEM);
570 583
584 mapping_set_unevictable(mapping);
585
571 for (i = 0; i < npages; i++) { 586 for (i = 0; i < npages; i++) {
572 p = shmem_read_mapping_page(mapping, i); 587 p = shmem_read_mapping_page(mapping, i);
573 if (IS_ERR(p)) 588 if (IS_ERR(p))
@@ -586,8 +601,14 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj)
586 return pages; 601 return pages;
587 602
588fail: 603fail:
589 while (i--) 604 mapping_clear_unevictable(mapping);
590 put_page(pages[i]); 605 pagevec_init(&pvec);
606 while (i--) {
607 if (!pagevec_add(&pvec, pages[i]))
608 drm_gem_check_release_pagevec(&pvec);
609 }
610 if (pagevec_count(&pvec))
611 drm_gem_check_release_pagevec(&pvec);
591 612
592 kvfree(pages); 613 kvfree(pages);
593 return ERR_CAST(p); 614 return ERR_CAST(p);
@@ -605,6 +626,11 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
605 bool dirty, bool accessed) 626 bool dirty, bool accessed)
606{ 627{
607 int i, npages; 628 int i, npages;
629 struct address_space *mapping;
630 struct pagevec pvec;
631
632 mapping = file_inode(obj->filp)->i_mapping;
633 mapping_clear_unevictable(mapping);
608 634
609 /* We already BUG_ON() for non-page-aligned sizes in 635 /* We already BUG_ON() for non-page-aligned sizes in
610 * drm_gem_object_init(), so we should never hit this unless 636 * drm_gem_object_init(), so we should never hit this unless
@@ -614,6 +640,7 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
614 640
615 npages = obj->size >> PAGE_SHIFT; 641 npages = obj->size >> PAGE_SHIFT;
616 642
643 pagevec_init(&pvec);
617 for (i = 0; i < npages; i++) { 644 for (i = 0; i < npages; i++) {
618 if (dirty) 645 if (dirty)
619 set_page_dirty(pages[i]); 646 set_page_dirty(pages[i]);
@@ -622,8 +649,11 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
622 mark_page_accessed(pages[i]); 649 mark_page_accessed(pages[i]);
623 650
624 /* Undo the reference we took when populating the table */ 651 /* Undo the reference we took when populating the table */
625 put_page(pages[i]); 652 if (!pagevec_add(&pvec, pages[i]))
653 drm_gem_check_release_pagevec(&pvec);
626 } 654 }
655 if (pagevec_count(&pvec))
656 drm_gem_check_release_pagevec(&pvec);
627 657
628 kvfree(pages); 658 kvfree(pages);
629} 659}
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 24a750436559..adce9a26bac9 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -71,11 +71,6 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev)
71 if (!nmode) 71 if (!nmode)
72 return NULL; 72 return NULL;
73 73
74 if (drm_mode_object_add(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) {
75 kfree(nmode);
76 return NULL;
77 }
78
79 return nmode; 74 return nmode;
80} 75}
81EXPORT_SYMBOL(drm_mode_create); 76EXPORT_SYMBOL(drm_mode_create);
@@ -92,8 +87,6 @@ void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
92 if (!mode) 87 if (!mode)
93 return; 88 return;
94 89
95 drm_mode_object_unregister(dev, &mode->base);
96
97 kfree(mode); 90 kfree(mode);
98} 91}
99EXPORT_SYMBOL(drm_mode_destroy); 92EXPORT_SYMBOL(drm_mode_destroy);
@@ -911,11 +904,9 @@ EXPORT_SYMBOL(drm_mode_set_crtcinfo);
911 */ 904 */
912void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src) 905void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src)
913{ 906{
914 int id = dst->base.id;
915 struct list_head head = dst->head; 907 struct list_head head = dst->head;
916 908
917 *dst = *src; 909 *dst = *src;
918 dst->base.id = id;
919 dst->head = head; 910 dst->head = head;
920} 911}
921EXPORT_SYMBOL(drm_mode_copy); 912EXPORT_SYMBOL(drm_mode_copy);
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 2763a5ec845b..f2f71d71494a 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -217,9 +217,11 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
217} 217}
218EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint); 218EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
219 219
220/* 220/**
221 * drm_of_find_panel_or_bridge - return connected panel or bridge device 221 * drm_of_find_panel_or_bridge - return connected panel or bridge device
222 * @np: device tree node containing encoder output ports 222 * @np: device tree node containing encoder output ports
223 * @port: port in the device tree node
224 * @endpoint: endpoint in the device tree node
223 * @panel: pointer to hold returned drm_panel 225 * @panel: pointer to hold returned drm_panel
224 * @bridge: pointer to hold returned drm_bridge 226 * @bridge: pointer to hold returned drm_bridge
225 * 227 *
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index c33f95e08e1b..dbd5b873e8f2 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -36,6 +36,9 @@ static LIST_HEAD(panel_list);
36 * The DRM panel helpers allow drivers to register panel objects with a 36 * The DRM panel helpers allow drivers to register panel objects with a
37 * central registry and provide functions to retrieve those panels in display 37 * central registry and provide functions to retrieve those panels in display
38 * drivers. 38 * drivers.
39 *
40 * For easy integration into drivers using the &drm_bridge infrastructure please
41 * take look at drm_panel_bridge_add() and devm_drm_panel_bridge_add().
39 */ 42 */
40 43
41/** 44/**
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 5f650d8fc66b..4cfb56893b7f 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -220,6 +220,9 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
220 format_modifier_count++; 220 format_modifier_count++;
221 } 221 }
222 222
223 if (format_modifier_count)
224 config->allow_fb_modifiers = true;
225
223 plane->modifier_count = format_modifier_count; 226 plane->modifier_count = format_modifier_count;
224 plane->modifiers = kmalloc_array(format_modifier_count, 227 plane->modifiers = kmalloc_array(format_modifier_count,
225 sizeof(format_modifiers[0]), 228 sizeof(format_modifiers[0]),
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 98e091175921..cde71ee95a8f 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -105,13 +105,20 @@ static void store_vblank(struct drm_device *dev, unsigned int pipe,
105 write_sequnlock(&vblank->seqlock); 105 write_sequnlock(&vblank->seqlock);
106} 106}
107 107
108static u32 drm_max_vblank_count(struct drm_device *dev, unsigned int pipe)
109{
110 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
111
112 return vblank->max_vblank_count ?: dev->max_vblank_count;
113}
114
108/* 115/*
109 * "No hw counter" fallback implementation of .get_vblank_counter() hook, 116 * "No hw counter" fallback implementation of .get_vblank_counter() hook,
110 * if there is no useable hardware frame counter available. 117 * if there is no useable hardware frame counter available.
111 */ 118 */
112static u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe) 119static u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe)
113{ 120{
114 WARN_ON_ONCE(dev->max_vblank_count != 0); 121 WARN_ON_ONCE(drm_max_vblank_count(dev, pipe) != 0);
115 return 0; 122 return 0;
116} 123}
117 124
@@ -198,6 +205,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
198 ktime_t t_vblank; 205 ktime_t t_vblank;
199 int count = DRM_TIMESTAMP_MAXRETRIES; 206 int count = DRM_TIMESTAMP_MAXRETRIES;
200 int framedur_ns = vblank->framedur_ns; 207 int framedur_ns = vblank->framedur_ns;
208 u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
201 209
202 /* 210 /*
203 * Interrupts were disabled prior to this call, so deal with counter 211 * Interrupts were disabled prior to this call, so deal with counter
@@ -216,9 +224,9 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
216 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq); 224 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq);
217 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); 225 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
218 226
219 if (dev->max_vblank_count != 0) { 227 if (max_vblank_count) {
220 /* trust the hw counter when it's around */ 228 /* trust the hw counter when it's around */
221 diff = (cur_vblank - vblank->last) & dev->max_vblank_count; 229 diff = (cur_vblank - vblank->last) & max_vblank_count;
222 } else if (rc && framedur_ns) { 230 } else if (rc && framedur_ns) {
223 u64 diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time)); 231 u64 diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
224 232
@@ -1205,6 +1213,37 @@ void drm_crtc_vblank_reset(struct drm_crtc *crtc)
1205EXPORT_SYMBOL(drm_crtc_vblank_reset); 1213EXPORT_SYMBOL(drm_crtc_vblank_reset);
1206 1214
1207/** 1215/**
1216 * drm_crtc_set_max_vblank_count - configure the hw max vblank counter value
1217 * @crtc: CRTC in question
1218 * @max_vblank_count: max hardware vblank counter value
1219 *
1220 * Update the maximum hardware vblank counter value for @crtc
1221 * at runtime. Useful for hardware where the operation of the
1222 * hardware vblank counter depends on the currently active
1223 * display configuration.
1224 *
1225 * For example, if the hardware vblank counter does not work
1226 * when a specific connector is active the maximum can be set
1227 * to zero. And when that specific connector isn't active the
1228 * maximum can again be set to the appropriate non-zero value.
1229 *
1230 * If used, must be called before drm_vblank_on().
1231 */
1232void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc,
1233 u32 max_vblank_count)
1234{
1235 struct drm_device *dev = crtc->dev;
1236 unsigned int pipe = drm_crtc_index(crtc);
1237 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1238
1239 WARN_ON(dev->max_vblank_count);
1240 WARN_ON(!READ_ONCE(vblank->inmodeset));
1241
1242 vblank->max_vblank_count = max_vblank_count;
1243}
1244EXPORT_SYMBOL(drm_crtc_set_max_vblank_count);
1245
1246/**
1208 * drm_crtc_vblank_on - enable vblank events on a CRTC 1247 * drm_crtc_vblank_on - enable vblank events on a CRTC
1209 * @crtc: CRTC in question 1248 * @crtc: CRTC in question
1210 * 1249 *
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 2092a650df7d..b857df67aff0 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -819,7 +819,8 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata)
819 return; 819 return;
820 } 820 }
821 821
822 ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi, m, false); 822 ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
823 &hdata->connector, m);
823 if (!ret) 824 if (!ret)
824 ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf)); 825 ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
825 if (ret > 0) { 826 if (ret > 0) {
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index e6a62d5a00a3..15e32e5d9101 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -22,6 +22,7 @@
22#include <drm/drmP.h> 22#include <drm/drmP.h>
23#include <drm/drm_gem_cma_helper.h> 23#include <drm/drm_gem_cma_helper.h>
24#include <drm/drm_fb_cma_helper.h> 24#include <drm/drm_fb_cma_helper.h>
25#include <drm/drm_fb_helper.h>
25#include <drm/drm_gem_framebuffer_helper.h> 26#include <drm/drm_gem_framebuffer_helper.h>
26#include <drm/drm_atomic_helper.h> 27#include <drm/drm_atomic_helper.h>
27#include <drm/drm_crtc_helper.h> 28#include <drm/drm_crtc_helper.h>
@@ -33,32 +34,15 @@ static struct kirin_dc_ops *dc_ops;
33 34
34static int kirin_drm_kms_cleanup(struct drm_device *dev) 35static int kirin_drm_kms_cleanup(struct drm_device *dev)
35{ 36{
36 struct kirin_drm_private *priv = dev->dev_private;
37
38 if (priv->fbdev) {
39 drm_fbdev_cma_fini(priv->fbdev);
40 priv->fbdev = NULL;
41 }
42
43 drm_kms_helper_poll_fini(dev); 37 drm_kms_helper_poll_fini(dev);
44 dc_ops->cleanup(to_platform_device(dev->dev)); 38 dc_ops->cleanup(to_platform_device(dev->dev));
45 drm_mode_config_cleanup(dev); 39 drm_mode_config_cleanup(dev);
46 devm_kfree(dev->dev, priv);
47 dev->dev_private = NULL;
48 40
49 return 0; 41 return 0;
50} 42}
51 43
52static void kirin_fbdev_output_poll_changed(struct drm_device *dev)
53{
54 struct kirin_drm_private *priv = dev->dev_private;
55
56 drm_fbdev_cma_hotplug_event(priv->fbdev);
57}
58
59static const struct drm_mode_config_funcs kirin_drm_mode_config_funcs = { 44static const struct drm_mode_config_funcs kirin_drm_mode_config_funcs = {
60 .fb_create = drm_gem_fb_create, 45 .fb_create = drm_gem_fb_create,
61 .output_poll_changed = kirin_fbdev_output_poll_changed,
62 .atomic_check = drm_atomic_helper_check, 46 .atomic_check = drm_atomic_helper_check,
63 .atomic_commit = drm_atomic_helper_commit, 47 .atomic_commit = drm_atomic_helper_commit,
64}; 48};
@@ -76,14 +60,8 @@ static void kirin_drm_mode_config_init(struct drm_device *dev)
76 60
77static int kirin_drm_kms_init(struct drm_device *dev) 61static int kirin_drm_kms_init(struct drm_device *dev)
78{ 62{
79 struct kirin_drm_private *priv;
80 int ret; 63 int ret;
81 64
82 priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
83 if (!priv)
84 return -ENOMEM;
85
86 dev->dev_private = priv;
87 dev_set_drvdata(dev->dev, dev); 65 dev_set_drvdata(dev->dev, dev);
88 66
89 /* dev->mode_config initialization */ 67 /* dev->mode_config initialization */
@@ -117,26 +95,14 @@ static int kirin_drm_kms_init(struct drm_device *dev)
117 /* init kms poll for handling hpd */ 95 /* init kms poll for handling hpd */
118 drm_kms_helper_poll_init(dev); 96 drm_kms_helper_poll_init(dev);
119 97
120 priv->fbdev = drm_fbdev_cma_init(dev, 32,
121 dev->mode_config.num_connector);
122
123 if (IS_ERR(priv->fbdev)) {
124 DRM_ERROR("failed to initialize fbdev.\n");
125 ret = PTR_ERR(priv->fbdev);
126 goto err_cleanup_poll;
127 }
128 return 0; 98 return 0;
129 99
130err_cleanup_poll:
131 drm_kms_helper_poll_fini(dev);
132err_unbind_all: 100err_unbind_all:
133 component_unbind_all(dev->dev, dev); 101 component_unbind_all(dev->dev, dev);
134err_dc_cleanup: 102err_dc_cleanup:
135 dc_ops->cleanup(to_platform_device(dev->dev)); 103 dc_ops->cleanup(to_platform_device(dev->dev));
136err_mode_config_cleanup: 104err_mode_config_cleanup:
137 drm_mode_config_cleanup(dev); 105 drm_mode_config_cleanup(dev);
138 devm_kfree(dev->dev, priv);
139 dev->dev_private = NULL;
140 106
141 return ret; 107 return ret;
142} 108}
@@ -199,6 +165,8 @@ static int kirin_drm_bind(struct device *dev)
199 if (ret) 165 if (ret)
200 goto err_kms_cleanup; 166 goto err_kms_cleanup;
201 167
168 drm_fbdev_generic_setup(drm_dev, 32);
169
202 return 0; 170 return 0;
203 171
204err_kms_cleanup: 172err_kms_cleanup:
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
index 56cb62df065c..ad027d1cc826 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
@@ -19,10 +19,6 @@ struct kirin_dc_ops {
19 void (*cleanup)(struct platform_device *pdev); 19 void (*cleanup)(struct platform_device *pdev);
20}; 20};
21 21
22struct kirin_drm_private {
23 struct drm_fbdev_cma *fbdev;
24};
25
26extern const struct kirin_dc_ops ade_dc_ops; 22extern const struct kirin_dc_ops ade_dc_ops;
27 23
28#endif /* __KIRIN_DRM_DRV_H__ */ 24#endif /* __KIRIN_DRM_DRV_H__ */
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
index 544a8a2d3562..b91e48d2190d 100644
--- a/drivers/gpu/drm/i2c/ch7006_drv.c
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
@@ -359,10 +359,10 @@ static int ch7006_encoder_set_property(struct drm_encoder *encoder,
359 if (modes_changed) { 359 if (modes_changed) {
360 drm_helper_probe_single_connector_modes(connector, 0, 0); 360 drm_helper_probe_single_connector_modes(connector, 0, 0);
361 361
362 /* Disable the crtc to ensure a full modeset is
363 * performed whenever it's turned on again. */
364 if (crtc) 362 if (crtc)
365 drm_crtc_force_disable(crtc); 363 drm_crtc_helper_set_mode(crtc, &crtc->mode,
364 crtc->x, crtc->y,
365 crtc->primary->fb);
366 } 366 }
367 367
368 return 0; 368 return 0;
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index a6ba461749b2..ecdb8070ed35 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -849,7 +849,8 @@ tda998x_write_avi(struct tda998x_priv *priv, const struct drm_display_mode *mode
849{ 849{
850 union hdmi_infoframe frame; 850 union hdmi_infoframe frame;
851 851
852 drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false); 852 drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
853 &priv->connector, mode);
853 frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL; 854 frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
854 855
855 tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame); 856 tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame);
@@ -1122,7 +1123,6 @@ static void tda998x_connector_destroy(struct drm_connector *connector)
1122} 1123}
1123 1124
1124static const struct drm_connector_funcs tda998x_connector_funcs = { 1125static const struct drm_connector_funcs tda998x_connector_funcs = {
1125 .dpms = drm_helper_connector_dpms,
1126 .reset = drm_atomic_helper_connector_reset, 1126 .reset = drm_atomic_helper_connector_reset,
1127 .fill_modes = drm_helper_probe_single_connector_modes, 1127 .fill_modes = drm_helper_probe_single_connector_modes,
1128 .detect = tda998x_connector_detect, 1128 .detect = tda998x_connector_detect,
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 38dcee1ca062..9bad6a32adae 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2948,14 +2948,7 @@ static void intel_seq_print_mode(struct seq_file *m, int tabs,
2948 for (i = 0; i < tabs; i++) 2948 for (i = 0; i < tabs; i++)
2949 seq_putc(m, '\t'); 2949 seq_putc(m, '\t');
2950 2950
2951 seq_printf(m, "id %d:\"%s\" freq %d clock %d hdisp %d hss %d hse %d htot %d vdisp %d vss %d vse %d vtot %d type 0x%x flags 0x%x\n", 2951 seq_printf(m, DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
2952 mode->base.id, mode->name,
2953 mode->vrefresh, mode->clock,
2954 mode->hdisplay, mode->hsync_start,
2955 mode->hsync_end, mode->htotal,
2956 mode->vdisplay, mode->vsync_start,
2957 mode->vsync_end, mode->vtotal,
2958 mode->type, mode->flags);
2959} 2952}
2960 2953
2961static void intel_encoder_info(struct seq_file *m, 2954static void intel_encoder_info(struct seq_file *m,
diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c
index 4dd793b78996..d9dcee4ec51f 100644
--- a/drivers/gpu/drm/i915/icl_dsi.c
+++ b/drivers/gpu/drm/i915/icl_dsi.c
@@ -1178,9 +1178,9 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
1178 pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); 1178 pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
1179} 1179}
1180 1180
1181static bool gen11_dsi_compute_config(struct intel_encoder *encoder, 1181static int gen11_dsi_compute_config(struct intel_encoder *encoder,
1182 struct intel_crtc_state *pipe_config, 1182 struct intel_crtc_state *pipe_config,
1183 struct drm_connector_state *conn_state) 1183 struct drm_connector_state *conn_state)
1184{ 1184{
1185 struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, 1185 struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
1186 base); 1186 base);
@@ -1205,7 +1205,7 @@ static bool gen11_dsi_compute_config(struct intel_encoder *encoder,
1205 pipe_config->clock_set = true; 1205 pipe_config->clock_set = true;
1206 pipe_config->port_clock = intel_dsi_bitrate(intel_dsi) / 5; 1206 pipe_config->port_clock = intel_dsi_bitrate(intel_dsi) / 5;
1207 1207
1208 return true; 1208 return 0;
1209} 1209}
1210 1210
1211static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder, 1211static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_connector.c b/drivers/gpu/drm/i915/intel_connector.c
index 18e370f607bc..37d2c644f4b8 100644
--- a/drivers/gpu/drm/i915/intel_connector.c
+++ b/drivers/gpu/drm/i915/intel_connector.c
@@ -95,6 +95,10 @@ void intel_connector_destroy(struct drm_connector *connector)
95 intel_panel_fini(&intel_connector->panel); 95 intel_panel_fini(&intel_connector->panel);
96 96
97 drm_connector_cleanup(connector); 97 drm_connector_cleanup(connector);
98
99 if (intel_connector->port)
100 drm_dp_mst_put_port_malloc(intel_connector->port);
101
98 kfree(connector); 102 kfree(connector);
99} 103}
100 104
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 68f2fb89ece3..2e0fd9927db2 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -344,51 +344,52 @@ intel_crt_mode_valid(struct drm_connector *connector,
344 return MODE_OK; 344 return MODE_OK;
345} 345}
346 346
347static bool intel_crt_compute_config(struct intel_encoder *encoder, 347static int intel_crt_compute_config(struct intel_encoder *encoder,
348 struct intel_crtc_state *pipe_config, 348 struct intel_crtc_state *pipe_config,
349 struct drm_connector_state *conn_state) 349 struct drm_connector_state *conn_state)
350{ 350{
351 struct drm_display_mode *adjusted_mode = 351 struct drm_display_mode *adjusted_mode =
352 &pipe_config->base.adjusted_mode; 352 &pipe_config->base.adjusted_mode;
353 353
354 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 354 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
355 return false; 355 return -EINVAL;
356 356
357 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; 357 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
358 return true; 358
359 return 0;
359} 360}
360 361
361static bool pch_crt_compute_config(struct intel_encoder *encoder, 362static int pch_crt_compute_config(struct intel_encoder *encoder,
362 struct intel_crtc_state *pipe_config, 363 struct intel_crtc_state *pipe_config,
363 struct drm_connector_state *conn_state) 364 struct drm_connector_state *conn_state)
364{ 365{
365 struct drm_display_mode *adjusted_mode = 366 struct drm_display_mode *adjusted_mode =
366 &pipe_config->base.adjusted_mode; 367 &pipe_config->base.adjusted_mode;
367 368
368 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 369 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
369 return false; 370 return -EINVAL;
370 371
371 pipe_config->has_pch_encoder = true; 372 pipe_config->has_pch_encoder = true;
372 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; 373 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
373 374
374 return true; 375 return 0;
375} 376}
376 377
377static bool hsw_crt_compute_config(struct intel_encoder *encoder, 378static int hsw_crt_compute_config(struct intel_encoder *encoder,
378 struct intel_crtc_state *pipe_config, 379 struct intel_crtc_state *pipe_config,
379 struct drm_connector_state *conn_state) 380 struct drm_connector_state *conn_state)
380{ 381{
381 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 382 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
382 struct drm_display_mode *adjusted_mode = 383 struct drm_display_mode *adjusted_mode =
383 &pipe_config->base.adjusted_mode; 384 &pipe_config->base.adjusted_mode;
384 385
385 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 386 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
386 return false; 387 return -EINVAL;
387 388
388 /* HSW/BDW FDI limited to 4k */ 389 /* HSW/BDW FDI limited to 4k */
389 if (adjusted_mode->crtc_hdisplay > 4096 || 390 if (adjusted_mode->crtc_hdisplay > 4096 ||
390 adjusted_mode->crtc_hblank_start > 4096) 391 adjusted_mode->crtc_hblank_start > 4096)
391 return false; 392 return -EINVAL;
392 393
393 pipe_config->has_pch_encoder = true; 394 pipe_config->has_pch_encoder = true;
394 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; 395 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
@@ -397,7 +398,7 @@ static bool hsw_crt_compute_config(struct intel_encoder *encoder,
397 if (HAS_PCH_LPT(dev_priv)) { 398 if (HAS_PCH_LPT(dev_priv)) {
398 if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) { 399 if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {
399 DRM_DEBUG_KMS("LPT only supports 24bpp\n"); 400 DRM_DEBUG_KMS("LPT only supports 24bpp\n");
400 return false; 401 return -EINVAL;
401 } 402 }
402 403
403 pipe_config->pipe_bpp = 24; 404 pipe_config->pipe_bpp = 24;
@@ -406,7 +407,7 @@ static bool hsw_crt_compute_config(struct intel_encoder *encoder,
406 /* FDI must always be 2.7 GHz */ 407 /* FDI must always be 2.7 GHz */
407 pipe_config->port_clock = 135000 * 2; 408 pipe_config->port_clock = 135000 * 2;
408 409
409 return true; 410 return 0;
410} 411}
411 412
412static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) 413static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index f3e1d6a0b7dd..fd06d1fd39d3 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3875,9 +3875,9 @@ intel_ddi_compute_output_type(struct intel_encoder *encoder,
3875 } 3875 }
3876} 3876}
3877 3877
3878static bool intel_ddi_compute_config(struct intel_encoder *encoder, 3878static int intel_ddi_compute_config(struct intel_encoder *encoder,
3879 struct intel_crtc_state *pipe_config, 3879 struct intel_crtc_state *pipe_config,
3880 struct drm_connector_state *conn_state) 3880 struct drm_connector_state *conn_state)
3881{ 3881{
3882 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 3882 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
3883 enum port port = encoder->port; 3883 enum port port = encoder->port;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3da9c0f9e948..52c63135bc65 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11517,10 +11517,13 @@ encoder_retry:
11517 continue; 11517 continue;
11518 11518
11519 encoder = to_intel_encoder(connector_state->best_encoder); 11519 encoder = to_intel_encoder(connector_state->best_encoder);
11520 11520 ret = encoder->compute_config(encoder, pipe_config,
11521 if (!(encoder->compute_config(encoder, pipe_config, connector_state))) { 11521 connector_state);
11522 DRM_DEBUG_KMS("Encoder config failure\n"); 11522 if (ret < 0) {
11523 return -EINVAL; 11523 if (ret != -EDEADLK)
11524 DRM_DEBUG_KMS("Encoder config failure: %d\n",
11525 ret);
11526 return ret;
11524 } 11527 }
11525 } 11528 }
11526 11529
@@ -12695,6 +12698,10 @@ static int intel_atomic_check(struct drm_device *dev,
12695 "[modeset]" : "[fastset]"); 12698 "[modeset]" : "[fastset]");
12696 } 12699 }
12697 12700
12701 ret = drm_dp_mst_atomic_check(state);
12702 if (ret)
12703 return ret;
12704
12698 if (any_ms) { 12705 if (any_ms) {
12699 ret = intel_modeset_checks(state); 12706 ret = intel_modeset_checks(state);
12700 12707
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index fdd2cbc56fa3..d18b72b5f0b8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1808,7 +1808,7 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp,
1808} 1808}
1809 1809
1810/* Optimize link config in order: max bpp, min clock, min lanes */ 1810/* Optimize link config in order: max bpp, min clock, min lanes */
1811static bool 1811static int
1812intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, 1812intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
1813 struct intel_crtc_state *pipe_config, 1813 struct intel_crtc_state *pipe_config,
1814 const struct link_config_limits *limits) 1814 const struct link_config_limits *limits)
@@ -1834,17 +1834,17 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
1834 pipe_config->pipe_bpp = bpp; 1834 pipe_config->pipe_bpp = bpp;
1835 pipe_config->port_clock = link_clock; 1835 pipe_config->port_clock = link_clock;
1836 1836
1837 return true; 1837 return 0;
1838 } 1838 }
1839 } 1839 }
1840 } 1840 }
1841 } 1841 }
1842 1842
1843 return false; 1843 return -EINVAL;
1844} 1844}
1845 1845
1846/* Optimize link config in order: max bpp, min lanes, min clock */ 1846/* Optimize link config in order: max bpp, min lanes, min clock */
1847static bool 1847static int
1848intel_dp_compute_link_config_fast(struct intel_dp *intel_dp, 1848intel_dp_compute_link_config_fast(struct intel_dp *intel_dp,
1849 struct intel_crtc_state *pipe_config, 1849 struct intel_crtc_state *pipe_config,
1850 const struct link_config_limits *limits) 1850 const struct link_config_limits *limits)
@@ -1870,13 +1870,13 @@ intel_dp_compute_link_config_fast(struct intel_dp *intel_dp,
1870 pipe_config->pipe_bpp = bpp; 1870 pipe_config->pipe_bpp = bpp;
1871 pipe_config->port_clock = link_clock; 1871 pipe_config->port_clock = link_clock;
1872 1872
1873 return true; 1873 return 0;
1874 } 1874 }
1875 } 1875 }
1876 } 1876 }
1877 } 1877 }
1878 1878
1879 return false; 1879 return -EINVAL;
1880} 1880}
1881 1881
1882static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) 1882static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc)
@@ -1894,19 +1894,20 @@ static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc)
1894 return 0; 1894 return 0;
1895} 1895}
1896 1896
1897static bool intel_dp_dsc_compute_config(struct intel_dp *intel_dp, 1897static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
1898 struct intel_crtc_state *pipe_config, 1898 struct intel_crtc_state *pipe_config,
1899 struct drm_connector_state *conn_state, 1899 struct drm_connector_state *conn_state,
1900 struct link_config_limits *limits) 1900 struct link_config_limits *limits)
1901{ 1901{
1902 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 1902 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
1903 struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); 1903 struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
1904 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 1904 struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
1905 u8 dsc_max_bpc; 1905 u8 dsc_max_bpc;
1906 int pipe_bpp; 1906 int pipe_bpp;
1907 int ret;
1907 1908
1908 if (!intel_dp_supports_dsc(intel_dp, pipe_config)) 1909 if (!intel_dp_supports_dsc(intel_dp, pipe_config))
1909 return false; 1910 return -EINVAL;
1910 1911
1911 dsc_max_bpc = min_t(u8, DP_DSC_MAX_SUPPORTED_BPC, 1912 dsc_max_bpc = min_t(u8, DP_DSC_MAX_SUPPORTED_BPC,
1912 conn_state->max_requested_bpc); 1913 conn_state->max_requested_bpc);
@@ -1914,7 +1915,7 @@ static bool intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
1914 pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, dsc_max_bpc); 1915 pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, dsc_max_bpc);
1915 if (pipe_bpp < DP_DSC_MIN_SUPPORTED_BPC * 3) { 1916 if (pipe_bpp < DP_DSC_MIN_SUPPORTED_BPC * 3) {
1916 DRM_DEBUG_KMS("No DSC support for less than 8bpc\n"); 1917 DRM_DEBUG_KMS("No DSC support for less than 8bpc\n");
1917 return false; 1918 return -EINVAL;
1918 } 1919 }
1919 1920
1920 /* 1921 /*
@@ -1948,7 +1949,7 @@ static bool intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
1948 adjusted_mode->crtc_hdisplay); 1949 adjusted_mode->crtc_hdisplay);
1949 if (!dsc_max_output_bpp || !dsc_dp_slice_count) { 1950 if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
1950 DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n"); 1951 DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
1951 return false; 1952 return -EINVAL;
1952 } 1953 }
1953 pipe_config->dsc_params.compressed_bpp = min_t(u16, 1954 pipe_config->dsc_params.compressed_bpp = min_t(u16,
1954 dsc_max_output_bpp >> 4, 1955 dsc_max_output_bpp >> 4,
@@ -1965,16 +1966,19 @@ static bool intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
1965 pipe_config->dsc_params.dsc_split = true; 1966 pipe_config->dsc_params.dsc_split = true;
1966 } else { 1967 } else {
1967 DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n"); 1968 DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
1968 return false; 1969 return -EINVAL;
1969 } 1970 }
1970 } 1971 }
1971 if (intel_dp_compute_dsc_params(intel_dp, pipe_config) < 0) { 1972
1973 ret = intel_dp_compute_dsc_params(intel_dp, pipe_config);
1974 if (ret < 0) {
1972 DRM_DEBUG_KMS("Cannot compute valid DSC parameters for Input Bpp = %d " 1975 DRM_DEBUG_KMS("Cannot compute valid DSC parameters for Input Bpp = %d "
1973 "Compressed BPP = %d\n", 1976 "Compressed BPP = %d\n",
1974 pipe_config->pipe_bpp, 1977 pipe_config->pipe_bpp,
1975 pipe_config->dsc_params.compressed_bpp); 1978 pipe_config->dsc_params.compressed_bpp);
1976 return false; 1979 return ret;
1977 } 1980 }
1981
1978 pipe_config->dsc_params.compression_enable = true; 1982 pipe_config->dsc_params.compression_enable = true;
1979 DRM_DEBUG_KMS("DP DSC computed with Input Bpp = %d " 1983 DRM_DEBUG_KMS("DP DSC computed with Input Bpp = %d "
1980 "Compressed Bpp = %d Slice Count = %d\n", 1984 "Compressed Bpp = %d Slice Count = %d\n",
@@ -1982,10 +1986,10 @@ static bool intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
1982 pipe_config->dsc_params.compressed_bpp, 1986 pipe_config->dsc_params.compressed_bpp,
1983 pipe_config->dsc_params.slice_count); 1987 pipe_config->dsc_params.slice_count);
1984 1988
1985 return true; 1989 return 0;
1986} 1990}
1987 1991
1988static bool 1992static int
1989intel_dp_compute_link_config(struct intel_encoder *encoder, 1993intel_dp_compute_link_config(struct intel_encoder *encoder,
1990 struct intel_crtc_state *pipe_config, 1994 struct intel_crtc_state *pipe_config,
1991 struct drm_connector_state *conn_state) 1995 struct drm_connector_state *conn_state)
@@ -1994,7 +1998,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
1994 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); 1998 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
1995 struct link_config_limits limits; 1999 struct link_config_limits limits;
1996 int common_len; 2000 int common_len;
1997 bool ret; 2001 int ret;
1998 2002
1999 common_len = intel_dp_common_len_rate_limit(intel_dp, 2003 common_len = intel_dp_common_len_rate_limit(intel_dp,
2000 intel_dp->max_link_rate); 2004 intel_dp->max_link_rate);
@@ -2051,10 +2055,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
2051 &limits); 2055 &limits);
2052 2056
2053 /* enable compression if the mode doesn't fit available BW */ 2057 /* enable compression if the mode doesn't fit available BW */
2054 if (!ret) { 2058 if (ret) {
2055 if (!intel_dp_dsc_compute_config(intel_dp, pipe_config, 2059 ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
2056 conn_state, &limits)) 2060 conn_state, &limits);
2057 return false; 2061 if (ret < 0)
2062 return ret;
2058 } 2063 }
2059 2064
2060 if (pipe_config->dsc_params.compression_enable) { 2065 if (pipe_config->dsc_params.compression_enable) {
@@ -2079,10 +2084,10 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
2079 intel_dp_max_data_rate(pipe_config->port_clock, 2084 intel_dp_max_data_rate(pipe_config->port_clock,
2080 pipe_config->lane_count)); 2085 pipe_config->lane_count));
2081 } 2086 }
2082 return true; 2087 return 0;
2083} 2088}
2084 2089
2085bool 2090int
2086intel_dp_compute_config(struct intel_encoder *encoder, 2091intel_dp_compute_config(struct intel_encoder *encoder,
2087 struct intel_crtc_state *pipe_config, 2092 struct intel_crtc_state *pipe_config,
2088 struct drm_connector_state *conn_state) 2093 struct drm_connector_state *conn_state)
@@ -2098,6 +2103,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
2098 to_intel_digital_connector_state(conn_state); 2103 to_intel_digital_connector_state(conn_state);
2099 bool constant_n = drm_dp_has_quirk(&intel_dp->desc, 2104 bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
2100 DP_DPCD_QUIRK_CONSTANT_N); 2105 DP_DPCD_QUIRK_CONSTANT_N);
2106 int ret;
2101 2107
2102 if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A) 2108 if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
2103 pipe_config->has_pch_encoder = true; 2109 pipe_config->has_pch_encoder = true;
@@ -2119,8 +2125,6 @@ intel_dp_compute_config(struct intel_encoder *encoder,
2119 adjusted_mode); 2125 adjusted_mode);
2120 2126
2121 if (INTEL_GEN(dev_priv) >= 9) { 2127 if (INTEL_GEN(dev_priv) >= 9) {
2122 int ret;
2123
2124 ret = skl_update_scaler_crtc(pipe_config); 2128 ret = skl_update_scaler_crtc(pipe_config);
2125 if (ret) 2129 if (ret)
2126 return ret; 2130 return ret;
@@ -2135,20 +2139,21 @@ intel_dp_compute_config(struct intel_encoder *encoder,
2135 } 2139 }
2136 2140
2137 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 2141 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
2138 return false; 2142 return -EINVAL;
2139 2143
2140 if (HAS_GMCH_DISPLAY(dev_priv) && 2144 if (HAS_GMCH_DISPLAY(dev_priv) &&
2141 adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) 2145 adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
2142 return false; 2146 return -EINVAL;
2143 2147
2144 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) 2148 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
2145 return false; 2149 return -EINVAL;
2146 2150
2147 pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) && 2151 pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
2148 intel_dp_supports_fec(intel_dp, pipe_config); 2152 intel_dp_supports_fec(intel_dp, pipe_config);
2149 2153
2150 if (!intel_dp_compute_link_config(encoder, pipe_config, conn_state)) 2154 ret = intel_dp_compute_link_config(encoder, pipe_config, conn_state);
2151 return false; 2155 if (ret < 0)
2156 return ret;
2152 2157
2153 if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) { 2158 if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) {
2154 /* 2159 /*
@@ -2196,7 +2201,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
2196 2201
2197 intel_psr_compute_config(intel_dp, pipe_config); 2202 intel_psr_compute_config(intel_dp, pipe_config);
2198 2203
2199 return true; 2204 return 0;
2200} 2205}
2201 2206
2202void intel_dp_set_link_params(struct intel_dp *intel_dp, 2207void intel_dp_set_link_params(struct intel_dp *intel_dp,
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index f05427b74e34..5899debe2184 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -30,9 +30,9 @@
30#include <drm/drm_crtc_helper.h> 30#include <drm/drm_crtc_helper.h>
31#include <drm/drm_edid.h> 31#include <drm/drm_edid.h>
32 32
33static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, 33static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
34 struct intel_crtc_state *pipe_config, 34 struct intel_crtc_state *pipe_config,
35 struct drm_connector_state *conn_state) 35 struct drm_connector_state *conn_state)
36{ 36{
37 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 37 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
38 struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); 38 struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
@@ -41,15 +41,19 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
41 struct drm_connector *connector = conn_state->connector; 41 struct drm_connector *connector = conn_state->connector;
42 void *port = to_intel_connector(connector)->port; 42 void *port = to_intel_connector(connector)->port;
43 struct drm_atomic_state *state = pipe_config->base.state; 43 struct drm_atomic_state *state = pipe_config->base.state;
44 struct drm_crtc *crtc = pipe_config->base.crtc;
45 struct drm_crtc_state *old_crtc_state =
46 drm_atomic_get_old_crtc_state(state, crtc);
44 int bpp; 47 int bpp;
45 int lane_count, slots = 0; 48 int lane_count, slots =
49 to_intel_crtc_state(old_crtc_state)->dp_m_n.tu;
46 const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 50 const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
47 int mst_pbn; 51 int mst_pbn;
48 bool constant_n = drm_dp_has_quirk(&intel_dp->desc, 52 bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
49 DP_DPCD_QUIRK_CONSTANT_N); 53 DP_DPCD_QUIRK_CONSTANT_N);
50 54
51 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 55 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
52 return false; 56 return -EINVAL;
53 57
54 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; 58 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
55 pipe_config->has_pch_encoder = false; 59 pipe_config->has_pch_encoder = false;
@@ -86,7 +90,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
86 if (slots < 0) { 90 if (slots < 0) {
87 DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", 91 DRM_DEBUG_KMS("failed finding vcpi slots:%d\n",
88 slots); 92 slots);
89 return false; 93 return slots;
90 } 94 }
91 } 95 }
92 96
@@ -104,38 +108,42 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
104 108
105 intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); 109 intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
106 110
107 return true; 111 return 0;
108} 112}
109 113
110static int intel_dp_mst_atomic_check(struct drm_connector *connector, 114static int
111 struct drm_connector_state *new_conn_state) 115intel_dp_mst_atomic_check(struct drm_connector *connector,
116 struct drm_connector_state *new_conn_state)
112{ 117{
113 struct drm_atomic_state *state = new_conn_state->state; 118 struct drm_atomic_state *state = new_conn_state->state;
114 struct drm_connector_state *old_conn_state; 119 struct drm_connector_state *old_conn_state =
115 struct drm_crtc *old_crtc; 120 drm_atomic_get_old_connector_state(state, connector);
121 struct intel_connector *intel_connector =
122 to_intel_connector(connector);
123 struct drm_crtc *new_crtc = new_conn_state->crtc;
116 struct drm_crtc_state *crtc_state; 124 struct drm_crtc_state *crtc_state;
117 int slots, ret = 0; 125 struct drm_dp_mst_topology_mgr *mgr;
118 126 int ret = 0;
119 old_conn_state = drm_atomic_get_old_connector_state(state, connector);
120 old_crtc = old_conn_state->crtc;
121 if (!old_crtc)
122 return ret;
123 127
124 crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc); 128 if (!old_conn_state->crtc)
125 slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu; 129 return 0;
126 if (drm_atomic_crtc_needs_modeset(crtc_state) && slots > 0) {
127 struct drm_dp_mst_topology_mgr *mgr;
128 struct drm_encoder *old_encoder;
129 130
130 old_encoder = old_conn_state->best_encoder; 131 /* We only want to free VCPI if this state disables the CRTC on this
131 mgr = &enc_to_mst(old_encoder)->primary->dp.mst_mgr; 132 * connector
133 */
134 if (new_crtc) {
135 crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
132 136
133 ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots); 137 if (!crtc_state ||
134 if (ret) 138 !drm_atomic_crtc_needs_modeset(crtc_state) ||
135 DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n", slots, ret); 139 crtc_state->enable)
136 else 140 return 0;
137 to_intel_crtc_state(crtc_state)->dp_m_n.tu = 0;
138 } 141 }
142
143 mgr = &enc_to_mst(old_conn_state->best_encoder)->primary->dp.mst_mgr;
144 ret = drm_dp_atomic_release_vcpi_slots(state, mgr,
145 intel_connector->port);
146
139 return ret; 147 return ret;
140} 148}
141 149
@@ -457,6 +465,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
457 intel_connector->get_hw_state = intel_dp_mst_get_hw_state; 465 intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
458 intel_connector->mst_port = intel_dp; 466 intel_connector->mst_port = intel_dp;
459 intel_connector->port = port; 467 intel_connector->port = port;
468 drm_dp_mst_get_port_malloc(port);
460 469
461 connector = &intel_connector->base; 470 connector = &intel_connector->base;
462 ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, 471 ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f94a04b4ad87..19d9abd2666e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -222,9 +222,9 @@ struct intel_encoder {
222 enum intel_output_type (*compute_output_type)(struct intel_encoder *, 222 enum intel_output_type (*compute_output_type)(struct intel_encoder *,
223 struct intel_crtc_state *, 223 struct intel_crtc_state *,
224 struct drm_connector_state *); 224 struct drm_connector_state *);
225 bool (*compute_config)(struct intel_encoder *, 225 int (*compute_config)(struct intel_encoder *,
226 struct intel_crtc_state *, 226 struct intel_crtc_state *,
227 struct drm_connector_state *); 227 struct drm_connector_state *);
228 void (*pre_pll_enable)(struct intel_encoder *, 228 void (*pre_pll_enable)(struct intel_encoder *,
229 const struct intel_crtc_state *, 229 const struct intel_crtc_state *,
230 const struct drm_connector_state *); 230 const struct drm_connector_state *);
@@ -1074,7 +1074,6 @@ struct intel_hdmi {
1074 } dp_dual_mode; 1074 } dp_dual_mode;
1075 bool has_hdmi_sink; 1075 bool has_hdmi_sink;
1076 bool has_audio; 1076 bool has_audio;
1077 bool rgb_quant_range_selectable;
1078 struct intel_connector *attached_connector; 1077 struct intel_connector *attached_connector;
1079 struct cec_notifier *cec_notifier; 1078 struct cec_notifier *cec_notifier;
1080}; 1079};
@@ -1807,9 +1806,9 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
1807void intel_dp_encoder_reset(struct drm_encoder *encoder); 1806void intel_dp_encoder_reset(struct drm_encoder *encoder);
1808void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); 1807void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
1809void intel_dp_encoder_destroy(struct drm_encoder *encoder); 1808void intel_dp_encoder_destroy(struct drm_encoder *encoder);
1810bool intel_dp_compute_config(struct intel_encoder *encoder, 1809int intel_dp_compute_config(struct intel_encoder *encoder,
1811 struct intel_crtc_state *pipe_config, 1810 struct intel_crtc_state *pipe_config,
1812 struct drm_connector_state *conn_state); 1811 struct drm_connector_state *conn_state);
1813bool intel_dp_is_edp(struct intel_dp *intel_dp); 1812bool intel_dp_is_edp(struct intel_dp *intel_dp);
1814bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port); 1813bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
1815enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, 1814enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port,
@@ -1967,9 +1966,9 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg,
1967void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, 1966void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
1968 struct intel_connector *intel_connector); 1967 struct intel_connector *intel_connector);
1969struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder); 1968struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
1970bool intel_hdmi_compute_config(struct intel_encoder *encoder, 1969int intel_hdmi_compute_config(struct intel_encoder *encoder,
1971 struct intel_crtc_state *pipe_config, 1970 struct intel_crtc_state *pipe_config,
1972 struct drm_connector_state *conn_state); 1971 struct drm_connector_state *conn_state);
1973bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder, 1972bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
1974 struct drm_connector *connector, 1973 struct drm_connector *connector,
1975 bool high_tmds_clock_ratio, 1974 bool high_tmds_clock_ratio,
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 0042a7f69387..17a16917e134 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -235,9 +235,9 @@ intel_dvo_mode_valid(struct drm_connector *connector,
235 return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); 235 return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode);
236} 236}
237 237
238static bool intel_dvo_compute_config(struct intel_encoder *encoder, 238static int intel_dvo_compute_config(struct intel_encoder *encoder,
239 struct intel_crtc_state *pipe_config, 239 struct intel_crtc_state *pipe_config,
240 struct drm_connector_state *conn_state) 240 struct drm_connector_state *conn_state)
241{ 241{
242 struct intel_dvo *intel_dvo = enc_to_dvo(encoder); 242 struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
243 const struct drm_display_mode *fixed_mode = 243 const struct drm_display_mode *fixed_mode =
@@ -254,10 +254,11 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder,
254 intel_fixed_panel_mode(fixed_mode, adjusted_mode); 254 intel_fixed_panel_mode(fixed_mode, adjusted_mode);
255 255
256 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 256 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
257 return false; 257 return -EINVAL;
258 258
259 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; 259 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
260 return true; 260
261 return 0;
261} 262}
262 263
263static void intel_dvo_pre_enable(struct intel_encoder *encoder, 264static void intel_dvo_pre_enable(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 07e803a604bd..1da7bb148fca 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -479,18 +479,14 @@ static void intel_hdmi_set_avi_infoframe(struct intel_encoder *encoder,
479 const struct intel_crtc_state *crtc_state, 479 const struct intel_crtc_state *crtc_state,
480 const struct drm_connector_state *conn_state) 480 const struct drm_connector_state *conn_state)
481{ 481{
482 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
483 const struct drm_display_mode *adjusted_mode = 482 const struct drm_display_mode *adjusted_mode =
484 &crtc_state->base.adjusted_mode; 483 &crtc_state->base.adjusted_mode;
485 struct drm_connector *connector = &intel_hdmi->attached_connector->base;
486 bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported ||
487 connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB420;
488 union hdmi_infoframe frame; 484 union hdmi_infoframe frame;
489 int ret; 485 int ret;
490 486
491 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, 487 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
492 adjusted_mode, 488 conn_state->connector,
493 is_hdmi2_sink); 489 adjusted_mode);
494 if (ret < 0) { 490 if (ret < 0) {
495 DRM_ERROR("couldn't fill AVI infoframe\n"); 491 DRM_ERROR("couldn't fill AVI infoframe\n");
496 return; 492 return;
@@ -503,12 +499,12 @@ static void intel_hdmi_set_avi_infoframe(struct intel_encoder *encoder,
503 else 499 else
504 frame.avi.colorspace = HDMI_COLORSPACE_RGB; 500 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
505 501
506 drm_hdmi_avi_infoframe_quant_range(&frame.avi, adjusted_mode, 502 drm_hdmi_avi_infoframe_quant_range(&frame.avi,
503 conn_state->connector,
504 adjusted_mode,
507 crtc_state->limited_color_range ? 505 crtc_state->limited_color_range ?
508 HDMI_QUANTIZATION_RANGE_LIMITED : 506 HDMI_QUANTIZATION_RANGE_LIMITED :
509 HDMI_QUANTIZATION_RANGE_FULL, 507 HDMI_QUANTIZATION_RANGE_FULL);
510 intel_hdmi->rgb_quant_range_selectable,
511 is_hdmi2_sink);
512 508
513 drm_hdmi_avi_infoframe_content_type(&frame.avi, 509 drm_hdmi_avi_infoframe_content_type(&frame.avi,
514 conn_state); 510 conn_state);
@@ -1707,9 +1703,9 @@ intel_hdmi_ycbcr420_config(struct drm_connector *connector,
1707 return true; 1703 return true;
1708} 1704}
1709 1705
1710bool intel_hdmi_compute_config(struct intel_encoder *encoder, 1706int intel_hdmi_compute_config(struct intel_encoder *encoder,
1711 struct intel_crtc_state *pipe_config, 1707 struct intel_crtc_state *pipe_config,
1712 struct drm_connector_state *conn_state) 1708 struct drm_connector_state *conn_state)
1713{ 1709{
1714 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); 1710 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
1715 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 1711 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -1725,7 +1721,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
1725 bool force_dvi = intel_conn_state->force_audio == HDMI_AUDIO_OFF_DVI; 1721 bool force_dvi = intel_conn_state->force_audio == HDMI_AUDIO_OFF_DVI;
1726 1722
1727 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 1723 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
1728 return false; 1724 return -EINVAL;
1729 1725
1730 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; 1726 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
1731 pipe_config->has_hdmi_sink = !force_dvi && intel_hdmi->has_hdmi_sink; 1727 pipe_config->has_hdmi_sink = !force_dvi && intel_hdmi->has_hdmi_sink;
@@ -1756,7 +1752,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
1756 &clock_12bpc, &clock_10bpc, 1752 &clock_12bpc, &clock_10bpc,
1757 &clock_8bpc)) { 1753 &clock_8bpc)) {
1758 DRM_ERROR("Can't support YCBCR420 output\n"); 1754 DRM_ERROR("Can't support YCBCR420 output\n");
1759 return false; 1755 return -EINVAL;
1760 } 1756 }
1761 } 1757 }
1762 1758
@@ -1806,7 +1802,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
1806 if (hdmi_port_clock_valid(intel_hdmi, pipe_config->port_clock, 1802 if (hdmi_port_clock_valid(intel_hdmi, pipe_config->port_clock,
1807 false, force_dvi) != MODE_OK) { 1803 false, force_dvi) != MODE_OK) {
1808 DRM_DEBUG_KMS("unsupported HDMI clock, rejecting mode\n"); 1804 DRM_DEBUG_KMS("unsupported HDMI clock, rejecting mode\n");
1809 return false; 1805 return -EINVAL;
1810 } 1806 }
1811 1807
1812 /* Set user selected PAR to incoming mode's member */ 1808 /* Set user selected PAR to incoming mode's member */
@@ -1825,7 +1821,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
1825 } 1821 }
1826 } 1822 }
1827 1823
1828 return true; 1824 return 0;
1829} 1825}
1830 1826
1831static void 1827static void
@@ -1835,7 +1831,6 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
1835 1831
1836 intel_hdmi->has_hdmi_sink = false; 1832 intel_hdmi->has_hdmi_sink = false;
1837 intel_hdmi->has_audio = false; 1833 intel_hdmi->has_audio = false;
1838 intel_hdmi->rgb_quant_range_selectable = false;
1839 1834
1840 intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE; 1835 intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
1841 intel_hdmi->dp_dual_mode.max_tmds_clock = 0; 1836 intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
@@ -1919,9 +1914,6 @@ intel_hdmi_set_edid(struct drm_connector *connector)
1919 1914
1920 to_intel_connector(connector)->detect_edid = edid; 1915 to_intel_connector(connector)->detect_edid = edid;
1921 if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { 1916 if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
1922 intel_hdmi->rgb_quant_range_selectable =
1923 drm_rgb_quant_range_selectable(edid);
1924
1925 intel_hdmi->has_audio = drm_detect_monitor_audio(edid); 1917 intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
1926 intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); 1918 intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
1927 1919
diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c
index 96a8d9524b0c..7d15be5932e0 100644
--- a/drivers/gpu/drm/i915/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/intel_lspcon.c
@@ -462,10 +462,8 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
462 uint8_t buf[VIDEO_DIP_DATA_SIZE]; 462 uint8_t buf[VIDEO_DIP_DATA_SIZE];
463 struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base); 463 struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
464 struct intel_lspcon *lspcon = &dig_port->lspcon; 464 struct intel_lspcon *lspcon = &dig_port->lspcon;
465 struct intel_dp *intel_dp = &dig_port->dp; 465 const struct drm_display_mode *adjusted_mode =
466 struct drm_connector *connector = &intel_dp->attached_connector->base; 466 &crtc_state->base.adjusted_mode;
467 const struct drm_display_mode *mode = &crtc_state->base.adjusted_mode;
468 bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
469 467
470 if (!lspcon->active) { 468 if (!lspcon->active) {
471 DRM_ERROR("Writing infoframes while LSPCON disabled ?\n"); 469 DRM_ERROR("Writing infoframes while LSPCON disabled ?\n");
@@ -473,7 +471,8 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
473 } 471 }
474 472
475 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, 473 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
476 mode, is_hdmi2_sink); 474 conn_state->connector,
475 adjusted_mode);
477 if (ret < 0) { 476 if (ret < 0) {
478 DRM_ERROR("couldn't fill AVI infoframe\n"); 477 DRM_ERROR("couldn't fill AVI infoframe\n");
479 return; 478 return;
@@ -488,11 +487,12 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
488 frame.avi.colorspace = HDMI_COLORSPACE_RGB; 487 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
489 } 488 }
490 489
491 drm_hdmi_avi_infoframe_quant_range(&frame.avi, mode, 490 drm_hdmi_avi_infoframe_quant_range(&frame.avi,
491 conn_state->connector,
492 adjusted_mode,
492 crtc_state->limited_color_range ? 493 crtc_state->limited_color_range ?
493 HDMI_QUANTIZATION_RANGE_LIMITED : 494 HDMI_QUANTIZATION_RANGE_LIMITED :
494 HDMI_QUANTIZATION_RANGE_FULL, 495 HDMI_QUANTIZATION_RANGE_FULL);
495 false, is_hdmi2_sink);
496 496
497 ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf)); 497 ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf));
498 if (ret < 0) { 498 if (ret < 0) {
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index e6c5d985ea0a..3377d813dbb3 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -379,9 +379,9 @@ intel_lvds_mode_valid(struct drm_connector *connector,
379 return MODE_OK; 379 return MODE_OK;
380} 380}
381 381
382static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, 382static int intel_lvds_compute_config(struct intel_encoder *intel_encoder,
383 struct intel_crtc_state *pipe_config, 383 struct intel_crtc_state *pipe_config,
384 struct drm_connector_state *conn_state) 384 struct drm_connector_state *conn_state)
385{ 385{
386 struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); 386 struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
387 struct intel_lvds_encoder *lvds_encoder = 387 struct intel_lvds_encoder *lvds_encoder =
@@ -395,7 +395,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
395 /* Should never happen!! */ 395 /* Should never happen!! */
396 if (INTEL_GEN(dev_priv) < 4 && intel_crtc->pipe == 0) { 396 if (INTEL_GEN(dev_priv) < 4 && intel_crtc->pipe == 0) {
397 DRM_ERROR("Can't support LVDS on pipe A\n"); 397 DRM_ERROR("Can't support LVDS on pipe A\n");
398 return false; 398 return -EINVAL;
399 } 399 }
400 400
401 if (lvds_encoder->a3_power == LVDS_A3_POWER_UP) 401 if (lvds_encoder->a3_power == LVDS_A3_POWER_UP)
@@ -421,7 +421,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
421 adjusted_mode); 421 adjusted_mode);
422 422
423 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 423 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
424 return false; 424 return -EINVAL;
425 425
426 if (HAS_PCH_SPLIT(dev_priv)) { 426 if (HAS_PCH_SPLIT(dev_priv)) {
427 pipe_config->has_pch_encoder = true; 427 pipe_config->has_pch_encoder = true;
@@ -440,7 +440,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
440 * user's requested refresh rate. 440 * user's requested refresh rate.
441 */ 441 */
442 442
443 return true; 443 return 0;
444} 444}
445 445
446static enum drm_connector_status 446static enum drm_connector_status
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 5805ec1aba12..4a03b7f67dd5 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -103,7 +103,6 @@ struct intel_sdvo {
103 103
104 bool has_hdmi_monitor; 104 bool has_hdmi_monitor;
105 bool has_hdmi_audio; 105 bool has_hdmi_audio;
106 bool rgb_quant_range_selectable;
107 106
108 /* DDC bus used by this SDVO encoder */ 107 /* DDC bus used by this SDVO encoder */
109 uint8_t ddc_bus; 108 uint8_t ddc_bus;
@@ -981,29 +980,30 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
981} 980}
982 981
983static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, 982static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
984 const struct intel_crtc_state *pipe_config) 983 const struct intel_crtc_state *pipe_config,
984 const struct drm_connector_state *conn_state)
985{ 985{
986 const struct drm_display_mode *adjusted_mode =
987 &pipe_config->base.adjusted_mode;
986 uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)]; 988 uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)];
987 union hdmi_infoframe frame; 989 union hdmi_infoframe frame;
988 int ret; 990 int ret;
989 ssize_t len; 991 ssize_t len;
990 992
991 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, 993 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
992 &pipe_config->base.adjusted_mode, 994 conn_state->connector,
993 false); 995 adjusted_mode);
994 if (ret < 0) { 996 if (ret < 0) {
995 DRM_ERROR("couldn't fill AVI infoframe\n"); 997 DRM_ERROR("couldn't fill AVI infoframe\n");
996 return false; 998 return false;
997 } 999 }
998 1000
999 if (intel_sdvo->rgb_quant_range_selectable) { 1001 drm_hdmi_avi_infoframe_quant_range(&frame.avi,
1000 if (pipe_config->limited_color_range) 1002 conn_state->connector,
1001 frame.avi.quantization_range = 1003 adjusted_mode,
1002 HDMI_QUANTIZATION_RANGE_LIMITED; 1004 pipe_config->limited_color_range ?
1003 else 1005 HDMI_QUANTIZATION_RANGE_LIMITED :
1004 frame.avi.quantization_range = 1006 HDMI_QUANTIZATION_RANGE_FULL);
1005 HDMI_QUANTIZATION_RANGE_FULL;
1006 }
1007 1007
1008 len = hdmi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data)); 1008 len = hdmi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data));
1009 if (len < 0) 1009 if (len < 0)
@@ -1108,9 +1108,9 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config)
1108 pipe_config->clock_set = true; 1108 pipe_config->clock_set = true;
1109} 1109}
1110 1110
1111static bool intel_sdvo_compute_config(struct intel_encoder *encoder, 1111static int intel_sdvo_compute_config(struct intel_encoder *encoder,
1112 struct intel_crtc_state *pipe_config, 1112 struct intel_crtc_state *pipe_config,
1113 struct drm_connector_state *conn_state) 1113 struct drm_connector_state *conn_state)
1114{ 1114{
1115 struct intel_sdvo *intel_sdvo = to_sdvo(encoder); 1115 struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
1116 struct intel_sdvo_connector_state *intel_sdvo_state = 1116 struct intel_sdvo_connector_state *intel_sdvo_state =
@@ -1135,7 +1135,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1135 */ 1135 */
1136 if (IS_TV(intel_sdvo_connector)) { 1136 if (IS_TV(intel_sdvo_connector)) {
1137 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) 1137 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
1138 return false; 1138 return -EINVAL;
1139 1139
1140 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, 1140 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
1141 intel_sdvo_connector, 1141 intel_sdvo_connector,
@@ -1145,7 +1145,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1145 } else if (IS_LVDS(intel_sdvo_connector)) { 1145 } else if (IS_LVDS(intel_sdvo_connector)) {
1146 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, 1146 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
1147 intel_sdvo_connector->base.panel.fixed_mode)) 1147 intel_sdvo_connector->base.panel.fixed_mode))
1148 return false; 1148 return -EINVAL;
1149 1149
1150 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, 1150 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
1151 intel_sdvo_connector, 1151 intel_sdvo_connector,
@@ -1154,7 +1154,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1154 } 1154 }
1155 1155
1156 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 1156 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
1157 return false; 1157 return -EINVAL;
1158 1158
1159 /* 1159 /*
1160 * Make the CRTC code factor in the SDVO pixel multiplier. The 1160 * Make the CRTC code factor in the SDVO pixel multiplier. The
@@ -1194,7 +1194,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1194 if (intel_sdvo_connector->is_hdmi) 1194 if (intel_sdvo_connector->is_hdmi)
1195 adjusted_mode->picture_aspect_ratio = conn_state->picture_aspect_ratio; 1195 adjusted_mode->picture_aspect_ratio = conn_state->picture_aspect_ratio;
1196 1196
1197 return true; 1197 return 0;
1198} 1198}
1199 1199
1200#define UPDATE_PROPERTY(input, NAME) \ 1200#define UPDATE_PROPERTY(input, NAME) \
@@ -1316,7 +1316,8 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
1316 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); 1316 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
1317 intel_sdvo_set_colorimetry(intel_sdvo, 1317 intel_sdvo_set_colorimetry(intel_sdvo,
1318 SDVO_COLORIMETRY_RGB256); 1318 SDVO_COLORIMETRY_RGB256);
1319 intel_sdvo_set_avi_infoframe(intel_sdvo, crtc_state); 1319 intel_sdvo_set_avi_infoframe(intel_sdvo,
1320 crtc_state, conn_state);
1320 } else 1321 } else
1321 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI); 1322 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI);
1322 1323
@@ -1802,8 +1803,6 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
1802 if (intel_sdvo_connector->is_hdmi) { 1803 if (intel_sdvo_connector->is_hdmi) {
1803 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); 1804 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
1804 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); 1805 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
1805 intel_sdvo->rgb_quant_range_selectable =
1806 drm_rgb_quant_range_selectable(edid);
1807 } 1806 }
1808 } else 1807 } else
1809 status = connector_status_disconnected; 1808 status = connector_status_disconnected;
@@ -1852,7 +1851,6 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
1852 1851
1853 intel_sdvo->has_hdmi_monitor = false; 1852 intel_sdvo->has_hdmi_monitor = false;
1854 intel_sdvo->has_hdmi_audio = false; 1853 intel_sdvo->has_hdmi_audio = false;
1855 intel_sdvo->rgb_quant_range_selectable = false;
1856 1854
1857 if ((intel_sdvo_connector->output_flag & response) == 0) 1855 if ((intel_sdvo_connector->output_flag & response) == 0)
1858 ret = connector_status_disconnected; 1856 ret = connector_status_disconnected;
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 860f306a23ba..9bbe35a0f0f2 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -870,7 +870,7 @@ intel_tv_get_config(struct intel_encoder *encoder,
870 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; 870 pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
871} 871}
872 872
873static bool 873static int
874intel_tv_compute_config(struct intel_encoder *encoder, 874intel_tv_compute_config(struct intel_encoder *encoder,
875 struct intel_crtc_state *pipe_config, 875 struct intel_crtc_state *pipe_config,
876 struct drm_connector_state *conn_state) 876 struct drm_connector_state *conn_state)
@@ -880,10 +880,10 @@ intel_tv_compute_config(struct intel_encoder *encoder,
880 &pipe_config->base.adjusted_mode; 880 &pipe_config->base.adjusted_mode;
881 881
882 if (!tv_mode) 882 if (!tv_mode)
883 return false; 883 return -EINVAL;
884 884
885 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 885 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
886 return false; 886 return -EINVAL;
887 887
888 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; 888 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
889 adjusted_mode->crtc_clock = tv_mode->clock; 889 adjusted_mode->crtc_clock = tv_mode->clock;
@@ -898,7 +898,7 @@ intel_tv_compute_config(struct intel_encoder *encoder,
898 * or whether userspace is doing something stupid. 898 * or whether userspace is doing something stupid.
899 */ 899 */
900 900
901 return true; 901 return 0;
902} 902}
903 903
904static void 904static void
diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c
index 361e962a7969..9fc8085f76dc 100644
--- a/drivers/gpu/drm/i915/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/vlv_dsi.c
@@ -257,9 +257,9 @@ static void band_gap_reset(struct drm_i915_private *dev_priv)
257 mutex_unlock(&dev_priv->sb_lock); 257 mutex_unlock(&dev_priv->sb_lock);
258} 258}
259 259
260static bool intel_dsi_compute_config(struct intel_encoder *encoder, 260static int intel_dsi_compute_config(struct intel_encoder *encoder,
261 struct intel_crtc_state *pipe_config, 261 struct intel_crtc_state *pipe_config,
262 struct drm_connector_state *conn_state) 262 struct drm_connector_state *conn_state)
263{ 263{
264 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); 264 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
265 struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, 265 struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
@@ -285,7 +285,7 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
285 } 285 }
286 286
287 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) 287 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
288 return false; 288 return -EINVAL;
289 289
290 /* DSI uses short packets for sync events, so clear mode flags for DSI */ 290 /* DSI uses short packets for sync events, so clear mode flags for DSI */
291 adjusted_mode->flags = 0; 291 adjusted_mode->flags = 0;
@@ -303,16 +303,16 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
303 303
304 ret = bxt_dsi_pll_compute(encoder, pipe_config); 304 ret = bxt_dsi_pll_compute(encoder, pipe_config);
305 if (ret) 305 if (ret)
306 return false; 306 return -EINVAL;
307 } else { 307 } else {
308 ret = vlv_dsi_pll_compute(encoder, pipe_config); 308 ret = vlv_dsi_pll_compute(encoder, pipe_config);
309 if (ret) 309 if (ret)
310 return false; 310 return -EINVAL;
311 } 311 }
312 312
313 pipe_config->clock_set = true; 313 pipe_config->clock_set = true;
314 314
315 return true; 315 return 0;
316} 316}
317 317
318static bool glk_dsi_enable_io(struct intel_encoder *encoder) 318static bool glk_dsi_enable_io(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 994f0d8646bf..12ad00d01063 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -981,7 +981,8 @@ static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,
981 u8 buffer[17]; 981 u8 buffer[17];
982 ssize_t err; 982 ssize_t err;
983 983
984 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 984 err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
985 &hdmi->conn, mode);
985 if (err < 0) { 986 if (err < 0) {
986 dev_err(hdmi->dev, 987 dev_err(hdmi->dev,
987 "Failed to get AVI infoframe from mode: %zd\n", err); 988 "Failed to get AVI infoframe from mode: %zd\n", err);
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 3ee4d4a4ecba..1e360828ac38 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -152,6 +152,23 @@ static void meson_vpu_init(struct meson_drm *priv)
152 writel_relaxed(0x20000, priv->io_base + _REG(VPU_WRARB_MODE_L2C1)); 152 writel_relaxed(0x20000, priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
153} 153}
154 154
155static void meson_remove_framebuffers(void)
156{
157 struct apertures_struct *ap;
158
159 ap = alloc_apertures(1);
160 if (!ap)
161 return;
162
163 /* The framebuffer can be located anywhere in RAM */
164 ap->ranges[0].base = 0;
165 ap->ranges[0].size = ~0;
166
167 drm_fb_helper_remove_conflicting_framebuffers(ap, "meson-drm-fb",
168 false);
169 kfree(ap);
170}
171
155static int meson_drv_bind_master(struct device *dev, bool has_components) 172static int meson_drv_bind_master(struct device *dev, bool has_components)
156{ 173{
157 struct platform_device *pdev = to_platform_device(dev); 174 struct platform_device *pdev = to_platform_device(dev);
@@ -262,6 +279,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
262 if (ret) 279 if (ret)
263 goto free_drm; 280 goto free_drm;
264 281
282 /* Remove early framebuffers (ie. simplefb) */
283 meson_remove_framebuffers();
284
265 drm_mode_config_init(drm); 285 drm_mode_config_init(drm);
266 drm->mode_config.max_width = 3840; 286 drm->mode_config.max_width = 3840;
267 drm->mode_config.max_height = 2160; 287 drm->mode_config.max_height = 2160;
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 807111ebfdd9..bc25001b8207 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -365,7 +365,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
365 unsigned int wr_clk = 365 unsigned int wr_clk =
366 readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING)); 366 readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING));
367 367
368 DRM_DEBUG_DRIVER("%d:\"%s\"\n", mode->base.id, mode->name); 368 DRM_DEBUG_DRIVER("\"%s\"\n", mode->name);
369 369
370 /* Enable clocks */ 370 /* Enable clocks */
371 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); 371 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
@@ -555,12 +555,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
555 int vic = drm_match_cea_mode(mode); 555 int vic = drm_match_cea_mode(mode);
556 enum drm_mode_status status; 556 enum drm_mode_status status;
557 557
558 DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", 558 DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
559 mode->base.id, mode->name, mode->vrefresh, mode->clock,
560 mode->hdisplay, mode->hsync_start,
561 mode->hsync_end, mode->htotal,
562 mode->vdisplay, mode->vsync_start,
563 mode->vsync_end, mode->vtotal, mode->type, mode->flags);
564 559
565 /* Check against non-VIC supported modes */ 560 /* Check against non-VIC supported modes */
566 if (!vic) { 561 if (!vic) {
@@ -650,8 +645,7 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder,
650 struct meson_drm *priv = dw_hdmi->priv; 645 struct meson_drm *priv = dw_hdmi->priv;
651 int vic = drm_match_cea_mode(mode); 646 int vic = drm_match_cea_mode(mode);
652 647
653 DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n", 648 DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic);
654 mode->base.id, mode->name, vic);
655 649
656 /* VENC + VENC-DVI Mode setup */ 650 /* VENC + VENC-DVI Mode setup */
657 meson_venc_hdmi_mode_set(priv, vic, mode); 651 meson_venc_hdmi_mode_set(priv, vic, mode);
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 30726c9fe28c..6893934b26c0 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -12,6 +12,7 @@
12 */ 12 */
13#include <linux/module.h> 13#include <linux/module.h>
14#include <drm/drmP.h> 14#include <drm/drmP.h>
15#include <drm/drm_util.h>
15#include <drm/drm_fb_helper.h> 16#include <drm/drm_fb_helper.h>
16#include <drm/drm_crtc_helper.h> 17#include <drm/drm_crtc_helper.h>
17 18
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
index 8f2359dc87b4..cc32ea5f4289 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
@@ -244,14 +244,8 @@ static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc)
244 244
245 mode = &crtc->state->adjusted_mode; 245 mode = &crtc->state->adjusted_mode;
246 246
247 DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 247 DBG("%s: set mode: " DRM_MODE_FMT,
248 mdp4_crtc->name, mode->base.id, mode->name, 248 mdp4_crtc->name, DRM_MODE_ARG(mode));
249 mode->vrefresh, mode->clock,
250 mode->hdisplay, mode->hsync_start,
251 mode->hsync_end, mode->htotal,
252 mode->vdisplay, mode->vsync_start,
253 mode->vsync_end, mode->vtotal,
254 mode->type, mode->flags);
255 249
256 mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma), 250 mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma),
257 MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) | 251 MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) |
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c
index 6a1ebdace391..48ce218b8463 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c
@@ -58,14 +58,7 @@ static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder,
58 58
59 mode = adjusted_mode; 59 mode = adjusted_mode;
60 60
61 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 61 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
62 mode->base.id, mode->name,
63 mode->vrefresh, mode->clock,
64 mode->hdisplay, mode->hsync_start,
65 mode->hsync_end, mode->htotal,
66 mode->vdisplay, mode->vsync_start,
67 mode->vsync_end, mode->vtotal,
68 mode->type, mode->flags);
69 62
70 ctrl_pol = 0; 63 ctrl_pol = 0;
71 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 64 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c
index a8fd14d4846b..ff8f2da160c0 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c
@@ -104,14 +104,7 @@ static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder,
104 104
105 mode = adjusted_mode; 105 mode = adjusted_mode;
106 106
107 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 107 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
108 mode->base.id, mode->name,
109 mode->vrefresh, mode->clock,
110 mode->hdisplay, mode->hsync_start,
111 mode->hsync_end, mode->htotal,
112 mode->vdisplay, mode->vsync_start,
113 mode->vsync_end, mode->vtotal,
114 mode->type, mode->flags);
115 108
116 mdp4_dtv_encoder->pixclock = mode->clock * 1000; 109 mdp4_dtv_encoder->pixclock = mode->clock * 1000;
117 110
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c
index c9e34501a89e..fff77a4b12c2 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c
@@ -273,14 +273,7 @@ static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder,
273 273
274 mode = adjusted_mode; 274 mode = adjusted_mode;
275 275
276 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 276 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
277 mode->base.id, mode->name,
278 mode->vrefresh, mode->clock,
279 mode->hdisplay, mode->hsync_start,
280 mode->hsync_end, mode->htotal,
281 mode->vdisplay, mode->vsync_start,
282 mode->vsync_end, mode->vtotal,
283 mode->type, mode->flags);
284 277
285 mdp4_lcdc_encoder->pixclock = mode->clock * 1000; 278 mdp4_lcdc_encoder->pixclock = mode->clock * 1000;
286 279
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
index c1962f29ec7d..976585d8bfd6 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c
@@ -134,14 +134,7 @@ void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
134{ 134{
135 mode = adjusted_mode; 135 mode = adjusted_mode;
136 136
137 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 137 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
138 mode->base.id, mode->name,
139 mode->vrefresh, mode->clock,
140 mode->hdisplay, mode->hsync_start,
141 mode->hsync_end, mode->htotal,
142 mode->vdisplay, mode->vsync_start,
143 mode->vsync_end, mode->vtotal,
144 mode->type, mode->flags);
145 pingpong_tearcheck_setup(encoder, mode); 138 pingpong_tearcheck_setup(encoder, mode);
146 mdp5_crtc_set_pipeline(encoder->crtc); 139 mdp5_crtc_set_pipeline(encoder->crtc);
147} 140}
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index c5fde1a4191a..2f95e6525589 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -384,14 +384,7 @@ static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc)
384 384
385 mode = &crtc->state->adjusted_mode; 385 mode = &crtc->state->adjusted_mode;
386 386
387 DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 387 DBG("%s: set mode: " DRM_MODE_FMT, crtc->name, DRM_MODE_ARG(mode));
388 crtc->name, mode->base.id, mode->name,
389 mode->vrefresh, mode->clock,
390 mode->hdisplay, mode->hsync_start,
391 mode->hsync_end, mode->htotal,
392 mode->vdisplay, mode->vsync_start,
393 mode->vsync_end, mode->vtotal,
394 mode->type, mode->flags);
395 388
396 mixer_width = mode->hdisplay; 389 mixer_width = mode->hdisplay;
397 if (r_mixer) 390 if (r_mixer)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c
index fcd44d1d1068..d2a56e55e53d 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c
@@ -118,14 +118,7 @@ static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
118 118
119 mode = adjusted_mode; 119 mode = adjusted_mode;
120 120
121 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 121 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
122 mode->base.id, mode->name,
123 mode->vrefresh, mode->clock,
124 mode->hdisplay, mode->hsync_start,
125 mode->hsync_end, mode->htotal,
126 mode->vdisplay, mode->vsync_start,
127 mode->vsync_end, mode->vtotal,
128 mode->type, mode->flags);
129 122
130 ctrl_pol = 0; 123 ctrl_pol = 0;
131 124
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
index 7cebcb2b3a37..6153514db04c 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
@@ -16,6 +16,7 @@
16 * this program. If not, see <http://www.gnu.org/licenses/>. 16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19#include <drm/drm_util.h>
19 20
20#include "mdp5_kms.h" 21#include "mdp5_kms.h"
21#include "mdp5_smp.h" 22#include "mdp5_smp.h"
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index bdb063b2dc4a..979a8e929341 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -536,14 +536,7 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
536 struct mipi_dsi_host *host = msm_dsi->host; 536 struct mipi_dsi_host *host = msm_dsi->host;
537 bool is_dual_dsi = IS_DUAL_DSI(); 537 bool is_dual_dsi = IS_DUAL_DSI();
538 538
539 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 539 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
540 mode->base.id, mode->name,
541 mode->vrefresh, mode->clock,
542 mode->hdisplay, mode->hsync_start,
543 mode->hsync_end, mode->htotal,
544 mode->vdisplay, mode->vsync_start,
545 mode->vsync_end, mode->vtotal,
546 mode->type, mode->flags);
547 540
548 if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) 541 if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
549 return; 542 return;
diff --git a/drivers/gpu/drm/msm/edp/edp_bridge.c b/drivers/gpu/drm/msm/edp/edp_bridge.c
index 86366ba03e60..11166bf232ff 100644
--- a/drivers/gpu/drm/msm/edp/edp_bridge.c
+++ b/drivers/gpu/drm/msm/edp/edp_bridge.c
@@ -60,14 +60,7 @@ static void edp_bridge_mode_set(struct drm_bridge *bridge,
60 struct edp_bridge *edp_bridge = to_edp_bridge(bridge); 60 struct edp_bridge *edp_bridge = to_edp_bridge(bridge);
61 struct msm_edp *edp = edp_bridge->edp; 61 struct msm_edp *edp = edp_bridge->edp;
62 62
63 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 63 DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
64 mode->base.id, mode->name,
65 mode->vrefresh, mode->clock,
66 mode->hdisplay, mode->hsync_start,
67 mode->hsync_end, mode->htotal,
68 mode->vdisplay, mode->vsync_start,
69 mode->vsync_end, mode->vtotal,
70 mode->type, mode->flags);
71 64
72 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 65 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
73 if ((connector->encoder != NULL) && 66 if ((connector->encoder != NULL) &&
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index b42feb80531b..03197b8959ba 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -101,7 +101,8 @@ static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi)
101 u32 val; 101 u32 val;
102 int len; 102 int len;
103 103
104 drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false); 104 drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
105 hdmi->connector, mode);
105 106
106 len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer)); 107 len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer));
107 if (len < 0) { 108 if (len < 0) {
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 88ba003979e6..13e778825098 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -263,23 +263,12 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
263 263
264 drm_kms_helper_poll_init(drm); 264 drm_kms_helper_poll_init(drm);
265 265
266 mxsfb->fbdev = drm_fbdev_cma_init(drm, 32,
267 drm->mode_config.num_connector);
268 if (IS_ERR(mxsfb->fbdev)) {
269 ret = PTR_ERR(mxsfb->fbdev);
270 mxsfb->fbdev = NULL;
271 dev_err(drm->dev, "Failed to init FB CMA area\n");
272 goto err_cma;
273 }
274
275 platform_set_drvdata(pdev, drm); 266 platform_set_drvdata(pdev, drm);
276 267
277 drm_helper_hpd_irq_event(drm); 268 drm_helper_hpd_irq_event(drm);
278 269
279 return 0; 270 return 0;
280 271
281err_cma:
282 drm_irq_uninstall(drm);
283err_irq: 272err_irq:
284 drm_panel_detach(mxsfb->panel); 273 drm_panel_detach(mxsfb->panel);
285err_vblank: 274err_vblank:
@@ -290,11 +279,6 @@ err_vblank:
290 279
291static void mxsfb_unload(struct drm_device *drm) 280static void mxsfb_unload(struct drm_device *drm)
292{ 281{
293 struct mxsfb_drm_private *mxsfb = drm->dev_private;
294
295 if (mxsfb->fbdev)
296 drm_fbdev_cma_fini(mxsfb->fbdev);
297
298 drm_kms_helper_poll_fini(drm); 282 drm_kms_helper_poll_fini(drm);
299 drm_mode_config_cleanup(drm); 283 drm_mode_config_cleanup(drm);
300 284
@@ -307,13 +291,6 @@ static void mxsfb_unload(struct drm_device *drm)
307 pm_runtime_disable(drm->dev); 291 pm_runtime_disable(drm->dev);
308} 292}
309 293
310static void mxsfb_lastclose(struct drm_device *drm)
311{
312 struct mxsfb_drm_private *mxsfb = drm->dev_private;
313
314 drm_fbdev_cma_restore_mode(mxsfb->fbdev);
315}
316
317static void mxsfb_irq_preinstall(struct drm_device *drm) 294static void mxsfb_irq_preinstall(struct drm_device *drm)
318{ 295{
319 struct mxsfb_drm_private *mxsfb = drm->dev_private; 296 struct mxsfb_drm_private *mxsfb = drm->dev_private;
@@ -347,7 +324,6 @@ static struct drm_driver mxsfb_driver = {
347 .driver_features = DRIVER_GEM | DRIVER_MODESET | 324 .driver_features = DRIVER_GEM | DRIVER_MODESET |
348 DRIVER_PRIME | DRIVER_ATOMIC | 325 DRIVER_PRIME | DRIVER_ATOMIC |
349 DRIVER_HAVE_IRQ, 326 DRIVER_HAVE_IRQ,
350 .lastclose = mxsfb_lastclose,
351 .irq_handler = mxsfb_irq_handler, 327 .irq_handler = mxsfb_irq_handler,
352 .irq_preinstall = mxsfb_irq_preinstall, 328 .irq_preinstall = mxsfb_irq_preinstall,
353 .irq_uninstall = mxsfb_irq_preinstall, 329 .irq_uninstall = mxsfb_irq_preinstall,
@@ -412,6 +388,8 @@ static int mxsfb_probe(struct platform_device *pdev)
412 if (ret) 388 if (ret)
413 goto err_unload; 389 goto err_unload;
414 390
391 drm_fbdev_generic_setup(drm, 32);
392
415 return 0; 393 return 0;
416 394
417err_unload: 395err_unload:
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
index 5d0883fc805b..bedd6801edca 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
@@ -37,7 +37,6 @@ struct mxsfb_drm_private {
37 struct drm_simple_display_pipe pipe; 37 struct drm_simple_display_pipe pipe;
38 struct drm_connector connector; 38 struct drm_connector connector;
39 struct drm_panel *panel; 39 struct drm_panel *panel;
40 struct drm_fbdev_cma *fbdev;
41}; 40};
42 41
43int mxsfb_setup_crtc(struct drm_device *dev); 42int mxsfb_setup_crtc(struct drm_device *dev);
diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
index 6a4ca139cf5d..8fd8124d72ba 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
@@ -750,7 +750,9 @@ static int nv17_tv_set_property(struct drm_encoder *encoder,
750 /* Disable the crtc to ensure a full modeset is 750 /* Disable the crtc to ensure a full modeset is
751 * performed whenever it's turned on again. */ 751 * performed whenever it's turned on again. */
752 if (crtc) 752 if (crtc)
753 drm_crtc_force_disable(crtc); 753 drm_crtc_helper_set_mode(crtc, &crtc->mode,
754 crtc->x, crtc->y,
755 crtc->primary->fb);
754 } 756 }
755 757
756 return 0; 758 return 0;
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 26af45785939..67107f0b1299 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -561,7 +561,7 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
561 u32 max_ac_packet; 561 u32 max_ac_packet;
562 union hdmi_infoframe avi_frame; 562 union hdmi_infoframe avi_frame;
563 union hdmi_infoframe vendor_frame; 563 union hdmi_infoframe vendor_frame;
564 bool scdc_supported, high_tmds_clock_ratio = false, scrambling = false; 564 bool high_tmds_clock_ratio = false, scrambling = false;
565 u8 config; 565 u8 config;
566 int ret; 566 int ret;
567 int size; 567 int size;
@@ -571,10 +571,9 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
571 return; 571 return;
572 572
573 hdmi = &nv_connector->base.display_info.hdmi; 573 hdmi = &nv_connector->base.display_info.hdmi;
574 scdc_supported = hdmi->scdc.supported;
575 574
576 ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, mode, 575 ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi,
577 scdc_supported); 576 &nv_connector->base, mode);
578 if (!ret) { 577 if (!ret) {
579 /* We have an AVI InfoFrame, populate it to the display */ 578 /* We have an AVI InfoFrame, populate it to the display */
580 args.pwr.avi_infoframe_length 579 args.pwr.avi_infoframe_length
@@ -680,6 +679,8 @@ nv50_msto_payload(struct nv50_msto *msto)
680 struct nv50_mstm *mstm = mstc->mstm; 679 struct nv50_mstm *mstm = mstc->mstm;
681 int vcpi = mstc->port->vcpi.vcpi, i; 680 int vcpi = mstc->port->vcpi.vcpi, i;
682 681
682 WARN_ON(!mutex_is_locked(&mstm->mgr.payload_lock));
683
683 NV_ATOMIC(drm, "%s: vcpi %d\n", msto->encoder.name, vcpi); 684 NV_ATOMIC(drm, "%s: vcpi %d\n", msto->encoder.name, vcpi);
684 for (i = 0; i < mstm->mgr.max_payloads; i++) { 685 for (i = 0; i < mstm->mgr.max_payloads; i++) {
685 struct drm_dp_payload *payload = &mstm->mgr.payloads[i]; 686 struct drm_dp_payload *payload = &mstm->mgr.payloads[i];
@@ -704,14 +705,16 @@ nv50_msto_cleanup(struct nv50_msto *msto)
704 struct nv50_mstc *mstc = msto->mstc; 705 struct nv50_mstc *mstc = msto->mstc;
705 struct nv50_mstm *mstm = mstc->mstm; 706 struct nv50_mstm *mstm = mstc->mstm;
706 707
708 if (!msto->disabled)
709 return;
710
707 NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name); 711 NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name);
708 if (mstc->port && mstc->port->vcpi.vcpi > 0 && !nv50_msto_payload(msto)) 712
709 drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port); 713 drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port);
710 if (msto->disabled) { 714
711 msto->mstc = NULL; 715 msto->mstc = NULL;
712 msto->head = NULL; 716 msto->head = NULL;
713 msto->disabled = false; 717 msto->disabled = false;
714 }
715} 718}
716 719
717static void 720static void
@@ -731,8 +734,10 @@ nv50_msto_prepare(struct nv50_msto *msto)
731 (0x0100 << msto->head->base.index), 734 (0x0100 << msto->head->base.index),
732 }; 735 };
733 736
737 mutex_lock(&mstm->mgr.payload_lock);
738
734 NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name); 739 NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name);
735 if (mstc->port && mstc->port->vcpi.vcpi > 0) { 740 if (mstc->port->vcpi.vcpi > 0) {
736 struct drm_dp_payload *payload = nv50_msto_payload(msto); 741 struct drm_dp_payload *payload = nv50_msto_payload(msto);
737 if (payload) { 742 if (payload) {
738 args.vcpi.start_slot = payload->start_slot; 743 args.vcpi.start_slot = payload->start_slot;
@@ -746,7 +751,9 @@ nv50_msto_prepare(struct nv50_msto *msto)
746 msto->encoder.name, msto->head->base.base.name, 751 msto->encoder.name, msto->head->base.base.name,
747 args.vcpi.start_slot, args.vcpi.num_slots, 752 args.vcpi.start_slot, args.vcpi.num_slots,
748 args.vcpi.pbn, args.vcpi.aligned_pbn); 753 args.vcpi.pbn, args.vcpi.aligned_pbn);
754
749 nvif_mthd(&drm->display->disp.object, 0, &args, sizeof(args)); 755 nvif_mthd(&drm->display->disp.object, 0, &args, sizeof(args));
756 mutex_unlock(&mstm->mgr.payload_lock);
750} 757}
751 758
752static int 759static int
@@ -754,16 +761,23 @@ nv50_msto_atomic_check(struct drm_encoder *encoder,
754 struct drm_crtc_state *crtc_state, 761 struct drm_crtc_state *crtc_state,
755 struct drm_connector_state *conn_state) 762 struct drm_connector_state *conn_state)
756{ 763{
757 struct nv50_mstc *mstc = nv50_mstc(conn_state->connector); 764 struct drm_atomic_state *state = crtc_state->state;
765 struct drm_connector *connector = conn_state->connector;
766 struct nv50_mstc *mstc = nv50_mstc(connector);
758 struct nv50_mstm *mstm = mstc->mstm; 767 struct nv50_mstm *mstm = mstc->mstm;
759 int bpp = conn_state->connector->display_info.bpc * 3; 768 int bpp = connector->display_info.bpc * 3;
760 int slots; 769 int slots;
761 770
762 mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock, bpp); 771 mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock,
772 bpp);
763 773
764 slots = drm_dp_find_vcpi_slots(&mstm->mgr, mstc->pbn); 774 if (drm_atomic_crtc_needs_modeset(crtc_state) &&
765 if (slots < 0) 775 !drm_connector_is_unregistered(connector)) {
766 return slots; 776 slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr,
777 mstc->port, mstc->pbn);
778 if (slots < 0)
779 return slots;
780 }
767 781
768 return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, 782 return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state,
769 mstc->native); 783 mstc->native);
@@ -829,8 +843,7 @@ nv50_msto_disable(struct drm_encoder *encoder)
829 struct nv50_mstc *mstc = msto->mstc; 843 struct nv50_mstc *mstc = msto->mstc;
830 struct nv50_mstm *mstm = mstc->mstm; 844 struct nv50_mstm *mstm = mstc->mstm;
831 845
832 if (mstc->port) 846 drm_dp_mst_reset_vcpi_slots(&mstm->mgr, mstc->port);
833 drm_dp_mst_reset_vcpi_slots(&mstm->mgr, mstc->port);
834 847
835 mstm->outp->update(mstm->outp, msto->head->base.index, NULL, 0, 0); 848 mstm->outp->update(mstm->outp, msto->head->base.index, NULL, 0, 0);
836 mstm->modified = true; 849 mstm->modified = true;
@@ -927,12 +940,43 @@ nv50_mstc_get_modes(struct drm_connector *connector)
927 return ret; 940 return ret;
928} 941}
929 942
943static int
944nv50_mstc_atomic_check(struct drm_connector *connector,
945 struct drm_connector_state *new_conn_state)
946{
947 struct drm_atomic_state *state = new_conn_state->state;
948 struct nv50_mstc *mstc = nv50_mstc(connector);
949 struct drm_dp_mst_topology_mgr *mgr = &mstc->mstm->mgr;
950 struct drm_connector_state *old_conn_state =
951 drm_atomic_get_old_connector_state(state, connector);
952 struct drm_crtc_state *crtc_state;
953 struct drm_crtc *new_crtc = new_conn_state->crtc;
954
955 if (!old_conn_state->crtc)
956 return 0;
957
958 /* We only want to free VCPI if this state disables the CRTC on this
959 * connector
960 */
961 if (new_crtc) {
962 crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc);
963
964 if (!crtc_state ||
965 !drm_atomic_crtc_needs_modeset(crtc_state) ||
966 crtc_state->enable)
967 return 0;
968 }
969
970 return drm_dp_atomic_release_vcpi_slots(state, mgr, mstc->port);
971}
972
930static const struct drm_connector_helper_funcs 973static const struct drm_connector_helper_funcs
931nv50_mstc_help = { 974nv50_mstc_help = {
932 .get_modes = nv50_mstc_get_modes, 975 .get_modes = nv50_mstc_get_modes,
933 .mode_valid = nv50_mstc_mode_valid, 976 .mode_valid = nv50_mstc_mode_valid,
934 .best_encoder = nv50_mstc_best_encoder, 977 .best_encoder = nv50_mstc_best_encoder,
935 .atomic_best_encoder = nv50_mstc_atomic_best_encoder, 978 .atomic_best_encoder = nv50_mstc_atomic_best_encoder,
979 .atomic_check = nv50_mstc_atomic_check,
936}; 980};
937 981
938static enum drm_connector_status 982static enum drm_connector_status
@@ -942,7 +986,7 @@ nv50_mstc_detect(struct drm_connector *connector, bool force)
942 enum drm_connector_status conn_status; 986 enum drm_connector_status conn_status;
943 int ret; 987 int ret;
944 988
945 if (!mstc->port) 989 if (drm_connector_is_unregistered(connector))
946 return connector_status_disconnected; 990 return connector_status_disconnected;
947 991
948 ret = pm_runtime_get_sync(connector->dev->dev); 992 ret = pm_runtime_get_sync(connector->dev->dev);
@@ -961,7 +1005,10 @@ static void
961nv50_mstc_destroy(struct drm_connector *connector) 1005nv50_mstc_destroy(struct drm_connector *connector)
962{ 1006{
963 struct nv50_mstc *mstc = nv50_mstc(connector); 1007 struct nv50_mstc *mstc = nv50_mstc(connector);
1008
964 drm_connector_cleanup(&mstc->connector); 1009 drm_connector_cleanup(&mstc->connector);
1010 drm_dp_mst_put_port_malloc(mstc->port);
1011
965 kfree(mstc); 1012 kfree(mstc);
966} 1013}
967 1014
@@ -1009,6 +1056,7 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
1009 drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0); 1056 drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0);
1010 drm_object_attach_property(&mstc->connector.base, dev->mode_config.tile_property, 0); 1057 drm_object_attach_property(&mstc->connector.base, dev->mode_config.tile_property, 0);
1011 drm_connector_set_path_property(&mstc->connector, path); 1058 drm_connector_set_path_property(&mstc->connector, path);
1059 drm_dp_mst_get_port_malloc(port);
1012 return 0; 1060 return 0;
1013} 1061}
1014 1062
@@ -1073,10 +1121,6 @@ nv50_mstm_destroy_connector(struct drm_dp_mst_topology_mgr *mgr,
1073 1121
1074 drm_fb_helper_remove_one_connector(&drm->fbcon->helper, &mstc->connector); 1122 drm_fb_helper_remove_one_connector(&drm->fbcon->helper, &mstc->connector);
1075 1123
1076 drm_modeset_lock(&drm->dev->mode_config.connection_mutex, NULL);
1077 mstc->port = NULL;
1078 drm_modeset_unlock(&drm->dev->mode_config.connection_mutex);
1079
1080 drm_connector_put(&mstc->connector); 1124 drm_connector_put(&mstc->connector);
1081} 1125}
1082 1126
@@ -1099,11 +1143,8 @@ nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr *mgr,
1099 int ret; 1143 int ret;
1100 1144
1101 ret = nv50_mstc_new(mstm, port, path, &mstc); 1145 ret = nv50_mstc_new(mstm, port, path, &mstc);
1102 if (ret) { 1146 if (ret)
1103 if (mstc)
1104 mstc->connector.funcs->destroy(&mstc->connector);
1105 return NULL; 1147 return NULL;
1106 }
1107 1148
1108 return &mstc->connector; 1149 return &mstc->connector;
1109} 1150}
@@ -2117,6 +2158,10 @@ nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
2117 return ret; 2158 return ret;
2118 } 2159 }
2119 2160
2161 ret = drm_dp_mst_atomic_check(state);
2162 if (ret)
2163 return ret;
2164
2120 return 0; 2165 return 0;
2121} 2166}
2122 2167
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index f326ffd86766..5d273a655479 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -453,7 +453,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
453 if (drm_drv_uses_atomic_modeset(dev)) 453 if (drm_drv_uses_atomic_modeset(dev))
454 drm_atomic_helper_shutdown(dev); 454 drm_atomic_helper_shutdown(dev);
455 else 455 else
456 drm_crtc_force_disable_all(dev); 456 drm_helper_force_disable_all(dev);
457 } 457 }
458 458
459 /* disable flip completion events */ 459 /* disable flip completion events */
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index b81302c4bf9e..874d8f3cbff6 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -305,14 +305,9 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
305 drm_mode_destroy(dev, new_mode); 305 drm_mode_destroy(dev, new_mode);
306 306
307done: 307done:
308 DBG("connector: mode %s: " 308 DBG("connector: mode %s: " DRM_MODE_FMT,
309 "%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
310 (ret == MODE_OK) ? "valid" : "invalid", 309 (ret == MODE_OK) ? "valid" : "invalid",
311 mode->base.id, mode->name, mode->vrefresh, mode->clock, 310 DRM_MODE_ARG(mode));
312 mode->hdisplay, mode->hsync_start,
313 mode->hsync_end, mode->htotal,
314 mode->vdisplay, mode->vsync_start,
315 mode->vsync_end, mode->vtotal, mode->type, mode->flags);
316 311
317 return ret; 312 return ret;
318} 313}
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index caffc547ef97..40acf4ce7c9f 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -427,12 +427,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
427 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 427 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
428 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 428 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
429 429
430 DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 430 DBG("%s: set mode: " DRM_MODE_FMT,
431 omap_crtc->name, mode->base.id, mode->name, 431 omap_crtc->name, DRM_MODE_ARG(mode));
432 mode->vrefresh, mode->clock,
433 mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
434 mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
435 mode->type, mode->flags);
436 432
437 drm_display_mode_to_videomode(mode, &omap_crtc->vm); 433 drm_display_mode_to_videomode(mode, &omap_crtc->vm);
438} 434}
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 933ebc9f9faa..148b6b20274f 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -76,8 +76,8 @@ static void omap_encoder_hdmi_mode_set(struct drm_encoder *encoder,
76 struct hdmi_avi_infoframe avi; 76 struct hdmi_avi_infoframe avi;
77 int r; 77 int r;
78 78
79 r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode, 79 r = drm_hdmi_avi_infoframe_from_display_mode(&avi, connector,
80 false); 80 adjusted_mode);
81 if (r == 0) 81 if (r == 0)
82 dssdev->ops->hdmi.set_infoframe(dssdev, &avi); 82 dssdev->ops->hdmi.set_infoframe(dssdev, &avi);
83 } 83 }
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index aee99194499f..851c59f07eb1 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <drm/drm_crtc.h> 18#include <drm/drm_crtc.h>
19#include <drm/drm_util.h>
19#include <drm/drm_fb_helper.h> 20#include <drm/drm_fb_helper.h>
20 21
21#include "omap_drv.h" 22#include "omap_drv.h"
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 3f3537719beb..a71f44191273 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -204,6 +204,15 @@ config DRM_PANEL_SITRONIX_ST7789V
204 Say Y here if you want to enable support for the Sitronix 204 Say Y here if you want to enable support for the Sitronix
205 ST7789V controller for 240x320 LCD panels 205 ST7789V controller for 240x320 LCD panels
206 206
207config DRM_PANEL_TPO_TPG110
208 tristate "TPO TPG 800x400 panel"
209 depends on OF && SPI && GPIOLIB
210 depends on BACKLIGHT_CLASS_DEVICE
211 help
212 Say Y here if you want to enable support for TPO TPG110
213 400CH LTPS TFT LCD Single Chip Digital Driver for up to
214 800x400 LCD panels.
215
207config DRM_PANEL_TRULY_NT35597_WQXGA 216config DRM_PANEL_TRULY_NT35597_WQXGA
208 tristate "Truly WQXGA" 217 tristate "Truly WQXGA"
209 depends on OF 218 depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 4396658a7996..cd14ca39c6e0 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -21,4 +21,5 @@ obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
21obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o 21obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
22obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o 22obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
23obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o 23obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
24obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
24obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o 25obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
diff --git a/drivers/gpu/drm/panel/panel-tpo-tpg110.c b/drivers/gpu/drm/panel/panel-tpo-tpg110.c
new file mode 100644
index 000000000000..5a9f8f4d5d24
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-tpo-tpg110.c
@@ -0,0 +1,496 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Panel driver for the TPO TPG110 400CH LTPS TFT LCD Single Chip
4 * Digital Driver.
5 *
6 * This chip drives a TFT LCD, so it does not know what kind of
7 * display is actually connected to it, so the width and height of that
8 * display needs to be supplied from the machine configuration.
9 *
10 * Author:
11 * Linus Walleij <linus.walleij@linaro.org>
12 */
13#include <drm/drm_modes.h>
14#include <drm/drm_panel.h>
15#include <drm/drm_print.h>
16
17#include <linux/backlight.h>
18#include <linux/bitops.h>
19#include <linux/delay.h>
20#include <linux/gpio/consumer.h>
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/spi/spi.h>
26
27#define TPG110_TEST 0x00
28#define TPG110_CHIPID 0x01
29#define TPG110_CTRL1 0x02
30#define TPG110_RES_MASK GENMASK(2, 0)
31#define TPG110_RES_800X480 0x07
32#define TPG110_RES_640X480 0x06
33#define TPG110_RES_480X272 0x05
34#define TPG110_RES_480X640 0x04
35#define TPG110_RES_480X272_D 0x01 /* Dual scan: outputs 800x480 */
36#define TPG110_RES_400X240_D 0x00 /* Dual scan: outputs 800x480 */
37#define TPG110_CTRL2 0x03
38#define TPG110_CTRL2_PM BIT(0)
39#define TPG110_CTRL2_RES_PM_CTRL BIT(7)
40
41/**
42 * struct tpg110_panel_mode - lookup struct for the supported modes
43 */
44struct tpg110_panel_mode {
45 /**
46 * @name: the name of this panel
47 */
48 const char *name;
49 /**
50 * @magic: the magic value from the detection register
51 */
52 u32 magic;
53 /**
54 * @mode: the DRM display mode for this panel
55 */
56 struct drm_display_mode mode;
57 /**
58 * @bus_flags: the DRM bus flags for this panel e.g. inverted clock
59 */
60 u32 bus_flags;
61};
62
63/**
64 * struct tpg110 - state container for the TPG110 panel
65 */
66struct tpg110 {
67 /**
68 * @dev: the container device
69 */
70 struct device *dev;
71 /**
72 * @spi: the corresponding SPI device
73 */
74 struct spi_device *spi;
75 /**
76 * @panel: the DRM panel instance for this device
77 */
78 struct drm_panel panel;
79 /**
80 * @backlight: backlight for this panel
81 */
82 struct backlight_device *backlight;
83 /**
84 * @panel_type: the panel mode as detected
85 */
86 const struct tpg110_panel_mode *panel_mode;
87 /**
88 * @width: the width of this panel in mm
89 */
90 u32 width;
91 /**
92 * @height: the height of this panel in mm
93 */
94 u32 height;
95 /**
96 * @grestb: reset GPIO line
97 */
98 struct gpio_desc *grestb;
99};
100
101/*
102 * TPG110 modes, these are the simple modes, the dualscan modes that
103 * take 400x240 or 480x272 in and display as 800x480 are not listed.
104 */
105static const struct tpg110_panel_mode tpg110_modes[] = {
106 {
107 .name = "800x480 RGB",
108 .magic = TPG110_RES_800X480,
109 .mode = {
110 .clock = 33200,
111 .hdisplay = 800,
112 .hsync_start = 800 + 40,
113 .hsync_end = 800 + 40 + 1,
114 .htotal = 800 + 40 + 1 + 216,
115 .vdisplay = 480,
116 .vsync_start = 480 + 10,
117 .vsync_end = 480 + 10 + 1,
118 .vtotal = 480 + 10 + 1 + 35,
119 .vrefresh = 60,
120 },
121 .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
122 },
123 {
124 .name = "640x480 RGB",
125 .magic = TPG110_RES_640X480,
126 .mode = {
127 .clock = 25200,
128 .hdisplay = 640,
129 .hsync_start = 640 + 24,
130 .hsync_end = 640 + 24 + 1,
131 .htotal = 640 + 24 + 1 + 136,
132 .vdisplay = 480,
133 .vsync_start = 480 + 18,
134 .vsync_end = 480 + 18 + 1,
135 .vtotal = 480 + 18 + 1 + 27,
136 .vrefresh = 60,
137 },
138 .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
139 },
140 {
141 .name = "480x272 RGB",
142 .magic = TPG110_RES_480X272,
143 .mode = {
144 .clock = 9000,
145 .hdisplay = 480,
146 .hsync_start = 480 + 2,
147 .hsync_end = 480 + 2 + 1,
148 .htotal = 480 + 2 + 1 + 43,
149 .vdisplay = 272,
150 .vsync_start = 272 + 2,
151 .vsync_end = 272 + 2 + 1,
152 .vtotal = 272 + 2 + 1 + 12,
153 .vrefresh = 60,
154 },
155 .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
156 },
157 {
158 .name = "480x640 RGB",
159 .magic = TPG110_RES_480X640,
160 .mode = {
161 .clock = 20500,
162 .hdisplay = 480,
163 .hsync_start = 480 + 2,
164 .hsync_end = 480 + 2 + 1,
165 .htotal = 480 + 2 + 1 + 43,
166 .vdisplay = 640,
167 .vsync_start = 640 + 4,
168 .vsync_end = 640 + 4 + 1,
169 .vtotal = 640 + 4 + 1 + 8,
170 .vrefresh = 60,
171 },
172 .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
173 },
174 {
175 .name = "400x240 RGB",
176 .magic = TPG110_RES_400X240_D,
177 .mode = {
178 .clock = 8300,
179 .hdisplay = 400,
180 .hsync_start = 400 + 20,
181 .hsync_end = 400 + 20 + 1,
182 .htotal = 400 + 20 + 1 + 108,
183 .vdisplay = 240,
184 .vsync_start = 240 + 2,
185 .vsync_end = 240 + 2 + 1,
186 .vtotal = 240 + 2 + 1 + 20,
187 .vrefresh = 60,
188 },
189 .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
190 },
191};
192
193static inline struct tpg110 *
194to_tpg110(struct drm_panel *panel)
195{
196 return container_of(panel, struct tpg110, panel);
197}
198
199static u8 tpg110_readwrite_reg(struct tpg110 *tpg, bool write,
200 u8 address, u8 outval)
201{
202 struct spi_message m;
203 struct spi_transfer t[2];
204 u8 buf[2];
205 int ret;
206
207 spi_message_init(&m);
208 memset(t, 0, sizeof(t));
209
210 if (write) {
211 /*
212 * Clear address bit 0, 1 when writing, just to be sure
213 * The actual bit indicating a write here is bit 1, bit
214 * 0 is just surplus to pad it up to 8 bits.
215 */
216 buf[0] = address << 2;
217 buf[0] &= ~0x03;
218 buf[1] = outval;
219
220 t[0].bits_per_word = 8;
221 t[0].tx_buf = &buf[0];
222 t[0].len = 1;
223
224 t[1].tx_buf = &buf[1];
225 t[1].len = 1;
226 t[1].bits_per_word = 8;
227 } else {
228 /* Set address bit 0 to 1 to read */
229 buf[0] = address << 1;
230 buf[0] |= 0x01;
231
232 /*
233 * The last bit/clock is Hi-Z turnaround cycle, so we need
234 * to send only 7 bits here. The 8th bit is the high impedance
235 * turn-around cycle.
236 */
237 t[0].bits_per_word = 7;
238 t[0].tx_buf = &buf[0];
239 t[0].len = 1;
240
241 t[1].rx_buf = &buf[1];
242 t[1].len = 1;
243 t[1].bits_per_word = 8;
244 }
245
246 spi_message_add_tail(&t[0], &m);
247 spi_message_add_tail(&t[1], &m);
248 ret = spi_sync(tpg->spi, &m);
249 if (ret) {
250 DRM_DEV_ERROR(tpg->dev, "SPI message error %d\n", ret);
251 return ret;
252 }
253 if (write)
254 return 0;
255 /* Read */
256 return buf[1];
257}
258
259static u8 tpg110_read_reg(struct tpg110 *tpg, u8 address)
260{
261 return tpg110_readwrite_reg(tpg, false, address, 0);
262}
263
264static void tpg110_write_reg(struct tpg110 *tpg, u8 address, u8 outval)
265{
266 tpg110_readwrite_reg(tpg, true, address, outval);
267}
268
269static int tpg110_startup(struct tpg110 *tpg)
270{
271 u8 val;
272 int i;
273
274 /* De-assert the reset signal */
275 gpiod_set_value_cansleep(tpg->grestb, 0);
276 usleep_range(1000, 2000);
277 DRM_DEV_DEBUG(tpg->dev, "de-asserted GRESTB\n");
278
279 /* Test display communication */
280 tpg110_write_reg(tpg, TPG110_TEST, 0x55);
281 val = tpg110_read_reg(tpg, TPG110_TEST);
282 if (val != 0x55) {
283 DRM_DEV_ERROR(tpg->dev, "failed communication test\n");
284 return -ENODEV;
285 }
286
287 val = tpg110_read_reg(tpg, TPG110_CHIPID);
288 DRM_DEV_INFO(tpg->dev, "TPG110 chip ID: %d version: %d\n",
289 val >> 4, val & 0x0f);
290
291 /* Show display resolution */
292 val = tpg110_read_reg(tpg, TPG110_CTRL1);
293 val &= TPG110_RES_MASK;
294 switch (val) {
295 case TPG110_RES_400X240_D:
296 DRM_DEV_INFO(tpg->dev,
297 "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)\n");
298 break;
299 case TPG110_RES_480X272_D:
300 DRM_DEV_INFO(tpg->dev,
301 "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)\n");
302 break;
303 case TPG110_RES_480X640:
304 DRM_DEV_INFO(tpg->dev, "480x640 RGB\n");
305 break;
306 case TPG110_RES_480X272:
307 DRM_DEV_INFO(tpg->dev, "480x272 RGB\n");
308 break;
309 case TPG110_RES_640X480:
310 DRM_DEV_INFO(tpg->dev, "640x480 RGB\n");
311 break;
312 case TPG110_RES_800X480:
313 DRM_DEV_INFO(tpg->dev, "800x480 RGB\n");
314 break;
315 default:
316 DRM_DEV_ERROR(tpg->dev, "ILLEGAL RESOLUTION 0x%02x\n", val);
317 break;
318 }
319
320 /* From the producer side, this is the same resolution */
321 if (val == TPG110_RES_480X272_D)
322 val = TPG110_RES_480X272;
323
324 for (i = 0; i < ARRAY_SIZE(tpg110_modes); i++) {
325 const struct tpg110_panel_mode *pm;
326
327 pm = &tpg110_modes[i];
328 if (pm->magic == val) {
329 tpg->panel_mode = pm;
330 break;
331 }
332 }
333 if (i == ARRAY_SIZE(tpg110_modes)) {
334 DRM_DEV_ERROR(tpg->dev, "unsupported mode (%02x) detected\n",
335 val);
336 return -ENODEV;
337 }
338
339 val = tpg110_read_reg(tpg, TPG110_CTRL2);
340 DRM_DEV_INFO(tpg->dev, "resolution and standby is controlled by %s\n",
341 (val & TPG110_CTRL2_RES_PM_CTRL) ? "software" : "hardware");
342 /* Take control over resolution and standby */
343 val |= TPG110_CTRL2_RES_PM_CTRL;
344 tpg110_write_reg(tpg, TPG110_CTRL2, val);
345
346 return 0;
347}
348
349static int tpg110_disable(struct drm_panel *panel)
350{
351 struct tpg110 *tpg = to_tpg110(panel);
352 u8 val;
353
354 /* Put chip into standby */
355 val = tpg110_read_reg(tpg, TPG110_CTRL2_PM);
356 val &= ~TPG110_CTRL2_PM;
357 tpg110_write_reg(tpg, TPG110_CTRL2_PM, val);
358
359 backlight_disable(tpg->backlight);
360
361 return 0;
362}
363
364static int tpg110_enable(struct drm_panel *panel)
365{
366 struct tpg110 *tpg = to_tpg110(panel);
367 u8 val;
368
369 backlight_enable(tpg->backlight);
370
371 /* Take chip out of standby */
372 val = tpg110_read_reg(tpg, TPG110_CTRL2_PM);
373 val |= TPG110_CTRL2_PM;
374 tpg110_write_reg(tpg, TPG110_CTRL2_PM, val);
375
376 return 0;
377}
378
379/**
380 * tpg110_get_modes() - return the appropriate mode
381 * @panel: the panel to get the mode for
382 *
383 * This currently does not present a forest of modes, instead it
384 * presents the mode that is configured for the system under use,
385 * and which is detected by reading the registers of the display.
386 */
387static int tpg110_get_modes(struct drm_panel *panel)
388{
389 struct drm_connector *connector = panel->connector;
390 struct tpg110 *tpg = to_tpg110(panel);
391 struct drm_display_mode *mode;
392
393 strncpy(connector->display_info.name, tpg->panel_mode->name,
394 DRM_DISPLAY_INFO_LEN);
395 connector->display_info.width_mm = tpg->width;
396 connector->display_info.height_mm = tpg->height;
397 connector->display_info.bus_flags = tpg->panel_mode->bus_flags;
398
399 mode = drm_mode_duplicate(panel->drm, &tpg->panel_mode->mode);
400 drm_mode_set_name(mode);
401 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
402
403 mode->width_mm = tpg->width;
404 mode->height_mm = tpg->height;
405
406 drm_mode_probed_add(connector, mode);
407
408 return 1;
409}
410
411static const struct drm_panel_funcs tpg110_drm_funcs = {
412 .disable = tpg110_disable,
413 .enable = tpg110_enable,
414 .get_modes = tpg110_get_modes,
415};
416
417static int tpg110_probe(struct spi_device *spi)
418{
419 struct device *dev = &spi->dev;
420 struct device_node *np = dev->of_node;
421 struct tpg110 *tpg;
422 int ret;
423
424 tpg = devm_kzalloc(dev, sizeof(*tpg), GFP_KERNEL);
425 if (!tpg)
426 return -ENOMEM;
427 tpg->dev = dev;
428
429 /* We get the physical display dimensions from the DT */
430 ret = of_property_read_u32(np, "width-mm", &tpg->width);
431 if (ret)
432 DRM_DEV_ERROR(dev, "no panel width specified\n");
433 ret = of_property_read_u32(np, "height-mm", &tpg->height);
434 if (ret)
435 DRM_DEV_ERROR(dev, "no panel height specified\n");
436
437 /* Look for some optional backlight */
438 tpg->backlight = devm_of_find_backlight(dev);
439 if (IS_ERR(tpg->backlight))
440 return PTR_ERR(tpg->backlight);
441
442 /* This asserts the GRESTB signal, putting the display into reset */
443 tpg->grestb = devm_gpiod_get(dev, "grestb", GPIOD_OUT_HIGH);
444 if (IS_ERR(tpg->grestb)) {
445 DRM_DEV_ERROR(dev, "no GRESTB GPIO\n");
446 return -ENODEV;
447 }
448
449 spi->bits_per_word = 8;
450 spi->mode |= SPI_3WIRE_HIZ;
451 ret = spi_setup(spi);
452 if (ret < 0) {
453 DRM_DEV_ERROR(dev, "spi setup failed.\n");
454 return ret;
455 }
456 tpg->spi = spi;
457
458 ret = tpg110_startup(tpg);
459 if (ret)
460 return ret;
461
462 drm_panel_init(&tpg->panel);
463 tpg->panel.dev = dev;
464 tpg->panel.funcs = &tpg110_drm_funcs;
465 spi_set_drvdata(spi, tpg);
466
467 return drm_panel_add(&tpg->panel);
468}
469
470static int tpg110_remove(struct spi_device *spi)
471{
472 struct tpg110 *tpg = spi_get_drvdata(spi);
473
474 drm_panel_remove(&tpg->panel);
475 return 0;
476}
477
478static const struct of_device_id tpg110_match[] = {
479 { .compatible = "tpo,tpg110", },
480 {},
481};
482MODULE_DEVICE_TABLE(of, tpg110_match);
483
484static struct spi_driver tpg110_driver = {
485 .probe = tpg110_probe,
486 .remove = tpg110_remove,
487 .driver = {
488 .name = "tpo-tpg110-panel",
489 .of_match_table = tpg110_match,
490 },
491};
492module_spi_driver(tpg110_driver);
493
494MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
495MODULE_DESCRIPTION("TPO TPG110 panel driver");
496MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index dffc5093ff16..2e100f644236 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -25,6 +25,8 @@
25 25
26/* QXL cmd/ring handling */ 26/* QXL cmd/ring handling */
27 27
28#include <drm/drm_util.h>
29
28#include "qxl_drv.h" 30#include "qxl_drv.h"
29#include "qxl_object.h" 31#include "qxl_object.h"
30 32
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 72a1784dae54..1f8fddcc34d6 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -48,8 +48,8 @@ static int qxl_alloc_client_monitors_config(struct qxl_device *qdev,
48 } 48 }
49 if (!qdev->client_monitors_config) { 49 if (!qdev->client_monitors_config) {
50 qdev->client_monitors_config = kzalloc( 50 qdev->client_monitors_config = kzalloc(
51 sizeof(struct qxl_monitors_config) + 51 struct_size(qdev->client_monitors_config,
52 sizeof(struct qxl_head) * count, GFP_KERNEL); 52 heads, count), GFP_KERNEL);
53 if (!qdev->client_monitors_config) 53 if (!qdev->client_monitors_config)
54 return -ENOMEM; 54 return -ENOMEM;
55 } 55 }
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index e55cbeee7a53..ac98ad561870 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -27,6 +27,8 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <asm/unaligned.h> 28#include <asm/unaligned.h>
29 29
30#include <drm/drm_util.h>
31
30#define ATOM_DEBUG 32#define ATOM_DEBUG
31 33
32#include "atom.h" 34#include "atom.h"
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
index 770e31f5fd1b..96f71114237a 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -516,21 +516,17 @@ static int radeon_audio_set_avi_packet(struct drm_encoder *encoder,
516 if (!connector) 516 if (!connector)
517 return -EINVAL; 517 return -EINVAL;
518 518
519 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 519 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, connector, mode);
520 if (err < 0) { 520 if (err < 0) {
521 DRM_ERROR("failed to setup AVI infoframe: %d\n", err); 521 DRM_ERROR("failed to setup AVI infoframe: %d\n", err);
522 return err; 522 return err;
523 } 523 }
524 524
525 if (radeon_encoder->output_csc != RADEON_OUTPUT_CSC_BYPASS) { 525 if (radeon_encoder->output_csc != RADEON_OUTPUT_CSC_BYPASS) {
526 if (drm_rgb_quant_range_selectable(radeon_connector_edid(connector))) { 526 drm_hdmi_avi_infoframe_quant_range(&frame, connector, mode,
527 if (radeon_encoder->output_csc == RADEON_OUTPUT_CSC_TVRGB) 527 radeon_encoder->output_csc == RADEON_OUTPUT_CSC_TVRGB ?
528 frame.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED; 528 HDMI_QUANTIZATION_RANGE_LIMITED :
529 else 529 HDMI_QUANTIZATION_RANGE_FULL);
530 frame.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
531 } else {
532 frame.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
533 }
534 } 530 }
535 531
536 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); 532 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 9d3ac8b981da..b190478ad087 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1646,7 +1646,7 @@ void radeon_modeset_fini(struct radeon_device *rdev)
1646 if (rdev->mode_info.mode_config_initialized) { 1646 if (rdev->mode_info.mode_config_initialized) {
1647 drm_kms_helper_poll_fini(rdev->ddev); 1647 drm_kms_helper_poll_fini(rdev->ddev);
1648 radeon_hpd_fini(rdev); 1648 radeon_hpd_fini(rdev);
1649 drm_crtc_force_disable_all(rdev->ddev); 1649 drm_helper_force_disable_all(rdev->ddev);
1650 radeon_fbdev_fini(rdev); 1650 radeon_fbdev_fini(rdev);
1651 radeon_afmt_fini(rdev); 1651 radeon_afmt_fini(rdev);
1652 drm_mode_config_cleanup(rdev->ddev); 1652 drm_mode_config_cleanup(rdev->ddev);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 222a1fa41d7c..7e3257e8fd56 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -24,6 +24,7 @@
24 * Alex Deucher 24 * Alex Deucher
25 */ 25 */
26#include <drm/drmP.h> 26#include <drm/drmP.h>
27#include <drm/drm_util.h>
27#include <drm/drm_crtc_helper.h> 28#include <drm/drm_crtc_helper.h>
28#include <drm/radeon_drm.h> 29#include <drm/radeon_drm.h>
29#include "radeon.h" 30#include "radeon.h"
diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
index 603bb340e8cf..452461dc96f2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
@@ -7,10 +7,12 @@
7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) 7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
8 */ 8 */
9 9
10#include <linux/mod_devicetable.h>
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/platform_device.h> 12#include <linux/platform_device.h>
12 13
13#include <drm/bridge/dw_hdmi.h> 14#include <drm/bridge/dw_hdmi.h>
15#include <drm/drm_modes.h>
14 16
15#define RCAR_HDMI_PHY_OPMODE_PLLCFG 0x06 /* Mode of operation and PLL dividers */ 17#define RCAR_HDMI_PHY_OPMODE_PLLCFG 0x06 /* Mode of operation and PLL dividers */
16#define RCAR_HDMI_PHY_PLLCURRGMPCTRL 0x10 /* PLL current and Gmp (conductance) */ 18#define RCAR_HDMI_PHY_PLLCURRGMPCTRL 0x10 /* PLL current and Gmp (conductance) */
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 1c02b3e61299..27c945e030a0 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -295,7 +295,9 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
295 union hdmi_infoframe frame; 295 union hdmi_infoframe frame;
296 int rc; 296 int rc;
297 297
298 rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false); 298 rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
299 &hdmi->connector,
300 mode);
299 301
300 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444) 302 if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
301 frame.avi.colorspace = HDMI_COLORSPACE_YUV444; 303 frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index ea18cb2a76c0..08bec50d9c5d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -128,42 +128,6 @@ err_gem_object_unreference:
128} 128}
129 129
130static void 130static void
131rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state)
132{
133 struct drm_crtc *crtc;
134 struct drm_crtc_state *crtc_state;
135 struct drm_encoder *encoder;
136 u32 encoder_mask = 0;
137 int i;
138
139 for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
140 encoder_mask |= crtc_state->encoder_mask;
141 encoder_mask |= crtc->state->encoder_mask;
142 }
143
144 drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
145 rockchip_drm_psr_inhibit_get(encoder);
146}
147
148static void
149rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state)
150{
151 struct drm_crtc *crtc;
152 struct drm_crtc_state *crtc_state;
153 struct drm_encoder *encoder;
154 u32 encoder_mask = 0;
155 int i;
156
157 for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
158 encoder_mask |= crtc_state->encoder_mask;
159 encoder_mask |= crtc->state->encoder_mask;
160 }
161
162 drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
163 rockchip_drm_psr_inhibit_put(encoder);
164}
165
166static void
167rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state) 131rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
168{ 132{
169 struct drm_device *dev = old_state->dev; 133 struct drm_device *dev = old_state->dev;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index 01ff3c858875..22a70ab6e214 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <drm/drmP.h> 15#include <drm/drmP.h>
16#include <drm/drm_atomic.h>
16#include <drm/drm_crtc_helper.h> 17#include <drm/drm_crtc_helper.h>
17 18
18#include "rockchip_drm_drv.h" 19#include "rockchip_drm_drv.h"
@@ -109,6 +110,42 @@ int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder)
109} 110}
110EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put); 111EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put);
111 112
113void rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state)
114{
115 struct drm_crtc *crtc;
116 struct drm_crtc_state *crtc_state;
117 struct drm_encoder *encoder;
118 u32 encoder_mask = 0;
119 int i;
120
121 for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
122 encoder_mask |= crtc_state->encoder_mask;
123 encoder_mask |= crtc->state->encoder_mask;
124 }
125
126 drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
127 rockchip_drm_psr_inhibit_get(encoder);
128}
129EXPORT_SYMBOL(rockchip_drm_psr_inhibit_get_state);
130
131void rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state)
132{
133 struct drm_crtc *crtc;
134 struct drm_crtc_state *crtc_state;
135 struct drm_encoder *encoder;
136 u32 encoder_mask = 0;
137 int i;
138
139 for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
140 encoder_mask |= crtc_state->encoder_mask;
141 encoder_mask |= crtc->state->encoder_mask;
142 }
143
144 drm_for_each_encoder_mask(encoder, state->dev, encoder_mask)
145 rockchip_drm_psr_inhibit_put(encoder);
146}
147EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put_state);
148
112/** 149/**
113 * rockchip_drm_psr_inhibit_get - acquire PSR inhibit on given encoder 150 * rockchip_drm_psr_inhibit_get - acquire PSR inhibit on given encoder
114 * @encoder: encoder to obtain the PSR encoder 151 * @encoder: encoder to obtain the PSR encoder
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
index 860c62494496..25350ba3237b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
@@ -20,6 +20,9 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev);
20int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder); 20int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder);
21int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder); 21int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder);
22 22
23void rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state);
24void rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state);
25
23int rockchip_drm_psr_register(struct drm_encoder *encoder, 26int rockchip_drm_psr_register(struct drm_encoder *encoder,
24 int (*psr_set)(struct drm_encoder *, bool enable)); 27 int (*psr_set)(struct drm_encoder *, bool enable));
25void rockchip_drm_psr_unregister(struct drm_encoder *encoder); 28void rockchip_drm_psr_unregister(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index db8358e6d230..619b6db05d58 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -15,6 +15,7 @@
15#include <drm/drm.h> 15#include <drm/drm.h>
16#include <drm/drmP.h> 16#include <drm/drmP.h>
17#include <drm/drm_atomic.h> 17#include <drm/drm_atomic.h>
18#include <drm/drm_atomic_uapi.h>
18#include <drm/drm_crtc.h> 19#include <drm/drm_crtc.h>
19#include <drm/drm_crtc_helper.h> 20#include <drm/drm_crtc_helper.h>
20#include <drm/drm_flip_work.h> 21#include <drm/drm_flip_work.h>
@@ -45,14 +46,26 @@
45#include "rockchip_drm_vop.h" 46#include "rockchip_drm_vop.h"
46#include "rockchip_rgb.h" 47#include "rockchip_rgb.h"
47 48
48#define VOP_WIN_SET(x, win, name, v) \ 49#define VOP_WIN_SET(vop, win, name, v) \
49 vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name) 50 vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
50#define VOP_SCL_SET(x, win, name, v) \ 51#define VOP_SCL_SET(vop, win, name, v) \
51 vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name) 52 vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
52#define VOP_SCL_SET_EXT(x, win, name, v) \ 53#define VOP_SCL_SET_EXT(vop, win, name, v) \
53 vop_reg_set(vop, &win->phy->scl->ext->name, \ 54 vop_reg_set(vop, &win->phy->scl->ext->name, \
54 win->base, ~0, v, #name) 55 win->base, ~0, v, #name)
55 56
57#define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
58 do { \
59 if (win_yuv2yuv && win_yuv2yuv->name.mask) \
60 vop_reg_set(vop, &win_yuv2yuv->name, 0, ~0, v, #name); \
61 } while (0)
62
63#define VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop, win_yuv2yuv, name, v) \
64 do { \
65 if (win_yuv2yuv && win_yuv2yuv->phy->name.mask) \
66 vop_reg_set(vop, &win_yuv2yuv->phy->name, win_yuv2yuv->base, ~0, v, #name); \
67 } while (0)
68
56#define VOP_INTR_SET_MASK(vop, name, mask, v) \ 69#define VOP_INTR_SET_MASK(vop, name, mask, v) \
57 vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name) 70 vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
58 71
@@ -73,8 +86,11 @@
73#define VOP_INTR_GET_TYPE(vop, name, type) \ 86#define VOP_INTR_GET_TYPE(vop, name, type) \
74 vop_get_intr_type(vop, &vop->data->intr->name, type) 87 vop_get_intr_type(vop, &vop->data->intr->name, type)
75 88
76#define VOP_WIN_GET(x, win, name) \ 89#define VOP_WIN_GET(vop, win, name) \
77 vop_read_reg(x, win->offset, win->phy->name) 90 vop_read_reg(vop, win->offset, win->phy->name)
91
92#define VOP_WIN_HAS_REG(win, name) \
93 (!!(win->phy->name.mask))
78 94
79#define VOP_WIN_GET_YRGBADDR(vop, win) \ 95#define VOP_WIN_GET_YRGBADDR(vop, win) \
80 vop_readl(vop, win->base + win->phy->yrgb_mst.offset) 96 vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
@@ -85,6 +101,18 @@
85#define to_vop(x) container_of(x, struct vop, crtc) 101#define to_vop(x) container_of(x, struct vop, crtc)
86#define to_vop_win(x) container_of(x, struct vop_win, base) 102#define to_vop_win(x) container_of(x, struct vop_win, base)
87 103
104/*
105 * The coefficients of the following matrix are all fixed points.
106 * The format is S2.10 for the 3x3 part of the matrix, and S9.12 for the offsets.
107 * They are all represented in two's complement.
108 */
109static const uint32_t bt601_yuv2rgb[] = {
110 0x4A8, 0x0, 0x662,
111 0x4A8, 0x1E6F, 0x1CBF,
112 0x4A8, 0x812, 0x0,
113 0x321168, 0x0877CF, 0x2EB127
114};
115
88enum vop_pending { 116enum vop_pending {
89 VOP_PENDING_FB_UNREF, 117 VOP_PENDING_FB_UNREF,
90}; 118};
@@ -92,6 +120,7 @@ enum vop_pending {
92struct vop_win { 120struct vop_win {
93 struct drm_plane base; 121 struct drm_plane base;
94 const struct vop_win_data *data; 122 const struct vop_win_data *data;
123 const struct vop_win_yuv2yuv_data *yuv2yuv_data;
95 struct vop *vop; 124 struct vop *vop;
96}; 125};
97 126
@@ -686,6 +715,11 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
686 return -EINVAL; 715 return -EINVAL;
687 } 716 }
688 717
718 if (fb->format->is_yuv && state->rotation & DRM_MODE_REFLECT_Y) {
719 DRM_ERROR("Invalid Source: Yuv format does not support this rotation\n");
720 return -EINVAL;
721 }
722
689 return 0; 723 return 0;
690} 724}
691 725
@@ -713,6 +747,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
713 struct drm_crtc *crtc = state->crtc; 747 struct drm_crtc *crtc = state->crtc;
714 struct vop_win *vop_win = to_vop_win(plane); 748 struct vop_win *vop_win = to_vop_win(plane);
715 const struct vop_win_data *win = vop_win->data; 749 const struct vop_win_data *win = vop_win->data;
750 const struct vop_win_yuv2yuv_data *win_yuv2yuv = vop_win->yuv2yuv_data;
716 struct vop *vop = to_vop(state->crtc); 751 struct vop *vop = to_vop(state->crtc);
717 struct drm_framebuffer *fb = state->fb; 752 struct drm_framebuffer *fb = state->fb;
718 unsigned int actual_w, actual_h; 753 unsigned int actual_w, actual_h;
@@ -728,6 +763,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
728 bool rb_swap; 763 bool rb_swap;
729 int win_index = VOP_WIN_TO_INDEX(vop_win); 764 int win_index = VOP_WIN_TO_INDEX(vop_win);
730 int format; 765 int format;
766 int is_yuv = fb->format->is_yuv;
767 int i;
731 768
732 /* 769 /*
733 * can't update plane when vop is disabled. 770 * can't update plane when vop is disabled.
@@ -761,6 +798,13 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
761 offset += (src->y1 >> 16) * fb->pitches[0]; 798 offset += (src->y1 >> 16) * fb->pitches[0];
762 dma_addr = rk_obj->dma_addr + offset + fb->offsets[0]; 799 dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
763 800
801 /*
802 * For y-mirroring we need to move address
803 * to the beginning of the last line.
804 */
805 if (state->rotation & DRM_MODE_REFLECT_Y)
806 dma_addr += (actual_h - 1) * fb->pitches[0];
807
764 format = vop_convert_format(fb->format->format); 808 format = vop_convert_format(fb->format->format);
765 809
766 spin_lock(&vop->reg_lock); 810 spin_lock(&vop->reg_lock);
@@ -768,7 +812,13 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
768 VOP_WIN_SET(vop, win, format, format); 812 VOP_WIN_SET(vop, win, format, format);
769 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4)); 813 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
770 VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); 814 VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
771 if (fb->format->is_yuv) { 815 VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
816 VOP_WIN_SET(vop, win, y_mir_en,
817 (state->rotation & DRM_MODE_REFLECT_Y) ? 1 : 0);
818 VOP_WIN_SET(vop, win, x_mir_en,
819 (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
820
821 if (is_yuv) {
772 int hsub = drm_format_horz_chroma_subsampling(fb->format->format); 822 int hsub = drm_format_horz_chroma_subsampling(fb->format->format);
773 int vsub = drm_format_vert_chroma_subsampling(fb->format->format); 823 int vsub = drm_format_vert_chroma_subsampling(fb->format->format);
774 int bpp = fb->format->cpp[1]; 824 int bpp = fb->format->cpp[1];
@@ -782,6 +832,13 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
782 dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; 832 dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
783 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4)); 833 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
784 VOP_WIN_SET(vop, win, uv_mst, dma_addr); 834 VOP_WIN_SET(vop, win, uv_mst, dma_addr);
835
836 for (i = 0; i < NUM_YUV2YUV_COEFFICIENTS; i++) {
837 VOP_WIN_YUV2YUV_COEFFICIENT_SET(vop,
838 win_yuv2yuv,
839 y2r_coefficients[i],
840 bt601_yuv2rgb[i]);
841 }
785 } 842 }
786 843
787 if (win->phy->scl) 844 if (win->phy->scl)
@@ -820,10 +877,83 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
820 spin_unlock(&vop->reg_lock); 877 spin_unlock(&vop->reg_lock);
821} 878}
822 879
880static int vop_plane_atomic_async_check(struct drm_plane *plane,
881 struct drm_plane_state *state)
882{
883 struct vop_win *vop_win = to_vop_win(plane);
884 const struct vop_win_data *win = vop_win->data;
885 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
886 DRM_PLANE_HELPER_NO_SCALING;
887 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
888 DRM_PLANE_HELPER_NO_SCALING;
889 struct drm_crtc_state *crtc_state;
890
891 if (plane != state->crtc->cursor)
892 return -EINVAL;
893
894 if (!plane->state)
895 return -EINVAL;
896
897 if (!plane->state->fb)
898 return -EINVAL;
899
900 if (state->state)
901 crtc_state = drm_atomic_get_existing_crtc_state(state->state,
902 state->crtc);
903 else /* Special case for asynchronous cursor updates. */
904 crtc_state = plane->crtc->state;
905
906 return drm_atomic_helper_check_plane_state(plane->state, crtc_state,
907 min_scale, max_scale,
908 true, true);
909}
910
911static void vop_plane_atomic_async_update(struct drm_plane *plane,
912 struct drm_plane_state *new_state)
913{
914 struct vop *vop = to_vop(plane->state->crtc);
915 struct drm_plane_state *plane_state;
916
917 plane_state = plane->funcs->atomic_duplicate_state(plane);
918 plane_state->crtc_x = new_state->crtc_x;
919 plane_state->crtc_y = new_state->crtc_y;
920 plane_state->crtc_h = new_state->crtc_h;
921 plane_state->crtc_w = new_state->crtc_w;
922 plane_state->src_x = new_state->src_x;
923 plane_state->src_y = new_state->src_y;
924 plane_state->src_h = new_state->src_h;
925 plane_state->src_w = new_state->src_w;
926
927 if (plane_state->fb != new_state->fb)
928 drm_atomic_set_fb_for_plane(plane_state, new_state->fb);
929
930 swap(plane_state, plane->state);
931
932 if (plane->state->fb && plane->state->fb != new_state->fb) {
933 drm_framebuffer_get(plane->state->fb);
934 WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0);
935 drm_flip_work_queue(&vop->fb_unref_work, plane->state->fb);
936 set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
937 }
938
939 if (vop->is_enabled) {
940 rockchip_drm_psr_inhibit_get_state(new_state->state);
941 vop_plane_atomic_update(plane, plane->state);
942 spin_lock(&vop->reg_lock);
943 vop_cfg_done(vop);
944 spin_unlock(&vop->reg_lock);
945 rockchip_drm_psr_inhibit_put_state(new_state->state);
946 }
947
948 plane->funcs->atomic_destroy_state(plane, plane_state);
949}
950
823static const struct drm_plane_helper_funcs plane_helper_funcs = { 951static const struct drm_plane_helper_funcs plane_helper_funcs = {
824 .atomic_check = vop_plane_atomic_check, 952 .atomic_check = vop_plane_atomic_check,
825 .atomic_update = vop_plane_atomic_update, 953 .atomic_update = vop_plane_atomic_update,
826 .atomic_disable = vop_plane_atomic_disable, 954 .atomic_disable = vop_plane_atomic_disable,
955 .atomic_async_check = vop_plane_atomic_async_check,
956 .atomic_async_update = vop_plane_atomic_async_update,
827 .prepare_fb = drm_gem_fb_prepare_fb, 957 .prepare_fb = drm_gem_fb_prepare_fb,
828}; 958};
829 959
@@ -1274,6 +1404,18 @@ out:
1274 return ret; 1404 return ret;
1275} 1405}
1276 1406
1407static void vop_plane_add_properties(struct drm_plane *plane,
1408 const struct vop_win_data *win_data)
1409{
1410 unsigned int flags = 0;
1411
1412 flags |= VOP_WIN_HAS_REG(win_data, x_mir_en) ? DRM_MODE_REFLECT_X : 0;
1413 flags |= VOP_WIN_HAS_REG(win_data, y_mir_en) ? DRM_MODE_REFLECT_Y : 0;
1414 if (flags)
1415 drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
1416 DRM_MODE_ROTATE_0 | flags);
1417}
1418
1277static int vop_create_crtc(struct vop *vop) 1419static int vop_create_crtc(struct vop *vop)
1278{ 1420{
1279 const struct vop_data *vop_data = vop->data; 1421 const struct vop_data *vop_data = vop->data;
@@ -1311,6 +1453,7 @@ static int vop_create_crtc(struct vop *vop)
1311 1453
1312 plane = &vop_win->base; 1454 plane = &vop_win->base;
1313 drm_plane_helper_add(plane, &plane_helper_funcs); 1455 drm_plane_helper_add(plane, &plane_helper_funcs);
1456 vop_plane_add_properties(plane, win_data);
1314 if (plane->type == DRM_PLANE_TYPE_PRIMARY) 1457 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
1315 primary = plane; 1458 primary = plane;
1316 else if (plane->type == DRM_PLANE_TYPE_CURSOR) 1459 else if (plane->type == DRM_PLANE_TYPE_CURSOR)
@@ -1348,6 +1491,7 @@ static int vop_create_crtc(struct vop *vop)
1348 goto err_cleanup_crtc; 1491 goto err_cleanup_crtc;
1349 } 1492 }
1350 drm_plane_helper_add(&vop_win->base, &plane_helper_funcs); 1493 drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
1494 vop_plane_add_properties(&vop_win->base, win_data);
1351 } 1495 }
1352 1496
1353 port = of_get_child_by_name(dev->of_node, "port"); 1497 port = of_get_child_by_name(dev->of_node, "port");
@@ -1531,6 +1675,7 @@ static void vop_win_init(struct vop *vop)
1531 1675
1532 vop_win->data = win_data; 1676 vop_win->data = win_data;
1533 vop_win->vop = vop; 1677 vop_win->vop = vop;
1678 vop_win->yuv2yuv_data = &vop_data->win_yuv2yuv[i];
1534 } 1679 }
1535} 1680}
1536 1681
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 0fe40e1983d9..04ed401d2325 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -23,6 +23,8 @@
23#define VOP_MAJOR(version) ((version) >> 8) 23#define VOP_MAJOR(version) ((version) >> 8)
24#define VOP_MINOR(version) ((version) & 0xff) 24#define VOP_MINOR(version) ((version) & 0xff)
25 25
26#define NUM_YUV2YUV_COEFFICIENTS 12
27
26enum vop_data_format { 28enum vop_data_format {
27 VOP_FMT_ARGB8888 = 0, 29 VOP_FMT_ARGB8888 = 0,
28 VOP_FMT_RGB888, 30 VOP_FMT_RGB888,
@@ -124,6 +126,10 @@ struct vop_scl_regs {
124 struct vop_reg scale_cbcr_y; 126 struct vop_reg scale_cbcr_y;
125}; 127};
126 128
129struct vop_yuv2yuv_phy {
130 struct vop_reg y2r_coefficients[NUM_YUV2YUV_COEFFICIENTS];
131};
132
127struct vop_win_phy { 133struct vop_win_phy {
128 const struct vop_scl_regs *scl; 134 const struct vop_scl_regs *scl;
129 const uint32_t *data_formats; 135 const uint32_t *data_formats;
@@ -140,12 +146,20 @@ struct vop_win_phy {
140 struct vop_reg uv_mst; 146 struct vop_reg uv_mst;
141 struct vop_reg yrgb_vir; 147 struct vop_reg yrgb_vir;
142 struct vop_reg uv_vir; 148 struct vop_reg uv_vir;
149 struct vop_reg y_mir_en;
150 struct vop_reg x_mir_en;
143 151
144 struct vop_reg dst_alpha_ctl; 152 struct vop_reg dst_alpha_ctl;
145 struct vop_reg src_alpha_ctl; 153 struct vop_reg src_alpha_ctl;
146 struct vop_reg channel; 154 struct vop_reg channel;
147}; 155};
148 156
157struct vop_win_yuv2yuv_data {
158 uint32_t base;
159 const struct vop_yuv2yuv_phy *phy;
160 struct vop_reg y2r_en;
161};
162
149struct vop_win_data { 163struct vop_win_data {
150 uint32_t base; 164 uint32_t base;
151 const struct vop_win_phy *phy; 165 const struct vop_win_phy *phy;
@@ -159,6 +173,7 @@ struct vop_data {
159 const struct vop_misc *misc; 173 const struct vop_misc *misc;
160 const struct vop_modeset *modeset; 174 const struct vop_modeset *modeset;
161 const struct vop_output *output; 175 const struct vop_output *output;
176 const struct vop_win_yuv2yuv_data *win_yuv2yuv;
162 const struct vop_win_data *win; 177 const struct vop_win_data *win;
163 unsigned int win_size; 178 unsigned int win_size;
164 179
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 08fc40af52c8..bd76328c0fdb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -299,6 +299,114 @@ static const struct vop_data px30_vop_lit = {
299 .win_size = ARRAY_SIZE(px30_vop_lit_win_data), 299 .win_size = ARRAY_SIZE(px30_vop_lit_win_data),
300}; 300};
301 301
302static const struct vop_scl_regs rk3066_win_scl = {
303 .scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
304 .scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
305 .scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
306 .scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
307};
308
309static const struct vop_win_phy rk3066_win0_data = {
310 .scl = &rk3066_win_scl,
311 .data_formats = formats_win_full,
312 .nformats = ARRAY_SIZE(formats_win_full),
313 .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
314 .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4),
315 .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19),
316 .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
317 .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
318 .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
319 .yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
320 .uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
321 .yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
322 .uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
323};
324
325static const struct vop_win_phy rk3066_win1_data = {
326 .scl = &rk3066_win_scl,
327 .data_formats = formats_win_full,
328 .nformats = ARRAY_SIZE(formats_win_full),
329 .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
330 .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7),
331 .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23),
332 .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
333 .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
334 .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
335 .yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
336 .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
337 .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
338 .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
339};
340
341static const struct vop_win_phy rk3066_win2_data = {
342 .data_formats = formats_win_lite,
343 .nformats = ARRAY_SIZE(formats_win_lite),
344 .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
345 .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10),
346 .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27),
347 .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
348 .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
349 .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
350 .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
351};
352
353static const struct vop_modeset rk3066_modeset = {
354 .htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
355 .hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
356 .vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
357 .vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
358};
359
360static const struct vop_output rk3066_output = {
361 .pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
362};
363
364static const struct vop_common rk3066_common = {
365 .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
366 .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
367 .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
368 .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
369};
370
371static const struct vop_win_data rk3066_vop_win_data[] = {
372 { .base = 0x00, .phy = &rk3066_win0_data,
373 .type = DRM_PLANE_TYPE_PRIMARY },
374 { .base = 0x00, .phy = &rk3066_win1_data,
375 .type = DRM_PLANE_TYPE_OVERLAY },
376 { .base = 0x00, .phy = &rk3066_win2_data,
377 .type = DRM_PLANE_TYPE_CURSOR },
378};
379
380static const int rk3066_vop_intrs[] = {
381 /*
382 * hs_start interrupt fires at frame-start, so serves
383 * the same purpose as dsp_hold in the driver.
384 */
385 DSP_HOLD_VALID_INTR,
386 FS_INTR,
387 LINE_FLAG_INTR,
388 BUS_ERROR_INTR,
389};
390
391static const struct vop_intr rk3066_intr = {
392 .intrs = rk3066_vop_intrs,
393 .nintrs = ARRAY_SIZE(rk3066_vop_intrs),
394 .line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
395 .status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
396 .enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
397 .clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
398};
399
400static const struct vop_data rk3066_vop = {
401 .version = VOP_VERSION(2, 1),
402 .intr = &rk3066_intr,
403 .common = &rk3066_common,
404 .modeset = &rk3066_modeset,
405 .output = &rk3066_output,
406 .win = rk3066_vop_win_data,
407 .win_size = ARRAY_SIZE(rk3066_vop_win_data),
408};
409
302static const struct vop_scl_regs rk3188_win_scl = { 410static const struct vop_scl_regs rk3188_win_scl = {
303 .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0), 411 .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
304 .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16), 412 .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
@@ -550,6 +658,27 @@ static const struct vop_intr rk3368_vop_intr = {
550 .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0), 658 .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
551}; 659};
552 660
661static const struct vop_win_phy rk3368_win01_data = {
662 .scl = &rk3288_win_full_scl,
663 .data_formats = formats_win_full,
664 .nformats = ARRAY_SIZE(formats_win_full),
665 .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
666 .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
667 .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
668 .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
669 .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
670 .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
671 .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
672 .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
673 .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
674 .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
675 .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
676 .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
677 .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
678 .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
679 .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
680};
681
553static const struct vop_win_phy rk3368_win23_data = { 682static const struct vop_win_phy rk3368_win23_data = {
554 .data_formats = formats_win_lite, 683 .data_formats = formats_win_lite,
555 .nformats = ARRAY_SIZE(formats_win_lite), 684 .nformats = ARRAY_SIZE(formats_win_lite),
@@ -557,6 +686,7 @@ static const struct vop_win_phy rk3368_win23_data = {
557 .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4), 686 .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
558 .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5), 687 .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
559 .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20), 688 .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
689 .y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
560 .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0), 690 .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
561 .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0), 691 .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
562 .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0), 692 .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
@@ -566,9 +696,9 @@ static const struct vop_win_phy rk3368_win23_data = {
566}; 696};
567 697
568static const struct vop_win_data rk3368_vop_win_data[] = { 698static const struct vop_win_data rk3368_vop_win_data[] = {
569 { .base = 0x00, .phy = &rk3288_win01_data, 699 { .base = 0x00, .phy = &rk3368_win01_data,
570 .type = DRM_PLANE_TYPE_PRIMARY }, 700 .type = DRM_PLANE_TYPE_PRIMARY },
571 { .base = 0x40, .phy = &rk3288_win01_data, 701 { .base = 0x40, .phy = &rk3368_win01_data,
572 .type = DRM_PLANE_TYPE_OVERLAY }, 702 .type = DRM_PLANE_TYPE_OVERLAY },
573 { .base = 0x00, .phy = &rk3368_win23_data, 703 { .base = 0x00, .phy = &rk3368_win23_data,
574 .type = DRM_PLANE_TYPE_OVERLAY }, 704 .type = DRM_PLANE_TYPE_OVERLAY },
@@ -637,6 +767,34 @@ static const struct vop_output rk3399_output = {
637 .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3), 767 .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
638}; 768};
639 769
770static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
771 .y2r_coefficients = {
772 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
773 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
774 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
775 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
776 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
777 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
778 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
779 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
780 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
781 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
782 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
783 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
784 },
785};
786
787static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
788
789static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
790 { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
791 .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
792 { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
793 .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
794 { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
795 { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
796};
797
640static const struct vop_data rk3399_vop_big = { 798static const struct vop_data rk3399_vop_big = {
641 .version = VOP_VERSION(3, 5), 799 .version = VOP_VERSION(3, 5),
642 .feature = VOP_FEATURE_OUTPUT_RGB10, 800 .feature = VOP_FEATURE_OUTPUT_RGB10,
@@ -647,15 +805,22 @@ static const struct vop_data rk3399_vop_big = {
647 .misc = &rk3368_misc, 805 .misc = &rk3368_misc,
648 .win = rk3368_vop_win_data, 806 .win = rk3368_vop_win_data,
649 .win_size = ARRAY_SIZE(rk3368_vop_win_data), 807 .win_size = ARRAY_SIZE(rk3368_vop_win_data),
808 .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
650}; 809};
651 810
652static const struct vop_win_data rk3399_vop_lit_win_data[] = { 811static const struct vop_win_data rk3399_vop_lit_win_data[] = {
653 { .base = 0x00, .phy = &rk3288_win01_data, 812 { .base = 0x00, .phy = &rk3368_win01_data,
654 .type = DRM_PLANE_TYPE_PRIMARY }, 813 .type = DRM_PLANE_TYPE_PRIMARY },
655 { .base = 0x00, .phy = &rk3368_win23_data, 814 { .base = 0x00, .phy = &rk3368_win23_data,
656 .type = DRM_PLANE_TYPE_CURSOR}, 815 .type = DRM_PLANE_TYPE_CURSOR},
657}; 816};
658 817
818static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
819 { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
820 .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
821 { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
822};
823
659static const struct vop_data rk3399_vop_lit = { 824static const struct vop_data rk3399_vop_lit = {
660 .version = VOP_VERSION(3, 6), 825 .version = VOP_VERSION(3, 6),
661 .intr = &rk3366_vop_intr, 826 .intr = &rk3366_vop_intr,
@@ -665,6 +830,7 @@ static const struct vop_data rk3399_vop_lit = {
665 .misc = &rk3368_misc, 830 .misc = &rk3368_misc,
666 .win = rk3399_vop_lit_win_data, 831 .win = rk3399_vop_lit_win_data,
667 .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data), 832 .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
833 .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
668}; 834};
669 835
670static const struct vop_win_data rk3228_vop_win_data[] = { 836static const struct vop_win_data rk3228_vop_win_data[] = {
@@ -730,11 +896,11 @@ static const struct vop_intr rk3328_vop_intr = {
730}; 896};
731 897
732static const struct vop_win_data rk3328_vop_win_data[] = { 898static const struct vop_win_data rk3328_vop_win_data[] = {
733 { .base = 0xd0, .phy = &rk3288_win01_data, 899 { .base = 0xd0, .phy = &rk3368_win01_data,
734 .type = DRM_PLANE_TYPE_PRIMARY }, 900 .type = DRM_PLANE_TYPE_PRIMARY },
735 { .base = 0x1d0, .phy = &rk3288_win01_data, 901 { .base = 0x1d0, .phy = &rk3368_win01_data,
736 .type = DRM_PLANE_TYPE_OVERLAY }, 902 .type = DRM_PLANE_TYPE_OVERLAY },
737 { .base = 0x2d0, .phy = &rk3288_win01_data, 903 { .base = 0x2d0, .phy = &rk3368_win01_data,
738 .type = DRM_PLANE_TYPE_CURSOR }, 904 .type = DRM_PLANE_TYPE_CURSOR },
739}; 905};
740 906
@@ -759,6 +925,8 @@ static const struct of_device_id vop_driver_dt_match[] = {
759 .data = &px30_vop_big }, 925 .data = &px30_vop_big },
760 { .compatible = "rockchip,px30-vop-lit", 926 { .compatible = "rockchip,px30-vop-lit",
761 .data = &px30_vop_lit }, 927 .data = &px30_vop_lit },
928 { .compatible = "rockchip,rk3066-vop",
929 .data = &rk3066_vop },
762 { .compatible = "rockchip,rk3188-vop", 930 { .compatible = "rockchip,rk3188-vop",
763 .data = &rk3188_vop }, 931 .data = &rk3188_vop },
764 { .compatible = "rockchip,rk3288-vop", 932 { .compatible = "rockchip,rk3288-vop",
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
index 7348c68352ed..d837d4a7df4a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
@@ -983,4 +983,57 @@
983#define RK3188_REG_CFG_DONE 0x90 983#define RK3188_REG_CFG_DONE 0x90
984/* rk3188 register definition end */ 984/* rk3188 register definition end */
985 985
986/* rk3066 register definition */
987#define RK3066_SYS_CTRL0 0x00
988#define RK3066_SYS_CTRL1 0x04
989#define RK3066_DSP_CTRL0 0x08
990#define RK3066_DSP_CTRL1 0x0c
991#define RK3066_INT_STATUS 0x10
992#define RK3066_MCU_CTRL 0x14
993#define RK3066_BLEND_CTRL 0x18
994#define RK3066_WIN0_COLOR_KEY_CTRL 0x1c
995#define RK3066_WIN1_COLOR_KEY_CTRL 0x20
996#define RK3066_WIN2_COLOR_KEY_CTRL 0x24
997#define RK3066_WIN0_YRGB_MST0 0x28
998#define RK3066_WIN0_CBR_MST0 0x2c
999#define RK3066_WIN0_YRGB_MST1 0x30
1000#define RK3066_WIN0_CBR_MST1 0x34
1001#define RK3066_WIN0_VIR 0x38
1002#define RK3066_WIN0_ACT_INFO 0x3c
1003#define RK3066_WIN0_DSP_INFO 0x40
1004#define RK3066_WIN0_DSP_ST 0x44
1005#define RK3066_WIN0_SCL_FACTOR_YRGB 0x48
1006#define RK3066_WIN0_SCL_FACTOR_CBR 0x4c
1007#define RK3066_WIN0_SCL_OFFSET 0x50
1008#define RK3066_WIN1_YRGB_MST 0x54
1009#define RK3066_WIN1_CBR_MST 0x58
1010#define RK3066_WIN1_VIR 0x5c
1011#define RK3066_WIN1_ACT_INFO 0x60
1012#define RK3066_WIN1_DSP_INFO 0x64
1013#define RK3066_WIN1_DSP_ST 0x68
1014#define RK3066_WIN1_SCL_FACTOR_YRGB 0x6c
1015#define RK3066_WIN1_SCL_FACTOR_CBR 0x70
1016#define RK3066_WIN1_SCL_OFFSET 0x74
1017#define RK3066_WIN2_MST 0x78
1018#define RK3066_WIN2_VIR 0x7c
1019#define RK3066_WIN2_DSP_INFO 0x80
1020#define RK3066_WIN2_DSP_ST 0x84
1021#define RK3066_HWC_MST 0x88
1022#define RK3066_HWC_DSP_ST 0x8c
1023#define RK3066_HWC_COLOR_LUT0 0x90
1024#define RK3066_HWC_COLOR_LUT1 0x94
1025#define RK3066_HWC_COLOR_LUT2 0x98
1026#define RK3066_DSP_HTOTAL_HS_END 0x9c
1027#define RK3066_DSP_HACT_ST_END 0xa0
1028#define RK3066_DSP_VTOTAL_VS_END 0xa4
1029#define RK3066_DSP_VACT_ST_END 0xa8
1030#define RK3066_DSP_VS_ST_END_F1 0xac
1031#define RK3066_DSP_VACT_ST_END_F1 0xb0
1032#define RK3066_REG_CFG_DONE 0xc0
1033#define RK3066_MCU_BYPASS_WPORT 0x100
1034#define RK3066_MCU_BYPASS_RPORT 0x200
1035#define RK3066_WIN2_LUT_ADDR 0x400
1036#define RK3066_DSP_LUT_ADDR 0x800
1037/* rk3066 register definition end */
1038
986#endif /* _ROCKCHIP_VOP_REG_H */ 1039#endif /* _ROCKCHIP_VOP_REG_H */
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c
index ed76e52eb213..ec9f87483e39 100644
--- a/drivers/gpu/drm/sti/sti_crtc.c
+++ b/drivers/gpu/drm/sti/sti_crtc.c
@@ -53,18 +53,10 @@ sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
53 struct clk *compo_clk, *pix_clk; 53 struct clk *compo_clk, *pix_clk;
54 int rate = mode->clock * 1000; 54 int rate = mode->clock * 1000;
55 55
56 DRM_DEBUG_KMS("CRTC:%d (%s) mode:%d (%s)\n", 56 DRM_DEBUG_KMS("CRTC:%d (%s) mode: (%s)\n",
57 crtc->base.id, sti_mixer_to_str(mixer), 57 crtc->base.id, sti_mixer_to_str(mixer), mode->name);
58 mode->base.id, mode->name); 58
59 59 DRM_DEBUG_KMS(DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
60 DRM_DEBUG_KMS("%d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
61 mode->vrefresh, mode->clock,
62 mode->hdisplay,
63 mode->hsync_start, mode->hsync_end,
64 mode->htotal,
65 mode->vdisplay,
66 mode->vsync_start, mode->vsync_end,
67 mode->vtotal, mode->type, mode->flags);
68 60
69 if (mixer->id == STI_MIXER_MAIN) { 61 if (mixer->id == STI_MIXER_MAIN) {
70 compo_clk = compo->clk_compo_main; 62 compo_clk = compo->clk_compo_main;
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index fbef4ad6c8ef..458fcb5a93f2 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -434,7 +434,8 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi)
434 434
435 DRM_DEBUG_DRIVER("\n"); 435 DRM_DEBUG_DRIVER("\n");
436 436
437 ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe, mode, false); 437 ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe,
438 hdmi->drm_connector, mode);
438 if (ret < 0) { 439 if (ret < 0) {
439 DRM_ERROR("failed to setup AVI infoframe: %d\n", ret); 440 DRM_ERROR("failed to setup AVI infoframe: %d\n", ret);
440 return ret; 441 return ret;
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 061d2e0d9011..554a6f4561f3 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -52,7 +52,8 @@ static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
52 u8 buffer[17]; 52 u8 buffer[17];
53 int i, ret; 53 int i, ret;
54 54
55 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 55 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
56 &hdmi->connector, mode);
56 if (ret < 0) { 57 if (ret < 0) {
57 DRM_ERROR("Failed to get infoframes from mode\n"); 58 DRM_ERROR("Failed to get infoframes from mode\n");
58 return ret; 59 return ret;
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 0082468f703c..a7566c67bfb0 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -741,7 +741,8 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
741 u8 buffer[17]; 741 u8 buffer[17];
742 ssize_t err; 742 ssize_t err;
743 743
744 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 744 err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
745 &hdmi->output.connector, mode);
745 if (err < 0) { 746 if (err < 0) {
746 dev_err(hdmi->dev, "failed to setup AVI infoframe: %zd\n", err); 747 dev_err(hdmi->dev, "failed to setup AVI infoframe: %zd\n", err);
747 return; 748 return;
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index ef8692b7075a..44feac2a0359 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -2116,7 +2116,8 @@ tegra_sor_hdmi_setup_avi_infoframe(struct tegra_sor *sor,
2116 value &= ~INFOFRAME_CTRL_ENABLE; 2116 value &= ~INFOFRAME_CTRL_ENABLE;
2117 tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL); 2117 tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);
2118 2118
2119 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false); 2119 err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
2120 &sor->output.connector, mode);
2120 if (err < 0) { 2121 if (err < 0) {
2121 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err); 2122 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
2122 return err; 2123 return err;
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-core.c b/drivers/gpu/drm/tinydrm/core/tinydrm-core.c
index 01a6f2d42440..aeb93eadb047 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-core.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-core.c
@@ -10,11 +10,14 @@
10#include <drm/drm_atomic.h> 10#include <drm/drm_atomic.h>
11#include <drm/drm_atomic_helper.h> 11#include <drm/drm_atomic_helper.h>
12#include <drm/drm_crtc_helper.h> 12#include <drm/drm_crtc_helper.h>
13#include <drm/drm_drv.h>
13#include <drm/drm_fb_helper.h> 14#include <drm/drm_fb_helper.h>
14#include <drm/drm_gem_framebuffer_helper.h> 15#include <drm/drm_gem_framebuffer_helper.h>
16#include <drm/drm_print.h>
15#include <drm/tinydrm/tinydrm.h> 17#include <drm/tinydrm/tinydrm.h>
16#include <linux/device.h> 18#include <linux/device.h>
17#include <linux/dma-buf.h> 19#include <linux/dma-buf.h>
20#include <linux/module.h>
18 21
19/** 22/**
20 * DOC: overview 23 * DOC: overview
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
index eacfc0ec8ff1..d4576d6e8ce4 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
@@ -9,8 +9,11 @@
9 9
10#include <drm/drm_atomic_helper.h> 10#include <drm/drm_atomic_helper.h>
11#include <drm/drm_crtc_helper.h> 11#include <drm/drm_crtc_helper.h>
12#include <drm/drm_drv.h>
12#include <drm/drm_gem_framebuffer_helper.h> 13#include <drm/drm_gem_framebuffer_helper.h>
13#include <drm/drm_modes.h> 14#include <drm/drm_modes.h>
15#include <drm/drm_print.h>
16#include <drm/drm_vblank.h>
14#include <drm/tinydrm/tinydrm.h> 17#include <drm/tinydrm/tinydrm.h>
15 18
16struct tinydrm_connector { 19struct tinydrm_connector {
diff --git a/drivers/gpu/drm/tinydrm/hx8357d.c b/drivers/gpu/drm/tinydrm/hx8357d.c
index 81a2bbeb25d4..3ae11aa4b73b 100644
--- a/drivers/gpu/drm/tinydrm/hx8357d.c
+++ b/drivers/gpu/drm/tinydrm/hx8357d.c
@@ -16,6 +16,7 @@
16#include <linux/property.h> 16#include <linux/property.h>
17#include <linux/spi/spi.h> 17#include <linux/spi/spi.h>
18 18
19#include <drm/drm_drv.h>
19#include <drm/drm_gem_cma_helper.h> 20#include <drm/drm_gem_cma_helper.h>
20#include <drm/drm_gem_framebuffer_helper.h> 21#include <drm/drm_gem_framebuffer_helper.h>
21#include <drm/drm_modeset_helper.h> 22#include <drm/drm_modeset_helper.h>
diff --git a/drivers/gpu/drm/tinydrm/ili9225.c b/drivers/gpu/drm/tinydrm/ili9225.c
index 78f7c2d1b449..b0ad58b97227 100644
--- a/drivers/gpu/drm/tinydrm/ili9225.c
+++ b/drivers/gpu/drm/tinydrm/ili9225.c
@@ -20,7 +20,9 @@
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21#include <video/mipi_display.h> 21#include <video/mipi_display.h>
22 22
23#include <drm/drm_drv.h>
23#include <drm/drm_fb_cma_helper.h> 24#include <drm/drm_fb_cma_helper.h>
25#include <drm/drm_fourcc.h>
24#include <drm/drm_gem_cma_helper.h> 26#include <drm/drm_gem_cma_helper.h>
25#include <drm/drm_gem_framebuffer_helper.h> 27#include <drm/drm_gem_framebuffer_helper.h>
26#include <drm/tinydrm/mipi-dbi.h> 28#include <drm/tinydrm/mipi-dbi.h>
diff --git a/drivers/gpu/drm/tinydrm/ili9341.c b/drivers/gpu/drm/tinydrm/ili9341.c
index 51395bdc6ca2..bcdf10906ade 100644
--- a/drivers/gpu/drm/tinydrm/ili9341.c
+++ b/drivers/gpu/drm/tinydrm/ili9341.c
@@ -15,6 +15,7 @@
15#include <linux/property.h> 15#include <linux/property.h>
16#include <linux/spi/spi.h> 16#include <linux/spi/spi.h>
17 17
18#include <drm/drm_drv.h>
18#include <drm/drm_gem_cma_helper.h> 19#include <drm/drm_gem_cma_helper.h>
19#include <drm/drm_gem_framebuffer_helper.h> 20#include <drm/drm_gem_framebuffer_helper.h>
20#include <drm/drm_modeset_helper.h> 21#include <drm/drm_modeset_helper.h>
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index 3fa62e77c30b..97805ca37a04 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -17,6 +17,7 @@
17#include <linux/regulator/consumer.h> 17#include <linux/regulator/consumer.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19 19
20#include <drm/drm_drv.h>
20#include <drm/drm_gem_cma_helper.h> 21#include <drm/drm_gem_cma_helper.h>
21#include <drm/drm_gem_framebuffer_helper.h> 22#include <drm/drm_gem_framebuffer_helper.h>
22#include <drm/drm_modeset_helper.h> 23#include <drm/drm_modeset_helper.h>
diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index 3a05e56f9b0d..10294e1283dd 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -10,14 +10,17 @@
10 */ 10 */
11 11
12#include <linux/debugfs.h> 12#include <linux/debugfs.h>
13#include <linux/delay.h>
13#include <linux/dma-buf.h> 14#include <linux/dma-buf.h>
14#include <linux/gpio/consumer.h> 15#include <linux/gpio/consumer.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/regulator/consumer.h> 17#include <linux/regulator/consumer.h>
17#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
18 19
20#include <drm/drm_drv.h>
19#include <drm/drm_fb_cma_helper.h> 21#include <drm/drm_fb_cma_helper.h>
20#include <drm/drm_gem_cma_helper.h> 22#include <drm/drm_gem_cma_helper.h>
23#include <drm/drm_fourcc.h>
21#include <drm/drm_gem_framebuffer_helper.h> 24#include <drm/drm_gem_framebuffer_helper.h>
22#include <drm/tinydrm/mipi-dbi.h> 25#include <drm/tinydrm/mipi-dbi.h>
23#include <drm/tinydrm/tinydrm-helpers.h> 26#include <drm/tinydrm/tinydrm-helpers.h>
diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c
index 54d6fe0f37ce..b2a8f894946a 100644
--- a/drivers/gpu/drm/tinydrm/repaper.c
+++ b/drivers/gpu/drm/tinydrm/repaper.c
@@ -26,6 +26,7 @@
26#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
27#include <linux/thermal.h> 27#include <linux/thermal.h>
28 28
29#include <drm/drm_drv.h>
29#include <drm/drm_fb_cma_helper.h> 30#include <drm/drm_fb_cma_helper.h>
30#include <drm/drm_gem_cma_helper.h> 31#include <drm/drm_gem_cma_helper.h>
31#include <drm/drm_gem_framebuffer_helper.h> 32#include <drm/drm_gem_framebuffer_helper.h>
diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c
index a6a8a1081b73..bf518167760a 100644
--- a/drivers/gpu/drm/tinydrm/st7586.c
+++ b/drivers/gpu/drm/tinydrm/st7586.c
@@ -17,6 +17,7 @@
17#include <linux/spi/spi.h> 17#include <linux/spi/spi.h>
18#include <video/mipi_display.h> 18#include <video/mipi_display.h>
19 19
20#include <drm/drm_drv.h>
20#include <drm/drm_fb_cma_helper.h> 21#include <drm/drm_fb_cma_helper.h>
21#include <drm/drm_gem_cma_helper.h> 22#include <drm/drm_gem_cma_helper.h>
22#include <drm/drm_gem_framebuffer_helper.h> 23#include <drm/drm_gem_framebuffer_helper.h>
diff --git a/drivers/gpu/drm/tinydrm/st7735r.c b/drivers/gpu/drm/tinydrm/st7735r.c
index b39779e0dcd8..9bc93d5a0401 100644
--- a/drivers/gpu/drm/tinydrm/st7735r.c
+++ b/drivers/gpu/drm/tinydrm/st7735r.c
@@ -14,6 +14,7 @@
14#include <linux/spi/spi.h> 14#include <linux/spi/spi.h>
15#include <video/mipi_display.h> 15#include <video/mipi_display.h>
16 16
17#include <drm/drm_drv.h>
17#include <drm/drm_gem_cma_helper.h> 18#include <drm/drm_gem_cma_helper.h>
18#include <drm/drm_gem_framebuffer_helper.h> 19#include <drm/drm_gem_framebuffer_helper.h>
19#include <drm/tinydrm/mipi-dbi.h> 20#include <drm/tinydrm/mipi-dbi.h>
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index c24b078f0593..2c635f001c71 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -9,6 +9,7 @@
9#include <linux/mm_types.h> 9#include <linux/mm_types.h>
10#include <linux/reservation.h> 10#include <linux/reservation.h>
11#include <drm/drmP.h> 11#include <drm/drmP.h>
12#include <drm/drm_util.h>
12#include <drm/drm_encoder.h> 13#include <drm/drm_encoder.h>
13#include <drm/drm_gem_cma_helper.h> 14#include <drm/drm_gem_cma_helper.h>
14#include <drm/drm_atomic.h> 15#include <drm/drm_atomic.h>
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 2f276222e30f..051b61b62541 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -109,7 +109,6 @@ struct vc4_hdmi_encoder {
109 struct vc4_encoder base; 109 struct vc4_encoder base;
110 bool hdmi_monitor; 110 bool hdmi_monitor;
111 bool limited_rgb_range; 111 bool limited_rgb_range;
112 bool rgb_range_selectable;
113}; 112};
114 113
115static inline struct vc4_hdmi_encoder * 114static inline struct vc4_hdmi_encoder *
@@ -280,11 +279,6 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
280 279
281 vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); 280 vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
282 281
283 if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
284 vc4_encoder->rgb_range_selectable =
285 drm_rgb_quant_range_selectable(edid);
286 }
287
288 drm_connector_update_edid_property(connector, edid); 282 drm_connector_update_edid_property(connector, edid);
289 ret = drm_add_edid_modes(connector, edid); 283 ret = drm_add_edid_modes(connector, edid);
290 kfree(edid); 284 kfree(edid);
@@ -424,18 +418,18 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
424 union hdmi_infoframe frame; 418 union hdmi_infoframe frame;
425 int ret; 419 int ret;
426 420
427 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false); 421 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
422 hdmi->connector, mode);
428 if (ret < 0) { 423 if (ret < 0) {
429 DRM_ERROR("couldn't fill AVI infoframe\n"); 424 DRM_ERROR("couldn't fill AVI infoframe\n");
430 return; 425 return;
431 } 426 }
432 427
433 drm_hdmi_avi_infoframe_quant_range(&frame.avi, mode, 428 drm_hdmi_avi_infoframe_quant_range(&frame.avi,
429 hdmi->connector, mode,
434 vc4_encoder->limited_rgb_range ? 430 vc4_encoder->limited_rgb_range ?
435 HDMI_QUANTIZATION_RANGE_LIMITED : 431 HDMI_QUANTIZATION_RANGE_LIMITED :
436 HDMI_QUANTIZATION_RANGE_FULL, 432 HDMI_QUANTIZATION_RANGE_FULL);
437 vc4_encoder->rgb_range_selectable,
438 false);
439 433
440 frame.avi.right_bar = cstate->tv.margins.right; 434 frame.avi.right_bar = cstate->tv.margins.right;
441 frame.avi.left_bar = cstate->tv.margins.left; 435 frame.avi.left_bar = cstate->tv.margins.left;
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 2901ed0c5223..d098337c10e9 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -675,20 +675,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
675 uint32_t param = fourcc_mod_broadcom_param(fb->modifier); 675 uint32_t param = fourcc_mod_broadcom_param(fb->modifier);
676 u32 tile_w, tile, x_off, pix_per_tile; 676 u32 tile_w, tile, x_off, pix_per_tile;
677 677
678 /* Column-based NV12 or RGBA. 678 hvs_format = HVS_PIXEL_FORMAT_H264;
679 */
680 if (fb->format->num_planes > 1) {
681 if (hvs_format != HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE) {
682 DRM_DEBUG_KMS("SAND format only valid for NV12/21");
683 return -EINVAL;
684 }
685 hvs_format = HVS_PIXEL_FORMAT_H264;
686 } else {
687 if (base_format_mod == DRM_FORMAT_MOD_BROADCOM_SAND256) {
688 DRM_DEBUG_KMS("SAND256 format only valid for H.264");
689 return -EINVAL;
690 }
691 }
692 679
693 switch (base_format_mod) { 680 switch (base_format_mod) {
694 case DRM_FORMAT_MOD_BROADCOM_SAND64: 681 case DRM_FORMAT_MOD_BROADCOM_SAND64:
@@ -1151,8 +1138,6 @@ static bool vc4_format_mod_supported(struct drm_plane *plane,
1151 switch (fourcc_mod_broadcom_mod(modifier)) { 1138 switch (fourcc_mod_broadcom_mod(modifier)) {
1152 case DRM_FORMAT_MOD_LINEAR: 1139 case DRM_FORMAT_MOD_LINEAR:
1153 case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: 1140 case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
1154 case DRM_FORMAT_MOD_BROADCOM_SAND64:
1155 case DRM_FORMAT_MOD_BROADCOM_SAND128:
1156 return true; 1141 return true;
1157 default: 1142 default:
1158 return false; 1143 return false;
diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile
index f29deec83d1f..4e90cc8fa651 100644
--- a/drivers/gpu/drm/virtio/Makefile
+++ b/drivers/gpu/drm/virtio/Makefile
@@ -3,7 +3,7 @@
3# Makefile for the drm device driver. This driver provides support for the 3# Makefile for the drm device driver. This driver provides support for the
4# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 4# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
5 5
6virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_drm_bus.o virtgpu_gem.o \ 6virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o \
7 virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ 7 virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \
8 virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \ 8 virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \
9 virtgpu_ioctl.o virtgpu_prime.o 9 virtgpu_ioctl.o virtgpu_prime.o
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index e1c223e18d86..87d7c49cf057 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -243,12 +243,8 @@ static enum drm_connector_status virtio_gpu_conn_detect(
243 243
244static void virtio_gpu_conn_destroy(struct drm_connector *connector) 244static void virtio_gpu_conn_destroy(struct drm_connector *connector)
245{ 245{
246 struct virtio_gpu_output *virtio_gpu_output =
247 drm_connector_to_virtio_gpu_output(connector);
248
249 drm_connector_unregister(connector); 246 drm_connector_unregister(connector);
250 drm_connector_cleanup(connector); 247 drm_connector_cleanup(connector);
251 kfree(virtio_gpu_output);
252} 248}
253 249
254static const struct drm_connector_funcs virtio_gpu_connector_funcs = { 250static const struct drm_connector_funcs virtio_gpu_connector_funcs = {
@@ -362,7 +358,7 @@ static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = {
362 .atomic_commit = drm_atomic_helper_commit, 358 .atomic_commit = drm_atomic_helper_commit,
363}; 359};
364 360
365int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) 361void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
366{ 362{
367 int i; 363 int i;
368 364
@@ -381,7 +377,6 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
381 vgdev_output_init(vgdev, i); 377 vgdev_output_init(vgdev, i);
382 378
383 drm_mode_config_reset(vgdev->ddev); 379 drm_mode_config_reset(vgdev->ddev);
384 return 0;
385} 380}
386 381
387void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) 382void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
deleted file mode 100644
index 0887e0b64b9c..000000000000
--- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
+++ /dev/null
@@ -1,103 +0,0 @@
1/*
2 * Copyright (C) 2015 Red Hat, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include <linux/pci.h>
27#include <drm/drm_fb_helper.h>
28
29#include "virtgpu_drv.h"
30
31int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev)
32{
33 struct drm_device *dev;
34 int ret;
35
36 dev = drm_dev_alloc(driver, &vdev->dev);
37 if (IS_ERR(dev))
38 return PTR_ERR(dev);
39 vdev->priv = dev;
40
41 if (strcmp(vdev->dev.parent->bus->name, "pci") == 0) {
42 struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
43 const char *pname = dev_name(&pdev->dev);
44 bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
45 char unique[20];
46
47 DRM_INFO("pci: %s detected at %s\n",
48 vga ? "virtio-vga" : "virtio-gpu-pci",
49 pname);
50 dev->pdev = pdev;
51 if (vga)
52 drm_fb_helper_remove_conflicting_pci_framebuffers(pdev,
53 0,
54 "virtiodrmfb");
55
56 /*
57 * Normally the drm_dev_set_unique() call is done by core DRM.
58 * The following comment covers, why virtio cannot rely on it.
59 *
60 * Unlike the other virtual GPU drivers, virtio abstracts the
61 * underlying bus type by using struct virtio_device.
62 *
63 * Hence the dev_is_pci() check, used in core DRM, will fail
64 * and the unique returned will be the virtio_device "virtio0",
65 * while a "pci:..." one is required.
66 *
67 * A few other ideas were considered:
68 * - Extend the dev_is_pci() check [in drm_set_busid] to
69 * consider virtio.
70 * Seems like a bigger hack than what we have already.
71 *
72 * - Point drm_device::dev to the parent of the virtio_device
73 * Semantic changes:
74 * * Using the wrong device for i2c, framebuffer_alloc and
75 * prime import.
76 * Visual changes:
77 * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer,
78 * will print the wrong information.
79 *
80 * We could address the latter issues, by introducing
81 * drm_device::bus_dev, ... which would be used solely for this.
82 *
83 * So for the moment keep things as-is, with a bulky comment
84 * for the next person who feels like removing this
85 * drm_dev_set_unique() quirk.
86 */
87 snprintf(unique, sizeof(unique), "pci:%s", pname);
88 ret = drm_dev_set_unique(dev, unique);
89 if (ret)
90 goto err_free;
91
92 }
93
94 ret = drm_dev_register(dev, 0);
95 if (ret)
96 goto err_free;
97
98 return 0;
99
100err_free:
101 drm_dev_put(dev);
102 return ret;
103}
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 7df50920c1e0..af92964b6889 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -40,8 +40,60 @@ static int virtio_gpu_modeset = -1;
40MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); 40MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
41module_param_named(modeset, virtio_gpu_modeset, int, 0400); 41module_param_named(modeset, virtio_gpu_modeset, int, 0400);
42 42
43static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vdev)
44{
45 struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
46 const char *pname = dev_name(&pdev->dev);
47 bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
48 char unique[20];
49
50 DRM_INFO("pci: %s detected at %s\n",
51 vga ? "virtio-vga" : "virtio-gpu-pci",
52 pname);
53 dev->pdev = pdev;
54 if (vga)
55 drm_fb_helper_remove_conflicting_pci_framebuffers(pdev,
56 0,
57 "virtiodrmfb");
58
59 /*
60 * Normally the drm_dev_set_unique() call is done by core DRM.
61 * The following comment covers, why virtio cannot rely on it.
62 *
63 * Unlike the other virtual GPU drivers, virtio abstracts the
64 * underlying bus type by using struct virtio_device.
65 *
66 * Hence the dev_is_pci() check, used in core DRM, will fail
67 * and the unique returned will be the virtio_device "virtio0",
68 * while a "pci:..." one is required.
69 *
70 * A few other ideas were considered:
71 * - Extend the dev_is_pci() check [in drm_set_busid] to
72 * consider virtio.
73 * Seems like a bigger hack than what we have already.
74 *
75 * - Point drm_device::dev to the parent of the virtio_device
76 * Semantic changes:
77 * * Using the wrong device for i2c, framebuffer_alloc and
78 * prime import.
79 * Visual changes:
80 * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer,
81 * will print the wrong information.
82 *
83 * We could address the latter issues, by introducing
84 * drm_device::bus_dev, ... which would be used solely for this.
85 *
86 * So for the moment keep things as-is, with a bulky comment
87 * for the next person who feels like removing this
88 * drm_dev_set_unique() quirk.
89 */
90 snprintf(unique, sizeof(unique), "pci:%s", pname);
91 return drm_dev_set_unique(dev, unique);
92}
93
43static int virtio_gpu_probe(struct virtio_device *vdev) 94static int virtio_gpu_probe(struct virtio_device *vdev)
44{ 95{
96 struct drm_device *dev;
45 int ret; 97 int ret;
46 98
47 if (vgacon_text_force() && virtio_gpu_modeset == -1) 99 if (vgacon_text_force() && virtio_gpu_modeset == -1)
@@ -50,18 +102,39 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
50 if (virtio_gpu_modeset == 0) 102 if (virtio_gpu_modeset == 0)
51 return -EINVAL; 103 return -EINVAL;
52 104
53 ret = drm_virtio_init(&driver, vdev); 105 dev = drm_dev_alloc(&driver, &vdev->dev);
106 if (IS_ERR(dev))
107 return PTR_ERR(dev);
108 vdev->priv = dev;
109
110 if (!strcmp(vdev->dev.parent->bus->name, "pci")) {
111 ret = virtio_gpu_pci_quirk(dev, vdev);
112 if (ret)
113 goto err_free;
114 }
115
116 ret = virtio_gpu_init(dev);
54 if (ret) 117 if (ret)
55 return ret; 118 goto err_free;
119
120 ret = drm_dev_register(dev, 0);
121 if (ret)
122 goto err_free;
56 123
57 drm_fbdev_generic_setup(vdev->priv, 32); 124 drm_fbdev_generic_setup(vdev->priv, 32);
58 return 0; 125 return 0;
126
127err_free:
128 drm_dev_put(dev);
129 return ret;
59} 130}
60 131
61static void virtio_gpu_remove(struct virtio_device *vdev) 132static void virtio_gpu_remove(struct virtio_device *vdev)
62{ 133{
63 struct drm_device *dev = vdev->priv; 134 struct drm_device *dev = vdev->priv;
64 135
136 drm_dev_unregister(dev);
137 virtio_gpu_deinit(dev);
65 drm_put_dev(dev); 138 drm_put_dev(dev);
66} 139}
67 140
@@ -123,8 +196,6 @@ static const struct file_operations virtio_gpu_driver_fops = {
123 196
124static struct drm_driver driver = { 197static struct drm_driver driver = {
125 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, 198 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC,
126 .load = virtio_gpu_driver_load,
127 .unload = virtio_gpu_driver_unload,
128 .open = virtio_gpu_driver_open, 199 .open = virtio_gpu_driver_open,
129 .postclose = virtio_gpu_driver_postclose, 200 .postclose = virtio_gpu_driver_postclose,
130 201
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 63704915f8ce..cf896d879382 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -50,9 +50,6 @@
50#define DRIVER_MINOR 1 50#define DRIVER_MINOR 1
51#define DRIVER_PATCHLEVEL 0 51#define DRIVER_PATCHLEVEL 0
52 52
53/* virtgpu_drm_bus.c */
54int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev);
55
56struct virtio_gpu_object { 53struct virtio_gpu_object {
57 struct drm_gem_object gem_base; 54 struct drm_gem_object gem_base;
58 uint32_t hw_res_handle; 55 uint32_t hw_res_handle;
@@ -209,8 +206,8 @@ struct virtio_gpu_fpriv {
209extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; 206extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
210 207
211/* virtio_kms.c */ 208/* virtio_kms.c */
212int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags); 209int virtio_gpu_init(struct drm_device *dev);
213void virtio_gpu_driver_unload(struct drm_device *dev); 210void virtio_gpu_deinit(struct drm_device *dev);
214int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); 211int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file);
215void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); 212void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file);
216 213
@@ -320,7 +317,7 @@ int virtio_gpu_framebuffer_init(struct drm_device *dev,
320 struct virtio_gpu_framebuffer *vgfb, 317 struct virtio_gpu_framebuffer *vgfb,
321 const struct drm_mode_fb_cmd2 *mode_cmd, 318 const struct drm_mode_fb_cmd2 *mode_cmd,
322 struct drm_gem_object *obj); 319 struct drm_gem_object *obj);
323int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); 320void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev);
324void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); 321void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev);
325 322
326/* virtio_gpu_plane.c */ 323/* virtio_gpu_plane.c */
@@ -337,7 +334,6 @@ int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma);
337/* virtio_gpu_fence.c */ 334/* virtio_gpu_fence.c */
338struct virtio_gpu_fence *virtio_gpu_fence_alloc( 335struct virtio_gpu_fence *virtio_gpu_fence_alloc(
339 struct virtio_gpu_device *vgdev); 336 struct virtio_gpu_device *vgdev);
340void virtio_gpu_fence_cleanup(struct virtio_gpu_fence *fence);
341int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, 337int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
342 struct virtio_gpu_ctrl_hdr *cmd_hdr, 338 struct virtio_gpu_ctrl_hdr *cmd_hdr,
343 struct virtio_gpu_fence *fence); 339 struct virtio_gpu_fence *fence);
diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c
index 4d6826b27814..21bd4c4a32d1 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fence.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fence.c
@@ -81,14 +81,6 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev)
81 return fence; 81 return fence;
82} 82}
83 83
84void virtio_gpu_fence_cleanup(struct virtio_gpu_fence *fence)
85{
86 if (!fence)
87 return;
88
89 dma_fence_put(&fence->f);
90}
91
92int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, 84int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
93 struct virtio_gpu_ctrl_hdr *cmd_hdr, 85 struct virtio_gpu_ctrl_hdr *cmd_hdr,
94 struct virtio_gpu_fence *fence) 86 struct virtio_gpu_fence *fence)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 161b80fee492..14ce8188c052 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -351,7 +351,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
351 virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d); 351 virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d);
352 ret = virtio_gpu_object_attach(vgdev, qobj, fence); 352 ret = virtio_gpu_object_attach(vgdev, qobj, fence);
353 if (ret) { 353 if (ret) {
354 virtio_gpu_fence_cleanup(fence); 354 dma_fence_put(&fence->f);
355 goto fail_backoff; 355 goto fail_backoff;
356 } 356 }
357 ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f); 357 ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f);
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 1072064a0db2..84b6a6bf00c6 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -106,7 +106,7 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev,
106 vgdev->num_capsets = num_capsets; 106 vgdev->num_capsets = num_capsets;
107} 107}
108 108
109int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) 109int virtio_gpu_init(struct drm_device *dev)
110{ 110{
111 static vq_callback_t *callbacks[] = { 111 static vq_callback_t *callbacks[] = {
112 virtio_gpu_ctrl_ack, virtio_gpu_cursor_ack 112 virtio_gpu_ctrl_ack, virtio_gpu_cursor_ack
@@ -193,9 +193,7 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags)
193 num_capsets, &num_capsets); 193 num_capsets, &num_capsets);
194 DRM_INFO("number of cap sets: %d\n", num_capsets); 194 DRM_INFO("number of cap sets: %d\n", num_capsets);
195 195
196 ret = virtio_gpu_modeset_init(vgdev); 196 virtio_gpu_modeset_init(vgdev);
197 if (ret)
198 goto err_modeset;
199 197
200 virtio_device_ready(vgdev->vdev); 198 virtio_device_ready(vgdev->vdev);
201 vgdev->vqs_ready = true; 199 vgdev->vqs_ready = true;
@@ -209,7 +207,6 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags)
209 5 * HZ); 207 5 * HZ);
210 return 0; 208 return 0;
211 209
212err_modeset:
213err_scanouts: 210err_scanouts:
214 virtio_gpu_ttm_fini(vgdev); 211 virtio_gpu_ttm_fini(vgdev);
215err_ttm: 212err_ttm:
@@ -231,7 +228,7 @@ static void virtio_gpu_cleanup_cap_cache(struct virtio_gpu_device *vgdev)
231 } 228 }
232} 229}
233 230
234void virtio_gpu_driver_unload(struct drm_device *dev) 231void virtio_gpu_deinit(struct drm_device *dev)
235{ 232{
236 struct virtio_gpu_device *vgdev = dev->dev_private; 233 struct virtio_gpu_device *vgdev = dev->dev_private;
237 234
@@ -239,6 +236,7 @@ void virtio_gpu_driver_unload(struct drm_device *dev)
239 flush_work(&vgdev->ctrlq.dequeue_work); 236 flush_work(&vgdev->ctrlq.dequeue_work);
240 flush_work(&vgdev->cursorq.dequeue_work); 237 flush_work(&vgdev->cursorq.dequeue_work);
241 flush_work(&vgdev->config_changed_work); 238 flush_work(&vgdev->config_changed_work);
239 vgdev->vdev->config->reset(vgdev->vdev);
242 vgdev->vdev->config->del_vqs(vgdev->vdev); 240 vgdev->vdev->config->del_vqs(vgdev->vdev);
243 241
244 virtio_gpu_modeset_fini(vgdev); 242 virtio_gpu_modeset_fini(vgdev);
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index ead5c53d4e21..024c2aa0c929 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -130,11 +130,12 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
130 plane->state->src_h >> 16, 130 plane->state->src_h >> 16,
131 plane->state->src_x >> 16, 131 plane->state->src_x >> 16,
132 plane->state->src_y >> 16); 132 plane->state->src_y >> 16);
133 virtio_gpu_cmd_resource_flush(vgdev, handle, 133 if (handle)
134 plane->state->src_x >> 16, 134 virtio_gpu_cmd_resource_flush(vgdev, handle,
135 plane->state->src_y >> 16, 135 plane->state->src_x >> 16,
136 plane->state->src_w >> 16, 136 plane->state->src_y >> 16,
137 plane->state->src_h >> 16); 137 plane->state->src_w >> 16,
138 plane->state->src_h >> 16);
138} 139}
139 140
140static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, 141static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane,
@@ -168,8 +169,10 @@ static void virtio_gpu_cursor_cleanup_fb(struct drm_plane *plane,
168 return; 169 return;
169 170
170 vgfb = to_virtio_gpu_framebuffer(plane->state->fb); 171 vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
171 if (vgfb->fence) 172 if (vgfb->fence) {
172 virtio_gpu_fence_cleanup(vgfb->fence); 173 dma_fence_put(&vgfb->fence->f);
174 vgfb->fence = NULL;
175 }
173} 176}
174 177
175static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, 178static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index e27c4aedb809..6bc2008b0d0d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -192,8 +192,16 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work)
192 192
193 list_for_each_entry_safe(entry, tmp, &reclaim_list, list) { 193 list_for_each_entry_safe(entry, tmp, &reclaim_list, list) {
194 resp = (struct virtio_gpu_ctrl_hdr *)entry->resp_buf; 194 resp = (struct virtio_gpu_ctrl_hdr *)entry->resp_buf;
195 if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) 195 if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) {
196 DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type)); 196 if (resp->type >= cpu_to_le32(VIRTIO_GPU_RESP_ERR_UNSPEC)) {
197 struct virtio_gpu_ctrl_hdr *cmd;
198 cmd = (struct virtio_gpu_ctrl_hdr *)entry->buf;
199 DRM_ERROR("response 0x%x (command 0x%x)\n",
200 le32_to_cpu(resp->type),
201 le32_to_cpu(cmd->type));
202 } else
203 DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type));
204 }
197 if (resp->flags & cpu_to_le32(VIRTIO_GPU_FLAG_FENCE)) { 205 if (resp->flags & cpu_to_le32(VIRTIO_GPU_FLAG_FENCE)) {
198 u64 f = le64_to_cpu(resp->fence_id); 206 u64 f = le64_to_cpu(resp->fence_id);
199 207
diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c
index 78655269d843..9fc98bb4f3d9 100644
--- a/drivers/gpu/drm/zte/zx_hdmi.c
+++ b/drivers/gpu/drm/zte/zx_hdmi.c
@@ -125,7 +125,9 @@ static int zx_hdmi_config_video_avi(struct zx_hdmi *hdmi,
125 union hdmi_infoframe frame; 125 union hdmi_infoframe frame;
126 int ret; 126 int ret;
127 127
128 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false); 128 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
129 &hdmi->connector,
130 mode);
129 if (ret) { 131 if (ret) {
130 DRM_DEV_ERROR(hdmi->dev, "failed to get avi infoframe: %d\n", 132 DRM_DEV_ERROR(hdmi->dev, "failed to get avi infoframe: %d\n",
131 ret); 133 ret);
diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c
index 6b7aa23dfc0a..397496cf0bdf 100644
--- a/drivers/staging/vboxvideo/vbox_fb.c
+++ b/drivers/staging/vboxvideo/vbox_fb.c
@@ -95,11 +95,6 @@ int vboxfb_create(struct drm_fb_helper *helper,
95 95
96 strcpy(info->fix.id, "vboxdrmfb"); 96 strcpy(info->fix.id, "vboxdrmfb");
97 97
98 /*
99 * The last flag forces a mode set on VT switches even if the kernel
100 * does not think it is needed.
101 */
102 info->flags = FBINFO_DEFAULT | FBINFO_MISC_ALWAYS_SETPAR;
103 info->fbops = &vboxfb_ops; 98 info->fbops = &vboxfb_ops;
104 99
105 /* 100 /*
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index 9c56412bb2cf..9f93895dde88 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -10,9 +10,11 @@
10#ifndef __DW_HDMI__ 10#ifndef __DW_HDMI__
11#define __DW_HDMI__ 11#define __DW_HDMI__
12 12
13#include <drm/drmP.h> 13struct drm_connector;
14 14struct drm_display_mode;
15struct drm_encoder;
15struct dw_hdmi; 16struct dw_hdmi;
17struct platform_device;
16 18
17/** 19/**
18 * DOC: Supported input formats and encodings 20 * DOC: Supported input formats and encodings
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index db94ef00940e..3f5c577c9dbd 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -94,23 +94,11 @@ struct dma_buf_attachment;
94struct pci_dev; 94struct pci_dev;
95struct pci_controller; 95struct pci_controller;
96 96
97#define DRM_SWITCH_POWER_ON 0 97/*
98#define DRM_SWITCH_POWER_OFF 1 98 * NOTE: drmP.h is obsolete - do NOT add anything to this file
99#define DRM_SWITCH_POWER_CHANGING 2 99 *
100#define DRM_SWITCH_POWER_DYNAMIC_OFF 3 100 * Do not include drmP.h in new files.
101 101 * Work is ongoing to remove drmP.h includes from existing files
102/* returns true if currently okay to sleep */ 102 */
103static inline bool drm_can_sleep(void)
104{
105 if (in_atomic() || in_dbg_master() || irqs_disabled())
106 return false;
107 return true;
108}
109
110#if defined(CONFIG_DRM_DEBUG_SELFTEST_MODULE)
111#define EXPORT_SYMBOL_FOR_TESTS_ONLY(x) EXPORT_SYMBOL(x)
112#else
113#define EXPORT_SYMBOL_FOR_TESTS_ONLY(x)
114#endif
115 103
116#endif 104#endif
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index cac4a1b6b0e8..811b4a92568f 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -139,9 +139,9 @@ struct drm_crtc_commit {
139 /** 139 /**
140 * @abort_completion: 140 * @abort_completion:
141 * 141 *
142 * A flag that's set after drm_atomic_helper_setup_commit takes a second 142 * A flag that's set after drm_atomic_helper_setup_commit() takes a
143 * reference for the completion of $drm_crtc_state.event. It's used by 143 * second reference for the completion of $drm_crtc_state.event. It's
144 * the free code to remove the second reference if commit fails. 144 * used by the free code to remove the second reference if commit fails.
145 */ 145 */
146 bool abort_completion; 146 bool abort_completion;
147}; 147};
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index f82701d49ea6..994161374a49 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -366,6 +366,12 @@ struct drm_display_info {
366 bool has_hdmi_infoframe; 366 bool has_hdmi_infoframe;
367 367
368 /** 368 /**
369 * @rgb_quant_range_selectable: Does the sink support selecting
370 * the RGB quantization range?
371 */
372 bool rgb_quant_range_selectable;
373
374 /**
369 * @edid_hdmi_dc_modes: Mask of supported hdmi deep color modes. Even 375 * @edid_hdmi_dc_modes: Mask of supported hdmi deep color modes. Even
370 * more stuff redundant with @bus_formats. 376 * more stuff redundant with @bus_formats.
371 */ 377 */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 39c3900aab3c..85abd3fe9e83 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1149,9 +1149,6 @@ static inline uint32_t drm_crtc_mask(const struct drm_crtc *crtc)
1149 return 1 << drm_crtc_index(crtc); 1149 return 1 << drm_crtc_index(crtc);
1150} 1150}
1151 1151
1152int drm_crtc_force_disable(struct drm_crtc *crtc);
1153int drm_crtc_force_disable_all(struct drm_device *dev);
1154
1155int drm_mode_set_config_internal(struct drm_mode_set *set); 1152int drm_mode_set_config_internal(struct drm_mode_set *set);
1156struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx); 1153struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx);
1157 1154
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index d65f034843ce..0ee9a96b70da 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -56,6 +56,7 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
56int drm_helper_connector_dpms(struct drm_connector *connector, int mode); 56int drm_helper_connector_dpms(struct drm_connector *connector, int mode);
57 57
58void drm_helper_resume_force_mode(struct drm_device *dev); 58void drm_helper_resume_force_mode(struct drm_device *dev);
59int drm_helper_force_disable_all(struct drm_device *dev);
59 60
60/* drm_probe_helper.c */ 61/* drm_probe_helper.c */
61int drm_helper_probe_single_connector_modes(struct drm_connector 62int drm_helper_probe_single_connector_modes(struct drm_connector
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 42411b3ea0c8..d5e092dccf3e 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -24,25 +24,79 @@ struct inode;
24struct pci_dev; 24struct pci_dev;
25struct pci_controller; 25struct pci_controller;
26 26
27
27/** 28/**
28 * DRM device structure. This structure represent a complete card that 29 * enum drm_switch_power - power state of drm device
30 */
31
32enum switch_power_state {
33 /** @DRM_SWITCH_POWER_ON: Power state is ON */
34 DRM_SWITCH_POWER_ON = 0,
35
36 /** @DRM_SWITCH_POWER_OFF: Power state is OFF */
37 DRM_SWITCH_POWER_OFF = 1,
38
39 /** @DRM_SWITCH_POWER_CHANGING: Power state is changing */
40 DRM_SWITCH_POWER_CHANGING = 2,
41
42 /** @DRM_SWITCH_POWER_DYNAMIC_OFF: Suspended */
43 DRM_SWITCH_POWER_DYNAMIC_OFF = 3,
44};
45
46/**
47 * struct drm_device - DRM device structure
48 *
49 * This structure represent a complete card that
29 * may contain multiple heads. 50 * may contain multiple heads.
30 */ 51 */
31struct drm_device { 52struct drm_device {
32 struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */ 53 /**
33 int if_version; /**< Highest interface version set */ 54 * @legacy_dev_list:
34 55 *
35 /** \name Lifetime Management */ 56 * List of devices per driver for stealth attach cleanup
36 /*@{ */ 57 */
37 struct kref ref; /**< Object ref-count */ 58 struct list_head legacy_dev_list;
38 struct device *dev; /**< Device structure of bus-device */ 59
39 struct drm_driver *driver; /**< DRM driver managing the device */ 60 /** @if_version: Highest interface version set */
40 void *dev_private; /**< DRM driver private data */ 61 int if_version;
41 struct drm_minor *primary; /**< Primary node */ 62
42 struct drm_minor *render; /**< Render node */ 63 /** @ref: Object ref-count */
64 struct kref ref;
65
66 /** @dev: Device structure of bus-device */
67 struct device *dev;
68
69 /** @driver: DRM driver managing the device */
70 struct drm_driver *driver;
71
72 /**
73 * @dev_private:
74 *
75 * DRM driver private data. Instead of using this pointer it is
76 * recommended that drivers use drm_dev_init() and embed struct
77 * &drm_device in their larger per-device structure.
78 */
79 void *dev_private;
80
81 /** @primary: Primary node */
82 struct drm_minor *primary;
83
84 /** @render: Render node */
85 struct drm_minor *render;
86
87 /**
88 * @registered:
89 *
90 * Internally used by drm_dev_register() and drm_connector_register().
91 */
43 bool registered; 92 bool registered;
44 93
45 /* currently active master for this device. Protected by master_mutex */ 94 /**
95 * @master:
96 *
97 * Currently active master for this device.
98 * Protected by &master_mutex
99 */
46 struct drm_master *master; 100 struct drm_master *master;
47 101
48 /** 102 /**
@@ -63,76 +117,65 @@ struct drm_device {
63 */ 117 */
64 bool unplugged; 118 bool unplugged;
65 119
66 struct inode *anon_inode; /**< inode for private address-space */ 120 /** @anon_inode: inode for private address-space */
67 char *unique; /**< unique name of the device */ 121 struct inode *anon_inode;
68 /*@} */ 122
123 /** @unique: Unique name of the device */
124 char *unique;
69 125
70 /** \name Locks */ 126 /**
71 /*@{ */ 127 * @struct_mutex:
72 struct mutex struct_mutex; /**< For others */ 128 *
73 struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */ 129 * Lock for others (not &drm_minor.master and &drm_file.is_master)
74 /*@} */ 130 */
131 struct mutex struct_mutex;
75 132
76 /** \name Usage Counters */ 133 /**
77 /*@{ */ 134 * @master_mutex:
78 int open_count; /**< Outstanding files open, protected by drm_global_mutex. */ 135 *
79 spinlock_t buf_lock; /**< For drm_device::buf_use and a few other things. */ 136 * Lock for &drm_minor.master and &drm_file.is_master
80 int buf_use; /**< Buffers in use -- cannot alloc */ 137 */
81 atomic_t buf_alloc; /**< Buffer allocation in progress */ 138 struct mutex master_mutex;
82 /*@} */ 139
140 /**
141 * @open_count:
142 *
143 * Usage counter for outstanding files open,
144 * protected by drm_global_mutex
145 */
146 int open_count;
83 147
148 /** @filelist_mutex: Protects @filelist. */
84 struct mutex filelist_mutex; 149 struct mutex filelist_mutex;
150 /**
151 * @filelist:
152 *
153 * List of userspace clients, linked through &drm_file.lhead.
154 */
85 struct list_head filelist; 155 struct list_head filelist;
86 156
87 /** 157 /**
88 * @filelist_internal: 158 * @filelist_internal:
89 * 159 *
90 * List of open DRM files for in-kernel clients. Protected by @filelist_mutex. 160 * List of open DRM files for in-kernel clients.
161 * Protected by &filelist_mutex.
91 */ 162 */
92 struct list_head filelist_internal; 163 struct list_head filelist_internal;
93 164
94 /** 165 /**
95 * @clientlist_mutex: 166 * @clientlist_mutex:
96 * 167 *
97 * Protects @clientlist access. 168 * Protects &clientlist access.
98 */ 169 */
99 struct mutex clientlist_mutex; 170 struct mutex clientlist_mutex;
100 171
101 /** 172 /**
102 * @clientlist: 173 * @clientlist:
103 * 174 *
104 * List of in-kernel clients. Protected by @clientlist_mutex. 175 * List of in-kernel clients. Protected by &clientlist_mutex.
105 */ 176 */
106 struct list_head clientlist; 177 struct list_head clientlist;
107 178
108 /** \name Memory management */
109 /*@{ */
110 struct list_head maplist; /**< Linked list of regions */
111 struct drm_open_hash map_hash; /**< User token hash table for maps */
112
113 /** \name Context handle management */
114 /*@{ */
115 struct list_head ctxlist; /**< Linked list of context handles */
116 struct mutex ctxlist_mutex; /**< For ctxlist */
117
118 struct idr ctx_idr;
119
120 struct list_head vmalist; /**< List of vmas (for debugging) */
121
122 /*@} */
123
124 /** \name DMA support */
125 /*@{ */
126 struct drm_device_dma *dma; /**< Optional pointer for DMA support */
127 /*@} */
128
129 /** \name Context support */
130 /*@{ */
131
132 __volatile__ long context_flag; /**< Context swapping flag */
133 int last_context; /**< Last current context */
134 /*@} */
135
136 /** 179 /**
137 * @irq_enabled: 180 * @irq_enabled:
138 * 181 *
@@ -141,6 +184,10 @@ struct drm_device {
141 * to true manually. 184 * to true manually.
142 */ 185 */
143 bool irq_enabled; 186 bool irq_enabled;
187
188 /**
189 * @irq: Used by the drm_irq_install() and drm_irq_unistall() helpers.
190 */
144 int irq; 191 int irq;
145 192
146 /** 193 /**
@@ -168,7 +215,16 @@ struct drm_device {
168 */ 215 */
169 struct drm_vblank_crtc *vblank; 216 struct drm_vblank_crtc *vblank;
170 217
171 spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ 218 /**
219 * @vblank_time_lock:
220 *
221 * Protects vblank count and time updates during vblank enable/disable
222 */
223 spinlock_t vblank_time_lock;
224 /**
225 * @vbl_lock: Top-level vblank references lock, wraps the low-level
226 * @vblank_time_lock.
227 */
172 spinlock_t vbl_lock; 228 spinlock_t vbl_lock;
173 229
174 /** 230 /**
@@ -184,45 +240,61 @@ struct drm_device {
184 * races and imprecision over longer time periods, hence exposing a 240 * races and imprecision over longer time periods, hence exposing a
185 * hardware vblank counter is always recommended. 241 * hardware vblank counter is always recommended.
186 * 242 *
187 * If non-zeor, &drm_crtc_funcs.get_vblank_counter must be set. 243 * This is the statically configured device wide maximum. The driver
244 * can instead choose to use a runtime configurable per-crtc value
245 * &drm_vblank_crtc.max_vblank_count, in which case @max_vblank_count
246 * must be left at zero. See drm_crtc_set_max_vblank_count() on how
247 * to use the per-crtc value.
248 *
249 * If non-zero, &drm_crtc_funcs.get_vblank_counter must be set.
188 */ 250 */
189 u32 max_vblank_count; /**< size of vblank counter register */ 251 u32 max_vblank_count;
252
253 /** @vblank_event_list: List of vblank events */
254 struct list_head vblank_event_list;
190 255
191 /** 256 /**
192 * List of events 257 * @event_lock:
258 *
259 * Protects @vblank_event_list and event delivery in
260 * general. See drm_send_event() and drm_send_event_locked().
193 */ 261 */
194 struct list_head vblank_event_list;
195 spinlock_t event_lock; 262 spinlock_t event_lock;
196 263
197 /*@} */ 264 /** @agp: AGP data */
265 struct drm_agp_head *agp;
198 266
199 struct drm_agp_head *agp; /**< AGP data */ 267 /** @pdev: PCI device structure */
268 struct pci_dev *pdev;
200 269
201 struct pci_dev *pdev; /**< PCI device structure */
202#ifdef __alpha__ 270#ifdef __alpha__
271 /** @hose: PCI hose, only used on ALPHA platforms. */
203 struct pci_controller *hose; 272 struct pci_controller *hose;
204#endif 273#endif
274 /** @num_crtcs: Number of CRTCs on this device */
275 unsigned int num_crtcs;
205 276
206 struct drm_sg_mem *sg; /**< Scatter gather memory */ 277 /** @mode_config: Current mode config */
207 unsigned int num_crtcs; /**< Number of CRTCs on this device */ 278 struct drm_mode_config mode_config;
208 279
209 struct { 280 /** @object_name_lock: GEM information */
210 int context;
211 struct drm_hw_lock *lock;
212 } sigdata;
213
214 struct drm_local_map *agp_buffer_map;
215 unsigned int agp_buffer_token;
216
217 struct drm_mode_config mode_config; /**< Current mode config */
218
219 /** \name GEM information */
220 /*@{ */
221 struct mutex object_name_lock; 281 struct mutex object_name_lock;
282
283 /** @object_name_idr: GEM information */
222 struct idr object_name_idr; 284 struct idr object_name_idr;
285
286 /** @vma_offset_manager: GEM information */
223 struct drm_vma_offset_manager *vma_offset_manager; 287 struct drm_vma_offset_manager *vma_offset_manager;
224 /*@} */ 288
225 int switch_power_state; 289 /**
290 * @switch_power_state:
291 *
292 * Power state of the client.
293 * Used by drivers supporting the switcheroo driver.
294 * The state is maintained in the
295 * &vga_switcheroo_client_ops.set_gpu_state callback
296 */
297 enum switch_power_state switch_power_state;
226 298
227 /** 299 /**
228 * @fb_helper: 300 * @fb_helper:
@@ -231,6 +303,56 @@ struct drm_device {
231 * Set by drm_fb_helper_init() and cleared by drm_fb_helper_fini(). 303 * Set by drm_fb_helper_init() and cleared by drm_fb_helper_fini().
232 */ 304 */
233 struct drm_fb_helper *fb_helper; 305 struct drm_fb_helper *fb_helper;
306
307 /* Everything below here is for legacy driver, never use! */
308 /* private: */
309
310 /* Context handle management - linked list of context handles */
311 struct list_head ctxlist;
312
313 /* Context handle management - mutex for &ctxlist */
314 struct mutex ctxlist_mutex;
315
316 /* Context handle management */
317 struct idr ctx_idr;
318
319 /* Memory management - linked list of regions */
320 struct list_head maplist;
321
322 /* Memory management - user token hash table for maps */
323 struct drm_open_hash map_hash;
324
325 /* Context handle management - list of vmas (for debugging) */
326 struct list_head vmalist;
327
328 /* Optional pointer for DMA support */
329 struct drm_device_dma *dma;
330
331 /* Context swapping flag */
332 __volatile__ long context_flag;
333
334 /* Last current context */
335 int last_context;
336
337 /* Lock for &buf_use and a few other things. */
338 spinlock_t buf_lock;
339
340 /* Usage counter for buffers in use -- cannot alloc */
341 int buf_use;
342
343 /* Buffer allocation in progress */
344 atomic_t buf_alloc;
345
346 struct {
347 int context;
348 struct drm_hw_lock *lock;
349 } sigdata;
350
351 struct drm_local_map *agp_buffer_map;
352 unsigned int agp_buffer_token;
353
354 /* Scatter gather memory */
355 struct drm_sg_mem *sg;
234}; 356};
235 357
236#endif 358#endif
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 371cc2816477..451d020f0137 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -44,7 +44,6 @@ struct drm_dp_vcpi {
44 44
45/** 45/**
46 * struct drm_dp_mst_port - MST port 46 * struct drm_dp_mst_port - MST port
47 * @kref: reference count for this port.
48 * @port_num: port number 47 * @port_num: port number
49 * @input: if this port is an input port. 48 * @input: if this port is an input port.
50 * @mcs: message capability status - DP 1.2 spec. 49 * @mcs: message capability status - DP 1.2 spec.
@@ -67,7 +66,18 @@ struct drm_dp_vcpi {
67 * in the MST topology. 66 * in the MST topology.
68 */ 67 */
69struct drm_dp_mst_port { 68struct drm_dp_mst_port {
70 struct kref kref; 69 /**
70 * @topology_kref: refcount for this port's lifetime in the topology,
71 * only the DP MST helpers should need to touch this
72 */
73 struct kref topology_kref;
74
75 /**
76 * @malloc_kref: refcount for the memory allocation containing this
77 * structure. See drm_dp_mst_get_port_malloc() and
78 * drm_dp_mst_put_port_malloc().
79 */
80 struct kref malloc_kref;
71 81
72 u8 port_num; 82 u8 port_num;
73 bool input; 83 bool input;
@@ -102,7 +112,6 @@ struct drm_dp_mst_port {
102 112
103/** 113/**
104 * struct drm_dp_mst_branch - MST branch device. 114 * struct drm_dp_mst_branch - MST branch device.
105 * @kref: reference count for this port.
106 * @rad: Relative Address to talk to this branch device. 115 * @rad: Relative Address to talk to this branch device.
107 * @lct: Link count total to talk to this branch device. 116 * @lct: Link count total to talk to this branch device.
108 * @num_ports: number of ports on the branch. 117 * @num_ports: number of ports on the branch.
@@ -121,7 +130,19 @@ struct drm_dp_mst_port {
121 * to downstream port of parent branches. 130 * to downstream port of parent branches.
122 */ 131 */
123struct drm_dp_mst_branch { 132struct drm_dp_mst_branch {
124 struct kref kref; 133 /**
134 * @topology_kref: refcount for this branch device's lifetime in the
135 * topology, only the DP MST helpers should need to touch this
136 */
137 struct kref topology_kref;
138
139 /**
140 * @malloc_kref: refcount for the memory allocation containing this
141 * structure. See drm_dp_mst_get_mstb_malloc() and
142 * drm_dp_mst_put_mstb_malloc().
143 */
144 struct kref malloc_kref;
145
125 u8 rad[8]; 146 u8 rad[8];
126 u8 lct; 147 u8 lct;
127 int num_ports; 148 int num_ports;
@@ -404,9 +425,15 @@ struct drm_dp_payload {
404 425
405#define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base) 426#define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base)
406 427
428struct drm_dp_vcpi_allocation {
429 struct drm_dp_mst_port *port;
430 int vcpi;
431 struct list_head next;
432};
433
407struct drm_dp_mst_topology_state { 434struct drm_dp_mst_topology_state {
408 struct drm_private_state base; 435 struct drm_private_state base;
409 int avail_slots; 436 struct list_head vcpis;
410 struct drm_dp_mst_topology_mgr *mgr; 437 struct drm_dp_mst_topology_mgr *mgr;
411}; 438};
412 439
@@ -617,13 +644,115 @@ void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
617int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr); 644int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
618struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, 645struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
619 struct drm_dp_mst_topology_mgr *mgr); 646 struct drm_dp_mst_topology_mgr *mgr);
620int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state, 647int __must_check
621 struct drm_dp_mst_topology_mgr *mgr, 648drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
622 struct drm_dp_mst_port *port, int pbn); 649 struct drm_dp_mst_topology_mgr *mgr,
623int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, 650 struct drm_dp_mst_port *port, int pbn);
624 struct drm_dp_mst_topology_mgr *mgr, 651int __must_check
625 int slots); 652drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
653 struct drm_dp_mst_topology_mgr *mgr,
654 struct drm_dp_mst_port *port);
626int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, 655int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
627 struct drm_dp_mst_port *port, bool power_up); 656 struct drm_dp_mst_port *port, bool power_up);
657int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
658
659void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
660void drm_dp_mst_put_port_malloc(struct drm_dp_mst_port *port);
661
662extern const struct drm_private_state_funcs drm_dp_mst_topology_state_funcs;
663
664/**
665 * __drm_dp_mst_state_iter_get - private atomic state iterator function for
666 * macro-internal use
667 * @state: &struct drm_atomic_state pointer
668 * @mgr: pointer to the &struct drm_dp_mst_topology_mgr iteration cursor
669 * @old_state: optional pointer to the old &struct drm_dp_mst_topology_state
670 * iteration cursor
671 * @new_state: optional pointer to the new &struct drm_dp_mst_topology_state
672 * iteration cursor
673 * @i: int iteration cursor, for macro-internal use
674 *
675 * Used by for_each_oldnew_mst_mgr_in_state(),
676 * for_each_old_mst_mgr_in_state(), and for_each_new_mst_mgr_in_state(). Don't
677 * call this directly.
678 *
679 * Returns:
680 * True if the current &struct drm_private_obj is a &struct
681 * drm_dp_mst_topology_mgr, false otherwise.
682 */
683static inline bool
684__drm_dp_mst_state_iter_get(struct drm_atomic_state *state,
685 struct drm_dp_mst_topology_mgr **mgr,
686 struct drm_dp_mst_topology_state **old_state,
687 struct drm_dp_mst_topology_state **new_state,
688 int i)
689{
690 struct __drm_private_objs_state *objs_state = &state->private_objs[i];
691
692 if (objs_state->ptr->funcs != &drm_dp_mst_topology_state_funcs)
693 return false;
694
695 *mgr = to_dp_mst_topology_mgr(objs_state->ptr);
696 if (old_state)
697 *old_state = to_dp_mst_topology_state(objs_state->old_state);
698 if (new_state)
699 *new_state = to_dp_mst_topology_state(objs_state->new_state);
700
701 return true;
702}
703
704/**
705 * for_each_oldnew_mst_mgr_in_state - iterate over all DP MST topology
706 * managers in an atomic update
707 * @__state: &struct drm_atomic_state pointer
708 * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor
709 * @old_state: &struct drm_dp_mst_topology_state iteration cursor for the old
710 * state
711 * @new_state: &struct drm_dp_mst_topology_state iteration cursor for the new
712 * state
713 * @__i: int iteration cursor, for macro-internal use
714 *
715 * This iterates over all DRM DP MST topology managers in an atomic update,
716 * tracking both old and new state. This is useful in places where the state
717 * delta needs to be considered, for example in atomic check functions.
718 */
719#define for_each_oldnew_mst_mgr_in_state(__state, mgr, old_state, new_state, __i) \
720 for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \
721 for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), &(old_state), &(new_state), (__i)))
722
723/**
724 * for_each_old_mst_mgr_in_state - iterate over all DP MST topology managers
725 * in an atomic update
726 * @__state: &struct drm_atomic_state pointer
727 * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor
728 * @old_state: &struct drm_dp_mst_topology_state iteration cursor for the old
729 * state
730 * @__i: int iteration cursor, for macro-internal use
731 *
732 * This iterates over all DRM DP MST topology managers in an atomic update,
733 * tracking only the old state. This is useful in disable functions, where we
734 * need the old state the hardware is still in.
735 */
736#define for_each_old_mst_mgr_in_state(__state, mgr, old_state, __i) \
737 for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \
738 for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), &(old_state), NULL, (__i)))
739
740/**
741 * for_each_new_mst_mgr_in_state - iterate over all DP MST topology managers
742 * in an atomic update
743 * @__state: &struct drm_atomic_state pointer
744 * @mgr: &struct drm_dp_mst_topology_mgr iteration cursor
745 * @new_state: &struct drm_dp_mst_topology_state iteration cursor for the new
746 * state
747 * @__i: int iteration cursor, for macro-internal use
748 *
749 * This iterates over all DRM DP MST topology managers in an atomic update,
750 * tracking only the new state. This is useful in enable functions, where we
751 * need the new state the hardware should be in when the atomic commit
752 * operation has completed.
753 */
754#define for_each_new_mst_mgr_in_state(__state, mgr, new_state, __i) \
755 for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \
756 for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), NULL, &(new_state), (__i)))
628 757
629#endif 758#endif
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index e3c404833115..8dc1a081fb36 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -352,18 +352,17 @@ drm_load_edid_firmware(struct drm_connector *connector)
352 352
353int 353int
354drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, 354drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
355 const struct drm_display_mode *mode, 355 struct drm_connector *connector,
356 bool is_hdmi2_sink); 356 const struct drm_display_mode *mode);
357int 357int
358drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, 358drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
359 struct drm_connector *connector, 359 struct drm_connector *connector,
360 const struct drm_display_mode *mode); 360 const struct drm_display_mode *mode);
361void 361void
362drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame, 362drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
363 struct drm_connector *connector,
363 const struct drm_display_mode *mode, 364 const struct drm_display_mode *mode,
364 enum hdmi_quantization_range rgb_quant_range, 365 enum hdmi_quantization_range rgb_quant_range);
365 bool rgb_quant_range_selectable,
366 bool is_hdmi2_sink);
367 366
368/** 367/**
369 * drm_eld_mnl - Get ELD monitor name length in bytes. 368 * drm_eld_mnl - Get ELD monitor name length in bytes.
@@ -471,7 +470,6 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
471enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code); 470enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code);
472bool drm_detect_hdmi_monitor(struct edid *edid); 471bool drm_detect_hdmi_monitor(struct edid *edid);
473bool drm_detect_monitor_audio(struct edid *edid); 472bool drm_detect_monitor_audio(struct edid *edid);
474bool drm_rgb_quant_range_selectable(struct edid *edid);
475enum hdmi_quantization_range 473enum hdmi_quantization_range
476drm_default_rgb_quant_range(const struct drm_display_mode *mode); 474drm_default_rgb_quant_range(const struct drm_display_mode *mode);
477int drm_add_modes_noedid(struct drm_connector *connector, 475int drm_add_modes_noedid(struct drm_connector *connector,
diff --git a/include/drm/drm_encoder_slave.h b/include/drm/drm_encoder_slave.h
index 1107b4b1c599..a09864f6d684 100644
--- a/include/drm/drm_encoder_slave.h
+++ b/include/drm/drm_encoder_slave.h
@@ -27,7 +27,6 @@
27#ifndef __DRM_ENCODER_SLAVE_H__ 27#ifndef __DRM_ENCODER_SLAVE_H__
28#define __DRM_ENCODER_SLAVE_H__ 28#define __DRM_ENCODER_SLAVE_H__
29 29
30#include <drm/drmP.h>
31#include <drm/drm_crtc.h> 30#include <drm/drm_crtc.h>
32#include <drm/drm_encoder.h> 31#include <drm/drm_encoder.h>
33 32
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index c94acedfb08e..f0b34c977ec5 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -23,13 +23,17 @@
23#ifndef __DRM_FRAMEBUFFER_H__ 23#ifndef __DRM_FRAMEBUFFER_H__
24#define __DRM_FRAMEBUFFER_H__ 24#define __DRM_FRAMEBUFFER_H__
25 25
26#include <linux/list.h>
27#include <linux/ctype.h> 26#include <linux/ctype.h>
27#include <linux/list.h>
28#include <linux/sched.h>
29
28#include <drm/drm_mode_object.h> 30#include <drm/drm_mode_object.h>
29 31
30struct drm_framebuffer; 32struct drm_clip_rect;
31struct drm_file;
32struct drm_device; 33struct drm_device;
34struct drm_file;
35struct drm_framebuffer;
36struct drm_gem_object;
33 37
34/** 38/**
35 * struct drm_framebuffer_funcs - framebuffer hooks 39 * struct drm_framebuffer_funcs - framebuffer hooks
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index 07c504940ba1..947ac95eb24a 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -2,9 +2,12 @@
2#ifndef __DRM_GEM_CMA_HELPER_H__ 2#ifndef __DRM_GEM_CMA_HELPER_H__
3#define __DRM_GEM_CMA_HELPER_H__ 3#define __DRM_GEM_CMA_HELPER_H__
4 4
5#include <drm/drmP.h> 5#include <drm/drm_file.h>
6#include <drm/drm_ioctl.h>
6#include <drm/drm_gem.h> 7#include <drm/drm_gem.h>
7 8
9struct drm_mode_create_dumb;
10
8/** 11/**
9 * struct drm_gem_cma_object - GEM object backed by CMA memory allocations 12 * struct drm_gem_cma_object - GEM object backed by CMA memory allocations
10 * @base: base GEM object 13 * @base: base GEM object
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index baded6514456..be4fed97e727 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -136,8 +136,7 @@ enum drm_mode_status {
136 .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ 136 .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
137 .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \ 137 .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
138 .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ 138 .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
139 .vscan = (vs), .flags = (f), \ 139 .vscan = (vs), .flags = (f)
140 .base.type = DRM_MODE_OBJECT_MODE
141 140
142#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */ 141#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */
143#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */ 142#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */
@@ -214,20 +213,6 @@ struct drm_display_mode {
214 struct list_head head; 213 struct list_head head;
215 214
216 /** 215 /**
217 * @base:
218 *
219 * A display mode is a normal modeset object, possibly including public
220 * userspace id.
221 *
222 * FIXME:
223 *
224 * This can probably be removed since the entire concept of userspace
225 * managing modes explicitly has never landed in upstream kernel mode
226 * setting support.
227 */
228 struct drm_mode_object base;
229
230 /**
231 * @name: 216 * @name:
232 * 217 *
233 * Human-readable name of the mode, filled out with drm_mode_set_name(). 218 * Human-readable name of the mode, filled out with drm_mode_set_name().
@@ -429,14 +414,14 @@ struct drm_display_mode {
429/** 414/**
430 * DRM_MODE_FMT - printf string for &struct drm_display_mode 415 * DRM_MODE_FMT - printf string for &struct drm_display_mode
431 */ 416 */
432#define DRM_MODE_FMT "%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x" 417#define DRM_MODE_FMT "\"%s\": %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x"
433 418
434/** 419/**
435 * DRM_MODE_ARG - printf arguments for &struct drm_display_mode 420 * DRM_MODE_ARG - printf arguments for &struct drm_display_mode
436 * @m: display mode 421 * @m: display mode
437 */ 422 */
438#define DRM_MODE_ARG(m) \ 423#define DRM_MODE_ARG(m) \
439 (m)->base.id, (m)->name, (m)->vrefresh, (m)->clock, \ 424 (m)->name, (m)->vrefresh, (m)->clock, \
440 (m)->hdisplay, (m)->hsync_start, (m)->hsync_end, (m)->htotal, \ 425 (m)->hdisplay, (m)->hsync_start, (m)->hsync_end, (m)->htotal, \
441 (m)->vdisplay, (m)->vsync_start, (m)->vsync_end, (m)->vtotal, \ 426 (m)->vdisplay, (m)->vsync_start, (m)->vsync_end, (m)->vtotal, \
442 (m)->type, (m)->flags 427 (m)->type, (m)->flags
diff --git a/include/drm/drm_util.h b/include/drm/drm_util.h
index 88abdca89baa..8163d35f8327 100644
--- a/include/drm/drm_util.h
+++ b/include/drm/drm_util.h
@@ -26,7 +26,58 @@
26#ifndef _DRM_UTIL_H_ 26#ifndef _DRM_UTIL_H_
27#define _DRM_UTIL_H_ 27#define _DRM_UTIL_H_
28 28
29/* helper for handling conditionals in various for_each macros */ 29/**
30 * DOC: drm utils
31 *
32 * Macros and inline functions that does not naturally belong in other places
33 */
34
35#include <linux/interrupt.h>
36#include <linux/kgdb.h>
37#include <linux/preempt.h>
38#include <linux/smp.h>
39
40/*
41 * Use EXPORT_SYMBOL_FOR_TESTS_ONLY() for functions that shall
42 * only be visible for drmselftests.
43 */
44#if defined(CONFIG_DRM_DEBUG_SELFTEST_MODULE)
45#define EXPORT_SYMBOL_FOR_TESTS_ONLY(x) EXPORT_SYMBOL(x)
46#else
47#define EXPORT_SYMBOL_FOR_TESTS_ONLY(x)
48#endif
49
50/**
51 * for_each_if - helper for handling conditionals in various for_each macros
52 * @condition: The condition to check
53 *
54 * Typical use::
55 *
56 * #define for_each_foo_bar(x, y) \'
57 * list_for_each_entry(x, y->list, head) \'
58 * for_each_if(x->something == SOMETHING)
59 *
60 * The for_each_if() macro makes the use of for_each_foo_bar() less error
61 * prone.
62 */
30#define for_each_if(condition) if (!(condition)) {} else 63#define for_each_if(condition) if (!(condition)) {} else
31 64
65/**
66 * drm_can_sleep - returns true if currently okay to sleep
67 *
68 * This function shall not be used in new code.
69 * The check for running in atomic context may not work - see linux/preempt.h.
70 *
71 * FIXME: All users of drm_can_sleep should be removed (see todo.rst)
72 *
73 * Returns:
74 * True if kgdb is active or we are in an atomic context or irqs are disabled
75 */
76static inline bool drm_can_sleep(void)
77{
78 if (in_atomic() || in_dbg_master() || irqs_disabled())
79 return false;
80 return true;
81}
82
32#endif 83#endif
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 6ad9630d4f48..e528bb2f659d 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -129,6 +129,26 @@ struct drm_vblank_crtc {
129 */ 129 */
130 u32 last; 130 u32 last;
131 /** 131 /**
132 * @max_vblank_count:
133 *
134 * Maximum value of the vblank registers for this crtc. This value +1
135 * will result in a wrap-around of the vblank register. It is used
136 * by the vblank core to handle wrap-arounds.
137 *
138 * If set to zero the vblank core will try to guess the elapsed vblanks
139 * between times when the vblank interrupt is disabled through
140 * high-precision timestamps. That approach is suffering from small
141 * races and imprecision over longer time periods, hence exposing a
142 * hardware vblank counter is always recommended.
143 *
144 * This is the runtime configurable per-crtc maximum set through
145 * drm_crtc_set_max_vblank_count(). If this is used the driver
146 * must leave the device wide &drm_device.max_vblank_count at zero.
147 *
148 * If non-zero, &drm_crtc_funcs.get_vblank_counter must be set.
149 */
150 u32 max_vblank_count;
151 /**
132 * @inmodeset: Tracks whether the vblank is disabled due to a modeset. 152 * @inmodeset: Tracks whether the vblank is disabled due to a modeset.
133 * For legacy driver bit 2 additionally tracks whether an additional 153 * For legacy driver bit 2 additionally tracks whether an additional
134 * temporary vblank reference has been acquired to paper over the 154 * temporary vblank reference has been acquired to paper over the
@@ -206,4 +226,6 @@ bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
206void drm_calc_timestamping_constants(struct drm_crtc *crtc, 226void drm_calc_timestamping_constants(struct drm_crtc *crtc,
207 const struct drm_display_mode *mode); 227 const struct drm_display_mode *mode);
208wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc); 228wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc);
229void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc,
230 u32 max_vblank_count);
209#endif 231#endif
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 0b44260a5ee9..41106c835747 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -581,10 +581,18 @@ extern "C" {
581 * Indicates the superblock size(s) used for the AFBC buffer. The buffer 581 * Indicates the superblock size(s) used for the AFBC buffer. The buffer
582 * size (in pixels) must be aligned to a multiple of the superblock size. 582 * size (in pixels) must be aligned to a multiple of the superblock size.
583 * Four lowest significant bits(LSBs) are reserved for block size. 583 * Four lowest significant bits(LSBs) are reserved for block size.
584 *
585 * Where one superblock size is specified, it applies to all planes of the
586 * buffer (e.g. 16x16, 32x8). When multiple superblock sizes are specified,
587 * the first applies to the Luma plane and the second applies to the Chroma
588 * plane(s). e.g. (32x8_64x4 means 32x8 Luma, with 64x4 Chroma).
589 * Multiple superblock sizes are only valid for multi-plane YCbCr formats.
584 */ 590 */
585#define AFBC_FORMAT_MOD_BLOCK_SIZE_MASK 0xf 591#define AFBC_FORMAT_MOD_BLOCK_SIZE_MASK 0xf
586#define AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 (1ULL) 592#define AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 (1ULL)
587#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 (2ULL) 593#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 (2ULL)
594#define AFBC_FORMAT_MOD_BLOCK_SIZE_64x4 (3ULL)
595#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4 (4ULL)
588 596
589/* 597/*
590 * AFBC lossless colorspace transform 598 * AFBC lossless colorspace transform
@@ -644,6 +652,21 @@ extern "C" {
644 */ 652 */
645#define AFBC_FORMAT_MOD_SC (1ULL << 9) 653#define AFBC_FORMAT_MOD_SC (1ULL << 9)
646 654
655/*
656 * AFBC double-buffer
657 *
658 * Indicates that the buffer is allocated in a layout safe for front-buffer
659 * rendering.
660 */
661#define AFBC_FORMAT_MOD_DB (1ULL << 10)
662
663/*
664 * AFBC buffer content hints
665 *
666 * Indicates that the buffer includes per-superblock content hints.
667 */
668#define AFBC_FORMAT_MOD_BCH (1ULL << 11)
669
647#if defined(__cplusplus) 670#if defined(__cplusplus)
648} 671}
649#endif 672#endif