aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-09-27 15:45:27 -0400
committerDave Airlie <airlied@redhat.com>2017-09-27 15:46:15 -0400
commit29baa82aa55f40d67cfc8138c944fd8880c27e8e (patch)
tree19119a07d3ec8eb1407a68b48ec627239ee3e681
parente19b205be43d11bff638cad4487008c48d21c103 (diff)
parentac6c35a4d8c77083525044a192cb1a8711381e94 (diff)
Merge tag 'drm-misc-next-2017-09-20' of git://anongit.freedesktop.org/git/drm-misc into drm-next
UAPI Changes: Cross-subsystem Changes: Core Changes: - DP SDP defines (Ville) - polish for scdc helpers (Thierry Reding) - fix lifetimes for connector/plane state across crtc changes (Maarten Lankhorst). - sparse fixes (Ville+Thierry) - make legacy kms ioctls all interruptible (Maarten) - push edid override into the edid helpers (out of probe helpers) (Jani) - DP ESI defines for link status (DK) Driver Changes: - drm-panel is now in drm-misc! - minor panel-simple cleanups/refactoring by various folks - drm_bridge_add cleanup (Inki Dae) - constify a few i2c_device_id structs (Arvind Yadav) - More patches from Noralf's fb/gem helper cleanup - bridge/synopsis: reset fix (Philippe Cornu) - fix tracepoint include handling in drivers (Thierry) - rockchip: lvds support (Sandy Huang) - move sun4i into drm-misc fold (Maxime Ripard) - sun4i: refactor driver load + support TCON backend/layer muxing (Chen-Yu Tsai) - pl111: support more pl11x variants (Linus Walleij) - bridge/adv7511: robustify probing/edid handling (Lars-Petersen Clausen) New hw support: - S6E63J0X03 panel (Hoegeun Kwon) - OTM8009A panel (Philippe CORNU) - Seiko 43WVF1G panel (Marco Franchi) - tve200 driver (Linus Walleij) Plus assorted of tiny patches all over, including our first outreachy patches from applicants for the winter round! * tag 'drm-misc-next-2017-09-20' of git://anongit.freedesktop.org/git/drm-misc: (101 commits) drm: add backwards compatibility support for drm_kms_helper.edid_firmware drm: handle override and firmware EDID at drm_do_get_edid() level drm/dp: DPCD register defines for link status within ESI field drm/rockchip: Replace dev_* with DRM_DEV_* drm/tinydrm: Drop driver registered message drm/gem-fb-helper: Use debug message on gem lookup failure drm/imx: Use drm_gem_fb_create() and drm_gem_fb_prepare_fb() drm/bridge: adv7511: Constify HDMI CODEC platform data drm/bridge: adv7511: Enable connector polling when no interrupt is specified drm/bridge: adv7511: Remove private copy of the EDID drm/bridge: adv7511: Properly update EDID when no EDID was found drm/crtc: Convert setcrtc ioctl locking to interruptible. drm/atomic: Convert pageflip ioctl locking to interruptible. drm/legacy: Convert setplane ioctl locking to interruptible. drm/legacy: Convert cursor ioctl locking to interruptible. drm/atomic: Convert atomic ioctl locking to interruptible. drm/atomic: Prepare drm_modeset_lock infrastructure for interruptible waiting, v2. drm/tve200: Clean up panel bridging drm/doc: Update todo.rst drm/dp/mst: Sideband message transaction to power up/down nodes ...
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt2
-rw-r--r--Documentation/devicetree/bindings/display/faraday,tve200.txt54
-rw-r--r--Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt21
-rw-r--r--Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt24
-rw-r--r--Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt23
-rw-r--r--Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt99
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/gpu/drm-uapi.rst55
-rw-r--r--Documentation/gpu/index.rst1
-rw-r--r--Documentation/gpu/todo.rst26
-rw-r--r--Documentation/gpu/tve200.rst6
-rw-r--r--MAINTAINERS10
-rw-r--r--drivers/dma-buf/sw_sync.c10
-rw-r--r--drivers/gpu/drm/Kconfig4
-rw-r--r--drivers/gpu/drm/Makefile5
-rw-r--r--drivers/gpu/drm/arc/arcpgu_drv.c3
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c3
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c3
-rw-r--r--drivers/gpu/drm/armada/Makefile2
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c2
-rw-r--r--drivers/gpu/drm/armada/armada_gem.c36
-rw-r--r--drivers/gpu/drm/armada/armada_gem.h4
-rw-r--r--drivers/gpu/drm/armada/armada_trace.h2
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c2
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h1
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511.h2
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_audio.c2
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c24
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c103
-rw-r--r--drivers/gpu/drm/drm_atomic.c18
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c311
-rw-r--r--drivers/gpu/drm/drm_bridge.c7
-rw-r--r--drivers/gpu/drm/drm_connector.c1
-rw-r--r--drivers/gpu/drm/drm_crtc.c7
-rw-r--r--drivers/gpu/drm/drm_debugfs_crc.c2
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c74
-rw-r--r--drivers/gpu/drm/drm_edid.c15
-rw-r--r--drivers/gpu/drm/drm_edid_load.c16
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c6
-rw-r--r--drivers/gpu/drm/drm_gem.c6
-rw-r--r--drivers/gpu/drm/drm_gem_framebuffer_helper.c4
-rw-r--r--drivers/gpu/drm/drm_kms_helper_common.c28
-rw-r--r--drivers/gpu/drm/drm_mode_object.c5
-rw-r--r--drivers/gpu/drm/drm_modeset_lock.c96
-rw-r--r--drivers/gpu/drm/drm_plane.c21
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c19
-rw-r--r--drivers/gpu/drm/drm_scdc_helper.c12
-rw-r--r--drivers/gpu/drm/drm_syncobj.c8
-rw-r--r--drivers/gpu/drm/drm_trace.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_mic.c6
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_dp.c6
-rw-r--r--drivers/gpu/drm/gma500/mdfld_intel_display.c2
-rw-r--r--drivers/gpu/drm/i2c/ch7006_drv.c2
-rw-r--r--drivers/gpu/drm/i2c/sil164_drv.c2
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/intel_display.c105
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c3
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c3
-rw-r--r--drivers/gpu/drm/mediatek/mtk_hdmi.c6
-rw-r--r--drivers/gpu/drm/panel/Kconfig25
-rw-r--r--drivers/gpu/drm/panel/Makefile3
-rw-r--r--drivers/gpu/drm/panel/panel-orisetech-otm8009a.c491
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c532
-rw-r--r--drivers/gpu/drm/panel/panel-seiko-43wvf1g.c372
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c15
-rw-r--r--drivers/gpu/drm/pl111/Kconfig3
-rw-r--r--drivers/gpu/drm/pl111/Makefile4
-rw-r--r--drivers/gpu/drm/pl111/pl111_connector.c126
-rw-r--r--drivers/gpu/drm/pl111/pl111_debugfs.c6
-rw-r--r--drivers/gpu/drm/pl111/pl111_display.c79
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm.h37
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c149
-rw-r--r--drivers/gpu/drm/pl111/pl111_versatile.c270
-rw-r--r--drivers/gpu/drm/pl111/pl111_versatile.h9
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig8
-rw-r--r--drivers/gpu/drm/rockchip/Makefile1
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c26
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-reg.c2
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi.c86
-rw-r--r--drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c19
-rw-r--r--drivers/gpu/drm/rockchip/inno_hdmi.c14
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c14
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.h1
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fb.c8
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c18
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c32
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_lvds.c581
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_lvds.h114
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c2
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c3
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c6
-rw-r--r--drivers/gpu/drm/stm/drv.c3
-rw-r--r--drivers/gpu/drm/stm/dw_mipi_dsi-stm.c8
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c91
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.c196
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.h3
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c3
-rw-r--r--drivers/gpu/drm/tinydrm/mi0283qt.c14
-rw-r--r--drivers/gpu/drm/tinydrm/mipi-dbi.c2
-rw-r--r--drivers/gpu/drm/tinydrm/repaper.c12
-rw-r--r--drivers/gpu/drm/tinydrm/st7586.c14
-rw-r--r--drivers/gpu/drm/tve200/Kconfig16
-rw-r--r--drivers/gpu/drm/tve200/Makefile4
-rw-r--r--drivers/gpu/drm/tve200/tve200_display.c337
-rw-r--r--drivers/gpu/drm/tve200/tve200_drm.h126
-rw-r--r--drivers/gpu/drm/tve200/tve200_drv.c302
-rw-r--r--drivers/gpu/drm/vc4/Makefile2
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c15
-rw-r--r--drivers/gpu/drm/vc4/vc4_trace.h2
-rw-r--r--drivers/gpu/drm/zte/zx_drm_drv.c3
-rw-r--r--include/drm/drm_atomic.h94
-rw-r--r--include/drm/drm_bridge.h2
-rw-r--r--include/drm/drm_connector.h10
-rw-r--r--include/drm/drm_crtc.h31
-rw-r--r--include/drm/drm_dp_helper.h17
-rw-r--r--include/drm/drm_dp_mst_helper.h2
-rw-r--r--include/drm/drm_edid.h2
-rw-r--r--include/drm/drm_gem_framebuffer_helper.h2
-rw-r--r--include/drm/drm_modeset_helper_vtables.h2
-rw-r--r--include/drm/drm_modeset_lock.h12
-rw-r--r--include/drm/drm_plane.h16
-rw-r--r--include/linux/sync_file.h4
-rw-r--r--include/uapi/drm/drm_mode.h4
124 files changed, 4775 insertions, 960 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 05496622b4ef..b24108f2a438 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -854,7 +854,7 @@
854 The filter can be disabled or changed to another 854 The filter can be disabled or changed to another
855 driver later using sysfs. 855 driver later using sysfs.
856 856
857 drm_kms_helper.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>] 857 drm.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
858 Broken monitors, graphic adapters, KVMs and EDIDless 858 Broken monitors, graphic adapters, KVMs and EDIDless
859 panels may send no or incorrect EDID data sets. 859 panels may send no or incorrect EDID data sets.
860 This parameter allows to specify an EDID data sets 860 This parameter allows to specify an EDID data sets
diff --git a/Documentation/devicetree/bindings/display/faraday,tve200.txt b/Documentation/devicetree/bindings/display/faraday,tve200.txt
new file mode 100644
index 000000000000..82e3bc0b7485
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/faraday,tve200.txt
@@ -0,0 +1,54 @@
1* Faraday TV Encoder TVE200
2
3Required properties:
4
5- compatible: must be one of:
6 "faraday,tve200"
7 "cortina,gemini-tvc", "faraday,tve200"
8
9- reg: base address and size of the control registers block
10
11- interrupts: contains an interrupt specifier for the interrupt
12 line from the TVE200
13
14- clock-names: should contain "PCLK" for the clock line clocking the
15 silicon and "TVE" for the 27MHz clock to the video driver
16
17- clocks: contains phandle and clock specifier pairs for the entries
18 in the clock-names property. See
19 Documentation/devicetree/bindings/clock/clock-bindings.txt
20
21Optional properties:
22
23- resets: contains the reset line phandle for the block
24
25Required sub-nodes:
26
27- port: describes LCD panel signals, following the common binding
28 for video transmitter interfaces; see
29 Documentation/devicetree/bindings/media/video-interfaces.txt
30 This port should have the properties:
31 reg = <0>;
32 It should have one endpoint connected to a remote endpoint where
33 the display is connected.
34
35Example:
36
37display-controller@6a000000 {
38 #address-cells = <1>;
39 #size-cells = <0>;
40 compatible = "faraday,tve200";
41 reg = <0x6a000000 0x1000>;
42 interrupts = <13 IRQ_TYPE_EDGE_RISING>;
43 resets = <&syscon GEMINI_RESET_TVC>;
44 clocks = <&syscon GEMINI_CLK_GATE_TVC>,
45 <&syscon GEMINI_CLK_TVC>;
46 clock-names = "PCLK", "TVE";
47
48 port@0 {
49 reg = <0>;
50 display_out: endpoint {
51 remote-endpoint = <&panel_in>;
52 };
53 };
54};
diff --git a/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
new file mode 100644
index 000000000000..6862028e7b2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
@@ -0,0 +1,21 @@
1Orise Tech OTM8009A 3.97" 480x800 TFT LCD panel (MIPI-DSI video mode)
2
3The Orise Tech OTM8009A is a 3.97" 480x800 TFT LCD panel connected using
4a MIPI-DSI video interface. Its backlight is managed through the DSI link.
5
6Required properties:
7 - compatible: "orisetech,otm8009a"
8 - reg: the virtual channel number of a DSI peripheral
9
10Optional properties:
11 - reset-gpios: a GPIO spec for the reset pin (active low).
12
13Example:
14&dsi {
15 ...
16 panel@0 {
17 compatible = "orisetech,otm8009a";
18 reg = <0>;
19 reset-gpios = <&gpioh 7 GPIO_ACTIVE_LOW>;
20 };
21};
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt
new file mode 100644
index 000000000000..3f1a8392af7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e63j0x03.txt
@@ -0,0 +1,24 @@
1Samsung S6E63J0X03 1.63" 320x320 AMOLED panel (interface: MIPI-DSI command mode)
2
3Required properties:
4 - compatible: "samsung,s6e63j0x03"
5 - reg: the virtual channel number of a DSI peripheral
6 - vdd3-supply: I/O voltage supply
7 - vci-supply: voltage supply for analog circuits
8 - reset-gpios: a GPIO spec for the reset pin (active low)
9 - te-gpios: a GPIO spec for the tearing effect synchronization signal
10 gpio pin (active high)
11
12Example:
13&dsi {
14 ...
15
16 panel@0 {
17 compatible = "samsung,s6e63j0x03";
18 reg = <0>;
19 vdd3-supply = <&ldo16_reg>;
20 vci-supply = <&ldo20_reg>;
21 reset-gpios = <&gpe0 1 GPIO_ACTIVE_LOW>;
22 te-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>;
23 };
24};
diff --git a/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt b/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
new file mode 100644
index 000000000000..aae57ef36cdd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/seiko,43wvf1g.txt
@@ -0,0 +1,23 @@
1Seiko Instruments Inc. 4.3" WVGA (800 x RGB x 480) TFT with Touch-Panel
2
3Required properties:
4- compatible: should be "sii,43wvf1g".
5- "dvdd-supply": 3v3 digital regulator.
6- "avdd-supply": 5v analog regulator.
7
8Optional properties:
9- backlight: phandle for the backlight control.
10
11Example:
12
13 panel {
14 compatible = "sii,43wvf1g";
15 backlight = <&backlight_display>;
16 dvdd-supply = <&reg_lcd_3v3>;
17 avdd-supply = <&reg_lcd_5v>;
18 port {
19 panel_in: endpoint {
20 remote-endpoint = <&display_out>;
21 };
22 };
23 };
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt
new file mode 100644
index 000000000000..da6939efdb43
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt
@@ -0,0 +1,99 @@
1Rockchip RK3288 LVDS interface
2================================
3
4Required properties:
5- compatible: matching the soc type, one of
6 - "rockchip,rk3288-lvds";
7
8- reg: physical base address of the controller and length
9 of memory mapped region.
10- clocks: must include clock specifiers corresponding to entries in the
11 clock-names property.
12- clock-names: must contain "pclk_lvds"
13
14- avdd1v0-supply: regulator phandle for 1.0V analog power
15- avdd1v8-supply: regulator phandle for 1.8V analog power
16- avdd3v3-supply: regulator phandle for 3.3V analog power
17
18- rockchip,grf: phandle to the general register files syscon
19- rockchip,output: "rgb", "lvds" or "duallvds", This describes the output interface
20
21Optional properties:
22- pinctrl-names: must contain a "lcdc" entry.
23- pinctrl-0: pin control group to be used for this controller.
24
25Required nodes:
26
27The lvds has two video ports as described by
28 Documentation/devicetree/bindings/media/video-interfaces.txt
29Their connections are modeled using the OF graph bindings specified in
30 Documentation/devicetree/bindings/graph.txt.
31
32- video port 0 for the VOP input, the remote endpoint maybe vopb or vopl
33- video port 1 for either a panel or subsequent encoder
34
35the lvds panel described by
36 Documentation/devicetree/bindings/display/panel/simple-panel.txt
37
38Panel required properties:
39- ports for remote LVDS output
40
41Panel optional properties:
42- data-mapping: should be "vesa-24","jeida-24" or "jeida-18".
43This describes decribed by:
44 Documentation/devicetree/bindings/display/panel/panel-lvds.txt
45
46Example:
47
48lvds_panel: lvds-panel {
49 compatible = "auo,b101ean01";
50 enable-gpios = <&gpio7 21 GPIO_ACTIVE_HIGH>;
51 data-mapping = "jeida-24";
52
53 ports {
54 panel_in_lvds: endpoint {
55 remote-endpoint = <&lvds_out_panel>;
56 };
57 };
58};
59
60For Rockchip RK3288:
61
62 lvds: lvds@ff96c000 {
63 compatible = "rockchip,rk3288-lvds";
64 rockchip,grf = <&grf>;
65 reg = <0xff96c000 0x4000>;
66 clocks = <&cru PCLK_LVDS_PHY>;
67 clock-names = "pclk_lvds";
68 pinctrl-names = "lcdc";
69 pinctrl-0 = <&lcdc_ctl>;
70 avdd1v0-supply = <&vdd10_lcd>;
71 avdd1v8-supply = <&vcc18_lcd>;
72 avdd3v3-supply = <&vcca_33>;
73 rockchip,output = "rgb";
74 ports {
75 #address-cells = <1>;
76 #size-cells = <0>;
77
78 lvds_in: port@0 {
79 reg = <0>;
80
81 lvds_in_vopb: endpoint@0 {
82 reg = <0>;
83 remote-endpoint = <&vopb_out_lvds>;
84 };
85 lvds_in_vopl: endpoint@1 {
86 reg = <1>;
87 remote-endpoint = <&vopl_out_lvds>;
88 };
89 };
90
91 lvds_out: port@1 {
92 reg = <1>;
93
94 lvds_out_panel: endpoint {
95 remote-endpoint = <&panel_in_lvds>;
96 };
97 };
98 };
99 };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 1afd298eddd7..6cf1dc5bc77e 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -248,6 +248,7 @@ ontat On Tat Industrial Company
248opencores OpenCores.org 248opencores OpenCores.org
249option Option NV 249option Option NV
250ORCL Oracle Corporation 250ORCL Oracle Corporation
251orisetech Orise Technology
251ortustech Ortus Technology Co., Ltd. 252ortustech Ortus Technology Co., Ltd.
252ovti OmniVision Technologies 253ovti OmniVision Technologies
253oxsemi Oxford Semiconductor, Ltd. 254oxsemi Oxford Semiconductor, Ltd.
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
index 679373b4a03f..a2214cc1f821 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -168,6 +168,61 @@ IOCTL Support on Device Nodes
168.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c 168.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
169 :doc: driver specific ioctls 169 :doc: driver specific ioctls
170 170
171Recommended IOCTL Return Values
172-------------------------------
173
174In theory a driver's IOCTL callback is only allowed to return very few error
175codes. In practice it's good to abuse a few more. This section documents common
176practice within the DRM subsystem:
177
178ENOENT:
179 Strictly this should only be used when a file doesn't exist e.g. when
180 calling the open() syscall. We reuse that to signal any kind of object
181 lookup failure, e.g. for unknown GEM buffer object handles, unknown KMS
182 object handles and similar cases.
183
184ENOSPC:
185 Some drivers use this to differentiate "out of kernel memory" from "out
186 of VRAM". Sometimes also applies to other limited gpu resources used for
187 rendering (e.g. when you have a special limited compression buffer).
188 Sometimes resource allocation/reservation issues in command submission
189 IOCTLs are also signalled through EDEADLK.
190
191 Simply running out of kernel/system memory is signalled through ENOMEM.
192
193EPERM/EACCESS:
194 Returned for an operation that is valid, but needs more privileges.
195 E.g. root-only or much more common, DRM master-only operations return
196 this when when called by unpriviledged clients. There's no clear
197 difference between EACCESS and EPERM.
198
199ENODEV:
200 Feature (like PRIME, modesetting, GEM) is not supported by the driver.
201
202ENXIO:
203 Remote failure, either a hardware transaction (like i2c), but also used
204 when the exporting driver of a shared dma-buf or fence doesn't support a
205 feature needed.
206
207EINTR:
208 DRM drivers assume that userspace restarts all IOCTLs. Any DRM IOCTL can
209 return EINTR and in such a case should be restarted with the IOCTL
210 parameters left unchanged.
211
212EIO:
213 The GPU died and couldn't be resurrected through a reset. Modesetting
214 hardware failures are signalled through the "link status" connector
215 property.
216
217EINVAL:
218 Catch-all for anything that is an invalid argument combination which
219 cannot work.
220
221IOCTL also use other error codes like ETIME, EFAULT, EBUSY, ENOTTY but their
222usage is in line with the common meanings. The above list tries to just document
223DRM specific patterns. Note that ENOTTY has the slightly unintuitive meaning of
224"this IOCTL does not exist", and is used exactly as such in DRM.
225
171.. kernel-doc:: include/drm/drm_ioctl.h 226.. kernel-doc:: include/drm/drm_ioctl.h
172 :internal: 227 :internal:
173 228
diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst
index 35d673bf9b56..c36586dad29d 100644
--- a/Documentation/gpu/index.rst
+++ b/Documentation/gpu/index.rst
@@ -15,6 +15,7 @@ Linux GPU Driver Developer's Guide
15 pl111 15 pl111
16 tegra 16 tegra
17 tinydrm 17 tinydrm
18 tve200
18 vc4 19 vc4
19 vga-switcheroo 20 vga-switcheroo
20 vgaarbiter 21 vgaarbiter
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 22af55d06ab8..de9512afd611 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -75,17 +75,6 @@ helpers.
75 75
76Contact: Ville Syrjälä, Daniel Vetter, driver maintainers 76Contact: Ville Syrjälä, Daniel Vetter, driver maintainers
77 77
78Implement deferred fbdev setup in the helper
79--------------------------------------------
80
81Many (especially embedded drivers) want to delay fbdev setup until there's a
82real screen plugged in. This is to avoid the dreaded fallback to the low-res
83fbdev default. Many drivers have a hacked-up (and often broken) version of this,
84better to do it once in the shared helpers. Thierry has a patch series, but that
85one needs to be rebased and final polish applied.
86
87Contact: Thierry Reding, Daniel Vetter, driver maintainers
88
89Convert early atomic drivers to async commit helpers 78Convert early atomic drivers to async commit helpers
90---------------------------------------------------- 79----------------------------------------------------
91 80
@@ -138,6 +127,8 @@ interfaces to fix these issues:
138 the acquire context explicitly on stack and then also pass it down into 127 the acquire context explicitly on stack and then also pass it down into
139 drivers explicitly so that the legacy-on-atomic functions can use them. 128 drivers explicitly so that the legacy-on-atomic functions can use them.
140 129
130 Except for some driver code this is done.
131
141* A bunch of the vtable hooks are now in the wrong place: DRM has a split 132* A bunch of the vtable hooks are now in the wrong place: DRM has a split
142 between core vfunc tables (named ``drm_foo_funcs``), which are used to 133 between core vfunc tables (named ``drm_foo_funcs``), which are used to
143 implement the userspace ABI. And then there's the optional hooks for the 134 implement the userspace ABI. And then there's the optional hooks for the
@@ -151,6 +142,8 @@ interfaces to fix these issues:
151 connector at runtime. That's almost all of them, and would allow us to get 142 connector at runtime. That's almost all of them, and would allow us to get
152 rid of a lot of ``best_encoder`` boilerplate in drivers. 143 rid of a lot of ``best_encoder`` boilerplate in drivers.
153 144
145 This was almost done, but new drivers added a few more cases again.
146
154Contact: Daniel Vetter 147Contact: Daniel Vetter
155 148
156Get rid of dev->struct_mutex from GEM drivers 149Get rid of dev->struct_mutex from GEM drivers
@@ -177,6 +170,17 @@ following drivers still use ``struct_mutex``: ``msm``, ``omapdrm`` and
177 170
178Contact: Daniel Vetter, respective driver maintainers 171Contact: Daniel Vetter, respective driver maintainers
179 172
173Convert instances of dev_info/dev_err/dev_warn to their DRM_DEV_* equivalent
174----------------------------------------------------------------------------
175
176For drivers which could have multiple instances, it is necessary to
177differentiate between which is which in the logs. Since DRM_INFO/WARN/ERROR
178don't do this, drivers used dev_info/warn/err to make this differentiation. We
179now have DRM_DEV_* variants of the drm print macros, so we can start to convert
180those drivers back to using drm-formwatted specific log messages.
181
182Contact: Sean Paul, Maintainer of the driver you plan to convert
183
180Core refactorings 184Core refactorings
181================= 185=================
182 186
diff --git a/Documentation/gpu/tve200.rst b/Documentation/gpu/tve200.rst
new file mode 100644
index 000000000000..69b17b324e12
--- /dev/null
+++ b/Documentation/gpu/tve200.rst
@@ -0,0 +1,6 @@
1==================================
2 drm/tve200 Faraday TV Encoder 200
3==================================
4
5.. kernel-doc:: drivers/gpu/drm/tve200/tve200_drv.c
6 :doc: Faraday TV Encoder 200
diff --git a/MAINTAINERS b/MAINTAINERS
index 6671f375f7fc..7ab4c373c370 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4366,6 +4366,12 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
4366S: Maintained 4366S: Maintained
4367F: drivers/gpu/drm/bochs/ 4367F: drivers/gpu/drm/bochs/
4368 4368
4369DRM DRIVER FOR FARADAY TVE200 TV ENCODER
4370M: Linus Walleij <linus.walleij@linaro.org>
4371T: git git://anongit.freedesktop.org/drm/drm-misc
4372S: Maintained
4373F: drivers/gpu/drm/tve200/
4374
4369DRM DRIVER FOR INTEL I810 VIDEO CARDS 4375DRM DRIVER FOR INTEL I810 VIDEO CARDS
4370S: Orphan / Obsolete 4376S: Orphan / Obsolete
4371F: drivers/gpu/drm/i810/ 4377F: drivers/gpu/drm/i810/
@@ -4509,7 +4515,7 @@ L: dri-devel@lists.freedesktop.org
4509S: Supported 4515S: Supported
4510F: drivers/gpu/drm/sun4i/ 4516F: drivers/gpu/drm/sun4i/
4511F: Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt 4517F: Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
4512T: git git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git 4518T: git git://anongit.freedesktop.org/drm/drm-misc
4513 4519
4514DRM DRIVERS FOR AMLOGIC SOCS 4520DRM DRIVERS FOR AMLOGIC SOCS
4515M: Neil Armstrong <narmstrong@baylibre.com> 4521M: Neil Armstrong <narmstrong@baylibre.com>
@@ -4693,7 +4699,7 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
4693DRM PANEL DRIVERS 4699DRM PANEL DRIVERS
4694M: Thierry Reding <thierry.reding@gmail.com> 4700M: Thierry Reding <thierry.reding@gmail.com>
4695L: dri-devel@lists.freedesktop.org 4701L: dri-devel@lists.freedesktop.org
4696T: git git://anongit.freedesktop.org/tegra/linux.git 4702T: git git://anongit.freedesktop.org/drm/drm-misc
4697S: Maintained 4703S: Maintained
4698F: drivers/gpu/drm/drm_panel.c 4704F: drivers/gpu/drm/drm_panel.c
4699F: drivers/gpu/drm/panel/ 4705F: drivers/gpu/drm/panel/
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 38cc7389a6c1..24f83f9eeaed 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -321,8 +321,16 @@ static int sw_sync_debugfs_open(struct inode *inode, struct file *file)
321static int sw_sync_debugfs_release(struct inode *inode, struct file *file) 321static int sw_sync_debugfs_release(struct inode *inode, struct file *file)
322{ 322{
323 struct sync_timeline *obj = file->private_data; 323 struct sync_timeline *obj = file->private_data;
324 struct sync_pt *pt, *next;
325
326 spin_lock_irq(&obj->lock);
327
328 list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
329 dma_fence_set_error(&pt->base, -ENOENT);
330 dma_fence_signal_locked(&pt->base);
331 }
324 332
325 smp_wmb(); 333 spin_unlock_irq(&obj->lock);
326 334
327 sync_timeline_put(obj); 335 sync_timeline_put(obj);
328 return 0; 336 return 0;
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 83cb2a88c204..c9f09fc298bb 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -110,7 +110,7 @@ config DRM_FBDEV_OVERALLOC
110 110
111config DRM_LOAD_EDID_FIRMWARE 111config DRM_LOAD_EDID_FIRMWARE
112 bool "Allow to specify an EDID data set instead of probing for it" 112 bool "Allow to specify an EDID data set instead of probing for it"
113 depends on DRM_KMS_HELPER 113 depends on DRM
114 help 114 help
115 Say Y here, if you want to use EDID data to be loaded from the 115 Say Y here, if you want to use EDID data to be loaded from the
116 /lib/firmware directory or one of the provided built-in 116 /lib/firmware directory or one of the provided built-in
@@ -278,6 +278,8 @@ source "drivers/gpu/drm/tinydrm/Kconfig"
278 278
279source "drivers/gpu/drm/pl111/Kconfig" 279source "drivers/gpu/drm/pl111/Kconfig"
280 280
281source "drivers/gpu/drm/tve200/Kconfig"
282
281# Keep legacy drivers last 283# Keep legacy drivers last
282 284
283menuconfig DRM_LEGACY 285menuconfig DRM_LEGACY
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index a8acc197dec3..0ee184f56a60 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -28,6 +28,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o
28drm-$(CONFIG_OF) += drm_of.o 28drm-$(CONFIG_OF) += drm_of.o
29drm-$(CONFIG_AGP) += drm_agpsupport.o 29drm-$(CONFIG_AGP) += drm_agpsupport.o
30drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o 30drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
31drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
31 32
32drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ 33drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
33 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ 34 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
@@ -36,7 +37,6 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
36 drm_scdc_helper.o drm_gem_framebuffer_helper.o 37 drm_scdc_helper.o drm_gem_framebuffer_helper.o
37 38
38drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o 39drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
39drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
40drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o 40drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
41drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o 41drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
42drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o 42drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
@@ -44,8 +44,6 @@ drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
44obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o 44obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
45obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/ 45obj-$(CONFIG_DRM_DEBUG_MM_SELFTEST) += selftests/
46 46
47CFLAGS_drm_trace_points.o := -I$(src)
48
49obj-$(CONFIG_DRM) += drm.o 47obj-$(CONFIG_DRM) += drm.o
50obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o 48obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
51obj-$(CONFIG_DRM_ARM) += arm/ 49obj-$(CONFIG_DRM_ARM) += arm/
@@ -100,3 +98,4 @@ obj-$(CONFIG_DRM_ZTE) += zte/
100obj-$(CONFIG_DRM_MXSFB) += mxsfb/ 98obj-$(CONFIG_DRM_MXSFB) += mxsfb/
101obj-$(CONFIG_DRM_TINYDRM) += tinydrm/ 99obj-$(CONFIG_DRM_TINYDRM) += tinydrm/
102obj-$(CONFIG_DRM_PL111) += pl111/ 100obj-$(CONFIG_DRM_PL111) += pl111/
101obj-$(CONFIG_DRM_TVE200) += tve200/
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 289eda54e5aa..074fd4ea7ece 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -18,6 +18,7 @@
18#include <drm/drm_crtc_helper.h> 18#include <drm/drm_crtc_helper.h>
19#include <drm/drm_fb_cma_helper.h> 19#include <drm/drm_fb_cma_helper.h>
20#include <drm/drm_gem_cma_helper.h> 20#include <drm/drm_gem_cma_helper.h>
21#include <drm/drm_gem_framebuffer_helper.h>
21#include <drm/drm_atomic_helper.h> 22#include <drm/drm_atomic_helper.h>
22#include <linux/of_reserved_mem.h> 23#include <linux/of_reserved_mem.h>
23 24
@@ -32,7 +33,7 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev)
32} 33}
33 34
34static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = { 35static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
35 .fb_create = drm_fb_cma_create, 36 .fb_create = drm_gem_fb_create,
36 .output_poll_changed = arcpgu_fb_output_poll_changed, 37 .output_poll_changed = arcpgu_fb_output_poll_changed,
37 .atomic_check = drm_atomic_helper_check, 38 .atomic_check = drm_atomic_helper_check,
38 .atomic_commit = drm_atomic_helper_commit, 39 .atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index f9bda7b0d2ec..764d0c83710c 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -25,6 +25,7 @@
25#include <drm/drm_fb_helper.h> 25#include <drm/drm_fb_helper.h>
26#include <drm/drm_fb_cma_helper.h> 26#include <drm/drm_fb_cma_helper.h>
27#include <drm/drm_gem_cma_helper.h> 27#include <drm/drm_gem_cma_helper.h>
28#include <drm/drm_gem_framebuffer_helper.h>
28#include <drm/drm_of.h> 29#include <drm/drm_of.h>
29 30
30#include "hdlcd_drv.h" 31#include "hdlcd_drv.h"
@@ -106,7 +107,7 @@ static void hdlcd_fb_output_poll_changed(struct drm_device *drm)
106} 107}
107 108
108static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = { 109static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
109 .fb_create = drm_fb_cma_create, 110 .fb_create = drm_gem_fb_create,
110 .output_poll_changed = hdlcd_fb_output_poll_changed, 111 .output_poll_changed = hdlcd_fb_output_poll_changed,
111 .atomic_check = drm_atomic_helper_check, 112 .atomic_check = drm_atomic_helper_check,
112 .atomic_commit = drm_atomic_helper_commit, 113 .atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 1a57cc28955e..b8944666a18f 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -26,6 +26,7 @@
26#include <drm/drm_crtc_helper.h> 26#include <drm/drm_crtc_helper.h>
27#include <drm/drm_fb_cma_helper.h> 27#include <drm/drm_fb_cma_helper.h>
28#include <drm/drm_gem_cma_helper.h> 28#include <drm/drm_gem_cma_helper.h>
29#include <drm/drm_gem_framebuffer_helper.h>
29#include <drm/drm_of.h> 30#include <drm/drm_of.h>
30 31
31#include "malidp_drv.h" 32#include "malidp_drv.h"
@@ -249,7 +250,7 @@ static const struct drm_mode_config_helper_funcs malidp_mode_config_helpers = {
249}; 250};
250 251
251static const struct drm_mode_config_funcs malidp_mode_config_funcs = { 252static const struct drm_mode_config_funcs malidp_mode_config_funcs = {
252 .fb_create = drm_fb_cma_create, 253 .fb_create = drm_gem_fb_create,
253 .output_poll_changed = malidp_output_poll_changed, 254 .output_poll_changed = malidp_output_poll_changed,
254 .atomic_check = drm_atomic_helper_check, 255 .atomic_check = drm_atomic_helper_check,
255 .atomic_commit = drm_atomic_helper_commit, 256 .atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile
index 64c0b4546fb2..a18f156c8b66 100644
--- a/drivers/gpu/drm/armada/Makefile
+++ b/drivers/gpu/drm/armada/Makefile
@@ -4,5 +4,3 @@ armada-y += armada_510.o
4armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o 4armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
5 5
6obj-$(CONFIG_DRM_ARMADA) := armada.o 6obj-$(CONFIG_DRM_ARMADA) := armada.o
7
8CFLAGS_armada_trace.o := -I$(src)
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 0b3227c039d7..2fbd9d3393e8 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -70,8 +70,6 @@ static struct drm_driver armada_drm_driver = {
70 .gem_prime_export = armada_gem_prime_export, 70 .gem_prime_export = armada_gem_prime_export,
71 .gem_prime_import = armada_gem_prime_import, 71 .gem_prime_import = armada_gem_prime_import,
72 .dumb_create = armada_gem_dumb_create, 72 .dumb_create = armada_gem_dumb_create,
73 .dumb_map_offset = armada_gem_dumb_map_offset,
74 .dumb_destroy = armada_gem_dumb_destroy,
75 .gem_vm_ops = &armada_gem_vm_ops, 73 .gem_vm_ops = &armada_gem_vm_ops,
76 .major = 1, 74 .major = 1,
77 .minor = 0, 75 .minor = 0,
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index a76ca21d063b..79835380d5c6 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -270,42 +270,6 @@ int armada_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
270 return ret; 270 return ret;
271} 271}
272 272
273int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
274 uint32_t handle, uint64_t *offset)
275{
276 struct armada_gem_object *obj;
277 int ret = 0;
278
279 obj = armada_gem_object_lookup(file, handle);
280 if (!obj) {
281 DRM_ERROR("failed to lookup gem object\n");
282 return -EINVAL;
283 }
284
285 /* Don't allow imported objects to be mapped */
286 if (obj->obj.import_attach) {
287 ret = -EINVAL;
288 goto err_unref;
289 }
290
291 ret = drm_gem_create_mmap_offset(&obj->obj);
292 if (ret == 0) {
293 *offset = drm_vma_node_offset_addr(&obj->obj.vma_node);
294 DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset);
295 }
296
297 err_unref:
298 drm_gem_object_unreference_unlocked(&obj->obj);
299
300 return ret;
301}
302
303int armada_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
304 uint32_t handle)
305{
306 return drm_gem_handle_delete(file, handle);
307}
308
309/* Private driver gem ioctls */ 273/* Private driver gem ioctls */
310int armada_gem_create_ioctl(struct drm_device *dev, void *data, 274int armada_gem_create_ioctl(struct drm_device *dev, void *data,
311 struct drm_file *file) 275 struct drm_file *file)
diff --git a/drivers/gpu/drm/armada/armada_gem.h b/drivers/gpu/drm/armada/armada_gem.h
index 6e524e0676bb..1ac90792b166 100644
--- a/drivers/gpu/drm/armada/armada_gem.h
+++ b/drivers/gpu/drm/armada/armada_gem.h
@@ -35,10 +35,6 @@ struct armada_gem_object *armada_gem_alloc_private_object(struct drm_device *,
35 size_t); 35 size_t);
36int armada_gem_dumb_create(struct drm_file *, struct drm_device *, 36int armada_gem_dumb_create(struct drm_file *, struct drm_device *,
37 struct drm_mode_create_dumb *); 37 struct drm_mode_create_dumb *);
38int armada_gem_dumb_map_offset(struct drm_file *, struct drm_device *,
39 uint32_t, uint64_t *);
40int armada_gem_dumb_destroy(struct drm_file *, struct drm_device *,
41 uint32_t);
42struct dma_buf *armada_gem_prime_export(struct drm_device *dev, 38struct dma_buf *armada_gem_prime_export(struct drm_device *dev,
43 struct drm_gem_object *obj, int flags); 39 struct drm_gem_object *obj, int flags);
44struct drm_gem_object *armada_gem_prime_import(struct drm_device *, 40struct drm_gem_object *armada_gem_prime_import(struct drm_device *,
diff --git a/drivers/gpu/drm/armada/armada_trace.h b/drivers/gpu/drm/armada/armada_trace.h
index dc0cba70fd1a..be245a24610f 100644
--- a/drivers/gpu/drm/armada/armada_trace.h
+++ b/drivers/gpu/drm/armada/armada_trace.h
@@ -62,5 +62,5 @@ TRACE_EVENT(armada_ovl_plane_work,
62 62
63/* This part must be outside protection */ 63/* This part must be outside protection */
64#undef TRACE_INCLUDE_PATH 64#undef TRACE_INCLUDE_PATH
65#define TRACE_INCLUDE_PATH . 65#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/armada
66#include <trace/define_trace.h> 66#include <trace/define_trace.h>
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 74d66e11f688..c6e8061ffcfc 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -458,7 +458,7 @@ static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data)
458static struct drm_framebuffer *atmel_hlcdc_fb_create(struct drm_device *dev, 458static struct drm_framebuffer *atmel_hlcdc_fb_create(struct drm_device *dev,
459 struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) 459 struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd)
460{ 460{
461 return drm_fb_cma_create(dev, file_priv, mode_cmd); 461 return drm_gem_fb_create(dev, file_priv, mode_cmd);
462} 462}
463 463
464static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev) 464static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index 4237b0446721..6833ee253cfa 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -34,6 +34,7 @@
34#include <drm/drm_crtc_helper.h> 34#include <drm/drm_crtc_helper.h>
35#include <drm/drm_fb_cma_helper.h> 35#include <drm/drm_fb_cma_helper.h>
36#include <drm/drm_gem_cma_helper.h> 36#include <drm/drm_gem_cma_helper.h>
37#include <drm/drm_gem_framebuffer_helper.h>
37#include <drm/drm_panel.h> 38#include <drm/drm_panel.h>
38#include <drm/drm_plane_helper.h> 39#include <drm/drm_plane_helper.h>
39#include <drm/drmP.h> 40#include <drm/drmP.h>
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index fe18a5d2d84b..12ef2d8ee110 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -328,8 +328,6 @@ struct adv7511 {
328 enum adv7511_sync_polarity hsync_polarity; 328 enum adv7511_sync_polarity hsync_polarity;
329 bool rgb; 329 bool rgb;
330 330
331 struct edid *edid;
332
333 struct gpio_desc *gpio_pd; 331 struct gpio_desc *gpio_pd;
334 332
335 struct regulator_bulk_data *supplies; 333 struct regulator_bulk_data *supplies;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
index 67469c26bae8..1b4783d45c53 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -210,7 +210,7 @@ static const struct hdmi_codec_ops adv7511_codec_ops = {
210 .get_dai_id = adv7511_hdmi_i2s_get_dai_id, 210 .get_dai_id = adv7511_hdmi_i2s_get_dai_id,
211}; 211};
212 212
213static struct hdmi_codec_pdata codec_data = { 213static const struct hdmi_codec_pdata codec_data = {
214 .ops = &adv7511_codec_ops, 214 .ops = &adv7511_codec_ops,
215 .max_i2s_channels = 2, 215 .max_i2s_channels = 2,
216 .i2s = 1, 216 .i2s = 1,
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index b2431aee7887..bd7dbae1119e 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -199,17 +199,14 @@ static const uint16_t adv7511_csc_ycbcr_to_rgb[] = {
199 199
200static void adv7511_set_config_csc(struct adv7511 *adv7511, 200static void adv7511_set_config_csc(struct adv7511 *adv7511,
201 struct drm_connector *connector, 201 struct drm_connector *connector,
202 bool rgb) 202 bool rgb, bool hdmi_mode)
203{ 203{
204 struct adv7511_video_config config; 204 struct adv7511_video_config config;
205 bool output_format_422, output_format_ycbcr; 205 bool output_format_422, output_format_ycbcr;
206 unsigned int mode; 206 unsigned int mode;
207 uint8_t infoframe[17]; 207 uint8_t infoframe[17];
208 208
209 if (adv7511->edid) 209 config.hdmi_mode = hdmi_mode;
210 config.hdmi_mode = drm_detect_hdmi_monitor(adv7511->edid);
211 else
212 config.hdmi_mode = false;
213 210
214 hdmi_avi_infoframe_init(&config.avi_infoframe); 211 hdmi_avi_infoframe_init(&config.avi_infoframe);
215 212
@@ -589,15 +586,14 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
589 if (!adv7511->powered) 586 if (!adv7511->powered)
590 __adv7511_power_off(adv7511); 587 __adv7511_power_off(adv7511);
591 588
592 kfree(adv7511->edid);
593 adv7511->edid = edid;
594 if (!edid)
595 return 0;
596 589
597 drm_mode_connector_update_edid_property(connector, edid); 590 drm_mode_connector_update_edid_property(connector, edid);
598 count = drm_add_edid_modes(connector, edid); 591 count = drm_add_edid_modes(connector, edid);
599 592
600 adv7511_set_config_csc(adv7511, connector, adv7511->rgb); 593 adv7511_set_config_csc(adv7511, connector, adv7511->rgb,
594 drm_detect_hdmi_monitor(edid));
595
596 kfree(edid);
601 597
602 return count; 598 return count;
603} 599}
@@ -833,7 +829,11 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
833 return -ENODEV; 829 return -ENODEV;
834 } 830 }
835 831
836 adv->connector.polled = DRM_CONNECTOR_POLL_HPD; 832 if (adv->i2c_main->irq)
833 adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
834 else
835 adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
836 DRM_CONNECTOR_POLL_DISCONNECT;
837 837
838 ret = drm_connector_init(bridge->dev, &adv->connector, 838 ret = drm_connector_init(bridge->dev, &adv->connector,
839 &adv7511_connector_funcs, 839 &adv7511_connector_funcs,
@@ -1158,8 +1158,6 @@ static int adv7511_remove(struct i2c_client *i2c)
1158 1158
1159 i2c_unregister_device(adv7511->i2c_edid); 1159 i2c_unregister_device(adv7511->i2c_edid);
1160 1160
1161 kfree(adv7511->edid);
1162
1163 return 0; 1161 return 0;
1164} 1162}
1165 1163
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 63c7a01b7053..f4f633a0dffa 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -30,19 +30,20 @@
30#include <video/mipi_display.h> 30#include <video/mipi_display.h>
31 31
32#define DSI_VERSION 0x00 32#define DSI_VERSION 0x00
33
33#define DSI_PWR_UP 0x04 34#define DSI_PWR_UP 0x04
34#define RESET 0 35#define RESET 0
35#define POWERUP BIT(0) 36#define POWERUP BIT(0)
36 37
37#define DSI_CLKMGR_CFG 0x08 38#define DSI_CLKMGR_CFG 0x08
38#define TO_CLK_DIVIDSION(div) (((div) & 0xff) << 8) 39#define TO_CLK_DIVISION(div) (((div) & 0xff) << 8)
39#define TX_ESC_CLK_DIVIDSION(div) (((div) & 0xff) << 0) 40#define TX_ESC_CLK_DIVISION(div) ((div) & 0xff)
40 41
41#define DSI_DPI_VCID 0x0c 42#define DSI_DPI_VCID 0x0c
42#define DPI_VID(vid) (((vid) & 0x3) << 0) 43#define DPI_VCID(vcid) ((vcid) & 0x3)
43 44
44#define DSI_DPI_COLOR_CODING 0x10 45#define DSI_DPI_COLOR_CODING 0x10
45#define EN18_LOOSELY BIT(8) 46#define LOOSELY18_EN BIT(8)
46#define DPI_COLOR_CODING_16BIT_1 0x0 47#define DPI_COLOR_CODING_16BIT_1 0x0
47#define DPI_COLOR_CODING_16BIT_2 0x1 48#define DPI_COLOR_CODING_16BIT_2 0x1
48#define DPI_COLOR_CODING_16BIT_3 0x2 49#define DPI_COLOR_CODING_16BIT_3 0x2
@@ -61,22 +62,25 @@
61#define OUTVACT_LPCMD_TIME(p) (((p) & 0xff) << 16) 62#define OUTVACT_LPCMD_TIME(p) (((p) & 0xff) << 16)
62#define INVACT_LPCMD_TIME(p) ((p) & 0xff) 63#define INVACT_LPCMD_TIME(p) ((p) & 0xff)
63 64
65#define DSI_DBI_VCID 0x1c
64#define DSI_DBI_CFG 0x20 66#define DSI_DBI_CFG 0x20
67#define DSI_DBI_PARTITIONING_EN 0x24
65#define DSI_DBI_CMDSIZE 0x28 68#define DSI_DBI_CMDSIZE 0x28
66 69
67#define DSI_PCKHDL_CFG 0x2c 70#define DSI_PCKHDL_CFG 0x2c
68#define EN_CRC_RX BIT(4) 71#define CRC_RX_EN BIT(4)
69#define EN_ECC_RX BIT(3) 72#define ECC_RX_EN BIT(3)
70#define EN_BTA BIT(2) 73#define BTA_EN BIT(2)
71#define EN_EOTP_RX BIT(1) 74#define EOTP_RX_EN BIT(1)
72#define EN_EOTP_TX BIT(0) 75#define EOTP_TX_EN BIT(0)
76
77#define DSI_GEN_VCID 0x30
73 78
74#define DSI_MODE_CFG 0x34 79#define DSI_MODE_CFG 0x34
75#define ENABLE_VIDEO_MODE 0 80#define ENABLE_VIDEO_MODE 0
76#define ENABLE_CMD_MODE BIT(0) 81#define ENABLE_CMD_MODE BIT(0)
77 82
78#define DSI_VID_MODE_CFG 0x38 83#define DSI_VID_MODE_CFG 0x38
79#define FRAME_BTA_ACK BIT(14)
80#define ENABLE_LOW_POWER (0x3f << 8) 84#define ENABLE_LOW_POWER (0x3f << 8)
81#define ENABLE_LOW_POWER_MASK (0x3f << 8) 85#define ENABLE_LOW_POWER_MASK (0x3f << 8)
82#define VID_MODE_TYPE_NON_BURST_SYNC_PULSES 0x0 86#define VID_MODE_TYPE_NON_BURST_SYNC_PULSES 0x0
@@ -85,8 +89,13 @@
85#define VID_MODE_TYPE_MASK 0x3 89#define VID_MODE_TYPE_MASK 0x3
86 90
87#define DSI_VID_PKT_SIZE 0x3c 91#define DSI_VID_PKT_SIZE 0x3c
88#define VID_PKT_SIZE(p) (((p) & 0x3fff) << 0) 92#define VID_PKT_SIZE(p) ((p) & 0x3fff)
89#define VID_PKT_MAX_SIZE 0x3fff 93
94#define DSI_VID_NUM_CHUNKS 0x40
95#define VID_NUM_CHUNKS(c) ((c) & 0x1fff)
96
97#define DSI_VID_NULL_SIZE 0x44
98#define VID_NULL_SIZE(b) ((b) & 0x1fff)
90 99
91#define DSI_VID_HSA_TIME 0x48 100#define DSI_VID_HSA_TIME 0x48
92#define DSI_VID_HBP_TIME 0x4c 101#define DSI_VID_HBP_TIME 0x4c
@@ -95,6 +104,8 @@
95#define DSI_VID_VBP_LINES 0x58 104#define DSI_VID_VBP_LINES 0x58
96#define DSI_VID_VFP_LINES 0x5c 105#define DSI_VID_VFP_LINES 0x5c
97#define DSI_VID_VACTIVE_LINES 0x60 106#define DSI_VID_VACTIVE_LINES 0x60
107#define DSI_EDPI_CMD_SIZE 0x64
108
98#define DSI_CMD_MODE_CFG 0x68 109#define DSI_CMD_MODE_CFG 0x68
99#define MAX_RD_PKT_SIZE_LP BIT(24) 110#define MAX_RD_PKT_SIZE_LP BIT(24)
100#define DCS_LW_TX_LP BIT(19) 111#define DCS_LW_TX_LP BIT(19)
@@ -108,8 +119,8 @@
108#define GEN_SW_2P_TX_LP BIT(10) 119#define GEN_SW_2P_TX_LP BIT(10)
109#define GEN_SW_1P_TX_LP BIT(9) 120#define GEN_SW_1P_TX_LP BIT(9)
110#define GEN_SW_0P_TX_LP BIT(8) 121#define GEN_SW_0P_TX_LP BIT(8)
111#define EN_ACK_RQST BIT(1) 122#define ACK_RQST_EN BIT(1)
112#define EN_TEAR_FX BIT(0) 123#define TEAR_FX_EN BIT(0)
113 124
114#define CMD_MODE_ALL_LP (MAX_RD_PKT_SIZE_LP | \ 125#define CMD_MODE_ALL_LP (MAX_RD_PKT_SIZE_LP | \
115 DCS_LW_TX_LP | \ 126 DCS_LW_TX_LP | \
@@ -125,27 +136,31 @@
125 GEN_SW_0P_TX_LP) 136 GEN_SW_0P_TX_LP)
126 137
127#define DSI_GEN_HDR 0x6c 138#define DSI_GEN_HDR 0x6c
139/* TODO These 2 defines will be reworked thanks to mipi_dsi_create_packet() */
128#define GEN_HDATA(data) (((data) & 0xffff) << 8) 140#define GEN_HDATA(data) (((data) & 0xffff) << 8)
129#define GEN_HDATA_MASK (0xffff << 8)
130#define GEN_HTYPE(type) (((type) & 0xff) << 0) 141#define GEN_HTYPE(type) (((type) & 0xff) << 0)
131#define GEN_HTYPE_MASK 0xff
132 142
133#define DSI_GEN_PLD_DATA 0x70 143#define DSI_GEN_PLD_DATA 0x70
134 144
135#define DSI_CMD_PKT_STATUS 0x74 145#define DSI_CMD_PKT_STATUS 0x74
136#define GEN_CMD_EMPTY BIT(0)
137#define GEN_CMD_FULL BIT(1)
138#define GEN_PLD_W_EMPTY BIT(2)
139#define GEN_PLD_W_FULL BIT(3)
140#define GEN_PLD_R_EMPTY BIT(4)
141#define GEN_PLD_R_FULL BIT(5)
142#define GEN_RD_CMD_BUSY BIT(6) 146#define GEN_RD_CMD_BUSY BIT(6)
147#define GEN_PLD_R_FULL BIT(5)
148#define GEN_PLD_R_EMPTY BIT(4)
149#define GEN_PLD_W_FULL BIT(3)
150#define GEN_PLD_W_EMPTY BIT(2)
151#define GEN_CMD_FULL BIT(1)
152#define GEN_CMD_EMPTY BIT(0)
143 153
144#define DSI_TO_CNT_CFG 0x78 154#define DSI_TO_CNT_CFG 0x78
145#define HSTX_TO_CNT(p) (((p) & 0xffff) << 16) 155#define HSTX_TO_CNT(p) (((p) & 0xffff) << 16)
146#define LPRX_TO_CNT(p) ((p) & 0xffff) 156#define LPRX_TO_CNT(p) ((p) & 0xffff)
147 157
158#define DSI_HS_RD_TO_CNT 0x7c
159#define DSI_LP_RD_TO_CNT 0x80
160#define DSI_HS_WR_TO_CNT 0x84
161#define DSI_LP_WR_TO_CNT 0x88
148#define DSI_BTA_TO_CNT 0x8c 162#define DSI_BTA_TO_CNT 0x8c
163
149#define DSI_LPCLK_CTRL 0x94 164#define DSI_LPCLK_CTRL 0x94
150#define AUTO_CLKLANE_CTRL BIT(1) 165#define AUTO_CLKLANE_CTRL BIT(1)
151#define PHY_TXREQUESTCLKHS BIT(0) 166#define PHY_TXREQUESTCLKHS BIT(0)
@@ -154,6 +169,7 @@
154#define PHY_CLKHS2LP_TIME(lbcc) (((lbcc) & 0x3ff) << 16) 169#define PHY_CLKHS2LP_TIME(lbcc) (((lbcc) & 0x3ff) << 16)
155#define PHY_CLKLP2HS_TIME(lbcc) ((lbcc) & 0x3ff) 170#define PHY_CLKLP2HS_TIME(lbcc) ((lbcc) & 0x3ff)
156 171
172/* TODO Next register is slightly different between 1.30 & 1.31 IP version */
157#define DSI_PHY_TMR_CFG 0x9c 173#define DSI_PHY_TMR_CFG 0x9c
158#define PHY_HS2LP_TIME(lbcc) (((lbcc) & 0xff) << 24) 174#define PHY_HS2LP_TIME(lbcc) (((lbcc) & 0xff) << 24)
159#define PHY_LP2HS_TIME(lbcc) (((lbcc) & 0xff) << 16) 175#define PHY_LP2HS_TIME(lbcc) (((lbcc) & 0xff) << 16)
@@ -170,12 +186,15 @@
170#define PHY_UNSHUTDOWNZ BIT(0) 186#define PHY_UNSHUTDOWNZ BIT(0)
171 187
172#define DSI_PHY_IF_CFG 0xa4 188#define DSI_PHY_IF_CFG 0xa4
173#define N_LANES(n) ((((n) - 1) & 0x3) << 0)
174#define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8) 189#define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8)
190#define N_LANES(n) (((n) - 1) & 0x3)
191
192#define DSI_PHY_ULPS_CTRL 0xa8
193#define DSI_PHY_TX_TRIGGERS 0xac
175 194
176#define DSI_PHY_STATUS 0xb0 195#define DSI_PHY_STATUS 0xb0
177#define LOCK BIT(0) 196#define PHY_STOP_STATE_CLK_LANE BIT(2)
178#define STOP_STATE_CLK_LANE BIT(2) 197#define PHY_LOCK BIT(0)
179 198
180#define DSI_PHY_TST_CTRL0 0xb4 199#define DSI_PHY_TST_CTRL0 0xb4
181#define PHY_TESTCLK BIT(1) 200#define PHY_TESTCLK BIT(1)
@@ -187,12 +206,13 @@
187#define PHY_TESTEN BIT(16) 206#define PHY_TESTEN BIT(16)
188#define PHY_UNTESTEN 0 207#define PHY_UNTESTEN 0
189#define PHY_TESTDOUT(n) (((n) & 0xff) << 8) 208#define PHY_TESTDOUT(n) (((n) & 0xff) << 8)
190#define PHY_TESTDIN(n) (((n) & 0xff) << 0) 209#define PHY_TESTDIN(n) ((n) & 0xff)
191 210
192#define DSI_INT_ST0 0xbc 211#define DSI_INT_ST0 0xbc
193#define DSI_INT_ST1 0xc0 212#define DSI_INT_ST1 0xc0
194#define DSI_INT_MSK0 0xc4 213#define DSI_INT_MSK0 0xc4
195#define DSI_INT_MSK1 0xc8 214#define DSI_INT_MSK1 0xc8
215#define DSI_PHY_TMR_RD_CFG 0xf4
196 216
197#define PHY_STATUS_TIMEOUT_US 10000 217#define PHY_STATUS_TIMEOUT_US 10000
198#define CMD_PKT_STATUS_TIMEOUT_US 20000 218#define CMD_PKT_STATUS_TIMEOUT_US 20000
@@ -307,7 +327,7 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
307 u32 val = 0; 327 u32 val = 0;
308 328
309 if (msg->flags & MIPI_DSI_MSG_REQ_ACK) 329 if (msg->flags & MIPI_DSI_MSG_REQ_ACK)
310 val |= EN_ACK_RQST; 330 val |= ACK_RQST_EN;
311 if (lpm) 331 if (lpm)
312 val |= CMD_MODE_ALL_LP; 332 val |= CMD_MODE_ALL_LP;
313 333
@@ -506,8 +526,8 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
506 * timeout clock division should be computed with the 526 * timeout clock division should be computed with the
507 * high speed transmission counter timeout and byte lane... 527 * high speed transmission counter timeout and byte lane...
508 */ 528 */
509 dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) | 529 dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) |
510 TX_ESC_CLK_DIVIDSION(esc_clk_division)); 530 TX_ESC_CLK_DIVISION(esc_clk_division));
511} 531}
512 532
513static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi, 533static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
@@ -520,7 +540,7 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
520 color = DPI_COLOR_CODING_24BIT; 540 color = DPI_COLOR_CODING_24BIT;
521 break; 541 break;
522 case MIPI_DSI_FMT_RGB666: 542 case MIPI_DSI_FMT_RGB666:
523 color = DPI_COLOR_CODING_18BIT_2 | EN18_LOOSELY; 543 color = DPI_COLOR_CODING_18BIT_2 | LOOSELY18_EN;
524 break; 544 break;
525 case MIPI_DSI_FMT_RGB666_PACKED: 545 case MIPI_DSI_FMT_RGB666_PACKED:
526 color = DPI_COLOR_CODING_18BIT_1; 546 color = DPI_COLOR_CODING_18BIT_1;
@@ -535,7 +555,7 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
535 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 555 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
536 val |= HSYNC_ACTIVE_LOW; 556 val |= HSYNC_ACTIVE_LOW;
537 557
538 dsi_write(dsi, DSI_DPI_VCID, DPI_VID(dsi->channel)); 558 dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel));
539 dsi_write(dsi, DSI_DPI_COLOR_CODING, color); 559 dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
540 dsi_write(dsi, DSI_DPI_CFG_POL, val); 560 dsi_write(dsi, DSI_DPI_CFG_POL, val);
541 /* 561 /*
@@ -550,7 +570,7 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
550 570
551static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) 571static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
552{ 572{
553 dsi_write(dsi, DSI_PCKHDL_CFG, EN_CRC_RX | EN_ECC_RX | EN_BTA); 573 dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN);
554} 574}
555 575
556static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi, 576static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
@@ -571,7 +591,7 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
571 /* 591 /*
572 * TODO dw drv improvements 592 * TODO dw drv improvements
573 * compute high speed transmission counter timeout according 593 * compute high speed transmission counter timeout according
574 * to the timeout clock division (TO_CLK_DIVIDSION) and byte lane... 594 * to the timeout clock division (TO_CLK_DIVISION) and byte lane...
575 */ 595 */
576 dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000)); 596 dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
577 /* 597 /*
@@ -684,13 +704,13 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
684 dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK | 704 dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
685 PHY_UNRSTZ | PHY_UNSHUTDOWNZ); 705 PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
686 706
687 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, 707 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val,
688 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US); 708 val & PHY_LOCK, 1000, PHY_STATUS_TIMEOUT_US);
689 if (ret < 0) 709 if (ret < 0)
690 DRM_DEBUG_DRIVER("failed to wait phy lock state\n"); 710 DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
691 711
692 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, 712 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
693 val, val & STOP_STATE_CLK_LANE, 1000, 713 val, val & PHY_STOP_STATE_CLK_LANE, 1000,
694 PHY_STATUS_TIMEOUT_US); 714 PHY_STATUS_TIMEOUT_US);
695 if (ret < 0) 715 if (ret < 0)
696 DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n"); 716 DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
@@ -865,15 +885,14 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
865 * Note that the reset was not defined in the initial device tree, so 885 * Note that the reset was not defined in the initial device tree, so
866 * we have to be prepared for it not being found. 886 * we have to be prepared for it not being found.
867 */ 887 */
868 apb_rst = devm_reset_control_get(dev, "apb"); 888 apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb");
869 if (IS_ERR(apb_rst)) { 889 if (IS_ERR(apb_rst)) {
870 ret = PTR_ERR(apb_rst); 890 ret = PTR_ERR(apb_rst);
871 if (ret == -ENOENT) { 891
872 apb_rst = NULL; 892 if (ret != -EPROBE_DEFER)
873 } else {
874 dev_err(dev, "Unable to get reset control: %d\n", ret); 893 dev_err(dev, "Unable to get reset control: %d\n", ret);
875 return ERR_PTR(ret); 894
876 } 895 return ERR_PTR(ret);
877 } 896 }
878 897
879 if (apb_rst) { 898 if (apb_rst) {
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 2fd383d7253a..366c56fe5f58 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -163,13 +163,6 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
163 crtc->funcs->atomic_destroy_state(crtc, 163 crtc->funcs->atomic_destroy_state(crtc,
164 state->crtcs[i].state); 164 state->crtcs[i].state);
165 165
166 if (state->crtcs[i].commit) {
167 kfree(state->crtcs[i].commit->event);
168 state->crtcs[i].commit->event = NULL;
169 drm_crtc_commit_put(state->crtcs[i].commit);
170 }
171
172 state->crtcs[i].commit = NULL;
173 state->crtcs[i].ptr = NULL; 166 state->crtcs[i].ptr = NULL;
174 state->crtcs[i].state = NULL; 167 state->crtcs[i].state = NULL;
175 } 168 }
@@ -199,6 +192,10 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
199 } 192 }
200 state->num_private_objs = 0; 193 state->num_private_objs = 0;
201 194
195 if (state->fake_commit) {
196 drm_crtc_commit_put(state->fake_commit);
197 state->fake_commit = NULL;
198 }
202} 199}
203EXPORT_SYMBOL(drm_atomic_state_default_clear); 200EXPORT_SYMBOL(drm_atomic_state_default_clear);
204 201
@@ -2237,7 +2234,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
2237 (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) 2234 (arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
2238 return -EINVAL; 2235 return -EINVAL;
2239 2236
2240 drm_modeset_acquire_init(&ctx, 0); 2237 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
2241 2238
2242 state = drm_atomic_state_alloc(dev); 2239 state = drm_atomic_state_alloc(dev);
2243 if (!state) 2240 if (!state)
@@ -2350,8 +2347,9 @@ out:
2350 2347
2351 if (ret == -EDEADLK) { 2348 if (ret == -EDEADLK) {
2352 drm_atomic_state_clear(state); 2349 drm_atomic_state_clear(state);
2353 drm_modeset_backoff(&ctx); 2350 ret = drm_modeset_backoff(&ctx);
2354 goto retry; 2351 if (!ret)
2352 goto retry;
2355 } 2353 }
2356 2354
2357 drm_atomic_state_put(state); 2355 drm_atomic_state_put(state);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 4e53aae9a1fb..01c34bc5b5b0 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1262,12 +1262,12 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
1262void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev, 1262void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
1263 struct drm_atomic_state *old_state) 1263 struct drm_atomic_state *old_state)
1264{ 1264{
1265 struct drm_crtc_state *unused; 1265 struct drm_crtc_state *new_crtc_state;
1266 struct drm_crtc *crtc; 1266 struct drm_crtc *crtc;
1267 int i; 1267 int i;
1268 1268
1269 for_each_new_crtc_in_state(old_state, crtc, unused, i) { 1269 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
1270 struct drm_crtc_commit *commit = old_state->crtcs[i].commit; 1270 struct drm_crtc_commit *commit = new_crtc_state->commit;
1271 int ret; 1271 int ret;
1272 1272
1273 if (!commit) 1273 if (!commit)
@@ -1388,35 +1388,31 @@ int drm_atomic_helper_async_check(struct drm_device *dev,
1388{ 1388{
1389 struct drm_crtc *crtc; 1389 struct drm_crtc *crtc;
1390 struct drm_crtc_state *crtc_state; 1390 struct drm_crtc_state *crtc_state;
1391 struct drm_crtc_commit *commit; 1391 struct drm_plane *plane;
1392 struct drm_plane *__plane, *plane = NULL; 1392 struct drm_plane_state *old_plane_state, *new_plane_state;
1393 struct drm_plane_state *__plane_state, *plane_state = NULL;
1394 const struct drm_plane_helper_funcs *funcs; 1393 const struct drm_plane_helper_funcs *funcs;
1395 int i, j, n_planes = 0; 1394 int i, n_planes = 0;
1396 1395
1397 for_each_new_crtc_in_state(state, crtc, crtc_state, i) { 1396 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1398 if (drm_atomic_crtc_needs_modeset(crtc_state)) 1397 if (drm_atomic_crtc_needs_modeset(crtc_state))
1399 return -EINVAL; 1398 return -EINVAL;
1400 } 1399 }
1401 1400
1402 for_each_new_plane_in_state(state, __plane, __plane_state, i) { 1401 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i)
1403 n_planes++; 1402 n_planes++;
1404 plane = __plane;
1405 plane_state = __plane_state;
1406 }
1407 1403
1408 /* FIXME: we support only single plane updates for now */ 1404 /* FIXME: we support only single plane updates for now */
1409 if (!plane || n_planes != 1) 1405 if (n_planes != 1)
1410 return -EINVAL; 1406 return -EINVAL;
1411 1407
1412 if (!plane_state->crtc) 1408 if (!new_plane_state->crtc)
1413 return -EINVAL; 1409 return -EINVAL;
1414 1410
1415 funcs = plane->helper_private; 1411 funcs = plane->helper_private;
1416 if (!funcs->atomic_async_update) 1412 if (!funcs->atomic_async_update)
1417 return -EINVAL; 1413 return -EINVAL;
1418 1414
1419 if (plane_state->fence) 1415 if (new_plane_state->fence)
1420 return -EINVAL; 1416 return -EINVAL;
1421 1417
1422 /* 1418 /*
@@ -1424,31 +1420,11 @@ int drm_atomic_helper_async_check(struct drm_device *dev,
1424 * the plane. This prevents our async update's changes from getting 1420 * the plane. This prevents our async update's changes from getting
1425 * overridden by a previous synchronous update's state. 1421 * overridden by a previous synchronous update's state.
1426 */ 1422 */
1427 for_each_new_crtc_in_state(state, crtc, crtc_state, i) { 1423 if (old_plane_state->commit &&
1428 if (plane->crtc != crtc) 1424 !try_wait_for_completion(&old_plane_state->commit->hw_done))
1429 continue; 1425 return -EBUSY;
1430 1426
1431 spin_lock(&crtc->commit_lock); 1427 return funcs->atomic_async_check(plane, new_plane_state);
1432 commit = list_first_entry_or_null(&crtc->commit_list,
1433 struct drm_crtc_commit,
1434 commit_entry);
1435 if (!commit) {
1436 spin_unlock(&crtc->commit_lock);
1437 continue;
1438 }
1439 spin_unlock(&crtc->commit_lock);
1440
1441 if (!crtc->state->state)
1442 continue;
1443
1444 for_each_plane_in_state(crtc->state->state, __plane,
1445 __plane_state, j) {
1446 if (__plane == plane)
1447 return -EINVAL;
1448 }
1449 }
1450
1451 return funcs->atomic_async_check(plane, plane_state);
1452} 1428}
1453EXPORT_SYMBOL(drm_atomic_helper_async_check); 1429EXPORT_SYMBOL(drm_atomic_helper_async_check);
1454 1430
@@ -1633,8 +1609,7 @@ static int stall_checks(struct drm_crtc *crtc, bool nonblock)
1633 return -EBUSY; 1609 return -EBUSY;
1634 } 1610 }
1635 } else if (i == 1) { 1611 } else if (i == 1) {
1636 stall_commit = commit; 1612 stall_commit = drm_crtc_commit_get(commit);
1637 drm_crtc_commit_get(stall_commit);
1638 break; 1613 break;
1639 } 1614 }
1640 1615
@@ -1668,6 +1643,38 @@ static void release_crtc_commit(struct completion *completion)
1668 drm_crtc_commit_put(commit); 1643 drm_crtc_commit_put(commit);
1669} 1644}
1670 1645
1646static void init_commit(struct drm_crtc_commit *commit, struct drm_crtc *crtc)
1647{
1648 init_completion(&commit->flip_done);
1649 init_completion(&commit->hw_done);
1650 init_completion(&commit->cleanup_done);
1651 INIT_LIST_HEAD(&commit->commit_entry);
1652 kref_init(&commit->ref);
1653 commit->crtc = crtc;
1654}
1655
1656static struct drm_crtc_commit *
1657crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc)
1658{
1659 if (crtc) {
1660 struct drm_crtc_state *new_crtc_state;
1661
1662 new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1663
1664 return new_crtc_state->commit;
1665 }
1666
1667 if (!state->fake_commit) {
1668 state->fake_commit = kzalloc(sizeof(*state->fake_commit), GFP_KERNEL);
1669 if (!state->fake_commit)
1670 return NULL;
1671
1672 init_commit(state->fake_commit, NULL);
1673 }
1674
1675 return state->fake_commit;
1676}
1677
1671/** 1678/**
1672 * drm_atomic_helper_setup_commit - setup possibly nonblocking commit 1679 * drm_atomic_helper_setup_commit - setup possibly nonblocking commit
1673 * @state: new modeset state to be committed 1680 * @state: new modeset state to be committed
@@ -1716,6 +1723,10 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
1716{ 1723{
1717 struct drm_crtc *crtc; 1724 struct drm_crtc *crtc;
1718 struct drm_crtc_state *old_crtc_state, *new_crtc_state; 1725 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
1726 struct drm_connector *conn;
1727 struct drm_connector_state *old_conn_state, *new_conn_state;
1728 struct drm_plane *plane;
1729 struct drm_plane_state *old_plane_state, *new_plane_state;
1719 struct drm_crtc_commit *commit; 1730 struct drm_crtc_commit *commit;
1720 int i, ret; 1731 int i, ret;
1721 1732
@@ -1724,14 +1735,9 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
1724 if (!commit) 1735 if (!commit)
1725 return -ENOMEM; 1736 return -ENOMEM;
1726 1737
1727 init_completion(&commit->flip_done); 1738 init_commit(commit, crtc);
1728 init_completion(&commit->hw_done);
1729 init_completion(&commit->cleanup_done);
1730 INIT_LIST_HEAD(&commit->commit_entry);
1731 kref_init(&commit->ref);
1732 commit->crtc = crtc;
1733 1739
1734 state->crtcs[i].commit = commit; 1740 new_crtc_state->commit = commit;
1735 1741
1736 ret = stall_checks(crtc, nonblock); 1742 ret = stall_checks(crtc, nonblock);
1737 if (ret) 1743 if (ret)
@@ -1765,25 +1771,46 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
1765 drm_crtc_commit_get(commit); 1771 drm_crtc_commit_get(commit);
1766 } 1772 }
1767 1773
1768 return 0; 1774 for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
1769} 1775 /* commit tracked through new_crtc_state->commit, no need to do it explicitly */
1770EXPORT_SYMBOL(drm_atomic_helper_setup_commit); 1776 if (new_conn_state->crtc)
1777 continue;
1771 1778
1779 /* Userspace is not allowed to get ahead of the previous
1780 * commit with nonblocking ones. */
1781 if (nonblock && old_conn_state->commit &&
1782 !try_wait_for_completion(&old_conn_state->commit->flip_done))
1783 return -EBUSY;
1772 1784
1773static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc) 1785 commit = crtc_or_fake_commit(state, old_conn_state->crtc);
1774{ 1786 if (!commit)
1775 struct drm_crtc_commit *commit; 1787 return -ENOMEM;
1776 int i = 0;
1777 1788
1778 list_for_each_entry(commit, &crtc->commit_list, commit_entry) { 1789 new_conn_state->commit = drm_crtc_commit_get(commit);
1779 /* skip the first entry, that's the current commit */ 1790 }
1780 if (i == 1) 1791
1781 return commit; 1792 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
1782 i++; 1793 /*
1794 * Unlike connectors, always track planes explicitly for
1795 * async pageflip support.
1796 */
1797
1798 /* Userspace is not allowed to get ahead of the previous
1799 * commit with nonblocking ones. */
1800 if (nonblock && old_plane_state->commit &&
1801 !try_wait_for_completion(&old_plane_state->commit->flip_done))
1802 return -EBUSY;
1803
1804 commit = crtc_or_fake_commit(state, old_plane_state->crtc);
1805 if (!commit)
1806 return -ENOMEM;
1807
1808 new_plane_state->commit = drm_crtc_commit_get(commit);
1783 } 1809 }
1784 1810
1785 return NULL; 1811 return 0;
1786} 1812}
1813EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
1787 1814
1788/** 1815/**
1789 * drm_atomic_helper_wait_for_dependencies - wait for required preceeding commits 1816 * drm_atomic_helper_wait_for_dependencies - wait for required preceeding commits
@@ -1800,17 +1827,17 @@ static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
1800void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state) 1827void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)
1801{ 1828{
1802 struct drm_crtc *crtc; 1829 struct drm_crtc *crtc;
1803 struct drm_crtc_state *new_crtc_state; 1830 struct drm_crtc_state *old_crtc_state;
1831 struct drm_plane *plane;
1832 struct drm_plane_state *old_plane_state;
1833 struct drm_connector *conn;
1834 struct drm_connector_state *old_conn_state;
1804 struct drm_crtc_commit *commit; 1835 struct drm_crtc_commit *commit;
1805 int i; 1836 int i;
1806 long ret; 1837 long ret;
1807 1838
1808 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { 1839 for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1809 spin_lock(&crtc->commit_lock); 1840 commit = old_crtc_state->commit;
1810 commit = preceeding_commit(crtc);
1811 if (commit)
1812 drm_crtc_commit_get(commit);
1813 spin_unlock(&crtc->commit_lock);
1814 1841
1815 if (!commit) 1842 if (!commit)
1816 continue; 1843 continue;
@@ -1828,8 +1855,48 @@ void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)
1828 if (ret == 0) 1855 if (ret == 0)
1829 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", 1856 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
1830 crtc->base.id, crtc->name); 1857 crtc->base.id, crtc->name);
1858 }
1859
1860 for_each_old_connector_in_state(old_state, conn, old_conn_state, i) {
1861 commit = old_conn_state->commit;
1831 1862
1832 drm_crtc_commit_put(commit); 1863 if (!commit)
1864 continue;
1865
1866 ret = wait_for_completion_timeout(&commit->hw_done,
1867 10*HZ);
1868 if (ret == 0)
1869 DRM_ERROR("[CONNECTOR:%d:%s] hw_done timed out\n",
1870 conn->base.id, conn->name);
1871
1872 /* Currently no support for overwriting flips, hence
1873 * stall for previous one to execute completely. */
1874 ret = wait_for_completion_timeout(&commit->flip_done,
1875 10*HZ);
1876 if (ret == 0)
1877 DRM_ERROR("[CONNECTOR:%d:%s] flip_done timed out\n",
1878 conn->base.id, conn->name);
1879 }
1880
1881 for_each_old_plane_in_state(old_state, plane, old_plane_state, i) {
1882 commit = old_plane_state->commit;
1883
1884 if (!commit)
1885 continue;
1886
1887 ret = wait_for_completion_timeout(&commit->hw_done,
1888 10*HZ);
1889 if (ret == 0)
1890 DRM_ERROR("[PLANE:%d:%s] hw_done timed out\n",
1891 plane->base.id, plane->name);
1892
1893 /* Currently no support for overwriting flips, hence
1894 * stall for previous one to execute completely. */
1895 ret = wait_for_completion_timeout(&commit->flip_done,
1896 10*HZ);
1897 if (ret == 0)
1898 DRM_ERROR("[PLANE:%d:%s] flip_done timed out\n",
1899 plane->base.id, plane->name);
1833 } 1900 }
1834} 1901}
1835EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); 1902EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
@@ -1852,19 +1919,34 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
1852void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state) 1919void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state)
1853{ 1920{
1854 struct drm_crtc *crtc; 1921 struct drm_crtc *crtc;
1855 struct drm_crtc_state *new_crtc_state; 1922 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
1856 struct drm_crtc_commit *commit; 1923 struct drm_crtc_commit *commit;
1857 int i; 1924 int i;
1858 1925
1859 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { 1926 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
1860 commit = old_state->crtcs[i].commit; 1927 commit = new_crtc_state->commit;
1861 if (!commit) 1928 if (!commit)
1862 continue; 1929 continue;
1863 1930
1931 /*
1932 * copy new_crtc_state->commit to old_crtc_state->commit,
1933 * it's unsafe to touch new_crtc_state after hw_done,
1934 * but we still need to do so in cleanup_done().
1935 */
1936 if (old_crtc_state->commit)
1937 drm_crtc_commit_put(old_crtc_state->commit);
1938
1939 old_crtc_state->commit = drm_crtc_commit_get(commit);
1940
1864 /* backend must have consumed any event by now */ 1941 /* backend must have consumed any event by now */
1865 WARN_ON(new_crtc_state->event); 1942 WARN_ON(new_crtc_state->event);
1866 complete_all(&commit->hw_done); 1943 complete_all(&commit->hw_done);
1867 } 1944 }
1945
1946 if (old_state->fake_commit) {
1947 complete_all(&old_state->fake_commit->hw_done);
1948 complete_all(&old_state->fake_commit->flip_done);
1949 }
1868} 1950}
1869EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done); 1951EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
1870 1952
@@ -1882,39 +1964,25 @@ EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
1882void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state) 1964void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
1883{ 1965{
1884 struct drm_crtc *crtc; 1966 struct drm_crtc *crtc;
1885 struct drm_crtc_state *new_crtc_state; 1967 struct drm_crtc_state *old_crtc_state;
1886 struct drm_crtc_commit *commit; 1968 struct drm_crtc_commit *commit;
1887 int i; 1969 int i;
1888 long ret;
1889 1970
1890 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { 1971 for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1891 commit = old_state->crtcs[i].commit; 1972 commit = old_crtc_state->commit;
1892 if (WARN_ON(!commit)) 1973 if (WARN_ON(!commit))
1893 continue; 1974 continue;
1894 1975
1895 complete_all(&commit->cleanup_done); 1976 complete_all(&commit->cleanup_done);
1896 WARN_ON(!try_wait_for_completion(&commit->hw_done)); 1977 WARN_ON(!try_wait_for_completion(&commit->hw_done));
1897 1978
1898 /* commit_list borrows our reference, need to remove before we
1899 * clean up our drm_atomic_state. But only after it actually
1900 * completed, otherwise subsequent commits won't stall properly. */
1901 if (try_wait_for_completion(&commit->flip_done))
1902 goto del_commit;
1903
1904 /* We must wait for the vblank event to signal our completion
1905 * before releasing our reference, since the vblank work does
1906 * not hold a reference of its own. */
1907 ret = wait_for_completion_timeout(&commit->flip_done,
1908 10*HZ);
1909 if (ret == 0)
1910 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
1911 crtc->base.id, crtc->name);
1912
1913del_commit:
1914 spin_lock(&crtc->commit_lock); 1979 spin_lock(&crtc->commit_lock);
1915 list_del(&commit->commit_entry); 1980 list_del(&commit->commit_entry);
1916 spin_unlock(&crtc->commit_lock); 1981 spin_unlock(&crtc->commit_lock);
1917 } 1982 }
1983
1984 if (old_state->fake_commit)
1985 complete_all(&old_state->fake_commit->cleanup_done);
1918} 1986}
1919EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done); 1987EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
1920 1988
@@ -2294,20 +2362,44 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
2294 struct drm_private_state *old_obj_state, *new_obj_state; 2362 struct drm_private_state *old_obj_state, *new_obj_state;
2295 2363
2296 if (stall) { 2364 if (stall) {
2297 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { 2365 /*
2298 spin_lock(&crtc->commit_lock); 2366 * We have to stall for hw_done here before
2299 commit = list_first_entry_or_null(&crtc->commit_list, 2367 * drm_atomic_helper_wait_for_dependencies() because flip
2300 struct drm_crtc_commit, commit_entry); 2368 * depth > 1 is not yet supported by all drivers. As long as
2301 if (commit) 2369 * obj->state is directly dereferenced anywhere in the drivers
2302 drm_crtc_commit_get(commit); 2370 * atomic_commit_tail function, then it's unsafe to swap state
2303 spin_unlock(&crtc->commit_lock); 2371 * before drm_atomic_helper_commit_hw_done() is called.
2372 */
2373
2374 for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
2375 commit = old_crtc_state->commit;
2376
2377 if (!commit)
2378 continue;
2379
2380 ret = wait_for_completion_interruptible(&commit->hw_done);
2381 if (ret)
2382 return ret;
2383 }
2384
2385 for_each_old_connector_in_state(state, connector, old_conn_state, i) {
2386 commit = old_conn_state->commit;
2304 2387
2305 if (!commit) 2388 if (!commit)
2306 continue; 2389 continue;
2307 2390
2308 ret = wait_for_completion_interruptible(&commit->hw_done); 2391 ret = wait_for_completion_interruptible(&commit->hw_done);
2309 drm_crtc_commit_put(commit); 2392 if (ret)
2393 return ret;
2394 }
2310 2395
2396 for_each_old_plane_in_state(state, plane, old_plane_state, i) {
2397 commit = old_plane_state->commit;
2398
2399 if (!commit)
2400 continue;
2401
2402 ret = wait_for_completion_interruptible(&commit->hw_done);
2311 if (ret) 2403 if (ret)
2312 return ret; 2404 return ret;
2313 } 2405 }
@@ -2332,13 +2424,13 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
2332 state->crtcs[i].state = old_crtc_state; 2424 state->crtcs[i].state = old_crtc_state;
2333 crtc->state = new_crtc_state; 2425 crtc->state = new_crtc_state;
2334 2426
2335 if (state->crtcs[i].commit) { 2427 if (new_crtc_state->commit) {
2336 spin_lock(&crtc->commit_lock); 2428 spin_lock(&crtc->commit_lock);
2337 list_add(&state->crtcs[i].commit->commit_entry, 2429 list_add(&new_crtc_state->commit->commit_entry,
2338 &crtc->commit_list); 2430 &crtc->commit_list);
2339 spin_unlock(&crtc->commit_lock); 2431 spin_unlock(&crtc->commit_lock);
2340 2432
2341 state->crtcs[i].commit->event = NULL; 2433 new_crtc_state->commit->event = NULL;
2342 } 2434 }
2343 } 2435 }
2344 2436
@@ -3186,6 +3278,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
3186 state->connectors_changed = false; 3278 state->connectors_changed = false;
3187 state->color_mgmt_changed = false; 3279 state->color_mgmt_changed = false;
3188 state->zpos_changed = false; 3280 state->zpos_changed = false;
3281 state->commit = NULL;
3189 state->event = NULL; 3282 state->event = NULL;
3190 state->pageflip_flags = 0; 3283 state->pageflip_flags = 0;
3191} 3284}
@@ -3224,6 +3317,12 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
3224 */ 3317 */
3225void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) 3318void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
3226{ 3319{
3320 if (state->commit) {
3321 kfree(state->commit->event);
3322 state->commit->event = NULL;
3323 drm_crtc_commit_put(state->commit);
3324 }
3325
3227 drm_property_blob_put(state->mode_blob); 3326 drm_property_blob_put(state->mode_blob);
3228 drm_property_blob_put(state->degamma_lut); 3327 drm_property_blob_put(state->degamma_lut);
3229 drm_property_blob_put(state->ctm); 3328 drm_property_blob_put(state->ctm);
@@ -3286,6 +3385,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
3286 drm_framebuffer_get(state->fb); 3385 drm_framebuffer_get(state->fb);
3287 3386
3288 state->fence = NULL; 3387 state->fence = NULL;
3388 state->commit = NULL;
3289} 3389}
3290EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); 3390EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
3291 3391
@@ -3327,6 +3427,9 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
3327 3427
3328 if (state->fence) 3428 if (state->fence)
3329 dma_fence_put(state->fence); 3429 dma_fence_put(state->fence);
3430
3431 if (state->commit)
3432 drm_crtc_commit_put(state->commit);
3330} 3433}
3331EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); 3434EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
3332 3435
@@ -3405,6 +3508,7 @@ __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
3405 memcpy(state, connector->state, sizeof(*state)); 3508 memcpy(state, connector->state, sizeof(*state));
3406 if (state->crtc) 3509 if (state->crtc)
3407 drm_connector_get(connector); 3510 drm_connector_get(connector);
3511 state->commit = NULL;
3408} 3512}
3409EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state); 3513EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
3410 3514
@@ -3531,6 +3635,9 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
3531{ 3635{
3532 if (state->crtc) 3636 if (state->crtc)
3533 drm_connector_put(state->connector); 3637 drm_connector_put(state->connector);
3638
3639 if (state->commit)
3640 drm_crtc_commit_put(state->commit);
3534} 3641}
3535EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state); 3642EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
3536 3643
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index dc8cdfe1dcac..1638bfe9627c 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -67,17 +67,12 @@ static LIST_HEAD(bridge_list);
67 * drm_bridge_add - add the given bridge to the global bridge list 67 * drm_bridge_add - add the given bridge to the global bridge list
68 * 68 *
69 * @bridge: bridge control structure 69 * @bridge: bridge control structure
70 *
71 * RETURNS:
72 * Unconditionally returns Zero.
73 */ 70 */
74int drm_bridge_add(struct drm_bridge *bridge) 71void drm_bridge_add(struct drm_bridge *bridge)
75{ 72{
76 mutex_lock(&bridge_lock); 73 mutex_lock(&bridge_lock);
77 list_add_tail(&bridge->list, &bridge_list); 74 list_add_tail(&bridge->list, &bridge_list);
78 mutex_unlock(&bridge_lock); 75 mutex_unlock(&bridge_lock);
79
80 return 0;
81} 76}
82EXPORT_SYMBOL(drm_bridge_add); 77EXPORT_SYMBOL(drm_bridge_add);
83 78
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index ba9f36cef68c..bb2e60f5feb6 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -615,7 +615,6 @@ static const struct drm_prop_enum_list drm_link_status_enum_list[] = {
615 { DRM_MODE_LINK_STATUS_GOOD, "Good" }, 615 { DRM_MODE_LINK_STATUS_GOOD, "Good" },
616 { DRM_MODE_LINK_STATUS_BAD, "Bad" }, 616 { DRM_MODE_LINK_STATUS_BAD, "Bad" },
617}; 617};
618DRM_ENUM_NAME_FN(drm_get_link_status_name, drm_link_status_enum_list)
619 618
620/** 619/**
621 * drm_display_info_set_bus_formats - set the supported bus formats 620 * drm_display_info_set_bus_formats - set the supported bus formats
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5af25ce5bf7c..68b4e976d5e0 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -577,7 +577,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
577 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); 577 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
578 578
579 mutex_lock(&crtc->dev->mode_config.mutex); 579 mutex_lock(&crtc->dev->mode_config.mutex);
580 drm_modeset_acquire_init(&ctx, 0); 580 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
581retry: 581retry:
582 ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); 582 ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
583 if (ret) 583 if (ret)
@@ -717,8 +717,9 @@ out:
717 kfree(connector_set); 717 kfree(connector_set);
718 drm_mode_destroy(dev, mode); 718 drm_mode_destroy(dev, mode);
719 if (ret == -EDEADLK) { 719 if (ret == -EDEADLK) {
720 drm_modeset_backoff(&ctx); 720 ret = drm_modeset_backoff(&ctx);
721 goto retry; 721 if (!ret)
722 goto retry;
722 } 723 }
723 drm_modeset_drop_locks(&ctx); 724 drm_modeset_drop_locks(&ctx);
724 drm_modeset_acquire_fini(&ctx); 725 drm_modeset_acquire_fini(&ctx);
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c
index f9e26dda56d6..9dd879589a2c 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -155,7 +155,7 @@ static int crtc_crc_open(struct inode *inode, struct file *filep)
155 int ret = 0; 155 int ret = 0;
156 156
157 if (drm_drv_uses_atomic_modeset(crtc->dev)) { 157 if (drm_drv_uses_atomic_modeset(crtc->dev)) {
158 ret = drm_modeset_lock_interruptible(&crtc->mutex, NULL); 158 ret = drm_modeset_lock_single_interruptible(&crtc->mutex);
159 if (ret) 159 if (ret)
160 return ret; 160 return ret;
161 161
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 41b492f99955..70dcfa58d3c2 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -294,6 +294,12 @@ static void drm_dp_encode_sideband_req(struct drm_dp_sideband_msg_req_body *req,
294 memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes); 294 memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
295 idx += req->u.i2c_write.num_bytes; 295 idx += req->u.i2c_write.num_bytes;
296 break; 296 break;
297
298 case DP_POWER_DOWN_PHY:
299 case DP_POWER_UP_PHY:
300 buf[idx] = (req->u.port_num.port_number & 0xf) << 4;
301 idx++;
302 break;
297 } 303 }
298 raw->cur_len = idx; 304 raw->cur_len = idx;
299} 305}
@@ -538,6 +544,21 @@ fail_len:
538 return false; 544 return false;
539} 545}
540 546
547static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_msg_rx *raw,
548 struct drm_dp_sideband_msg_reply_body *repmsg)
549{
550 int idx = 1;
551
552 repmsg->u.port_number.port_number = (raw->msg[idx] >> 4) & 0xf;
553 idx++;
554 if (idx > raw->curlen) {
555 DRM_DEBUG_KMS("power up/down phy parse length fail %d %d\n",
556 idx, raw->curlen);
557 return false;
558 }
559 return true;
560}
561
541static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw, 562static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
542 struct drm_dp_sideband_msg_reply_body *msg) 563 struct drm_dp_sideband_msg_reply_body *msg)
543{ 564{
@@ -567,6 +588,9 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
567 return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg); 588 return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg);
568 case DP_ALLOCATE_PAYLOAD: 589 case DP_ALLOCATE_PAYLOAD:
569 return drm_dp_sideband_parse_allocate_payload_ack(raw, msg); 590 return drm_dp_sideband_parse_allocate_payload_ack(raw, msg);
591 case DP_POWER_DOWN_PHY:
592 case DP_POWER_UP_PHY:
593 return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
570 default: 594 default:
571 DRM_ERROR("Got unknown reply 0x%02x\n", msg->req_type); 595 DRM_ERROR("Got unknown reply 0x%02x\n", msg->req_type);
572 return false; 596 return false;
@@ -693,6 +717,22 @@ static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_n
693 return 0; 717 return 0;
694} 718}
695 719
720static int build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
721 int port_num, bool power_up)
722{
723 struct drm_dp_sideband_msg_req_body req;
724
725 if (power_up)
726 req.req_type = DP_POWER_UP_PHY;
727 else
728 req.req_type = DP_POWER_DOWN_PHY;
729
730 req.u.port_num.port_number = port_num;
731 drm_dp_encode_sideband_req(&req, msg);
732 msg->path_msg = true;
733 return 0;
734}
735
696static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr, 736static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
697 struct drm_dp_vcpi *vcpi) 737 struct drm_dp_vcpi *vcpi)
698{ 738{
@@ -1724,6 +1764,40 @@ fail_put:
1724 return ret; 1764 return ret;
1725} 1765}
1726 1766
1767int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
1768 struct drm_dp_mst_port *port, bool power_up)
1769{
1770 struct drm_dp_sideband_msg_tx *txmsg;
1771 int len, ret;
1772
1773 port = drm_dp_get_validated_port_ref(mgr, port);
1774 if (!port)
1775 return -EINVAL;
1776
1777 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
1778 if (!txmsg) {
1779 drm_dp_put_port(port);
1780 return -ENOMEM;
1781 }
1782
1783 txmsg->dst = port->parent;
1784 len = build_power_updown_phy(txmsg, port->port_num, power_up);
1785 drm_dp_queue_down_tx(mgr, txmsg);
1786
1787 ret = drm_dp_mst_wait_tx_reply(port->parent, txmsg);
1788 if (ret > 0) {
1789 if (txmsg->reply.reply_type == 1)
1790 ret = -EINVAL;
1791 else
1792 ret = 0;
1793 }
1794 kfree(txmsg);
1795 drm_dp_put_port(port);
1796
1797 return ret;
1798}
1799EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
1800
1727static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr, 1801static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
1728 int id, 1802 int id,
1729 struct drm_dp_payload *payload) 1803 struct drm_dp_payload *payload)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6bb6337be920..00ddabfbf980 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1533,6 +1533,10 @@ static void connector_bad_edid(struct drm_connector *connector,
1533 * level, drivers must make all reasonable efforts to expose it as an I2C 1533 * level, drivers must make all reasonable efforts to expose it as an I2C
1534 * adapter and use drm_get_edid() instead of abusing this function. 1534 * adapter and use drm_get_edid() instead of abusing this function.
1535 * 1535 *
1536 * The EDID may be overridden using debugfs override_edid or firmare EDID
1537 * (drm_load_edid_firmware() and drm.edid_firmware parameter), in this priority
1538 * order. Having either of them bypasses actual EDID reads.
1539 *
1536 * Return: Pointer to valid EDID or NULL if we couldn't find any. 1540 * Return: Pointer to valid EDID or NULL if we couldn't find any.
1537 */ 1541 */
1538struct edid *drm_do_get_edid(struct drm_connector *connector, 1542struct edid *drm_do_get_edid(struct drm_connector *connector,
@@ -1542,6 +1546,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
1542{ 1546{
1543 int i, j = 0, valid_extensions = 0; 1547 int i, j = 0, valid_extensions = 0;
1544 u8 *edid, *new; 1548 u8 *edid, *new;
1549 struct edid *override = NULL;
1550
1551 if (connector->override_edid)
1552 override = drm_edid_duplicate((const struct edid *)
1553 connector->edid_blob_ptr->data);
1554
1555 if (!override)
1556 override = drm_load_edid_firmware(connector);
1557
1558 if (!IS_ERR_OR_NULL(override))
1559 return override;
1545 1560
1546 if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) 1561 if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
1547 return NULL; 1562 return NULL;
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
index 1c0495acf341..a4915099aaa9 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -31,6 +31,22 @@ module_param_string(edid_firmware, edid_firmware, sizeof(edid_firmware), 0644);
31MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob " 31MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob "
32 "from built-in data or /lib/firmware instead. "); 32 "from built-in data or /lib/firmware instead. ");
33 33
34/* Use only for backward compatibility with drm_kms_helper.edid_firmware */
35int __drm_set_edid_firmware_path(const char *path)
36{
37 scnprintf(edid_firmware, sizeof(edid_firmware), "%s", path);
38
39 return 0;
40}
41EXPORT_SYMBOL(__drm_set_edid_firmware_path);
42
43/* Use only for backward compatibility with drm_kms_helper.edid_firmware */
44int __drm_get_edid_firmware_path(char *buf, size_t bufsize)
45{
46 return scnprintf(buf, bufsize, "%s", edid_firmware);
47}
48EXPORT_SYMBOL(__drm_get_edid_firmware_path);
49
34#define GENERIC_EDIDS 6 50#define GENERIC_EDIDS 6
35static const char * const generic_edid_name[GENERIC_EDIDS] = { 51static const char * const generic_edid_name[GENERIC_EDIDS] = {
36 "edid/800x600.bin", 52 "edid/800x600.bin",
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 1b8f013ffa65..6a31d13f2f81 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -910,6 +910,9 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
910 if (!drm_fbdev_emulation || !fb_helper) 910 if (!drm_fbdev_emulation || !fb_helper)
911 return; 911 return;
912 912
913 cancel_work_sync(&fb_helper->resume_work);
914 cancel_work_sync(&fb_helper->dirty_work);
915
913 info = fb_helper->fbdev; 916 info = fb_helper->fbdev;
914 if (info) { 917 if (info) {
915 if (info->cmap.len) 918 if (info->cmap.len)
@@ -918,9 +921,6 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
918 } 921 }
919 fb_helper->fbdev = NULL; 922 fb_helper->fbdev = NULL;
920 923
921 cancel_work_sync(&fb_helper->resume_work);
922 cancel_work_sync(&fb_helper->dirty_work);
923
924 mutex_lock(&kernel_fb_helper_lock); 924 mutex_lock(&kernel_fb_helper_lock);
925 if (!list_empty(&fb_helper->kernel_fb_list)) { 925 if (!list_empty(&fb_helper->kernel_fb_list)) {
926 list_del(&fb_helper->kernel_fb_list); 926 list_del(&fb_helper->kernel_fb_list);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index c55f338e380b..7199bba68c37 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -334,6 +334,12 @@ int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
334 if (!obj) 334 if (!obj)
335 return -ENOENT; 335 return -ENOENT;
336 336
337 /* Don't allow imported objects to be mapped */
338 if (obj->import_attach) {
339 ret = -EINVAL;
340 goto out;
341 }
342
337 ret = drm_gem_create_mmap_offset(obj); 343 ret = drm_gem_create_mmap_offset(obj);
338 if (ret) 344 if (ret)
339 goto out; 345 goto out;
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index d54a083dc5dd..fc7e995541c9 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -154,7 +154,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
154 154
155 objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]); 155 objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
156 if (!objs[i]) { 156 if (!objs[i]) {
157 DRM_DEV_ERROR(dev->dev, "Failed to lookup GEM\n"); 157 DRM_DEBUG_KMS("Failed to lookup GEM object\n");
158 ret = -ENOENT; 158 ret = -ENOENT;
159 goto err_gem_object_put; 159 goto err_gem_object_put;
160 } 160 }
@@ -232,7 +232,7 @@ int drm_gem_fb_prepare_fb(struct drm_plane *plane,
232 struct dma_buf *dma_buf; 232 struct dma_buf *dma_buf;
233 struct dma_fence *fence; 233 struct dma_fence *fence;
234 234
235 if ((plane->state->fb == state->fb) || !state->fb) 235 if (plane->state->fb == state->fb || !state->fb)
236 return 0; 236 return 0;
237 237
238 dma_buf = drm_gem_fb_get_obj(state->fb, 0)->dma_buf; 238 dma_buf = drm_gem_fb_get_obj(state->fb, 0)->dma_buf;
diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c
index 6e35a56a6102..93e2b30fe1a5 100644
--- a/drivers/gpu/drm/drm_kms_helper_common.c
+++ b/drivers/gpu/drm/drm_kms_helper_common.c
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28#include <linux/module.h> 28#include <linux/module.h>
29#include <drm/drmP.h>
29 30
30#include "drm_crtc_helper_internal.h" 31#include "drm_crtc_helper_internal.h"
31 32
@@ -33,6 +34,33 @@ MODULE_AUTHOR("David Airlie, Jesse Barnes");
33MODULE_DESCRIPTION("DRM KMS helper"); 34MODULE_DESCRIPTION("DRM KMS helper");
34MODULE_LICENSE("GPL and additional rights"); 35MODULE_LICENSE("GPL and additional rights");
35 36
37#if IS_ENABLED(CONFIG_DRM_LOAD_EDID_FIRMWARE)
38
39/* Backward compatibility for drm_kms_helper.edid_firmware */
40static int edid_firmware_set(const char *val, const struct kernel_param *kp)
41{
42 DRM_NOTE("drm_kms_firmware.edid_firmware is deprecated, please use drm.edid_firmware intead.\n");
43
44 return __drm_set_edid_firmware_path(val);
45}
46
47static int edid_firmware_get(char *buffer, const struct kernel_param *kp)
48{
49 return __drm_get_edid_firmware_path(buffer, PAGE_SIZE);
50}
51
52static const struct kernel_param_ops edid_firmware_ops = {
53 .set = edid_firmware_set,
54 .get = edid_firmware_get,
55};
56
57module_param_cb(edid_firmware, &edid_firmware_ops, NULL, 0644);
58__MODULE_PARM_TYPE(edid_firmware, "charp");
59MODULE_PARM_DESC(edid_firmware,
60 "DEPRECATED. Use drm.edid_firmware module parameter instead.");
61
62#endif
63
36static int __init drm_kms_helper_init(void) 64static int __init drm_kms_helper_init(void)
37{ 65{
38 int ret; 66 int ret;
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 1055533792f3..7a1ea91d3343 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -247,8 +247,9 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
247} 247}
248EXPORT_SYMBOL(drm_object_property_set_value); 248EXPORT_SYMBOL(drm_object_property_set_value);
249 249
250int __drm_object_property_get_value(struct drm_mode_object *obj, 250static int __drm_object_property_get_value(struct drm_mode_object *obj,
251 struct drm_property *property, uint64_t *val) 251 struct drm_property *property,
252 uint64_t *val)
252{ 253{
253 int i; 254 int i;
254 255
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c
index af4e906c630d..e123497da0ca 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -39,23 +39,28 @@
39 * 39 *
40 * The basic usage pattern is to:: 40 * The basic usage pattern is to::
41 * 41 *
42 * drm_modeset_acquire_init(&ctx) 42 * drm_modeset_acquire_init(ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE)
43 * retry: 43 * retry:
44 * foreach (lock in random_ordered_set_of_locks) { 44 * foreach (lock in random_ordered_set_of_locks) {
45 * ret = drm_modeset_lock(lock, &ctx) 45 * ret = drm_modeset_lock(lock, ctx)
46 * if (ret == -EDEADLK) { 46 * if (ret == -EDEADLK) {
47 * drm_modeset_backoff(&ctx); 47 * ret = drm_modeset_backoff(ctx);
48 * goto retry; 48 * if (!ret)
49 * goto retry;
49 * } 50 * }
51 * if (ret)
52 * goto out;
50 * } 53 * }
51 * ... do stuff ... 54 * ... do stuff ...
52 * drm_modeset_drop_locks(&ctx); 55 * out:
53 * drm_modeset_acquire_fini(&ctx); 56 * drm_modeset_drop_locks(ctx);
57 * drm_modeset_acquire_fini(ctx);
54 * 58 *
55 * If all that is needed is a single modeset lock, then the &struct 59 * If all that is needed is a single modeset lock, then the &struct
56 * drm_modeset_acquire_ctx is not needed and the locking can be simplified 60 * drm_modeset_acquire_ctx is not needed and the locking can be simplified
57 * by passing a NULL instead of ctx in the drm_modeset_lock() 61 * by passing a NULL instead of ctx in the drm_modeset_lock() call or
58 * call and, when done, by calling drm_modeset_unlock(). 62 * calling drm_modeset_lock_single_interruptible(). To unlock afterwards
63 * call drm_modeset_unlock().
59 * 64 *
60 * On top of these per-object locks using &ww_mutex there's also an overall 65 * On top of these per-object locks using &ww_mutex there's also an overall
61 * &drm_mode_config.mutex, for protecting everything else. Mostly this means 66 * &drm_mode_config.mutex, for protecting everything else. Mostly this means
@@ -178,7 +183,11 @@ EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked);
178/** 183/**
179 * drm_modeset_acquire_init - initialize acquire context 184 * drm_modeset_acquire_init - initialize acquire context
180 * @ctx: the acquire context 185 * @ctx: the acquire context
181 * @flags: for future 186 * @flags: 0 or %DRM_MODESET_ACQUIRE_INTERRUPTIBLE
187 *
188 * When passing %DRM_MODESET_ACQUIRE_INTERRUPTIBLE to @flags,
189 * all calls to drm_modeset_lock() will perform an interruptible
190 * wait.
182 */ 191 */
183void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx, 192void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx,
184 uint32_t flags) 193 uint32_t flags)
@@ -186,6 +195,9 @@ void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx,
186 memset(ctx, 0, sizeof(*ctx)); 195 memset(ctx, 0, sizeof(*ctx));
187 ww_acquire_init(&ctx->ww_ctx, &crtc_ww_class); 196 ww_acquire_init(&ctx->ww_ctx, &crtc_ww_class);
188 INIT_LIST_HEAD(&ctx->locked); 197 INIT_LIST_HEAD(&ctx->locked);
198
199 if (flags & DRM_MODESET_ACQUIRE_INTERRUPTIBLE)
200 ctx->interruptible = true;
189} 201}
190EXPORT_SYMBOL(drm_modeset_acquire_init); 202EXPORT_SYMBOL(drm_modeset_acquire_init);
191 203
@@ -261,8 +273,19 @@ static inline int modeset_lock(struct drm_modeset_lock *lock,
261 return ret; 273 return ret;
262} 274}
263 275
264static int modeset_backoff(struct drm_modeset_acquire_ctx *ctx, 276/**
265 bool interruptible) 277 * drm_modeset_backoff - deadlock avoidance backoff
278 * @ctx: the acquire context
279 *
280 * If deadlock is detected (ie. drm_modeset_lock() returns -EDEADLK),
281 * you must call this function to drop all currently held locks and
282 * block until the contended lock becomes available.
283 *
284 * This function returns 0 on success, or -ERESTARTSYS if this context
285 * is initialized with %DRM_MODESET_ACQUIRE_INTERRUPTIBLE and the
286 * wait has been interrupted.
287 */
288int drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx)
266{ 289{
267 struct drm_modeset_lock *contended = ctx->contended; 290 struct drm_modeset_lock *contended = ctx->contended;
268 291
@@ -273,36 +296,11 @@ static int modeset_backoff(struct drm_modeset_acquire_ctx *ctx,
273 296
274 drm_modeset_drop_locks(ctx); 297 drm_modeset_drop_locks(ctx);
275 298
276 return modeset_lock(contended, ctx, interruptible, true); 299 return modeset_lock(contended, ctx, ctx->interruptible, true);
277}
278
279/**
280 * drm_modeset_backoff - deadlock avoidance backoff
281 * @ctx: the acquire context
282 *
283 * If deadlock is detected (ie. drm_modeset_lock() returns -EDEADLK),
284 * you must call this function to drop all currently held locks and
285 * block until the contended lock becomes available.
286 */
287void drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx)
288{
289 modeset_backoff(ctx, false);
290} 300}
291EXPORT_SYMBOL(drm_modeset_backoff); 301EXPORT_SYMBOL(drm_modeset_backoff);
292 302
293/** 303/**
294 * drm_modeset_backoff_interruptible - deadlock avoidance backoff
295 * @ctx: the acquire context
296 *
297 * Interruptible version of drm_modeset_backoff()
298 */
299int drm_modeset_backoff_interruptible(struct drm_modeset_acquire_ctx *ctx)
300{
301 return modeset_backoff(ctx, true);
302}
303EXPORT_SYMBOL(drm_modeset_backoff_interruptible);
304
305/**
306 * drm_modeset_lock_init - initialize lock 304 * drm_modeset_lock_init - initialize lock
307 * @lock: lock to init 305 * @lock: lock to init
308 */ 306 */
@@ -324,14 +322,18 @@ EXPORT_SYMBOL(drm_modeset_lock_init);
324 * deadlock scenario has been detected and it is an error to attempt 322 * deadlock scenario has been detected and it is an error to attempt
325 * to take any more locks without first calling drm_modeset_backoff(). 323 * to take any more locks without first calling drm_modeset_backoff().
326 * 324 *
325 * If the @ctx is not NULL and initialized with
326 * %DRM_MODESET_ACQUIRE_INTERRUPTIBLE, this function will fail with
327 * -ERESTARTSYS when interrupted.
328 *
327 * If @ctx is NULL then the function call behaves like a normal, 329 * If @ctx is NULL then the function call behaves like a normal,
328 * non-nesting mutex_lock() call. 330 * uninterruptible non-nesting mutex_lock() call.
329 */ 331 */
330int drm_modeset_lock(struct drm_modeset_lock *lock, 332int drm_modeset_lock(struct drm_modeset_lock *lock,
331 struct drm_modeset_acquire_ctx *ctx) 333 struct drm_modeset_acquire_ctx *ctx)
332{ 334{
333 if (ctx) 335 if (ctx)
334 return modeset_lock(lock, ctx, false, false); 336 return modeset_lock(lock, ctx, ctx->interruptible, false);
335 337
336 ww_mutex_lock(&lock->mutex, NULL); 338 ww_mutex_lock(&lock->mutex, NULL);
337 return 0; 339 return 0;
@@ -339,21 +341,19 @@ int drm_modeset_lock(struct drm_modeset_lock *lock,
339EXPORT_SYMBOL(drm_modeset_lock); 341EXPORT_SYMBOL(drm_modeset_lock);
340 342
341/** 343/**
342 * drm_modeset_lock_interruptible - take modeset lock 344 * drm_modeset_lock_single_interruptible - take a single modeset lock
343 * @lock: lock to take 345 * @lock: lock to take
344 * @ctx: acquire ctx
345 * 346 *
346 * Interruptible version of drm_modeset_lock() 347 * This function behaves as drm_modeset_lock() with a NULL context,
348 * but performs interruptible waits.
349 *
350 * This function returns 0 on success, or -ERESTARTSYS when interrupted.
347 */ 351 */
348int drm_modeset_lock_interruptible(struct drm_modeset_lock *lock, 352int drm_modeset_lock_single_interruptible(struct drm_modeset_lock *lock)
349 struct drm_modeset_acquire_ctx *ctx)
350{ 353{
351 if (ctx)
352 return modeset_lock(lock, ctx, true, false);
353
354 return ww_mutex_lock_interruptible(&lock->mutex, NULL); 354 return ww_mutex_lock_interruptible(&lock->mutex, NULL);
355} 355}
356EXPORT_SYMBOL(drm_modeset_lock_interruptible); 356EXPORT_SYMBOL(drm_modeset_lock_single_interruptible);
357 357
358/** 358/**
359 * drm_modeset_unlock - drop modeset lock 359 * drm_modeset_unlock - drop modeset lock
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 7a00351d5b5d..72cba9805edc 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -667,7 +667,7 @@ static int setplane_internal(struct drm_plane *plane,
667 struct drm_modeset_acquire_ctx ctx; 667 struct drm_modeset_acquire_ctx ctx;
668 int ret; 668 int ret;
669 669
670 drm_modeset_acquire_init(&ctx, 0); 670 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
671retry: 671retry:
672 ret = drm_modeset_lock_all_ctx(plane->dev, &ctx); 672 ret = drm_modeset_lock_all_ctx(plane->dev, &ctx);
673 if (ret) 673 if (ret)
@@ -678,8 +678,9 @@ retry:
678 678
679fail: 679fail:
680 if (ret == -EDEADLK) { 680 if (ret == -EDEADLK) {
681 drm_modeset_backoff(&ctx); 681 ret = drm_modeset_backoff(&ctx);
682 goto retry; 682 if (!ret)
683 goto retry;
683 } 684 }
684 drm_modeset_drop_locks(&ctx); 685 drm_modeset_drop_locks(&ctx);
685 drm_modeset_acquire_fini(&ctx); 686 drm_modeset_acquire_fini(&ctx);
@@ -834,7 +835,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
834 return -ENOENT; 835 return -ENOENT;
835 } 836 }
836 837
837 drm_modeset_acquire_init(&ctx, 0); 838 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
838retry: 839retry:
839 ret = drm_modeset_lock(&crtc->mutex, &ctx); 840 ret = drm_modeset_lock(&crtc->mutex, &ctx);
840 if (ret) 841 if (ret)
@@ -876,8 +877,9 @@ retry:
876 } 877 }
877out: 878out:
878 if (ret == -EDEADLK) { 879 if (ret == -EDEADLK) {
879 drm_modeset_backoff(&ctx); 880 ret = drm_modeset_backoff(&ctx);
880 goto retry; 881 if (!ret)
882 goto retry;
881 } 883 }
882 884
883 drm_modeset_drop_locks(&ctx); 885 drm_modeset_drop_locks(&ctx);
@@ -985,7 +987,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
985 return -EINVAL; 987 return -EINVAL;
986 } 988 }
987 989
988 drm_modeset_acquire_init(&ctx, 0); 990 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
989retry: 991retry:
990 ret = drm_modeset_lock(&crtc->mutex, &ctx); 992 ret = drm_modeset_lock(&crtc->mutex, &ctx);
991 if (ret) 993 if (ret)
@@ -1074,8 +1076,9 @@ out:
1074 crtc->primary->old_fb = NULL; 1076 crtc->primary->old_fb = NULL;
1075 1077
1076 if (ret == -EDEADLK) { 1078 if (ret == -EDEADLK) {
1077 drm_modeset_backoff(&ctx); 1079 ret = drm_modeset_backoff(&ctx);
1078 goto retry; 1080 if (!ret)
1081 goto retry;
1079 } 1082 }
1080 1083
1081 drm_modeset_drop_locks(&ctx); 1084 drm_modeset_drop_locks(&ctx);
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 904966cde32b..5840aabbf24e 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -353,8 +353,6 @@ EXPORT_SYMBOL(drm_helper_probe_detect);
353 * drm_mode_probed_add(). New modes start their life with status as OK. 353 * drm_mode_probed_add(). New modes start their life with status as OK.
354 * Modes are added from a single source using the following priority order. 354 * Modes are added from a single source using the following priority order.
355 * 355 *
356 * - debugfs 'override_edid' (used for testing only)
357 * - firmware EDID (drm_load_edid_firmware())
358 * - &drm_connector_helper_funcs.get_modes vfunc 356 * - &drm_connector_helper_funcs.get_modes vfunc
359 * - if the connector status is connector_status_connected, standard 357 * - if the connector status is connector_status_connected, standard
360 * VESA DMT modes up to 1024x768 are automatically added 358 * VESA DMT modes up to 1024x768 are automatically added
@@ -483,22 +481,7 @@ retry:
483 goto prune; 481 goto prune;
484 } 482 }
485 483
486 if (connector->override_edid) { 484 count = (*connector_funcs->get_modes)(connector);
487 struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
488
489 count = drm_add_edid_modes(connector, edid);
490 drm_edid_to_eld(connector, edid);
491 } else {
492 struct edid *edid = drm_load_edid_firmware(connector);
493 if (!IS_ERR_OR_NULL(edid)) {
494 drm_mode_connector_update_edid_property(connector, edid);
495 count = drm_add_edid_modes(connector, edid);
496 drm_edid_to_eld(connector, edid);
497 kfree(edid);
498 }
499 if (count == 0)
500 count = (*connector_funcs->get_modes)(connector);
501 }
502 485
503 if (count == 0 && connector->status == connector_status_connected) 486 if (count == 0 && connector->status == connector_status_connected)
504 count = drm_add_modes_noedid(connector, 1024, 768); 487 count = drm_add_modes_noedid(connector, 1024, 768);
diff --git a/drivers/gpu/drm/drm_scdc_helper.c b/drivers/gpu/drm/drm_scdc_helper.c
index 935653eb3616..657ea5ab6c3f 100644
--- a/drivers/gpu/drm/drm_scdc_helper.c
+++ b/drivers/gpu/drm/drm_scdc_helper.c
@@ -134,7 +134,6 @@ EXPORT_SYMBOL(drm_scdc_write);
134 * Returns: 134 * Returns:
135 * True if the scrambling is enabled, false otherwise. 135 * True if the scrambling is enabled, false otherwise.
136 */ 136 */
137
138bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter) 137bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter)
139{ 138{
140 u8 status; 139 u8 status;
@@ -142,7 +141,7 @@ bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter)
142 141
143 ret = drm_scdc_readb(adapter, SCDC_SCRAMBLER_STATUS, &status); 142 ret = drm_scdc_readb(adapter, SCDC_SCRAMBLER_STATUS, &status);
144 if (ret < 0) { 143 if (ret < 0) {
145 DRM_ERROR("Failed to read scrambling status, error %d\n", ret); 144 DRM_ERROR("Failed to read scrambling status: %d\n", ret);
146 return false; 145 return false;
147 } 146 }
148 147
@@ -162,7 +161,6 @@ EXPORT_SYMBOL(drm_scdc_get_scrambling_status);
162 * Returns: 161 * Returns:
163 * True if scrambling is set/reset successfully, false otherwise. 162 * True if scrambling is set/reset successfully, false otherwise.
164 */ 163 */
165
166bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable) 164bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable)
167{ 165{
168 u8 config; 166 u8 config;
@@ -170,7 +168,7 @@ bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable)
170 168
171 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config); 169 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);
172 if (ret < 0) { 170 if (ret < 0) {
173 DRM_ERROR("Failed to read tmds config, err=%d\n", ret); 171 DRM_ERROR("Failed to read TMDS config: %d\n", ret);
174 return false; 172 return false;
175 } 173 }
176 174
@@ -181,7 +179,7 @@ bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable)
181 179
182 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config); 180 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config);
183 if (ret < 0) { 181 if (ret < 0) {
184 DRM_ERROR("Failed to enable scrambling, error %d\n", ret); 182 DRM_ERROR("Failed to enable scrambling: %d\n", ret);
185 return false; 183 return false;
186 } 184 }
187 185
@@ -225,7 +223,7 @@ bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set)
225 223
226 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config); 224 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);
227 if (ret < 0) { 225 if (ret < 0) {
228 DRM_ERROR("Failed to read tmds config, err=%d\n", ret); 226 DRM_ERROR("Failed to read TMDS config: %d\n", ret);
229 return false; 227 return false;
230 } 228 }
231 229
@@ -236,7 +234,7 @@ bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set)
236 234
237 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config); 235 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config);
238 if (ret < 0) { 236 if (ret < 0) {
239 DRM_ERROR("Failed to set TMDS clock ratio, error %d\n", ret); 237 DRM_ERROR("Failed to set TMDS clock ratio: %d\n", ret);
240 return false; 238 return false;
241 } 239 }
242 240
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 0422b8c2c2e7..26d60615b4d4 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -417,8 +417,8 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private,
417 return 0; 417 return 0;
418} 418}
419 419
420int drm_syncobj_import_sync_file_fence(struct drm_file *file_private, 420static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private,
421 int fd, int handle) 421 int fd, int handle)
422{ 422{
423 struct dma_fence *fence = sync_file_get_fence(fd); 423 struct dma_fence *fence = sync_file_get_fence(fd);
424 struct drm_syncobj *syncobj; 424 struct drm_syncobj *syncobj;
@@ -438,8 +438,8 @@ int drm_syncobj_import_sync_file_fence(struct drm_file *file_private,
438 return 0; 438 return 0;
439} 439}
440 440
441int drm_syncobj_export_sync_file(struct drm_file *file_private, 441static int drm_syncobj_export_sync_file(struct drm_file *file_private,
442 int handle, int *p_fd) 442 int handle, int *p_fd)
443{ 443{
444 int ret; 444 int ret;
445 struct dma_fence *fence; 445 struct dma_fence *fence;
diff --git a/drivers/gpu/drm/drm_trace.h b/drivers/gpu/drm/drm_trace.h
index 14c5a777682e..16c64d067e67 100644
--- a/drivers/gpu/drm/drm_trace.h
+++ b/drivers/gpu/drm/drm_trace.h
@@ -61,5 +61,5 @@ TRACE_EVENT(drm_vblank_event_delivered,
61 61
62/* This part must be outside protection */ 62/* This part must be outside protection */
63#undef TRACE_INCLUDE_PATH 63#undef TRACE_INCLUDE_PATH
64#define TRACE_INCLUDE_PATH . 64#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm
65#include <trace/define_trace.h> 65#include <trace/define_trace.h>
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index ba4a32b132ba..2174814273e2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -420,11 +420,7 @@ static int exynos_mic_probe(struct platform_device *pdev)
420 mic->bridge.funcs = &mic_bridge_funcs; 420 mic->bridge.funcs = &mic_bridge_funcs;
421 mic->bridge.of_node = dev->of_node; 421 mic->bridge.of_node = dev->of_node;
422 422
423 ret = drm_bridge_add(&mic->bridge); 423 drm_bridge_add(&mic->bridge);
424 if (ret) {
425 DRM_ERROR("mic: Failed to add MIC to the global bridge list\n");
426 return ret;
427 }
428 424
429 pm_runtime_enable(dev); 425 pm_runtime_enable(dev);
430 426
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
index c52f9adf5e04..a4bb89b7878f 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_dp.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -1901,10 +1901,8 @@ cdv_intel_dp_destroy(struct drm_connector *connector)
1901 1901
1902 if (is_edp(gma_encoder)) { 1902 if (is_edp(gma_encoder)) {
1903 /* cdv_intel_panel_destroy_backlight(connector->dev); */ 1903 /* cdv_intel_panel_destroy_backlight(connector->dev); */
1904 if (intel_dp->panel_fixed_mode) { 1904 kfree(intel_dp->panel_fixed_mode);
1905 kfree(intel_dp->panel_fixed_mode); 1905 intel_dp->panel_fixed_mode = NULL;
1906 intel_dp->panel_fixed_mode = NULL;
1907 }
1908 } 1906 }
1909 i2c_del_adapter(&intel_dp->adapter); 1907 i2c_del_adapter(&intel_dp->adapter);
1910 drm_connector_unregister(connector); 1908 drm_connector_unregister(connector);
diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c
index 531e4450c000..5c066448be5b 100644
--- a/drivers/gpu/drm/gma500/mdfld_intel_display.c
+++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c
@@ -99,7 +99,7 @@ void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
99 /* Wait for for the pipe enable to take effect. */ 99 /* Wait for for the pipe enable to take effect. */
100 for (count = 0; count < COUNT_MAX; count++) { 100 for (count = 0; count < COUNT_MAX; count++) {
101 temp = REG_READ(map->conf); 101 temp = REG_READ(map->conf);
102 if ((temp & PIPEACONF_PIPE_STATE) == 1) 102 if (temp & PIPEACONF_PIPE_STATE)
103 break; 103 break;
104 } 104 }
105} 105}
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
index e9e8ae2ec06b..544a8a2d3562 100644
--- a/drivers/gpu/drm/i2c/ch7006_drv.c
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
@@ -485,7 +485,7 @@ static int ch7006_encoder_init(struct i2c_client *client,
485 return 0; 485 return 0;
486} 486}
487 487
488static struct i2c_device_id ch7006_ids[] = { 488static const struct i2c_device_id ch7006_ids[] = {
489 { "ch7006", 0 }, 489 { "ch7006", 0 },
490 { } 490 { }
491}; 491};
diff --git a/drivers/gpu/drm/i2c/sil164_drv.c b/drivers/gpu/drm/i2c/sil164_drv.c
index db0b03fb0ff1..ecaa58757529 100644
--- a/drivers/gpu/drm/i2c/sil164_drv.c
+++ b/drivers/gpu/drm/i2c/sil164_drv.c
@@ -415,7 +415,7 @@ sil164_encoder_init(struct i2c_client *client,
415 return 0; 415 return 0;
416} 416}
417 417
418static struct i2c_device_id sil164_ids[] = { 418static const struct i2c_device_id sil164_ids[] = {
419 { "sil164", 0 }, 419 { "sil164", 0 },
420 { } 420 { }
421}; 421};
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 54e3255dde13..4d1f45acf2cd 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1746,7 +1746,7 @@ static const struct of_device_id tda998x_dt_ids[] = {
1746MODULE_DEVICE_TABLE(of, tda998x_dt_ids); 1746MODULE_DEVICE_TABLE(of, tda998x_dt_ids);
1747#endif 1747#endif
1748 1748
1749static struct i2c_device_id tda998x_ids[] = { 1749static const struct i2c_device_id tda998x_ids[] = {
1750 { "tda998x", 0 }, 1750 { "tda998x", 0 },
1751 { } 1751 { }
1752}; 1752};
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 18d9da53282b..b6b175aa5d25 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -707,8 +707,7 @@ struct drm_i915_display_funcs {
707 struct drm_atomic_state *old_state); 707 struct drm_atomic_state *old_state);
708 void (*crtc_disable)(struct intel_crtc_state *old_crtc_state, 708 void (*crtc_disable)(struct intel_crtc_state *old_crtc_state,
709 struct drm_atomic_state *old_state); 709 struct drm_atomic_state *old_state);
710 void (*update_crtcs)(struct drm_atomic_state *state, 710 void (*update_crtcs)(struct drm_atomic_state *state);
711 unsigned int *crtc_vblank_mask);
712 void (*audio_codec_enable)(struct drm_connector *connector, 711 void (*audio_codec_enable)(struct drm_connector *connector,
713 struct intel_encoder *encoder, 712 struct intel_encoder *encoder,
714 const struct drm_display_mode *adjusted_mode); 713 const struct drm_display_mode *adjusted_mode);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 00cd17c76fdc..4b34fa6954f9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12129,73 +12129,10 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
12129 return dev->driver->get_vblank_counter(dev, crtc->pipe); 12129 return dev->driver->get_vblank_counter(dev, crtc->pipe);
12130} 12130}
12131 12131
12132static void intel_atomic_wait_for_vblanks(struct drm_device *dev,
12133 struct drm_i915_private *dev_priv,
12134 unsigned crtc_mask)
12135{
12136 unsigned last_vblank_count[I915_MAX_PIPES];
12137 enum pipe pipe;
12138 int ret;
12139
12140 if (!crtc_mask)
12141 return;
12142
12143 for_each_pipe(dev_priv, pipe) {
12144 struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv,
12145 pipe);
12146
12147 if (!((1 << pipe) & crtc_mask))
12148 continue;
12149
12150 ret = drm_crtc_vblank_get(&crtc->base);
12151 if (WARN_ON(ret != 0)) {
12152 crtc_mask &= ~(1 << pipe);
12153 continue;
12154 }
12155
12156 last_vblank_count[pipe] = drm_crtc_vblank_count(&crtc->base);
12157 }
12158
12159 for_each_pipe(dev_priv, pipe) {
12160 struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv,
12161 pipe);
12162 long lret;
12163
12164 if (!((1 << pipe) & crtc_mask))
12165 continue;
12166
12167 lret = wait_event_timeout(dev->vblank[pipe].queue,
12168 last_vblank_count[pipe] !=
12169 drm_crtc_vblank_count(&crtc->base),
12170 msecs_to_jiffies(50));
12171
12172 WARN(!lret, "pipe %c vblank wait timed out\n", pipe_name(pipe));
12173
12174 drm_crtc_vblank_put(&crtc->base);
12175 }
12176}
12177
12178static bool needs_vblank_wait(struct intel_crtc_state *crtc_state)
12179{
12180 /* fb updated, need to unpin old fb */
12181 if (crtc_state->fb_changed)
12182 return true;
12183
12184 /* wm changes, need vblank before final wm's */
12185 if (crtc_state->update_wm_post)
12186 return true;
12187
12188 if (crtc_state->wm.need_postvbl_update)
12189 return true;
12190
12191 return false;
12192}
12193
12194static void intel_update_crtc(struct drm_crtc *crtc, 12132static void intel_update_crtc(struct drm_crtc *crtc,
12195 struct drm_atomic_state *state, 12133 struct drm_atomic_state *state,
12196 struct drm_crtc_state *old_crtc_state, 12134 struct drm_crtc_state *old_crtc_state,
12197 struct drm_crtc_state *new_crtc_state, 12135 struct drm_crtc_state *new_crtc_state)
12198 unsigned int *crtc_vblank_mask)
12199{ 12136{
12200 struct drm_device *dev = crtc->dev; 12137 struct drm_device *dev = crtc->dev;
12201 struct drm_i915_private *dev_priv = to_i915(dev); 12138 struct drm_i915_private *dev_priv = to_i915(dev);
@@ -12218,13 +12155,9 @@ static void intel_update_crtc(struct drm_crtc *crtc,
12218 } 12155 }
12219 12156
12220 drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); 12157 drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
12221
12222 if (needs_vblank_wait(pipe_config))
12223 *crtc_vblank_mask |= drm_crtc_mask(crtc);
12224} 12158}
12225 12159
12226static void intel_update_crtcs(struct drm_atomic_state *state, 12160static void intel_update_crtcs(struct drm_atomic_state *state)
12227 unsigned int *crtc_vblank_mask)
12228{ 12161{
12229 struct drm_crtc *crtc; 12162 struct drm_crtc *crtc;
12230 struct drm_crtc_state *old_crtc_state, *new_crtc_state; 12163 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
@@ -12235,12 +12168,11 @@ static void intel_update_crtcs(struct drm_atomic_state *state,
12235 continue; 12168 continue;
12236 12169
12237 intel_update_crtc(crtc, state, old_crtc_state, 12170 intel_update_crtc(crtc, state, old_crtc_state,
12238 new_crtc_state, crtc_vblank_mask); 12171 new_crtc_state);
12239 } 12172 }
12240} 12173}
12241 12174
12242static void skl_update_crtcs(struct drm_atomic_state *state, 12175static void skl_update_crtcs(struct drm_atomic_state *state)
12243 unsigned int *crtc_vblank_mask)
12244{ 12176{
12245 struct drm_i915_private *dev_priv = to_i915(state->dev); 12177 struct drm_i915_private *dev_priv = to_i915(state->dev);
12246 struct intel_atomic_state *intel_state = to_intel_atomic_state(state); 12178 struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
@@ -12299,7 +12231,7 @@ static void skl_update_crtcs(struct drm_atomic_state *state,
12299 vbl_wait = true; 12231 vbl_wait = true;
12300 12232
12301 intel_update_crtc(crtc, state, old_crtc_state, 12233 intel_update_crtc(crtc, state, old_crtc_state,
12302 new_crtc_state, crtc_vblank_mask); 12234 new_crtc_state);
12303 12235
12304 if (vbl_wait) 12236 if (vbl_wait)
12305 intel_wait_for_vblank(dev_priv, pipe); 12237 intel_wait_for_vblank(dev_priv, pipe);
@@ -12361,7 +12293,6 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
12361 struct intel_crtc_state *intel_cstate; 12293 struct intel_crtc_state *intel_cstate;
12362 bool hw_check = intel_state->modeset; 12294 bool hw_check = intel_state->modeset;
12363 u64 put_domains[I915_MAX_PIPES] = {}; 12295 u64 put_domains[I915_MAX_PIPES] = {};
12364 unsigned crtc_vblank_mask = 0;
12365 int i; 12296 int i;
12366 12297
12367 intel_atomic_commit_fence_wait(intel_state); 12298 intel_atomic_commit_fence_wait(intel_state);
@@ -12451,7 +12382,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
12451 } 12382 }
12452 12383
12453 /* Now enable the clocks, plane, pipe, and connectors that we set up. */ 12384 /* Now enable the clocks, plane, pipe, and connectors that we set up. */
12454 dev_priv->display.update_crtcs(state, &crtc_vblank_mask); 12385 dev_priv->display.update_crtcs(state);
12455 12386
12456 /* FIXME: We should call drm_atomic_helper_commit_hw_done() here 12387 /* FIXME: We should call drm_atomic_helper_commit_hw_done() here
12457 * already, but still need the state for the delayed optimization. To 12388 * already, but still need the state for the delayed optimization. To
@@ -12462,8 +12393,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
12462 * - switch over to the vblank wait helper in the core after that since 12393 * - switch over to the vblank wait helper in the core after that since
12463 * we don't need out special handling any more. 12394 * we don't need out special handling any more.
12464 */ 12395 */
12465 if (!state->legacy_cursor_update) 12396 drm_atomic_helper_wait_for_flip_done(dev, state);
12466 intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);
12467 12397
12468 /* 12398 /*
12469 * Now that the vblank has passed, we can go ahead and program the 12399 * Now that the vblank has passed, we can go ahead and program the
@@ -13061,6 +12991,14 @@ intel_legacy_cursor_update(struct drm_plane *plane,
13061 goto slow; 12991 goto slow;
13062 12992
13063 old_plane_state = plane->state; 12993 old_plane_state = plane->state;
12994 /*
12995 * Don't do an async update if there is an outstanding commit modifying
12996 * the plane. This prevents our async update's changes from getting
12997 * overridden by a previous synchronous update's state.
12998 */
12999 if (old_plane_state->commit &&
13000 !try_wait_for_completion(&old_plane_state->commit->hw_done))
13001 goto slow;
13064 13002
13065 /* 13003 /*
13066 * If any parameters change that may affect watermarks, 13004 * If any parameters change that may affect watermarks,
@@ -13120,17 +13058,12 @@ intel_legacy_cursor_update(struct drm_plane *plane,
13120 } 13058 }
13121 13059
13122 old_fb = old_plane_state->fb; 13060 old_fb = old_plane_state->fb;
13123 old_vma = to_intel_plane_state(old_plane_state)->vma;
13124 13061
13125 i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb), 13062 i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb),
13126 intel_plane->frontbuffer_bit); 13063 intel_plane->frontbuffer_bit);
13127 13064
13128 /* Swap plane state */ 13065 /* Swap plane state */
13129 new_plane_state->fence = old_plane_state->fence; 13066 plane->state = new_plane_state;
13130 *to_intel_plane_state(old_plane_state) = *to_intel_plane_state(new_plane_state);
13131 new_plane_state->fence = NULL;
13132 new_plane_state->fb = old_fb;
13133 to_intel_plane_state(new_plane_state)->vma = NULL;
13134 13067
13135 if (plane->state->visible) { 13068 if (plane->state->visible) {
13136 trace_intel_update_plane(plane, to_intel_crtc(crtc)); 13069 trace_intel_update_plane(plane, to_intel_crtc(crtc));
@@ -13142,13 +13075,17 @@ intel_legacy_cursor_update(struct drm_plane *plane,
13142 intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc)); 13075 intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
13143 } 13076 }
13144 13077
13078 old_vma = fetch_and_zero(&to_intel_plane_state(old_plane_state)->vma);
13145 if (old_vma) 13079 if (old_vma)
13146 intel_unpin_fb_vma(old_vma); 13080 intel_unpin_fb_vma(old_vma);
13147 13081
13148out_unlock: 13082out_unlock:
13149 mutex_unlock(&dev_priv->drm.struct_mutex); 13083 mutex_unlock(&dev_priv->drm.struct_mutex);
13150out_free: 13084out_free:
13151 intel_plane_destroy_state(plane, new_plane_state); 13085 if (ret)
13086 intel_plane_destroy_state(plane, new_plane_state);
13087 else
13088 intel_plane_destroy_state(plane, old_plane_state);
13152 return ret; 13089 return ret;
13153 13090
13154slow: 13091slow:
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index f91cb72d0830..93c7e3f9b4a8 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -24,6 +24,7 @@
24#include <drm/drm_fb_helper.h> 24#include <drm/drm_fb_helper.h>
25#include <drm/drm_crtc_helper.h> 25#include <drm/drm_crtc_helper.h>
26#include <drm/drm_gem_cma_helper.h> 26#include <drm/drm_gem_cma_helper.h>
27#include <drm/drm_gem_framebuffer_helper.h>
27#include <drm/drm_fb_cma_helper.h> 28#include <drm/drm_fb_cma_helper.h>
28#include <drm/drm_plane_helper.h> 29#include <drm/drm_plane_helper.h>
29#include <drm/drm_of.h> 30#include <drm/drm_of.h>
@@ -105,7 +106,7 @@ static int imx_drm_atomic_check(struct drm_device *dev,
105} 106}
106 107
107static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { 108static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
108 .fb_create = drm_fb_cma_create, 109 .fb_create = drm_gem_fb_create,
109 .output_poll_changed = imx_drm_output_poll_changed, 110 .output_poll_changed = imx_drm_output_poll_changed,
110 .atomic_check = imx_drm_atomic_check, 111 .atomic_check = imx_drm_atomic_check,
111 .atomic_commit = drm_atomic_helper_commit, 112 .atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index cf98596c7ce1..247c60e6bed2 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -18,6 +18,7 @@
18#include <drm/drm_atomic_helper.h> 18#include <drm/drm_atomic_helper.h>
19#include <drm/drm_fb_cma_helper.h> 19#include <drm/drm_fb_cma_helper.h>
20#include <drm/drm_gem_cma_helper.h> 20#include <drm/drm_gem_cma_helper.h>
21#include <drm/drm_gem_framebuffer_helper.h>
21#include <drm/drm_plane_helper.h> 22#include <drm/drm_plane_helper.h>
22 23
23#include "video/imx-ipu-v3.h" 24#include "video/imx-ipu-v3.h"
@@ -690,7 +691,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
690} 691}
691 692
692static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = { 693static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = {
693 .prepare_fb = drm_fb_cma_prepare_fb, 694 .prepare_fb = drm_gem_fb_prepare_fb,
694 .atomic_check = ipu_plane_atomic_check, 695 .atomic_check = ipu_plane_atomic_check,
695 .atomic_disable = ipu_plane_atomic_disable, 696 .atomic_disable = ipu_plane_atomic_disable,
696 .atomic_update = ipu_plane_atomic_update, 697 .atomic_update = ipu_plane_atomic_update,
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 690c67507cbc..3ff502771ba2 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1696,11 +1696,7 @@ static int mtk_drm_hdmi_probe(struct platform_device *pdev)
1696 1696
1697 hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs; 1697 hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs;
1698 hdmi->bridge.of_node = pdev->dev.of_node; 1698 hdmi->bridge.of_node = pdev->dev.of_node;
1699 ret = drm_bridge_add(&hdmi->bridge); 1699 drm_bridge_add(&hdmi->bridge);
1700 if (ret) {
1701 dev_err(dev, "failed to add bridge, ret = %d\n", ret);
1702 return ret;
1703 }
1704 1700
1705 ret = mtk_hdmi_clk_enable_audio(hdmi); 1701 ret = mtk_hdmi_clk_enable_audio(hdmi);
1706 if (ret) { 1702 if (ret) {
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index d84a031fae24..718d8ce15b1f 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -63,6 +63,15 @@ config DRM_PANEL_LG_LG4573
63 Say Y here if you want to enable support for LG4573 RGB panel. 63 Say Y here if you want to enable support for LG4573 RGB panel.
64 To compile this driver as a module, choose M here. 64 To compile this driver as a module, choose M here.
65 65
66config DRM_PANEL_ORISETECH_OTM8009A
67 tristate "Orise Technology otm8009a 480x800 dsi 2dl panel"
68 depends on OF
69 depends on DRM_MIPI_DSI
70 depends on BACKLIGHT_CLASS_DEVICE
71 help
72 Say Y here if you want to enable support for Orise Technology
73 otm8009a 480x800 dsi 2dl panel.
74
66config DRM_PANEL_PANASONIC_VVX10F034N00 75config DRM_PANEL_PANASONIC_VVX10F034N00
67 tristate "Panasonic VVX10F034N00 1920x1200 video mode panel" 76 tristate "Panasonic VVX10F034N00 1920x1200 video mode panel"
68 depends on OF 77 depends on OF
@@ -80,12 +89,28 @@ config DRM_PANEL_SAMSUNG_S6E3HA2
80 depends on BACKLIGHT_CLASS_DEVICE 89 depends on BACKLIGHT_CLASS_DEVICE
81 select VIDEOMODE_HELPERS 90 select VIDEOMODE_HELPERS
82 91
92config DRM_PANEL_SAMSUNG_S6E63J0X03
93 tristate "Samsung S6E63J0X03 DSI command mode panel"
94 depends on OF
95 depends on DRM_MIPI_DSI
96 depends on BACKLIGHT_CLASS_DEVICE
97 select VIDEOMODE_HELPERS
98
83config DRM_PANEL_SAMSUNG_S6E8AA0 99config DRM_PANEL_SAMSUNG_S6E8AA0
84 tristate "Samsung S6E8AA0 DSI video mode panel" 100 tristate "Samsung S6E8AA0 DSI video mode panel"
85 depends on OF 101 depends on OF
86 select DRM_MIPI_DSI 102 select DRM_MIPI_DSI
87 select VIDEOMODE_HELPERS 103 select VIDEOMODE_HELPERS
88 104
105config DRM_PANEL_SEIKO_43WVF1G
106 tristate "Seiko 43WVF1G panel"
107 depends on OF
108 depends on BACKLIGHT_CLASS_DEVICE
109 select VIDEOMODE_HELPERS
110 help
111 Say Y here if you want to enable support for the Seiko
112 43WVF1G controller for 800x480 LCD panels
113
89config DRM_PANEL_SHARP_LQ101R1SX01 114config DRM_PANEL_SHARP_LQ101R1SX01
90 tristate "Sharp LQ101R1SX01 panel" 115 tristate "Sharp LQ101R1SX01 panel"
91 depends on OF 116 depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 9f6610d08b00..c8483fdd5b9b 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -3,10 +3,13 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
3obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o 3obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
4obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o 4obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
5obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o 5obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
6obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o
6obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o 7obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
7obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o 8obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
8obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o 9obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
10obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
9obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o 11obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
12obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
10obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o 13obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
11obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o 14obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
12obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o 15obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
new file mode 100644
index 000000000000..c189cd6329c8
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
@@ -0,0 +1,491 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2017
3 *
4 * Authors: Philippe Cornu <philippe.cornu@st.com>
5 * Yannick Fertre <yannick.fertre@st.com>
6 *
7 * License terms: GNU General Public License (GPL), version 2
8 */
9#include <drm/drmP.h>
10#include <drm/drm_mipi_dsi.h>
11#include <drm/drm_panel.h>
12#include <linux/backlight.h>
13#include <linux/gpio/consumer.h>
14#include <video/mipi_display.h>
15
16#define DRV_NAME "orisetech_otm8009a"
17
18#define OTM8009A_BACKLIGHT_DEFAULT 240
19#define OTM8009A_BACKLIGHT_MAX 255
20
21/* Manufacturer Command Set */
22#define MCS_ADRSFT 0x0000 /* Address Shift Function */
23#define MCS_PANSET 0xB3A6 /* Panel Type Setting */
24#define MCS_SD_CTRL 0xC0A2 /* Source Driver Timing Setting */
25#define MCS_P_DRV_M 0xC0B4 /* Panel Driving Mode */
26#define MCS_OSC_ADJ 0xC181 /* Oscillator Adjustment for Idle/Normal mode */
27#define MCS_RGB_VID_SET 0xC1A1 /* RGB Video Mode Setting */
28#define MCS_SD_PCH_CTRL 0xC480 /* Source Driver Precharge Control */
29#define MCS_NO_DOC1 0xC48A /* Command not documented */
30#define MCS_PWR_CTRL1 0xC580 /* Power Control Setting 1 */
31#define MCS_PWR_CTRL2 0xC590 /* Power Control Setting 2 for Normal Mode */
32#define MCS_PWR_CTRL4 0xC5B0 /* Power Control Setting 4 for DC Voltage */
33#define MCS_PANCTRLSET1 0xCB80 /* Panel Control Setting 1 */
34#define MCS_PANCTRLSET2 0xCB90 /* Panel Control Setting 2 */
35#define MCS_PANCTRLSET3 0xCBA0 /* Panel Control Setting 3 */
36#define MCS_PANCTRLSET4 0xCBB0 /* Panel Control Setting 4 */
37#define MCS_PANCTRLSET5 0xCBC0 /* Panel Control Setting 5 */
38#define MCS_PANCTRLSET6 0xCBD0 /* Panel Control Setting 6 */
39#define MCS_PANCTRLSET7 0xCBE0 /* Panel Control Setting 7 */
40#define MCS_PANCTRLSET8 0xCBF0 /* Panel Control Setting 8 */
41#define MCS_PANU2D1 0xCC80 /* Panel U2D Setting 1 */
42#define MCS_PANU2D2 0xCC90 /* Panel U2D Setting 2 */
43#define MCS_PANU2D3 0xCCA0 /* Panel U2D Setting 3 */
44#define MCS_PAND2U1 0xCCB0 /* Panel D2U Setting 1 */
45#define MCS_PAND2U2 0xCCC0 /* Panel D2U Setting 2 */
46#define MCS_PAND2U3 0xCCD0 /* Panel D2U Setting 3 */
47#define MCS_GOAVST 0xCE80 /* GOA VST Setting */
48#define MCS_GOACLKA1 0xCEA0 /* GOA CLKA1 Setting */
49#define MCS_GOACLKA3 0xCEB0 /* GOA CLKA3 Setting */
50#define MCS_GOAECLK 0xCFC0 /* GOA ECLK Setting */
51#define MCS_NO_DOC2 0xCFD0 /* Command not documented */
52#define MCS_GVDDSET 0xD800 /* GVDD/NGVDD */
53#define MCS_VCOMDC 0xD900 /* VCOM Voltage Setting */
54#define MCS_GMCT2_2P 0xE100 /* Gamma Correction 2.2+ Setting */
55#define MCS_GMCT2_2N 0xE200 /* Gamma Correction 2.2- Setting */
56#define MCS_NO_DOC3 0xF5B6 /* Command not documented */
57#define MCS_CMD2_ENA1 0xFF00 /* Enable Access Command2 "CMD2" */
58#define MCS_CMD2_ENA2 0xFF80 /* Enable Access Orise Command2 */
59
60struct otm8009a {
61 struct device *dev;
62 struct drm_panel panel;
63 struct backlight_device *bl_dev;
64 struct gpio_desc *reset_gpio;
65 bool prepared;
66 bool enabled;
67};
68
69static const struct drm_display_mode default_mode = {
70 .clock = 32729,
71 .hdisplay = 480,
72 .hsync_start = 480 + 120,
73 .hsync_end = 480 + 120 + 63,
74 .htotal = 480 + 120 + 63 + 120,
75 .vdisplay = 800,
76 .vsync_start = 800 + 12,
77 .vsync_end = 800 + 12 + 12,
78 .vtotal = 800 + 12 + 12 + 12,
79 .vrefresh = 50,
80 .flags = 0,
81 .width_mm = 52,
82 .height_mm = 86,
83};
84
85static inline struct otm8009a *panel_to_otm8009a(struct drm_panel *panel)
86{
87 return container_of(panel, struct otm8009a, panel);
88}
89
90static void otm8009a_dcs_write_buf(struct otm8009a *ctx, const void *data,
91 size_t len)
92{
93 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
94
95 if (mipi_dsi_dcs_write_buffer(dsi, data, len) < 0)
96 DRM_WARN("mipi dsi dcs write buffer failed\n");
97}
98
99#define dcs_write_seq(ctx, seq...) \
100({ \
101 static const u8 d[] = { seq }; \
102 otm8009a_dcs_write_buf(ctx, d, ARRAY_SIZE(d)); \
103})
104
105#define dcs_write_cmd_at(ctx, cmd, seq...) \
106({ \
107 dcs_write_seq(ctx, MCS_ADRSFT, (cmd) & 0xFF); \
108 dcs_write_seq(ctx, (cmd) >> 8, seq); \
109})
110
111static int otm8009a_init_sequence(struct otm8009a *ctx)
112{
113 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
114 int ret;
115
116 /* Enter CMD2 */
117 dcs_write_cmd_at(ctx, MCS_CMD2_ENA1, 0x80, 0x09, 0x01);
118
119 /* Enter Orise Command2 */
120 dcs_write_cmd_at(ctx, MCS_CMD2_ENA2, 0x80, 0x09);
121
122 dcs_write_cmd_at(ctx, MCS_SD_PCH_CTRL, 0x30);
123 mdelay(10);
124
125 dcs_write_cmd_at(ctx, MCS_NO_DOC1, 0x40);
126 mdelay(10);
127
128 dcs_write_cmd_at(ctx, MCS_PWR_CTRL4 + 1, 0xA9);
129 dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 1, 0x34);
130 dcs_write_cmd_at(ctx, MCS_P_DRV_M, 0x50);
131 dcs_write_cmd_at(ctx, MCS_VCOMDC, 0x4E);
132 dcs_write_cmd_at(ctx, MCS_OSC_ADJ, 0x66); /* 65Hz */
133 dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 2, 0x01);
134 dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 5, 0x34);
135 dcs_write_cmd_at(ctx, MCS_PWR_CTRL2 + 4, 0x33);
136 dcs_write_cmd_at(ctx, MCS_GVDDSET, 0x79, 0x79);
137 dcs_write_cmd_at(ctx, MCS_SD_CTRL + 1, 0x1B);
138 dcs_write_cmd_at(ctx, MCS_PWR_CTRL1 + 2, 0x83);
139 dcs_write_cmd_at(ctx, MCS_SD_PCH_CTRL + 1, 0x83);
140 dcs_write_cmd_at(ctx, MCS_RGB_VID_SET, 0x0E);
141 dcs_write_cmd_at(ctx, MCS_PANSET, 0x00, 0x01);
142
143 dcs_write_cmd_at(ctx, MCS_GOAVST, 0x85, 0x01, 0x00, 0x84, 0x01, 0x00);
144 dcs_write_cmd_at(ctx, MCS_GOACLKA1, 0x18, 0x04, 0x03, 0x39, 0x00, 0x00,
145 0x00, 0x18, 0x03, 0x03, 0x3A, 0x00, 0x00, 0x00);
146 dcs_write_cmd_at(ctx, MCS_GOACLKA3, 0x18, 0x02, 0x03, 0x3B, 0x00, 0x00,
147 0x00, 0x18, 0x01, 0x03, 0x3C, 0x00, 0x00, 0x00);
148 dcs_write_cmd_at(ctx, MCS_GOAECLK, 0x01, 0x01, 0x20, 0x20, 0x00, 0x00,
149 0x01, 0x02, 0x00, 0x00);
150
151 dcs_write_cmd_at(ctx, MCS_NO_DOC2, 0x00);
152
153 dcs_write_cmd_at(ctx, MCS_PANCTRLSET1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
154 dcs_write_cmd_at(ctx, MCS_PANCTRLSET2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
155 0, 0, 0, 0, 0);
156 dcs_write_cmd_at(ctx, MCS_PANCTRLSET3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
157 0, 0, 0, 0, 0);
158 dcs_write_cmd_at(ctx, MCS_PANCTRLSET4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
159 dcs_write_cmd_at(ctx, MCS_PANCTRLSET5, 0, 4, 4, 4, 4, 4, 0, 0, 0, 0,
160 0, 0, 0, 0, 0);
161 dcs_write_cmd_at(ctx, MCS_PANCTRLSET6, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4,
162 4, 0, 0, 0, 0);
163 dcs_write_cmd_at(ctx, MCS_PANCTRLSET7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
164 dcs_write_cmd_at(ctx, MCS_PANCTRLSET8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
165 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
166
167 dcs_write_cmd_at(ctx, MCS_PANU2D1, 0x00, 0x26, 0x09, 0x0B, 0x01, 0x25,
168 0x00, 0x00, 0x00, 0x00);
169 dcs_write_cmd_at(ctx, MCS_PANU2D2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x0A, 0x0C, 0x02);
171 dcs_write_cmd_at(ctx, MCS_PANU2D3, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
173 dcs_write_cmd_at(ctx, MCS_PAND2U1, 0x00, 0x25, 0x0C, 0x0A, 0x02, 0x26,
174 0x00, 0x00, 0x00, 0x00);
175 dcs_write_cmd_at(ctx, MCS_PAND2U2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x0B, 0x09, 0x01);
177 dcs_write_cmd_at(ctx, MCS_PAND2U3, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
179
180 dcs_write_cmd_at(ctx, MCS_PWR_CTRL1 + 1, 0x66);
181
182 dcs_write_cmd_at(ctx, MCS_NO_DOC3, 0x06);
183
184 dcs_write_cmd_at(ctx, MCS_GMCT2_2P, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10,
185 0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08, 0x0F, 0x10, 0x0A,
186 0x01);
187 dcs_write_cmd_at(ctx, MCS_GMCT2_2N, 0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10,
188 0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08, 0x0F, 0x10, 0x0A,
189 0x01);
190
191 /* Exit CMD2 */
192 dcs_write_cmd_at(ctx, MCS_CMD2_ENA1, 0xFF, 0xFF, 0xFF);
193
194 ret = mipi_dsi_dcs_nop(dsi);
195 if (ret)
196 return ret;
197
198 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
199 if (ret)
200 return ret;
201
202 /* Wait for sleep out exit */
203 mdelay(120);
204
205 /* Default portrait 480x800 rgb24 */
206 dcs_write_seq(ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
207
208 ret = mipi_dsi_dcs_set_column_address(dsi, 0,
209 default_mode.hdisplay - 1);
210 if (ret)
211 return ret;
212
213 ret = mipi_dsi_dcs_set_page_address(dsi, 0, default_mode.vdisplay - 1);
214 if (ret)
215 return ret;
216
217 /* See otm8009a driver documentation for pixel format descriptions */
218 ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT |
219 MIPI_DCS_PIXEL_FMT_24BIT << 4);
220 if (ret)
221 return ret;
222
223 /* Disable CABC feature */
224 dcs_write_seq(ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
225
226 ret = mipi_dsi_dcs_set_display_on(dsi);
227 if (ret)
228 return ret;
229
230 ret = mipi_dsi_dcs_nop(dsi);
231 if (ret)
232 return ret;
233
234 /* Send Command GRAM memory write (no parameters) */
235 dcs_write_seq(ctx, MIPI_DCS_WRITE_MEMORY_START);
236
237 return 0;
238}
239
240static int otm8009a_disable(struct drm_panel *panel)
241{
242 struct otm8009a *ctx = panel_to_otm8009a(panel);
243 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
244 int ret;
245
246 if (!ctx->enabled)
247 return 0; /* This is not an issue so we return 0 here */
248
249 /* Power off the backlight. Note: end-user still controls brightness */
250 ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
251 ret = backlight_update_status(ctx->bl_dev);
252 if (ret)
253 return ret;
254
255 ret = mipi_dsi_dcs_set_display_off(dsi);
256 if (ret)
257 return ret;
258
259 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
260 if (ret)
261 return ret;
262
263 msleep(120);
264
265 ctx->enabled = false;
266
267 return 0;
268}
269
270static int otm8009a_unprepare(struct drm_panel *panel)
271{
272 struct otm8009a *ctx = panel_to_otm8009a(panel);
273
274 if (!ctx->prepared)
275 return 0;
276
277 if (ctx->reset_gpio) {
278 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
279 msleep(20);
280 }
281
282 ctx->prepared = false;
283
284 return 0;
285}
286
287static int otm8009a_prepare(struct drm_panel *panel)
288{
289 struct otm8009a *ctx = panel_to_otm8009a(panel);
290 int ret;
291
292 if (ctx->prepared)
293 return 0;
294
295 if (ctx->reset_gpio) {
296 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
297 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
298 msleep(20);
299 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
300 msleep(100);
301 }
302
303 ret = otm8009a_init_sequence(ctx);
304 if (ret)
305 return ret;
306
307 ctx->prepared = true;
308
309 /*
310 * Power on the backlight. Note: end-user still controls brightness
311 * Note: ctx->prepared must be true before updating the backlight.
312 */
313 ctx->bl_dev->props.power = FB_BLANK_UNBLANK;
314 backlight_update_status(ctx->bl_dev);
315
316 return 0;
317}
318
319static int otm8009a_enable(struct drm_panel *panel)
320{
321 struct otm8009a *ctx = panel_to_otm8009a(panel);
322
323 ctx->enabled = true;
324
325 return 0;
326}
327
328static int otm8009a_get_modes(struct drm_panel *panel)
329{
330 struct drm_display_mode *mode;
331
332 mode = drm_mode_duplicate(panel->drm, &default_mode);
333 if (!mode) {
334 DRM_ERROR("failed to add mode %ux%ux@%u\n",
335 default_mode.hdisplay, default_mode.vdisplay,
336 default_mode.vrefresh);
337 return -ENOMEM;
338 }
339
340 drm_mode_set_name(mode);
341
342 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
343 drm_mode_probed_add(panel->connector, mode);
344
345 panel->connector->display_info.width_mm = mode->width_mm;
346 panel->connector->display_info.height_mm = mode->height_mm;
347
348 return 1;
349}
350
351static const struct drm_panel_funcs otm8009a_drm_funcs = {
352 .disable = otm8009a_disable,
353 .unprepare = otm8009a_unprepare,
354 .prepare = otm8009a_prepare,
355 .enable = otm8009a_enable,
356 .get_modes = otm8009a_get_modes,
357};
358
359/*
360 * DSI-BASED BACKLIGHT
361 */
362
363static int otm8009a_backlight_update_status(struct backlight_device *bd)
364{
365 struct otm8009a *ctx = bl_get_data(bd);
366 u8 data[2];
367
368 if (!ctx->prepared) {
369 DRM_DEBUG("lcd not ready yet for setting its backlight!\n");
370 return -ENXIO;
371 }
372
373 if (bd->props.power <= FB_BLANK_NORMAL) {
374 /* Power on the backlight with the requested brightness
375 * Note We can not use mipi_dsi_dcs_set_display_brightness()
376 * as otm8009a driver support only 8-bit brightness (1 param).
377 */
378 data[0] = MIPI_DCS_SET_DISPLAY_BRIGHTNESS;
379 data[1] = bd->props.brightness;
380 otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data));
381
382 /* set Brightness Control & Backlight on */
383 data[1] = 0x24;
384
385 } else {
386 /* Power off the backlight: set Brightness Control & Bl off */
387 data[1] = 0;
388 }
389
390 /* Update Brightness Control & Backlight */
391 data[0] = MIPI_DCS_WRITE_CONTROL_DISPLAY;
392 otm8009a_dcs_write_buf(ctx, data, ARRAY_SIZE(data));
393
394 return 0;
395}
396
397static const struct backlight_ops otm8009a_backlight_ops = {
398 .update_status = otm8009a_backlight_update_status,
399};
400
401static int otm8009a_probe(struct mipi_dsi_device *dsi)
402{
403 struct device *dev = &dsi->dev;
404 struct otm8009a *ctx;
405 int ret;
406
407 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
408 if (!ctx)
409 return -ENOMEM;
410
411 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
412 if (IS_ERR(ctx->reset_gpio)) {
413 dev_err(dev, "cannot get reset-gpio\n");
414 return PTR_ERR(ctx->reset_gpio);
415 }
416
417 mipi_dsi_set_drvdata(dsi, ctx);
418
419 ctx->dev = dev;
420
421 dsi->lanes = 2;
422 dsi->format = MIPI_DSI_FMT_RGB888;
423 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
424 MIPI_DSI_MODE_LPM;
425
426 drm_panel_init(&ctx->panel);
427 ctx->panel.dev = dev;
428 ctx->panel.funcs = &otm8009a_drm_funcs;
429
430 ctx->bl_dev = backlight_device_register(DRV_NAME "_backlight", dev, ctx,
431 &otm8009a_backlight_ops, NULL);
432 if (IS_ERR(ctx->bl_dev)) {
433 dev_err(dev, "failed to register backlight device\n");
434 return PTR_ERR(ctx->bl_dev);
435 }
436
437 ctx->bl_dev->props.max_brightness = OTM8009A_BACKLIGHT_MAX;
438 ctx->bl_dev->props.brightness = OTM8009A_BACKLIGHT_DEFAULT;
439 ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
440 ctx->bl_dev->props.type = BACKLIGHT_RAW;
441
442 drm_panel_add(&ctx->panel);
443
444 ret = mipi_dsi_attach(dsi);
445 if (ret < 0) {
446 dev_err(dev, "mipi_dsi_attach failed. Is host ready?\n");
447 drm_panel_remove(&ctx->panel);
448 backlight_device_unregister(ctx->bl_dev);
449 return ret;
450 }
451
452 DRM_INFO(DRV_NAME "_panel %ux%u@%u %ubpp dsi %udl - ready\n",
453 default_mode.hdisplay, default_mode.vdisplay,
454 default_mode.vrefresh,
455 mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);
456
457 return 0;
458}
459
460static int otm8009a_remove(struct mipi_dsi_device *dsi)
461{
462 struct otm8009a *ctx = mipi_dsi_get_drvdata(dsi);
463
464 mipi_dsi_detach(dsi);
465 drm_panel_remove(&ctx->panel);
466
467 backlight_device_unregister(ctx->bl_dev);
468
469 return 0;
470}
471
472static const struct of_device_id orisetech_otm8009a_of_match[] = {
473 { .compatible = "orisetech,otm8009a" },
474 { }
475};
476MODULE_DEVICE_TABLE(of, orisetech_otm8009a_of_match);
477
478static struct mipi_dsi_driver orisetech_otm8009a_driver = {
479 .probe = otm8009a_probe,
480 .remove = otm8009a_remove,
481 .driver = {
482 .name = DRV_NAME "_panel",
483 .of_match_table = orisetech_otm8009a_of_match,
484 },
485};
486module_mipi_dsi_driver(orisetech_otm8009a_driver);
487
488MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
489MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
490MODULE_DESCRIPTION("DRM driver for Orise Tech OTM8009A MIPI DSI panel");
491MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c b/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c
new file mode 100644
index 000000000000..aeb32aa58899
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c
@@ -0,0 +1,532 @@
1/*
2 * MIPI-DSI based S6E63J0X03 AMOLED lcd 1.63 inch panel driver.
3 *
4 * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd
5 *
6 * Inki Dae <inki.dae@samsung.com>
7 * Hoegeun Kwon <hoegeun.kwon@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <drm/drmP.h>
15#include <drm/drm_mipi_dsi.h>
16#include <drm/drm_panel.h>
17#include <linux/backlight.h>
18#include <linux/gpio/consumer.h>
19#include <linux/regulator/consumer.h>
20#include <video/mipi_display.h>
21
22#define MCS_LEVEL2_KEY 0xf0
23#define MCS_MTP_KEY 0xf1
24#define MCS_MTP_SET3 0xd4
25
26#define MAX_BRIGHTNESS 100
27#define DEFAULT_BRIGHTNESS 80
28
29#define NUM_GAMMA_STEPS 9
30#define GAMMA_CMD_CNT 28
31
32#define FIRST_COLUMN 20
33
34struct s6e63j0x03 {
35 struct device *dev;
36 struct drm_panel panel;
37 struct backlight_device *bl_dev;
38
39 struct regulator_bulk_data supplies[2];
40 struct gpio_desc *reset_gpio;
41};
42
43static const struct drm_display_mode default_mode = {
44 .clock = 4649,
45 .hdisplay = 320,
46 .hsync_start = 320 + 1,
47 .hsync_end = 320 + 1 + 1,
48 .htotal = 320 + 1 + 1 + 1,
49 .vdisplay = 320,
50 .vsync_start = 320 + 150,
51 .vsync_end = 320 + 150 + 1,
52 .vtotal = 320 + 150 + 1 + 2,
53 .vrefresh = 30,
54 .flags = 0,
55};
56
57static const unsigned char gamma_tbl[NUM_GAMMA_STEPS][GAMMA_CMD_CNT] = {
58 { /* Gamma 10 */
59 MCS_MTP_SET3,
60 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x52, 0x6b, 0x6f, 0x26,
61 0x28, 0x2d, 0x28, 0x26, 0x27, 0x33, 0x34, 0x32, 0x36, 0x36,
62 0x35, 0x00, 0xab, 0x00, 0xae, 0x00, 0xbf
63 },
64 { /* gamma 30 */
65 MCS_MTP_SET3,
66 0x00, 0x00, 0x00, 0x70, 0x7f, 0x7f, 0x4e, 0x64, 0x69, 0x26,
67 0x27, 0x2a, 0x28, 0x29, 0x27, 0x31, 0x32, 0x31, 0x35, 0x34,
68 0x35, 0x00, 0xc4, 0x00, 0xca, 0x00, 0xdc
69 },
70 { /* gamma 60 */
71 MCS_MTP_SET3,
72 0x00, 0x00, 0x00, 0x65, 0x7b, 0x7d, 0x5f, 0x67, 0x68, 0x2a,
73 0x28, 0x29, 0x28, 0x2a, 0x27, 0x31, 0x2f, 0x30, 0x34, 0x33,
74 0x34, 0x00, 0xd9, 0x00, 0xe4, 0x00, 0xf5
75 },
76 { /* gamma 90 */
77 MCS_MTP_SET3,
78 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x71, 0x67, 0x6a, 0x6c, 0x29,
79 0x28, 0x28, 0x28, 0x29, 0x27, 0x30, 0x2e, 0x30, 0x32, 0x31,
80 0x31, 0x00, 0xea, 0x00, 0xf6, 0x01, 0x09
81 },
82 { /* gamma 120 */
83 MCS_MTP_SET3,
84 0x00, 0x00, 0x00, 0x3d, 0x66, 0x68, 0x69, 0x69, 0x69, 0x28,
85 0x28, 0x27, 0x28, 0x28, 0x27, 0x30, 0x2e, 0x2f, 0x31, 0x31,
86 0x30, 0x00, 0xf9, 0x01, 0x05, 0x01, 0x1b
87 },
88 { /* gamma 150 */
89 MCS_MTP_SET3,
90 0x00, 0x00, 0x00, 0x31, 0x51, 0x53, 0x66, 0x66, 0x67, 0x28,
91 0x29, 0x27, 0x28, 0x27, 0x27, 0x2e, 0x2d, 0x2e, 0x31, 0x31,
92 0x30, 0x01, 0x04, 0x01, 0x11, 0x01, 0x29
93 },
94 { /* gamma 200 */
95 MCS_MTP_SET3,
96 0x00, 0x00, 0x00, 0x2f, 0x4f, 0x51, 0x67, 0x65, 0x65, 0x29,
97 0x2a, 0x28, 0x27, 0x25, 0x26, 0x2d, 0x2c, 0x2c, 0x30, 0x30,
98 0x30, 0x01, 0x14, 0x01, 0x23, 0x01, 0x3b
99 },
100 { /* gamma 240 */
101 MCS_MTP_SET3,
102 0x00, 0x00, 0x00, 0x2c, 0x4d, 0x50, 0x65, 0x63, 0x64, 0x2a,
103 0x2c, 0x29, 0x26, 0x24, 0x25, 0x2c, 0x2b, 0x2b, 0x30, 0x30,
104 0x30, 0x01, 0x1e, 0x01, 0x2f, 0x01, 0x47
105 },
106 { /* gamma 300 */
107 MCS_MTP_SET3,
108 0x00, 0x00, 0x00, 0x38, 0x61, 0x64, 0x65, 0x63, 0x64, 0x28,
109 0x2a, 0x27, 0x26, 0x23, 0x25, 0x2b, 0x2b, 0x2a, 0x30, 0x2f,
110 0x30, 0x01, 0x2d, 0x01, 0x3f, 0x01, 0x57
111 }
112};
113
114static inline struct s6e63j0x03 *panel_to_s6e63j0x03(struct drm_panel *panel)
115{
116 return container_of(panel, struct s6e63j0x03, panel);
117}
118
119static inline ssize_t s6e63j0x03_dcs_write_seq(struct s6e63j0x03 *ctx,
120 const void *seq, size_t len)
121{
122 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
123
124 return mipi_dsi_dcs_write_buffer(dsi, seq, len);
125}
126
127#define s6e63j0x03_dcs_write_seq_static(ctx, seq...) \
128 ({ \
129 static const u8 d[] = { seq }; \
130 s6e63j0x03_dcs_write_seq(ctx, d, ARRAY_SIZE(d)); \
131 })
132
133static inline int s6e63j0x03_enable_lv2_command(struct s6e63j0x03 *ctx)
134{
135 return s6e63j0x03_dcs_write_seq_static(ctx, MCS_LEVEL2_KEY, 0x5a, 0x5a);
136}
137
138static inline int s6e63j0x03_apply_mtp_key(struct s6e63j0x03 *ctx, bool on)
139{
140 if (on)
141 return s6e63j0x03_dcs_write_seq_static(ctx,
142 MCS_MTP_KEY, 0x5a, 0x5a);
143
144 return s6e63j0x03_dcs_write_seq_static(ctx, MCS_MTP_KEY, 0xa5, 0xa5);
145}
146
147static int s6e63j0x03_power_on(struct s6e63j0x03 *ctx)
148{
149 int ret;
150
151 ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
152 if (ret < 0)
153 return ret;
154
155 msleep(30);
156
157 gpiod_set_value(ctx->reset_gpio, 1);
158 usleep_range(1000, 2000);
159 gpiod_set_value(ctx->reset_gpio, 0);
160 usleep_range(5000, 6000);
161
162 return 0;
163}
164
165static int s6e63j0x03_power_off(struct s6e63j0x03 *ctx)
166{
167 return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
168}
169
170static unsigned int s6e63j0x03_get_brightness_index(unsigned int brightness)
171{
172 unsigned int index;
173
174 index = brightness / (MAX_BRIGHTNESS / NUM_GAMMA_STEPS);
175
176 if (index >= NUM_GAMMA_STEPS)
177 index = NUM_GAMMA_STEPS - 1;
178
179 return index;
180}
181
182static int s6e63j0x03_update_gamma(struct s6e63j0x03 *ctx,
183 unsigned int brightness)
184{
185 struct backlight_device *bl_dev = ctx->bl_dev;
186 unsigned int index = s6e63j0x03_get_brightness_index(brightness);
187 int ret;
188
189 ret = s6e63j0x03_apply_mtp_key(ctx, true);
190 if (ret < 0)
191 return ret;
192
193 ret = s6e63j0x03_dcs_write_seq(ctx, gamma_tbl[index], GAMMA_CMD_CNT);
194 if (ret < 0)
195 return ret;
196
197 ret = s6e63j0x03_apply_mtp_key(ctx, false);
198 if (ret < 0)
199 return ret;
200
201 bl_dev->props.brightness = brightness;
202
203 return 0;
204}
205
206static int s6e63j0x03_set_brightness(struct backlight_device *bl_dev)
207{
208 struct s6e63j0x03 *ctx = bl_get_data(bl_dev);
209 unsigned int brightness = bl_dev->props.brightness;
210
211 return s6e63j0x03_update_gamma(ctx, brightness);
212}
213
214static const struct backlight_ops s6e63j0x03_bl_ops = {
215 .update_status = s6e63j0x03_set_brightness,
216};
217
218static int s6e63j0x03_disable(struct drm_panel *panel)
219{
220 struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
221 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
222 int ret;
223
224 ret = mipi_dsi_dcs_set_display_off(dsi);
225 if (ret < 0)
226 return ret;
227
228 ctx->bl_dev->props.power = FB_BLANK_NORMAL;
229
230 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
231 if (ret < 0)
232 return ret;
233
234 msleep(120);
235
236 return 0;
237}
238
239static int s6e63j0x03_unprepare(struct drm_panel *panel)
240{
241 struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
242 int ret;
243
244 ret = s6e63j0x03_power_off(ctx);
245 if (ret < 0)
246 return ret;
247
248 ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
249
250 return 0;
251}
252
253static int s6e63j0x03_panel_init(struct s6e63j0x03 *ctx)
254{
255 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
256 int ret;
257
258 ret = s6e63j0x03_enable_lv2_command(ctx);
259 if (ret < 0)
260 return ret;
261
262 ret = s6e63j0x03_apply_mtp_key(ctx, true);
263 if (ret < 0)
264 return ret;
265
266 /* set porch adjustment */
267 ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf2, 0x1c, 0x28);
268 if (ret < 0)
269 return ret;
270
271 /* set frame freq */
272 ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb5, 0x00, 0x02, 0x00);
273 if (ret < 0)
274 return ret;
275
276 /* set caset, paset */
277 ret = mipi_dsi_dcs_set_column_address(dsi, FIRST_COLUMN,
278 default_mode.hdisplay - 1 + FIRST_COLUMN);
279 if (ret < 0)
280 return ret;
281
282 ret = mipi_dsi_dcs_set_page_address(dsi, 0, default_mode.vdisplay - 1);
283 if (ret < 0)
284 return ret;
285
286 /* set ltps timming 0, 1 */
287 ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf8, 0x08, 0x08, 0x08, 0x17,
288 0x00, 0x2a, 0x02, 0x26, 0x00, 0x00, 0x02, 0x00, 0x00);
289 if (ret < 0)
290 return ret;
291
292 ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xf7, 0x02);
293 if (ret < 0)
294 return ret;
295
296 /* set param pos te_edge */
297 ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb0, 0x01);
298 if (ret < 0)
299 return ret;
300
301 /* set te rising edge */
302 ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xe2, 0x0f);
303 if (ret < 0)
304 return ret;
305
306 /* set param pos default */
307 ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb0, 0x00);
308 if (ret < 0)
309 return ret;
310
311 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
312 if (ret < 0)
313 return ret;
314
315 ret = s6e63j0x03_apply_mtp_key(ctx, false);
316 if (ret < 0)
317 return ret;
318
319 return 0;
320}
321
322static int s6e63j0x03_prepare(struct drm_panel *panel)
323{
324 struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
325 int ret;
326
327 ret = s6e63j0x03_power_on(ctx);
328 if (ret < 0)
329 return ret;
330
331 ret = s6e63j0x03_panel_init(ctx);
332 if (ret < 0)
333 goto err;
334
335 ctx->bl_dev->props.power = FB_BLANK_NORMAL;
336
337 return 0;
338
339err:
340 s6e63j0x03_power_off(ctx);
341 return ret;
342}
343
344static int s6e63j0x03_enable(struct drm_panel *panel)
345{
346 struct s6e63j0x03 *ctx = panel_to_s6e63j0x03(panel);
347 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
348 int ret;
349
350 msleep(120);
351
352 ret = s6e63j0x03_apply_mtp_key(ctx, true);
353 if (ret < 0)
354 return ret;
355
356 /* set elvss_cond */
357 ret = s6e63j0x03_dcs_write_seq_static(ctx, 0xb1, 0x00, 0x09);
358 if (ret < 0)
359 return ret;
360
361 /* set pos */
362 ret = s6e63j0x03_dcs_write_seq_static(ctx,
363 MIPI_DCS_SET_ADDRESS_MODE, 0x40);
364 if (ret < 0)
365 return ret;
366
367 /* set default white brightness */
368 ret = mipi_dsi_dcs_set_display_brightness(dsi, 0x00ff);
369 if (ret < 0)
370 return ret;
371
372 /* set white ctrl */
373 ret = s6e63j0x03_dcs_write_seq_static(ctx,
374 MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
375 if (ret < 0)
376 return ret;
377
378 /* set acl off */
379 ret = s6e63j0x03_dcs_write_seq_static(ctx,
380 MIPI_DCS_WRITE_POWER_SAVE, 0x00);
381 if (ret < 0)
382 return ret;
383
384 ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
385 if (ret < 0)
386 return ret;
387
388 ret = s6e63j0x03_apply_mtp_key(ctx, false);
389 if (ret < 0)
390 return ret;
391
392 ret = mipi_dsi_dcs_set_display_on(dsi);
393 if (ret < 0)
394 return ret;
395
396 ctx->bl_dev->props.power = FB_BLANK_UNBLANK;
397
398 return 0;
399}
400
401static int s6e63j0x03_get_modes(struct drm_panel *panel)
402{
403 struct drm_connector *connector = panel->connector;
404 struct drm_display_mode *mode;
405
406 mode = drm_mode_duplicate(panel->drm, &default_mode);
407 if (!mode) {
408 DRM_ERROR("failed to add mode %ux%ux@%u\n",
409 default_mode.hdisplay, default_mode.vdisplay,
410 default_mode.vrefresh);
411 return -ENOMEM;
412 }
413
414 drm_mode_set_name(mode);
415
416 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
417 drm_mode_probed_add(connector, mode);
418
419 connector->display_info.width_mm = 29;
420 connector->display_info.height_mm = 29;
421
422 return 1;
423}
424
425static const struct drm_panel_funcs s6e63j0x03_funcs = {
426 .disable = s6e63j0x03_disable,
427 .unprepare = s6e63j0x03_unprepare,
428 .prepare = s6e63j0x03_prepare,
429 .enable = s6e63j0x03_enable,
430 .get_modes = s6e63j0x03_get_modes,
431};
432
433static int s6e63j0x03_probe(struct mipi_dsi_device *dsi)
434{
435 struct device *dev = &dsi->dev;
436 struct s6e63j0x03 *ctx;
437 int ret;
438
439 ctx = devm_kzalloc(dev, sizeof(struct s6e63j0x03), GFP_KERNEL);
440 if (!ctx)
441 return -ENOMEM;
442
443 mipi_dsi_set_drvdata(dsi, ctx);
444
445 ctx->dev = dev;
446
447 dsi->lanes = 1;
448 dsi->format = MIPI_DSI_FMT_RGB888;
449 dsi->mode_flags = MIPI_DSI_MODE_EOT_PACKET;
450
451 ctx->supplies[0].supply = "vdd3";
452 ctx->supplies[1].supply = "vci";
453 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
454 ctx->supplies);
455 if (ret < 0) {
456 dev_err(dev, "failed to get regulators: %d\n", ret);
457 return ret;
458 }
459
460 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
461 if (IS_ERR(ctx->reset_gpio)) {
462 dev_err(dev, "cannot get reset-gpio: %ld\n",
463 PTR_ERR(ctx->reset_gpio));
464 return PTR_ERR(ctx->reset_gpio);
465 }
466
467 drm_panel_init(&ctx->panel);
468 ctx->panel.dev = dev;
469 ctx->panel.funcs = &s6e63j0x03_funcs;
470
471 ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx,
472 &s6e63j0x03_bl_ops, NULL);
473 if (IS_ERR(ctx->bl_dev)) {
474 dev_err(dev, "failed to register backlight device\n");
475 return PTR_ERR(ctx->bl_dev);
476 }
477
478 ctx->bl_dev->props.max_brightness = MAX_BRIGHTNESS;
479 ctx->bl_dev->props.brightness = DEFAULT_BRIGHTNESS;
480 ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
481
482 ret = drm_panel_add(&ctx->panel);
483 if (ret < 0)
484 goto unregister_backlight;
485
486 ret = mipi_dsi_attach(dsi);
487 if (ret < 0)
488 goto remove_panel;
489
490 return ret;
491
492remove_panel:
493 drm_panel_remove(&ctx->panel);
494
495unregister_backlight:
496 backlight_device_unregister(ctx->bl_dev);
497
498 return ret;
499}
500
501static int s6e63j0x03_remove(struct mipi_dsi_device *dsi)
502{
503 struct s6e63j0x03 *ctx = mipi_dsi_get_drvdata(dsi);
504
505 mipi_dsi_detach(dsi);
506 drm_panel_remove(&ctx->panel);
507
508 backlight_device_unregister(ctx->bl_dev);
509
510 return 0;
511}
512
513static const struct of_device_id s6e63j0x03_of_match[] = {
514 { .compatible = "samsung,s6e63j0x03" },
515 { }
516};
517MODULE_DEVICE_TABLE(of, s6e63j0x03_of_match);
518
519static struct mipi_dsi_driver s6e63j0x03_driver = {
520 .probe = s6e63j0x03_probe,
521 .remove = s6e63j0x03_remove,
522 .driver = {
523 .name = "panel_samsung_s6e63j0x03",
524 .of_match_table = s6e63j0x03_of_match,
525 },
526};
527module_mipi_dsi_driver(s6e63j0x03_driver);
528
529MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
530MODULE_AUTHOR("Hoegeun Kwon <hoegeun.kwon@samsung.com>");
531MODULE_DESCRIPTION("MIPI-DSI based s6e63j0x03 AMOLED LCD Panel Driver");
532MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
new file mode 100644
index 000000000000..71c09ed436ae
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
@@ -0,0 +1,372 @@
1/*
2 * Copyright (C) 2017 NXP Semiconductors.
3 * Author: Marco Franchi <marco.franchi@nxp.com>
4 *
5 * Based on Panel Simple driver by Thierry Reding <treding@nvidia.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
10 */
11
12#include <linux/backlight.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/regulator/consumer.h>
16
17#include <drm/drmP.h>
18#include <drm/drm_crtc.h>
19#include <drm/drm_panel.h>
20
21#include <video/display_timing.h>
22#include <video/videomode.h>
23
24struct seiko_panel_desc {
25 const struct drm_display_mode *modes;
26 unsigned int num_modes;
27 const struct display_timing *timings;
28 unsigned int num_timings;
29
30 unsigned int bpc;
31
32 /**
33 * @width: width (in millimeters) of the panel's active display area
34 * @height: height (in millimeters) of the panel's active display area
35 */
36 struct {
37 unsigned int width;
38 unsigned int height;
39 } size;
40
41 u32 bus_format;
42 u32 bus_flags;
43};
44
45struct seiko_panel {
46 struct drm_panel base;
47 bool prepared;
48 bool enabled;
49 const struct seiko_panel_desc *desc;
50 struct backlight_device *backlight;
51 struct regulator *dvdd;
52 struct regulator *avdd;
53};
54
55static inline struct seiko_panel *to_seiko_panel(struct drm_panel *panel)
56{
57 return container_of(panel, struct seiko_panel, base);
58}
59
60static int seiko_panel_get_fixed_modes(struct seiko_panel *panel)
61{
62 struct drm_connector *connector = panel->base.connector;
63 struct drm_device *drm = panel->base.drm;
64 struct drm_display_mode *mode;
65 unsigned int i, num = 0;
66
67 if (!panel->desc)
68 return 0;
69
70 for (i = 0; i < panel->desc->num_timings; i++) {
71 const struct display_timing *dt = &panel->desc->timings[i];
72 struct videomode vm;
73
74 videomode_from_timing(dt, &vm);
75 mode = drm_mode_create(drm);
76 if (!mode) {
77 dev_err(drm->dev, "failed to add mode %ux%u\n",
78 dt->hactive.typ, dt->vactive.typ);
79 continue;
80 }
81
82 drm_display_mode_from_videomode(&vm, mode);
83
84 mode->type |= DRM_MODE_TYPE_DRIVER;
85
86 if (panel->desc->num_timings == 1)
87 mode->type |= DRM_MODE_TYPE_PREFERRED;
88
89 drm_mode_probed_add(connector, mode);
90 num++;
91 }
92
93 for (i = 0; i < panel->desc->num_modes; i++) {
94 const struct drm_display_mode *m = &panel->desc->modes[i];
95
96 mode = drm_mode_duplicate(drm, m);
97 if (!mode) {
98 dev_err(drm->dev, "failed to add mode %ux%u@%u\n",
99 m->hdisplay, m->vdisplay, m->vrefresh);
100 continue;
101 }
102
103 mode->type |= DRM_MODE_TYPE_DRIVER;
104
105 if (panel->desc->num_modes == 1)
106 mode->type |= DRM_MODE_TYPE_PREFERRED;
107
108 drm_mode_set_name(mode);
109
110 drm_mode_probed_add(connector, mode);
111 num++;
112 }
113
114 connector->display_info.bpc = panel->desc->bpc;
115 connector->display_info.width_mm = panel->desc->size.width;
116 connector->display_info.height_mm = panel->desc->size.height;
117 if (panel->desc->bus_format)
118 drm_display_info_set_bus_formats(&connector->display_info,
119 &panel->desc->bus_format, 1);
120 connector->display_info.bus_flags = panel->desc->bus_flags;
121
122 return num;
123}
124
125static int seiko_panel_disable(struct drm_panel *panel)
126{
127 struct seiko_panel *p = to_seiko_panel(panel);
128
129 if (!p->enabled)
130 return 0;
131
132 if (p->backlight) {
133 p->backlight->props.power = FB_BLANK_POWERDOWN;
134 p->backlight->props.state |= BL_CORE_FBBLANK;
135 backlight_update_status(p->backlight);
136 }
137
138 p->enabled = false;
139
140 return 0;
141}
142
143static int seiko_panel_unprepare(struct drm_panel *panel)
144{
145 struct seiko_panel *p = to_seiko_panel(panel);
146
147 if (!p->prepared)
148 return 0;
149
150 regulator_disable(p->avdd);
151
152 /* Add a 100ms delay as per the panel datasheet */
153 msleep(100);
154
155 regulator_disable(p->dvdd);
156
157 p->prepared = false;
158
159 return 0;
160}
161
162static int seiko_panel_prepare(struct drm_panel *panel)
163{
164 struct seiko_panel *p = to_seiko_panel(panel);
165 int err;
166
167 if (p->prepared)
168 return 0;
169
170 err = regulator_enable(p->dvdd);
171 if (err < 0) {
172 dev_err(panel->dev, "failed to enable dvdd: %d\n", err);
173 return err;
174 }
175
176 /* Add a 100ms delay as per the panel datasheet */
177 msleep(100);
178
179 err = regulator_enable(p->avdd);
180 if (err < 0) {
181 dev_err(panel->dev, "failed to enable avdd: %d\n", err);
182 goto disable_dvdd;
183 }
184
185 p->prepared = true;
186
187 return 0;
188
189disable_dvdd:
190 regulator_disable(p->dvdd);
191 return err;
192}
193
194static int seiko_panel_enable(struct drm_panel *panel)
195{
196 struct seiko_panel *p = to_seiko_panel(panel);
197
198 if (p->enabled)
199 return 0;
200
201 if (p->backlight) {
202 p->backlight->props.state &= ~BL_CORE_FBBLANK;
203 p->backlight->props.power = FB_BLANK_UNBLANK;
204 backlight_update_status(p->backlight);
205 }
206
207 p->enabled = true;
208
209 return 0;
210}
211
212static int seiko_panel_get_modes(struct drm_panel *panel)
213{
214 struct seiko_panel *p = to_seiko_panel(panel);
215
216 /* add hard-coded panel modes */
217 return seiko_panel_get_fixed_modes(p);
218}
219
220static int seiko_panel_get_timings(struct drm_panel *panel,
221 unsigned int num_timings,
222 struct display_timing *timings)
223{
224 struct seiko_panel *p = to_seiko_panel(panel);
225 unsigned int i;
226
227 if (p->desc->num_timings < num_timings)
228 num_timings = p->desc->num_timings;
229
230 if (timings)
231 for (i = 0; i < num_timings; i++)
232 timings[i] = p->desc->timings[i];
233
234 return p->desc->num_timings;
235}
236
237static const struct drm_panel_funcs seiko_panel_funcs = {
238 .disable = seiko_panel_disable,
239 .unprepare = seiko_panel_unprepare,
240 .prepare = seiko_panel_prepare,
241 .enable = seiko_panel_enable,
242 .get_modes = seiko_panel_get_modes,
243 .get_timings = seiko_panel_get_timings,
244};
245
246static int seiko_panel_probe(struct device *dev,
247 const struct seiko_panel_desc *desc)
248{
249 struct device_node *backlight;
250 struct seiko_panel *panel;
251 int err;
252
253 panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
254 if (!panel)
255 return -ENOMEM;
256
257 panel->enabled = false;
258 panel->prepared = false;
259 panel->desc = desc;
260
261 panel->dvdd = devm_regulator_get(dev, "dvdd");
262 if (IS_ERR(panel->dvdd))
263 return PTR_ERR(panel->dvdd);
264
265 panel->avdd = devm_regulator_get(dev, "avdd");
266 if (IS_ERR(panel->avdd))
267 return PTR_ERR(panel->avdd);
268
269 backlight = of_parse_phandle(dev->of_node, "backlight", 0);
270 if (backlight) {
271 panel->backlight = of_find_backlight_by_node(backlight);
272 of_node_put(backlight);
273
274 if (!panel->backlight)
275 return -EPROBE_DEFER;
276 }
277
278 drm_panel_init(&panel->base);
279 panel->base.dev = dev;
280 panel->base.funcs = &seiko_panel_funcs;
281
282 err = drm_panel_add(&panel->base);
283 if (err < 0)
284 return err;
285
286 dev_set_drvdata(dev, panel);
287
288 return 0;
289}
290
291static int seiko_panel_remove(struct platform_device *pdev)
292{
293 struct seiko_panel *panel = dev_get_drvdata(&pdev->dev);
294
295 drm_panel_detach(&panel->base);
296 drm_panel_remove(&panel->base);
297
298 seiko_panel_disable(&panel->base);
299
300 if (panel->backlight)
301 put_device(&panel->backlight->dev);
302
303 return 0;
304}
305
306static void seiko_panel_shutdown(struct platform_device *pdev)
307{
308 struct seiko_panel *panel = dev_get_drvdata(&pdev->dev);
309
310 seiko_panel_disable(&panel->base);
311}
312
313static const struct display_timing seiko_43wvf1g_timing = {
314 .pixelclock = { 33500000, 33500000, 33500000 },
315 .hactive = { 800, 800, 800 },
316 .hfront_porch = { 164, 164, 164 },
317 .hback_porch = { 89, 89, 89 },
318 .hsync_len = { 10, 10, 10 },
319 .vactive = { 480, 480, 480 },
320 .vfront_porch = { 10, 10, 10 },
321 .vback_porch = { 23, 23, 23 },
322 .vsync_len = { 10, 10, 10 },
323 .flags = DISPLAY_FLAGS_DE_LOW,
324};
325
326static const struct seiko_panel_desc seiko_43wvf1g = {
327 .timings = &seiko_43wvf1g_timing,
328 .num_timings = 1,
329 .bpc = 8,
330 .size = {
331 .width = 93,
332 .height = 57,
333 },
334 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
335 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
336};
337
338static const struct of_device_id platform_of_match[] = {
339 {
340 .compatible = "sii,43wvf1g",
341 .data = &seiko_43wvf1g,
342 }, {
343 /* sentinel */
344 }
345};
346MODULE_DEVICE_TABLE(of, platform_of_match);
347
348static int seiko_panel_platform_probe(struct platform_device *pdev)
349{
350 const struct of_device_id *id;
351
352 id = of_match_node(platform_of_match, pdev->dev.of_node);
353 if (!id)
354 return -ENODEV;
355
356 return seiko_panel_probe(&pdev->dev, id->data);
357}
358
359static struct platform_driver seiko_panel_platform_driver = {
360 .driver = {
361 .name = "seiko_panel",
362 .of_match_table = platform_of_match,
363 },
364 .probe = seiko_panel_platform_probe,
365 .remove = seiko_panel_remove,
366 .shutdown = seiko_panel_shutdown,
367};
368module_platform_driver(seiko_panel_platform_driver);
369
370MODULE_AUTHOR("Marco Franchi <marco.franchi@nxp.com");
371MODULE_DESCRIPTION("Seiko 43WVF1G panel driver");
372MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 474fa759e06e..a3c96d2ea41c 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -187,8 +187,7 @@ static int panel_simple_unprepare(struct drm_panel *panel)
187 if (!p->prepared) 187 if (!p->prepared)
188 return 0; 188 return 0;
189 189
190 if (p->enable_gpio) 190 gpiod_set_value_cansleep(p->enable_gpio, 0);
191 gpiod_set_value_cansleep(p->enable_gpio, 0);
192 191
193 regulator_disable(p->supply); 192 regulator_disable(p->supply);
194 193
@@ -214,8 +213,7 @@ static int panel_simple_prepare(struct drm_panel *panel)
214 return err; 213 return err;
215 } 214 }
216 215
217 if (p->enable_gpio) 216 gpiod_set_value_cansleep(p->enable_gpio, 1);
218 gpiod_set_value_cansleep(p->enable_gpio, 1);
219 217
220 if (p->desc->delay.prepare) 218 if (p->desc->delay.prepare)
221 msleep(p->desc->delay.prepare); 219 msleep(p->desc->delay.prepare);
@@ -315,7 +313,8 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
315 GPIOD_OUT_LOW); 313 GPIOD_OUT_LOW);
316 if (IS_ERR(panel->enable_gpio)) { 314 if (IS_ERR(panel->enable_gpio)) {
317 err = PTR_ERR(panel->enable_gpio); 315 err = PTR_ERR(panel->enable_gpio);
318 dev_err(dev, "failed to request GPIO: %d\n", err); 316 if (err != -EPROBE_DEFER)
317 dev_err(dev, "failed to request GPIO: %d\n", err);
319 return err; 318 return err;
320 } 319 }
321 320
@@ -369,6 +368,7 @@ static int panel_simple_remove(struct device *dev)
369 drm_panel_remove(&panel->base); 368 drm_panel_remove(&panel->base);
370 369
371 panel_simple_disable(&panel->base); 370 panel_simple_disable(&panel->base);
371 panel_simple_unprepare(&panel->base);
372 372
373 if (panel->ddc) 373 if (panel->ddc)
374 put_device(&panel->ddc->dev); 374 put_device(&panel->ddc->dev);
@@ -384,6 +384,7 @@ static void panel_simple_shutdown(struct device *dev)
384 struct panel_simple *panel = dev_get_drvdata(dev); 384 struct panel_simple *panel = dev_get_drvdata(dev);
385 385
386 panel_simple_disable(&panel->base); 386 panel_simple_disable(&panel->base);
387 panel_simple_unprepare(&panel->base);
387} 388}
388 389
389static const struct drm_display_mode ampire_am_480272h3tmqw_t01h_mode = { 390static const struct drm_display_mode ampire_am_480272h3tmqw_t01h_mode = {
@@ -1522,8 +1523,8 @@ static const struct panel_desc olimex_lcd_olinuxino_43ts = {
1522 .modes = &olimex_lcd_olinuxino_43ts_mode, 1523 .modes = &olimex_lcd_olinuxino_43ts_mode,
1523 .num_modes = 1, 1524 .num_modes = 1,
1524 .size = { 1525 .size = {
1525 .width = 105, 1526 .width = 95,
1526 .height = 67, 1527 .height = 54,
1527 }, 1528 },
1528 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1529 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1529}; 1530};
diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig
index bbfba87cd1a8..e5e2abd66491 100644
--- a/drivers/gpu/drm/pl111/Kconfig
+++ b/drivers/gpu/drm/pl111/Kconfig
@@ -6,7 +6,8 @@ config DRM_PL111
6 select DRM_KMS_HELPER 6 select DRM_KMS_HELPER
7 select DRM_KMS_CMA_HELPER 7 select DRM_KMS_CMA_HELPER
8 select DRM_GEM_CMA_HELPER 8 select DRM_GEM_CMA_HELPER
9 select DRM_PANEL 9 select DRM_BRIDGE
10 select DRM_PANEL_BRIDGE
10 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE 11 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
11 help 12 help
12 Choose this option for DRM support for the PL111 CLCD controller. 13 Choose this option for DRM support for the PL111 CLCD controller.
diff --git a/drivers/gpu/drm/pl111/Makefile b/drivers/gpu/drm/pl111/Makefile
index 59483d610ef5..fce1453a93e1 100644
--- a/drivers/gpu/drm/pl111/Makefile
+++ b/drivers/gpu/drm/pl111/Makefile
@@ -1,5 +1,5 @@
1pl111_drm-y += pl111_connector.o \ 1pl111_drm-y += pl111_display.o \
2 pl111_display.o \ 2 pl111_versatile.o \
3 pl111_drv.o 3 pl111_drv.o
4 4
5pl111_drm-$(CONFIG_DEBUG_FS) += pl111_debugfs.o 5pl111_drm-$(CONFIG_DEBUG_FS) += pl111_debugfs.o
diff --git a/drivers/gpu/drm/pl111/pl111_connector.c b/drivers/gpu/drm/pl111/pl111_connector.c
deleted file mode 100644
index d335f9a29ce4..000000000000
--- a/drivers/gpu/drm/pl111/pl111_connector.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/*
2 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
3 *
4 * Parts of this file were based on sources as follows:
5 *
6 * Copyright (c) 2006-2008 Intel Corporation
7 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
9 *
10 * This program is free software and is provided to you under the terms of the
11 * GNU General Public License version 2 as published by the Free Software
12 * Foundation, and any use by you of this program is subject to the terms of
13 * such GNU licence.
14 *
15 */
16
17/**
18 * pl111_drm_connector.c
19 * Implementation of the connector functions for PL111 DRM
20 */
21#include <linux/amba/clcd-regs.h>
22#include <linux/version.h>
23#include <linux/shmem_fs.h>
24#include <linux/dma-buf.h>
25
26#include <drm/drmP.h>
27#include <drm/drm_atomic_helper.h>
28#include <drm/drm_crtc_helper.h>
29#include <drm/drm_of.h>
30#include <drm/drm_panel.h>
31
32#include "pl111_drm.h"
33
34static void pl111_connector_destroy(struct drm_connector *connector)
35{
36 struct pl111_drm_connector *pl111_connector =
37 to_pl111_connector(connector);
38
39 if (pl111_connector->panel)
40 drm_panel_detach(pl111_connector->panel);
41
42 drm_connector_unregister(connector);
43 drm_connector_cleanup(connector);
44}
45
46static enum drm_connector_status pl111_connector_detect(struct drm_connector
47 *connector, bool force)
48{
49 struct pl111_drm_connector *pl111_connector =
50 to_pl111_connector(connector);
51
52 return (pl111_connector->panel ?
53 connector_status_connected :
54 connector_status_disconnected);
55}
56
57static int pl111_connector_helper_get_modes(struct drm_connector *connector)
58{
59 struct pl111_drm_connector *pl111_connector =
60 to_pl111_connector(connector);
61
62 if (!pl111_connector->panel)
63 return 0;
64
65 return drm_panel_get_modes(pl111_connector->panel);
66}
67
68const struct drm_connector_funcs connector_funcs = {
69 .fill_modes = drm_helper_probe_single_connector_modes,
70 .destroy = pl111_connector_destroy,
71 .detect = pl111_connector_detect,
72 .reset = drm_atomic_helper_connector_reset,
73 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
74 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
75};
76
77const struct drm_connector_helper_funcs connector_helper_funcs = {
78 .get_modes = pl111_connector_helper_get_modes,
79};
80
81/* Walks the OF graph to find the panel node and then asks DRM to look
82 * up the panel.
83 */
84static struct drm_panel *pl111_get_panel(struct device *dev)
85{
86 struct device_node *endpoint, *panel_node;
87 struct device_node *np = dev->of_node;
88 struct drm_panel *panel;
89
90 endpoint = of_graph_get_next_endpoint(np, NULL);
91 if (!endpoint) {
92 dev_err(dev, "no endpoint to fetch panel\n");
93 return NULL;
94 }
95
96 /* don't proceed if we have an endpoint but no panel_node tied to it */
97 panel_node = of_graph_get_remote_port_parent(endpoint);
98 of_node_put(endpoint);
99 if (!panel_node) {
100 dev_err(dev, "no valid panel node\n");
101 return NULL;
102 }
103
104 panel = of_drm_find_panel(panel_node);
105 of_node_put(panel_node);
106
107 return panel;
108}
109
110int pl111_connector_init(struct drm_device *dev)
111{
112 struct pl111_drm_dev_private *priv = dev->dev_private;
113 struct pl111_drm_connector *pl111_connector = &priv->connector;
114 struct drm_connector *connector = &pl111_connector->connector;
115
116 drm_connector_init(dev, connector, &connector_funcs,
117 DRM_MODE_CONNECTOR_DPI);
118 drm_connector_helper_add(connector, &connector_helper_funcs);
119
120 pl111_connector->panel = pl111_get_panel(dev->dev);
121 if (pl111_connector->panel)
122 drm_panel_attach(pl111_connector->panel, connector);
123
124 return 0;
125}
126
diff --git a/drivers/gpu/drm/pl111/pl111_debugfs.c b/drivers/gpu/drm/pl111/pl111_debugfs.c
index 0d9dee199b2c..7ddc7e3b9e7d 100644
--- a/drivers/gpu/drm/pl111/pl111_debugfs.c
+++ b/drivers/gpu/drm/pl111/pl111_debugfs.c
@@ -22,8 +22,14 @@ static const struct {
22 REGDEF(CLCD_TIM2), 22 REGDEF(CLCD_TIM2),
23 REGDEF(CLCD_TIM3), 23 REGDEF(CLCD_TIM3),
24 REGDEF(CLCD_UBAS), 24 REGDEF(CLCD_UBAS),
25 REGDEF(CLCD_LBAS),
25 REGDEF(CLCD_PL111_CNTL), 26 REGDEF(CLCD_PL111_CNTL),
26 REGDEF(CLCD_PL111_IENB), 27 REGDEF(CLCD_PL111_IENB),
28 REGDEF(CLCD_PL111_RIS),
29 REGDEF(CLCD_PL111_MIS),
30 REGDEF(CLCD_PL111_ICR),
31 REGDEF(CLCD_PL111_UCUR),
32 REGDEF(CLCD_PL111_LCUR),
27}; 33};
28 34
29int pl111_debugfs_regs(struct seq_file *m, void *unused) 35int pl111_debugfs_regs(struct seq_file *m, void *unused)
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
index b58c988d9da0..06c4bf756b69 100644
--- a/drivers/gpu/drm/pl111/pl111_display.c
+++ b/drivers/gpu/drm/pl111/pl111_display.c
@@ -21,7 +21,6 @@
21#include <linux/of_graph.h> 21#include <linux/of_graph.h>
22 22
23#include <drm/drmP.h> 23#include <drm/drmP.h>
24#include <drm/drm_panel.h>
25#include <drm/drm_gem_cma_helper.h> 24#include <drm/drm_gem_cma_helper.h>
26#include <drm/drm_gem_framebuffer_helper.h> 25#include <drm/drm_gem_framebuffer_helper.h>
27#include <drm/drm_fb_cma_helper.h> 26#include <drm/drm_fb_cma_helper.h>
@@ -94,7 +93,7 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
94 struct pl111_drm_dev_private *priv = drm->dev_private; 93 struct pl111_drm_dev_private *priv = drm->dev_private;
95 const struct drm_display_mode *mode = &cstate->mode; 94 const struct drm_display_mode *mode = &cstate->mode;
96 struct drm_framebuffer *fb = plane->state->fb; 95 struct drm_framebuffer *fb = plane->state->fb;
97 struct drm_connector *connector = &priv->connector.connector; 96 struct drm_connector *connector = priv->connector;
98 u32 cntl; 97 u32 cntl;
99 u32 ppl, hsw, hfp, hbp; 98 u32 ppl, hsw, hfp, hbp;
100 u32 lpp, vsw, vfp, vbp; 99 u32 lpp, vsw, vfp, vbp;
@@ -156,10 +155,8 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
156 155
157 writel(0, priv->regs + CLCD_TIM3); 156 writel(0, priv->regs + CLCD_TIM3);
158 157
159 drm_panel_prepare(priv->connector.panel); 158 /* Hard-code TFT panel */
160 159 cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1);
161 /* Enable and Power Up */
162 cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDPWR | CNTL_LCDVCOMP(1);
163 160
164 /* Note that the the hardware's format reader takes 'r' from 161 /* Note that the the hardware's format reader takes 'r' from
165 * the low bit, while DRM formats list channels from high bit 162 * the low bit, while DRM formats list channels from high bit
@@ -202,9 +199,21 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
202 break; 199 break;
203 } 200 }
204 201
205 writel(cntl, priv->regs + CLCD_PL111_CNTL); 202 /* Power sequence: first enable and chill */
203 writel(cntl, priv->regs + priv->ctrl);
204
205 /*
206 * We expect this delay to stabilize the contrast
207 * voltage Vee as stipulated by the manual
208 */
209 msleep(20);
210
211 if (priv->variant_display_enable)
212 priv->variant_display_enable(drm, fb->format->format);
206 213
207 drm_panel_enable(priv->connector.panel); 214 /* Power Up */
215 cntl |= CNTL_LCDPWR;
216 writel(cntl, priv->regs + priv->ctrl);
208 217
209 drm_crtc_vblank_on(crtc); 218 drm_crtc_vblank_on(crtc);
210} 219}
@@ -214,15 +223,28 @@ void pl111_display_disable(struct drm_simple_display_pipe *pipe)
214 struct drm_crtc *crtc = &pipe->crtc; 223 struct drm_crtc *crtc = &pipe->crtc;
215 struct drm_device *drm = crtc->dev; 224 struct drm_device *drm = crtc->dev;
216 struct pl111_drm_dev_private *priv = drm->dev_private; 225 struct pl111_drm_dev_private *priv = drm->dev_private;
226 u32 cntl;
217 227
218 drm_crtc_vblank_off(crtc); 228 drm_crtc_vblank_off(crtc);
219 229
220 drm_panel_disable(priv->connector.panel); 230 /* Power Down */
231 cntl = readl(priv->regs + priv->ctrl);
232 if (cntl & CNTL_LCDPWR) {
233 cntl &= ~CNTL_LCDPWR;
234 writel(cntl, priv->regs + priv->ctrl);
235 }
236
237 /*
238 * We expect this delay to stabilize the contrast voltage Vee as
239 * stipulated by the manual
240 */
241 msleep(20);
221 242
222 /* Disable and Power Down */ 243 if (priv->variant_display_disable)
223 writel(0, priv->regs + CLCD_PL111_CNTL); 244 priv->variant_display_disable(drm);
224 245
225 drm_panel_unprepare(priv->connector.panel); 246 /* Disable */
247 writel(0, priv->regs + priv->ctrl);
226 248
227 clk_disable_unprepare(priv->clk); 249 clk_disable_unprepare(priv->clk);
228} 250}
@@ -260,7 +282,7 @@ int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc)
260{ 282{
261 struct pl111_drm_dev_private *priv = drm->dev_private; 283 struct pl111_drm_dev_private *priv = drm->dev_private;
262 284
263 writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + CLCD_PL111_IENB); 285 writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb);
264 286
265 return 0; 287 return 0;
266} 288}
@@ -269,7 +291,7 @@ void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc)
269{ 291{
270 struct pl111_drm_dev_private *priv = drm->dev_private; 292 struct pl111_drm_dev_private *priv = drm->dev_private;
271 293
272 writel(0, priv->regs + CLCD_PL111_IENB); 294 writel(0, priv->regs + priv->ienb);
273} 295}
274 296
275static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe, 297static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe,
@@ -413,22 +435,6 @@ int pl111_display_init(struct drm_device *drm)
413 struct device_node *endpoint; 435 struct device_node *endpoint;
414 u32 tft_r0b0g0[3]; 436 u32 tft_r0b0g0[3];
415 int ret; 437 int ret;
416 static const u32 formats[] = {
417 DRM_FORMAT_ABGR8888,
418 DRM_FORMAT_XBGR8888,
419 DRM_FORMAT_ARGB8888,
420 DRM_FORMAT_XRGB8888,
421 DRM_FORMAT_BGR565,
422 DRM_FORMAT_RGB565,
423 DRM_FORMAT_ABGR1555,
424 DRM_FORMAT_XBGR1555,
425 DRM_FORMAT_ARGB1555,
426 DRM_FORMAT_XRGB1555,
427 DRM_FORMAT_ABGR4444,
428 DRM_FORMAT_XBGR4444,
429 DRM_FORMAT_ARGB4444,
430 DRM_FORMAT_XRGB4444,
431 };
432 438
433 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); 439 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
434 if (!endpoint) 440 if (!endpoint)
@@ -444,21 +450,16 @@ int pl111_display_init(struct drm_device *drm)
444 } 450 }
445 of_node_put(endpoint); 451 of_node_put(endpoint);
446 452
447 if (tft_r0b0g0[0] != 0 ||
448 tft_r0b0g0[1] != 8 ||
449 tft_r0b0g0[2] != 16) {
450 dev_err(dev, "arm,pl11x,tft-r0g0b0-pads != [0,8,16] not yet supported\n");
451 return -EINVAL;
452 }
453
454 ret = pl111_init_clock_divider(drm); 453 ret = pl111_init_clock_divider(drm);
455 if (ret) 454 if (ret)
456 return ret; 455 return ret;
457 456
458 ret = drm_simple_display_pipe_init(drm, &priv->pipe, 457 ret = drm_simple_display_pipe_init(drm, &priv->pipe,
459 &pl111_display_funcs, 458 &pl111_display_funcs,
460 formats, ARRAY_SIZE(formats), 459 priv->variant->formats,
461 NULL, &priv->connector.connector); 460 priv->variant->nformats,
461 NULL,
462 priv->connector);
462 if (ret) 463 if (ret)
463 return ret; 464 return ret;
464 465
diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h
index 5c685bfc8fdc..440f53ebee8c 100644
--- a/drivers/gpu/drm/pl111/pl111_drm.h
+++ b/drivers/gpu/drm/pl111/pl111_drm.h
@@ -21,25 +21,43 @@
21 21
22#include <drm/drm_gem.h> 22#include <drm/drm_gem.h>
23#include <drm/drm_simple_kms_helper.h> 23#include <drm/drm_simple_kms_helper.h>
24#include <drm/drm_connector.h>
25#include <drm/drm_encoder.h>
26#include <drm/drm_panel.h>
27#include <drm/drm_bridge.h>
24#include <linux/clk-provider.h> 28#include <linux/clk-provider.h>
29#include <linux/interrupt.h>
25 30
26#define CLCD_IRQ_NEXTBASE_UPDATE BIT(2) 31#define CLCD_IRQ_NEXTBASE_UPDATE BIT(2)
27 32
28struct drm_minor; 33struct drm_minor;
29 34
30struct pl111_drm_connector { 35/**
31 struct drm_connector connector; 36 * struct pl111_variant_data - encodes IP differences
32 struct drm_panel *panel; 37 * @name: the name of this variant
38 * @is_pl110: this is the early PL110 variant
39 * @formats: array of supported pixel formats on this variant
40 * @nformats: the length of the array of supported pixel formats
41 */
42struct pl111_variant_data {
43 const char *name;
44 bool is_pl110;
45 const u32 *formats;
46 unsigned int nformats;
33}; 47};
34 48
35struct pl111_drm_dev_private { 49struct pl111_drm_dev_private {
36 struct drm_device *drm; 50 struct drm_device *drm;
37 51
38 struct pl111_drm_connector connector; 52 struct drm_connector *connector;
53 struct drm_panel *panel;
54 struct drm_bridge *bridge;
39 struct drm_simple_display_pipe pipe; 55 struct drm_simple_display_pipe pipe;
40 struct drm_fbdev_cma *fbdev; 56 struct drm_fbdev_cma *fbdev;
41 57
42 void *regs; 58 void *regs;
59 u32 ienb;
60 u32 ctrl;
43 /* The pixel clock (a reference to our clock divider off of CLCDCLK). */ 61 /* The pixel clock (a reference to our clock divider off of CLCDCLK). */
44 struct clk *clk; 62 struct clk *clk;
45 /* pl111's internal clock divider. */ 63 /* pl111's internal clock divider. */
@@ -48,20 +66,15 @@ struct pl111_drm_dev_private {
48 * subsystem and pl111_display_enable(). 66 * subsystem and pl111_display_enable().
49 */ 67 */
50 spinlock_t tim2_lock; 68 spinlock_t tim2_lock;
69 const struct pl111_variant_data *variant;
70 void (*variant_display_enable) (struct drm_device *drm, u32 format);
71 void (*variant_display_disable) (struct drm_device *drm);
51}; 72};
52 73
53#define to_pl111_connector(x) \
54 container_of(x, struct pl111_drm_connector, connector)
55
56int pl111_display_init(struct drm_device *dev); 74int pl111_display_init(struct drm_device *dev);
57int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc); 75int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc);
58void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc); 76void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc);
59irqreturn_t pl111_irq(int irq, void *data); 77irqreturn_t pl111_irq(int irq, void *data);
60int pl111_connector_init(struct drm_device *dev);
61int pl111_encoder_init(struct drm_device *dev);
62int pl111_dumb_create(struct drm_file *file_priv,
63 struct drm_device *dev,
64 struct drm_mode_create_dumb *args);
65int pl111_debugfs_init(struct drm_minor *minor); 78int pl111_debugfs_init(struct drm_minor *minor);
66 79
67#endif /* _PL111_DRM_H_ */ 80#endif /* _PL111_DRM_H_ */
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index 581c452cede1..201d57d5cb54 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -41,9 +41,6 @@
41 * - Fix race between setting plane base address and getting IRQ for 41 * - Fix race between setting plane base address and getting IRQ for
42 * vsync firing the pageflip completion. 42 * vsync firing the pageflip completion.
43 * 43 *
44 * - Expose the correct set of formats we can support based on the
45 * "arm,pl11x,tft-r0g0b0-pads" DT property.
46 *
47 * - Use the "max-memory-bandwidth" DT property to filter the 44 * - Use the "max-memory-bandwidth" DT property to filter the
48 * supported formats. 45 * supported formats.
49 * 46 *
@@ -68,8 +65,12 @@
68#include <drm/drm_gem_cma_helper.h> 65#include <drm/drm_gem_cma_helper.h>
69#include <drm/drm_gem_framebuffer_helper.h> 66#include <drm/drm_gem_framebuffer_helper.h>
70#include <drm/drm_fb_cma_helper.h> 67#include <drm/drm_fb_cma_helper.h>
68#include <drm/drm_of.h>
69#include <drm/drm_bridge.h>
70#include <drm/drm_panel.h>
71 71
72#include "pl111_drm.h" 72#include "pl111_drm.h"
73#include "pl111_versatile.h"
73 74
74#define DRIVER_DESC "DRM module for PL111" 75#define DRIVER_DESC "DRM module for PL111"
75 76
@@ -83,6 +84,8 @@ static int pl111_modeset_init(struct drm_device *dev)
83{ 84{
84 struct drm_mode_config *mode_config; 85 struct drm_mode_config *mode_config;
85 struct pl111_drm_dev_private *priv = dev->dev_private; 86 struct pl111_drm_dev_private *priv = dev->dev_private;
87 struct drm_panel *panel;
88 struct drm_bridge *bridge;
86 int ret = 0; 89 int ret = 0;
87 90
88 drm_mode_config_init(dev); 91 drm_mode_config_init(dev);
@@ -93,34 +96,43 @@ static int pl111_modeset_init(struct drm_device *dev)
93 mode_config->min_height = 1; 96 mode_config->min_height = 1;
94 mode_config->max_height = 768; 97 mode_config->max_height = 768;
95 98
96 ret = pl111_connector_init(dev); 99 ret = drm_of_find_panel_or_bridge(dev->dev->of_node,
97 if (ret) { 100 0, 0, &panel, &bridge);
98 dev_err(dev->dev, "Failed to create pl111_drm_connector\n"); 101 if (ret && ret != -ENODEV)
99 goto out_config; 102 return ret;
100 } 103 if (panel) {
101 104 bridge = drm_panel_bridge_add(panel,
102 /* Don't actually attach if we didn't find a drm_panel 105 DRM_MODE_CONNECTOR_Unknown);
103 * attached to us. This will allow a kernel to include both 106 if (IS_ERR(bridge)) {
104 * the fbdev pl111 driver and this one, and choose between 107 ret = PTR_ERR(bridge);
105 * them based on which subsystem has support for the panel. 108 goto out_config;
106 */ 109 }
107 if (!priv->connector.panel) { 110 /*
108 dev_info(dev->dev, 111 * TODO: when we are using a different bridge than a panel
109 "Disabling due to lack of DRM panel device.\n"); 112 * (such as a dumb VGA connector) we need to devise a different
110 ret = -ENODEV; 113 * method to get the connector out of the bridge.
111 goto out_config; 114 */
112 } 115 }
113 116
114 ret = pl111_display_init(dev); 117 ret = pl111_display_init(dev);
115 if (ret != 0) { 118 if (ret != 0) {
116 dev_err(dev->dev, "Failed to init display\n"); 119 dev_err(dev->dev, "Failed to init display\n");
117 goto out_config; 120 goto out_bridge;
118 } 121 }
119 122
123 ret = drm_simple_display_pipe_attach_bridge(&priv->pipe,
124 bridge);
125 if (ret)
126 return ret;
127
128 priv->bridge = bridge;
129 priv->panel = panel;
130 priv->connector = panel->connector;
131
120 ret = drm_vblank_init(dev, 1); 132 ret = drm_vblank_init(dev, 1);
121 if (ret != 0) { 133 if (ret != 0) {
122 dev_err(dev->dev, "Failed to init vblank\n"); 134 dev_err(dev->dev, "Failed to init vblank\n");
123 goto out_config; 135 goto out_bridge;
124 } 136 }
125 137
126 drm_mode_config_reset(dev); 138 drm_mode_config_reset(dev);
@@ -132,6 +144,9 @@ static int pl111_modeset_init(struct drm_device *dev)
132 144
133 goto finish; 145 goto finish;
134 146
147out_bridge:
148 if (panel)
149 drm_panel_bridge_remove(bridge);
135out_config: 150out_config:
136 drm_mode_config_cleanup(dev); 151 drm_mode_config_cleanup(dev);
137finish: 152finish:
@@ -183,6 +198,7 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
183{ 198{
184 struct device *dev = &amba_dev->dev; 199 struct device *dev = &amba_dev->dev;
185 struct pl111_drm_dev_private *priv; 200 struct pl111_drm_dev_private *priv;
201 struct pl111_variant_data *variant = id->data;
186 struct drm_device *drm; 202 struct drm_device *drm;
187 int ret; 203 int ret;
188 204
@@ -196,6 +212,33 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
196 amba_set_drvdata(amba_dev, drm); 212 amba_set_drvdata(amba_dev, drm);
197 priv->drm = drm; 213 priv->drm = drm;
198 drm->dev_private = priv; 214 drm->dev_private = priv;
215 priv->variant = variant;
216
217 /*
218 * The PL110 and PL111 variants have two registers
219 * swapped: interrupt enable and control. For this reason
220 * we use offsets that we can change per variant.
221 */
222 if (variant->is_pl110) {
223 /*
224 * The ARM Versatile boards are even more special:
225 * their PrimeCell ID say they are PL110 but the
226 * control and interrupt enable registers are anyway
227 * swapped to the PL111 order so they are not following
228 * the PL110 datasheet.
229 */
230 if (of_machine_is_compatible("arm,versatile-ab") ||
231 of_machine_is_compatible("arm,versatile-pb")) {
232 priv->ienb = CLCD_PL111_IENB;
233 priv->ctrl = CLCD_PL111_CNTL;
234 } else {
235 priv->ienb = CLCD_PL110_IENB;
236 priv->ctrl = CLCD_PL110_CNTL;
237 }
238 } else {
239 priv->ienb = CLCD_PL111_IENB;
240 priv->ctrl = CLCD_PL111_CNTL;
241 }
199 242
200 priv->regs = devm_ioremap_resource(dev, &amba_dev->res); 243 priv->regs = devm_ioremap_resource(dev, &amba_dev->res);
201 if (IS_ERR(priv->regs)) { 244 if (IS_ERR(priv->regs)) {
@@ -204,15 +247,19 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
204 } 247 }
205 248
206 /* turn off interrupts before requesting the irq */ 249 /* turn off interrupts before requesting the irq */
207 writel(0, priv->regs + CLCD_PL111_IENB); 250 writel(0, priv->regs + priv->ienb);
208 251
209 ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0, 252 ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0,
210 "pl111", priv); 253 variant->name, priv);
211 if (ret != 0) { 254 if (ret != 0) {
212 dev_err(dev, "%s failed irq %d\n", __func__, ret); 255 dev_err(dev, "%s failed irq %d\n", __func__, ret);
213 return ret; 256 return ret;
214 } 257 }
215 258
259 ret = pl111_versatile_init(dev, priv);
260 if (ret)
261 goto dev_unref;
262
216 ret = pl111_modeset_init(drm); 263 ret = pl111_modeset_init(drm);
217 if (ret != 0) 264 if (ret != 0)
218 goto dev_unref; 265 goto dev_unref;
@@ -236,16 +283,70 @@ static int pl111_amba_remove(struct amba_device *amba_dev)
236 drm_dev_unregister(drm); 283 drm_dev_unregister(drm);
237 if (priv->fbdev) 284 if (priv->fbdev)
238 drm_fbdev_cma_fini(priv->fbdev); 285 drm_fbdev_cma_fini(priv->fbdev);
286 if (priv->panel)
287 drm_panel_bridge_remove(priv->bridge);
239 drm_mode_config_cleanup(drm); 288 drm_mode_config_cleanup(drm);
240 drm_dev_unref(drm); 289 drm_dev_unref(drm);
241 290
242 return 0; 291 return 0;
243} 292}
244 293
245static struct amba_id pl111_id_table[] = { 294/*
295 * This variant exist in early versions like the ARM Integrator
296 * and this version lacks the 565 and 444 pixel formats.
297 */
298static const u32 pl110_pixel_formats[] = {
299 DRM_FORMAT_ABGR8888,
300 DRM_FORMAT_XBGR8888,
301 DRM_FORMAT_ARGB8888,
302 DRM_FORMAT_XRGB8888,
303 DRM_FORMAT_ABGR1555,
304 DRM_FORMAT_XBGR1555,
305 DRM_FORMAT_ARGB1555,
306 DRM_FORMAT_XRGB1555,
307};
308
309static const struct pl111_variant_data pl110_variant = {
310 .name = "PL110",
311 .is_pl110 = true,
312 .formats = pl110_pixel_formats,
313 .nformats = ARRAY_SIZE(pl110_pixel_formats),
314};
315
316/* RealView, Versatile Express etc use this modern variant */
317static const u32 pl111_pixel_formats[] = {
318 DRM_FORMAT_ABGR8888,
319 DRM_FORMAT_XBGR8888,
320 DRM_FORMAT_ARGB8888,
321 DRM_FORMAT_XRGB8888,
322 DRM_FORMAT_BGR565,
323 DRM_FORMAT_RGB565,
324 DRM_FORMAT_ABGR1555,
325 DRM_FORMAT_XBGR1555,
326 DRM_FORMAT_ARGB1555,
327 DRM_FORMAT_XRGB1555,
328 DRM_FORMAT_ABGR4444,
329 DRM_FORMAT_XBGR4444,
330 DRM_FORMAT_ARGB4444,
331 DRM_FORMAT_XRGB4444,
332};
333
334static const struct pl111_variant_data pl111_variant = {
335 .name = "PL111",
336 .formats = pl111_pixel_formats,
337 .nformats = ARRAY_SIZE(pl111_pixel_formats),
338};
339
340static const struct amba_id pl111_id_table[] = {
341 {
342 .id = 0x00041110,
343 .mask = 0x000fffff,
344 .data = (void*)&pl110_variant,
345 },
246 { 346 {
247 .id = 0x00041111, 347 .id = 0x00041111,
248 .mask = 0x000fffff, 348 .mask = 0x000fffff,
349 .data = (void*)&pl111_variant,
249 }, 350 },
250 {0, 0}, 351 {0, 0},
251}; 352};
diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c
new file mode 100644
index 000000000000..97d4af6925a3
--- /dev/null
+++ b/drivers/gpu/drm/pl111/pl111_versatile.c
@@ -0,0 +1,270 @@
1#include <linux/device.h>
2#include <linux/of.h>
3#include <linux/regmap.h>
4#include <linux/mfd/syscon.h>
5#include <linux/bitops.h>
6#include <linux/module.h>
7#include <drm/drmP.h>
8#include "pl111_versatile.h"
9#include "pl111_drm.h"
10
11static struct regmap *versatile_syscon_map;
12
13/*
14 * We detect the different syscon types from the compatible strings.
15 */
16enum versatile_clcd {
17 INTEGRATOR_CLCD_CM,
18 VERSATILE_CLCD,
19 REALVIEW_CLCD_EB,
20 REALVIEW_CLCD_PB1176,
21 REALVIEW_CLCD_PB11MP,
22 REALVIEW_CLCD_PBA8,
23 REALVIEW_CLCD_PBX,
24};
25
26static const struct of_device_id versatile_clcd_of_match[] = {
27 {
28 .compatible = "arm,core-module-integrator",
29 .data = (void *)INTEGRATOR_CLCD_CM,
30 },
31 {
32 .compatible = "arm,versatile-sysreg",
33 .data = (void *)VERSATILE_CLCD,
34 },
35 {
36 .compatible = "arm,realview-eb-syscon",
37 .data = (void *)REALVIEW_CLCD_EB,
38 },
39 {
40 .compatible = "arm,realview-pb1176-syscon",
41 .data = (void *)REALVIEW_CLCD_PB1176,
42 },
43 {
44 .compatible = "arm,realview-pb11mp-syscon",
45 .data = (void *)REALVIEW_CLCD_PB11MP,
46 },
47 {
48 .compatible = "arm,realview-pba8-syscon",
49 .data = (void *)REALVIEW_CLCD_PBA8,
50 },
51 {
52 .compatible = "arm,realview-pbx-syscon",
53 .data = (void *)REALVIEW_CLCD_PBX,
54 },
55 {},
56};
57
58/*
59 * Core module CLCD control on the Integrator/CP, bits
60 * 8 thru 19 of the CM_CONTROL register controls a bunch
61 * of CLCD settings.
62 */
63#define INTEGRATOR_HDR_CTRL_OFFSET 0x0C
64#define INTEGRATOR_CLCD_LCDBIASEN BIT(8)
65#define INTEGRATOR_CLCD_LCDBIASUP BIT(9)
66#define INTEGRATOR_CLCD_LCDBIASDN BIT(10)
67/* Bits 11,12,13 controls the LCD type */
68#define INTEGRATOR_CLCD_LCDMUX_MASK (BIT(11)|BIT(12)|BIT(13))
69#define INTEGRATOR_CLCD_LCDMUX_LCD24 BIT(11)
70#define INTEGRATOR_CLCD_LCDMUX_VGA565 BIT(12)
71#define INTEGRATOR_CLCD_LCDMUX_SHARP (BIT(11)|BIT(12))
72#define INTEGRATOR_CLCD_LCDMUX_VGA555 BIT(13)
73#define INTEGRATOR_CLCD_LCDMUX_VGA24 (BIT(11)|BIT(12)|BIT(13))
74#define INTEGRATOR_CLCD_LCD0_EN BIT(14)
75#define INTEGRATOR_CLCD_LCD1_EN BIT(15)
76/* R/L flip on Sharp */
77#define INTEGRATOR_CLCD_LCD_STATIC1 BIT(16)
78/* U/D flip on Sharp */
79#define INTEGRATOR_CLCD_LCD_STATIC2 BIT(17)
80/* No connection on Sharp */
81#define INTEGRATOR_CLCD_LCD_STATIC BIT(18)
82/* 0 = 24bit VGA, 1 = 18bit VGA */
83#define INTEGRATOR_CLCD_LCD_N24BITEN BIT(19)
84
85#define INTEGRATOR_CLCD_MASK (INTEGRATOR_CLCD_LCDBIASEN | \
86 INTEGRATOR_CLCD_LCDBIASUP | \
87 INTEGRATOR_CLCD_LCDBIASDN | \
88 INTEGRATOR_CLCD_LCDMUX_MASK | \
89 INTEGRATOR_CLCD_LCD0_EN | \
90 INTEGRATOR_CLCD_LCD1_EN | \
91 INTEGRATOR_CLCD_LCD_STATIC1 | \
92 INTEGRATOR_CLCD_LCD_STATIC2 | \
93 INTEGRATOR_CLCD_LCD_STATIC | \
94 INTEGRATOR_CLCD_LCD_N24BITEN)
95
96static void pl111_integrator_enable(struct drm_device *drm, u32 format)
97{
98 u32 val;
99
100 dev_info(drm->dev, "enable Integrator CLCD connectors\n");
101
102 /* FIXME: really needed? */
103 val = INTEGRATOR_CLCD_LCD_STATIC1 | INTEGRATOR_CLCD_LCD_STATIC2 |
104 INTEGRATOR_CLCD_LCD0_EN | INTEGRATOR_CLCD_LCD1_EN;
105
106 switch (format) {
107 case DRM_FORMAT_XBGR8888:
108 case DRM_FORMAT_XRGB8888:
109 break;
110 case DRM_FORMAT_BGR565:
111 case DRM_FORMAT_RGB565:
112 /* truecolor RGB565 */
113 val |= INTEGRATOR_CLCD_LCDMUX_VGA565;
114 break;
115 case DRM_FORMAT_XBGR1555:
116 case DRM_FORMAT_XRGB1555:
117 /* Pseudocolor, RGB555, BGR555 */
118 val |= INTEGRATOR_CLCD_LCDMUX_VGA555;
119 break;
120 default:
121 dev_err(drm->dev, "unhandled format on Integrator 0x%08x\n",
122 format);
123 break;
124 }
125
126 regmap_update_bits(versatile_syscon_map,
127 INTEGRATOR_HDR_CTRL_OFFSET,
128 INTEGRATOR_CLCD_MASK,
129 val);
130}
131
132/*
133 * This configuration register in the Versatile and RealView
134 * family is uniformly present but appears more and more
135 * unutilized starting with the RealView series.
136 */
137#define SYS_CLCD 0x50
138#define SYS_CLCD_MODE_MASK (BIT(0)|BIT(1))
139#define SYS_CLCD_MODE_888 0
140#define SYS_CLCD_MODE_5551 BIT(0)
141#define SYS_CLCD_MODE_565_R_LSB BIT(1)
142#define SYS_CLCD_MODE_565_B_LSB (BIT(0)|BIT(1))
143#define SYS_CLCD_CONNECTOR_MASK (BIT(2)|BIT(3)|BIT(4)|BIT(5))
144#define SYS_CLCD_NLCDIOON BIT(2)
145#define SYS_CLCD_VDDPOSSWITCH BIT(3)
146#define SYS_CLCD_PWR3V5SWITCH BIT(4)
147#define SYS_CLCD_VDDNEGSWITCH BIT(5)
148
149static void pl111_versatile_disable(struct drm_device *drm)
150{
151 dev_info(drm->dev, "disable Versatile CLCD connectors\n");
152 regmap_update_bits(versatile_syscon_map,
153 SYS_CLCD,
154 SYS_CLCD_CONNECTOR_MASK,
155 0);
156}
157
158static void pl111_versatile_enable(struct drm_device *drm, u32 format)
159{
160 u32 val = 0;
161
162 dev_info(drm->dev, "enable Versatile CLCD connectors\n");
163
164 switch (format) {
165 case DRM_FORMAT_ABGR8888:
166 case DRM_FORMAT_XBGR8888:
167 case DRM_FORMAT_ARGB8888:
168 case DRM_FORMAT_XRGB8888:
169 val |= SYS_CLCD_MODE_888;
170 break;
171 case DRM_FORMAT_BGR565:
172 val |= SYS_CLCD_MODE_565_R_LSB;
173 break;
174 case DRM_FORMAT_RGB565:
175 val |= SYS_CLCD_MODE_565_B_LSB;
176 break;
177 case DRM_FORMAT_ABGR1555:
178 case DRM_FORMAT_XBGR1555:
179 case DRM_FORMAT_ARGB1555:
180 case DRM_FORMAT_XRGB1555:
181 val |= SYS_CLCD_MODE_5551;
182 break;
183 default:
184 dev_err(drm->dev, "unhandled format on Versatile 0x%08x\n",
185 format);
186 break;
187 }
188
189 /* Set up the MUX */
190 regmap_update_bits(versatile_syscon_map,
191 SYS_CLCD,
192 SYS_CLCD_MODE_MASK,
193 val);
194
195 /* Then enable the display */
196 regmap_update_bits(versatile_syscon_map,
197 SYS_CLCD,
198 SYS_CLCD_CONNECTOR_MASK,
199 SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH);
200}
201
202static void pl111_realview_clcd_disable(struct drm_device *drm)
203{
204 dev_info(drm->dev, "disable RealView CLCD connectors\n");
205 regmap_update_bits(versatile_syscon_map,
206 SYS_CLCD,
207 SYS_CLCD_CONNECTOR_MASK,
208 0);
209}
210
211static void pl111_realview_clcd_enable(struct drm_device *drm, u32 format)
212{
213 dev_info(drm->dev, "enable RealView CLCD connectors\n");
214 regmap_update_bits(versatile_syscon_map,
215 SYS_CLCD,
216 SYS_CLCD_CONNECTOR_MASK,
217 SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH);
218}
219
220int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv)
221{
222 const struct of_device_id *clcd_id;
223 enum versatile_clcd versatile_clcd_type;
224 struct device_node *np;
225 struct regmap *map;
226
227 np = of_find_matching_node_and_match(NULL, versatile_clcd_of_match,
228 &clcd_id);
229 if (!np) {
230 /* Non-ARM reference designs, just bail out */
231 return 0;
232 }
233 versatile_clcd_type = (enum versatile_clcd)clcd_id->data;
234
235 map = syscon_node_to_regmap(np);
236 if (IS_ERR(map)) {
237 dev_err(dev, "no Versatile syscon regmap\n");
238 return PTR_ERR(map);
239 }
240
241 switch (versatile_clcd_type) {
242 case INTEGRATOR_CLCD_CM:
243 versatile_syscon_map = map;
244 priv->variant_display_enable = pl111_integrator_enable;
245 dev_info(dev, "set up callbacks for Integrator PL110\n");
246 break;
247 case VERSATILE_CLCD:
248 versatile_syscon_map = map;
249 priv->variant_display_enable = pl111_versatile_enable;
250 priv->variant_display_disable = pl111_versatile_disable;
251 dev_info(dev, "set up callbacks for Versatile PL110+\n");
252 break;
253 case REALVIEW_CLCD_EB:
254 case REALVIEW_CLCD_PB1176:
255 case REALVIEW_CLCD_PB11MP:
256 case REALVIEW_CLCD_PBA8:
257 case REALVIEW_CLCD_PBX:
258 versatile_syscon_map = map;
259 priv->variant_display_enable = pl111_realview_clcd_enable;
260 priv->variant_display_disable = pl111_realview_clcd_disable;
261 dev_info(dev, "set up callbacks for RealView PL111\n");
262 break;
263 default:
264 dev_info(dev, "unknown Versatile system controller\n");
265 break;
266 }
267
268 return 0;
269}
270EXPORT_SYMBOL_GPL(pl111_versatile_init);
diff --git a/drivers/gpu/drm/pl111/pl111_versatile.h b/drivers/gpu/drm/pl111/pl111_versatile.h
new file mode 100644
index 000000000000..41aa6d969dc6
--- /dev/null
+++ b/drivers/gpu/drm/pl111/pl111_versatile.h
@@ -0,0 +1,9 @@
1#include <linux/device.h>
2#include "pl111_drm.h"
3
4#ifndef PL111_VERSATILE_H
5#define PL111_VERSATILE_H
6
7int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv);
8
9#endif
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index dcc539ba85d6..0c31f0a27b9c 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -57,4 +57,12 @@ config ROCKCHIP_INNO_HDMI
57 for the Innosilicon HDMI driver. If you want to enable 57 for the Innosilicon HDMI driver. If you want to enable
58 HDMI on RK3036 based SoC, you should select this option. 58 HDMI on RK3036 based SoC, you should select this option.
59 59
60config ROCKCHIP_LVDS
61 bool "Rockchip LVDS support"
62 depends on DRM_ROCKCHIP
63 help
64 Choose this option to enable support for Rockchip LVDS controllers.
65 Rockchip rk3288 SoC has LVDS TX Controller can be used, and it
66 support LVDS, rgb, dual LVDS output mode. say Y to enable its
67 driver.
60endif 68endif
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index fa8dc9d9aac2..a881d2cc4f25 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -12,5 +12,6 @@ rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
12rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o 12rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
13rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o 13rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
14rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o 14rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
15rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
15 16
16obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o 17obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 9606121fa185..4d3f6ad0abdd 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -88,7 +88,7 @@ static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
88 if (!analogix_dp_psr_supported(dp->dev)) 88 if (!analogix_dp_psr_supported(dp->dev))
89 return; 89 return;
90 90
91 dev_dbg(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); 91 DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
92 92
93 spin_lock_irqsave(&dp->psr_lock, flags); 93 spin_lock_irqsave(&dp->psr_lock, flags);
94 if (enabled) 94 if (enabled)
@@ -110,7 +110,7 @@ static void analogix_dp_psr_work(struct work_struct *work)
110 ret = rockchip_drm_wait_vact_end(dp->encoder.crtc, 110 ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
111 PSR_WAIT_LINE_FLAG_TIMEOUT_MS); 111 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
112 if (ret) { 112 if (ret) {
113 dev_err(dp->dev, "line flag interrupt did not arrive\n"); 113 DRM_DEV_ERROR(dp->dev, "line flag interrupt did not arrive\n");
114 return; 114 return;
115 } 115 }
116 116
@@ -140,13 +140,13 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
140 140
141 ret = clk_prepare_enable(dp->pclk); 141 ret = clk_prepare_enable(dp->pclk);
142 if (ret < 0) { 142 if (ret < 0) {
143 dev_err(dp->dev, "failed to enable pclk %d\n", ret); 143 DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
144 return ret; 144 return ret;
145 } 145 }
146 146
147 ret = rockchip_dp_pre_init(dp); 147 ret = rockchip_dp_pre_init(dp);
148 if (ret < 0) { 148 if (ret < 0) {
149 dev_err(dp->dev, "failed to dp pre init %d\n", ret); 149 DRM_DEV_ERROR(dp->dev, "failed to dp pre init %d\n", ret);
150 clk_disable_unprepare(dp->pclk); 150 clk_disable_unprepare(dp->pclk);
151 return ret; 151 return ret;
152 } 152 }
@@ -211,17 +211,17 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder)
211 else 211 else
212 val = dp->data->lcdsel_big; 212 val = dp->data->lcdsel_big;
213 213
214 dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG"); 214 DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
215 215
216 ret = clk_prepare_enable(dp->grfclk); 216 ret = clk_prepare_enable(dp->grfclk);
217 if (ret < 0) { 217 if (ret < 0) {
218 dev_err(dp->dev, "failed to enable grfclk %d\n", ret); 218 DRM_DEV_ERROR(dp->dev, "failed to enable grfclk %d\n", ret);
219 return; 219 return;
220 } 220 }
221 221
222 ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val); 222 ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
223 if (ret != 0) 223 if (ret != 0)
224 dev_err(dp->dev, "Could not write to GRF: %d\n", ret); 224 DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret);
225 225
226 clk_disable_unprepare(dp->grfclk); 226 clk_disable_unprepare(dp->grfclk);
227} 227}
@@ -277,7 +277,7 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp)
277 277
278 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 278 dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
279 if (IS_ERR(dp->grf)) { 279 if (IS_ERR(dp->grf)) {
280 dev_err(dev, "failed to get rockchip,grf property\n"); 280 DRM_DEV_ERROR(dev, "failed to get rockchip,grf property\n");
281 return PTR_ERR(dp->grf); 281 return PTR_ERR(dp->grf);
282 } 282 }
283 283
@@ -287,31 +287,31 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp)
287 } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) { 287 } else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) {
288 return -EPROBE_DEFER; 288 return -EPROBE_DEFER;
289 } else if (IS_ERR(dp->grfclk)) { 289 } else if (IS_ERR(dp->grfclk)) {
290 dev_err(dev, "failed to get grf clock\n"); 290 DRM_DEV_ERROR(dev, "failed to get grf clock\n");
291 return PTR_ERR(dp->grfclk); 291 return PTR_ERR(dp->grfclk);
292 } 292 }
293 293
294 dp->pclk = devm_clk_get(dev, "pclk"); 294 dp->pclk = devm_clk_get(dev, "pclk");
295 if (IS_ERR(dp->pclk)) { 295 if (IS_ERR(dp->pclk)) {
296 dev_err(dev, "failed to get pclk property\n"); 296 DRM_DEV_ERROR(dev, "failed to get pclk property\n");
297 return PTR_ERR(dp->pclk); 297 return PTR_ERR(dp->pclk);
298 } 298 }
299 299
300 dp->rst = devm_reset_control_get(dev, "dp"); 300 dp->rst = devm_reset_control_get(dev, "dp");
301 if (IS_ERR(dp->rst)) { 301 if (IS_ERR(dp->rst)) {
302 dev_err(dev, "failed to get dp reset control\n"); 302 DRM_DEV_ERROR(dev, "failed to get dp reset control\n");
303 return PTR_ERR(dp->rst); 303 return PTR_ERR(dp->rst);
304 } 304 }
305 305
306 ret = clk_prepare_enable(dp->pclk); 306 ret = clk_prepare_enable(dp->pclk);
307 if (ret < 0) { 307 if (ret < 0) {
308 dev_err(dp->dev, "failed to enable pclk %d\n", ret); 308 DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
309 return ret; 309 return ret;
310 } 310 }
311 311
312 ret = rockchip_dp_pre_init(dp); 312 ret = rockchip_dp_pre_init(dp);
313 if (ret < 0) { 313 if (ret < 0) {
314 dev_err(dp->dev, "failed to pre init %d\n", ret); 314 DRM_DEV_ERROR(dp->dev, "failed to pre init %d\n", ret);
315 clk_disable_unprepare(dp->pclk); 315 clk_disable_unprepare(dp->pclk);
316 return ret; 316 return ret;
317 } 317 }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
index b14d211f6c21..eb3042c6d1b2 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
@@ -323,7 +323,7 @@ int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
323 reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff; 323 reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff;
324 dp->fw_version |= reg << 24; 324 dp->fw_version |= reg << 24;
325 325
326 dev_dbg(dp->dev, "firmware version: %x\n", dp->fw_version); 326 DRM_DEV_DEBUG(dp->dev, "firmware version: %x\n", dp->fw_version);
327 327
328 return 0; 328 return 0;
329} 329}
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 9a20b9dc27c8..b15755b6129c 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -430,9 +430,9 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
430 430
431 testdin = max_mbps_to_testdin(dsi->lane_mbps); 431 testdin = max_mbps_to_testdin(dsi->lane_mbps);
432 if (testdin < 0) { 432 if (testdin < 0) {
433 dev_err(dsi->dev, 433 DRM_DEV_ERROR(dsi->dev,
434 "failed to get testdin for %dmbps lane clock\n", 434 "failed to get testdin for %dmbps lane clock\n",
435 dsi->lane_mbps); 435 dsi->lane_mbps);
436 return testdin; 436 return testdin;
437 } 437 }
438 438
@@ -443,7 +443,7 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
443 443
444 ret = clk_prepare_enable(dsi->phy_cfg_clk); 444 ret = clk_prepare_enable(dsi->phy_cfg_clk);
445 if (ret) { 445 if (ret) {
446 dev_err(dsi->dev, "Failed to enable phy_cfg_clk\n"); 446 DRM_DEV_ERROR(dsi->dev, "Failed to enable phy_cfg_clk\n");
447 return ret; 447 return ret;
448 } 448 }
449 449
@@ -501,7 +501,7 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
501 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, 501 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
502 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US); 502 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
503 if (ret < 0) { 503 if (ret < 0) {
504 dev_err(dsi->dev, "failed to wait for phy lock state\n"); 504 DRM_DEV_ERROR(dsi->dev, "failed to wait for phy lock state\n");
505 goto phy_init_end; 505 goto phy_init_end;
506 } 506 }
507 507
@@ -509,8 +509,8 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
509 val, val & STOP_STATE_CLK_LANE, 1000, 509 val, val & STOP_STATE_CLK_LANE, 1000,
510 PHY_STATUS_TIMEOUT_US); 510 PHY_STATUS_TIMEOUT_US);
511 if (ret < 0) 511 if (ret < 0)
512 dev_err(dsi->dev, 512 DRM_DEV_ERROR(dsi->dev,
513 "failed to wait for phy clk lane stop state\n"); 513 "failed to wait for phy clk lane stop state\n");
514 514
515phy_init_end: 515phy_init_end:
516 clk_disable_unprepare(dsi->phy_cfg_clk); 516 clk_disable_unprepare(dsi->phy_cfg_clk);
@@ -529,8 +529,9 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi,
529 529
530 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); 530 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
531 if (bpp < 0) { 531 if (bpp < 0) {
532 dev_err(dsi->dev, "failed to get bpp for pixel format %d\n", 532 DRM_DEV_ERROR(dsi->dev,
533 dsi->format); 533 "failed to get bpp for pixel format %d\n",
534 dsi->format);
534 return bpp; 535 return bpp;
535 } 536 }
536 537
@@ -541,7 +542,8 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi,
541 if (tmp < max_mbps) 542 if (tmp < max_mbps)
542 target_mbps = tmp; 543 target_mbps = tmp;
543 else 544 else
544 dev_err(dsi->dev, "DPHY clock frequency is out of range\n"); 545 DRM_DEV_ERROR(dsi->dev,
546 "DPHY clock frequency is out of range\n");
545 } 547 }
546 548
547 pllref = DIV_ROUND_UP(clk_get_rate(dsi->pllref_clk), USEC_PER_SEC); 549 pllref = DIV_ROUND_UP(clk_get_rate(dsi->pllref_clk), USEC_PER_SEC);
@@ -582,8 +584,9 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
582 struct dw_mipi_dsi *dsi = host_to_dsi(host); 584 struct dw_mipi_dsi *dsi = host_to_dsi(host);
583 585
584 if (device->lanes > dsi->pdata->max_data_lanes) { 586 if (device->lanes > dsi->pdata->max_data_lanes) {
585 dev_err(dsi->dev, "the number of data lanes(%u) is too many\n", 587 DRM_DEV_ERROR(dsi->dev,
586 device->lanes); 588 "the number of data lanes(%u) is too many\n",
589 device->lanes);
587 return -EINVAL; 590 return -EINVAL;
588 } 591 }
589 592
@@ -632,7 +635,8 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
632 val, !(val & GEN_CMD_FULL), 1000, 635 val, !(val & GEN_CMD_FULL), 1000,
633 CMD_PKT_STATUS_TIMEOUT_US); 636 CMD_PKT_STATUS_TIMEOUT_US);
634 if (ret < 0) { 637 if (ret < 0) {
635 dev_err(dsi->dev, "failed to get available command FIFO\n"); 638 DRM_DEV_ERROR(dsi->dev,
639 "failed to get available command FIFO\n");
636 return ret; 640 return ret;
637 } 641 }
638 642
@@ -643,7 +647,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
643 val, (val & mask) == mask, 647 val, (val & mask) == mask,
644 1000, CMD_PKT_STATUS_TIMEOUT_US); 648 1000, CMD_PKT_STATUS_TIMEOUT_US);
645 if (ret < 0) { 649 if (ret < 0) {
646 dev_err(dsi->dev, "failed to write command FIFO\n"); 650 DRM_DEV_ERROR(dsi->dev, "failed to write command FIFO\n");
647 return ret; 651 return ret;
648 } 652 }
649 653
@@ -663,8 +667,9 @@ static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
663 data |= tx_buf[1] << 8; 667 data |= tx_buf[1] << 8;
664 668
665 if (msg->tx_len > 2) { 669 if (msg->tx_len > 2) {
666 dev_err(dsi->dev, "too long tx buf length %zu for short write\n", 670 DRM_DEV_ERROR(dsi->dev,
667 msg->tx_len); 671 "too long tx buf length %zu for short write\n",
672 msg->tx_len);
668 return -EINVAL; 673 return -EINVAL;
669 } 674 }
670 675
@@ -682,8 +687,9 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
682 u32 val; 687 u32 val;
683 688
684 if (msg->tx_len < 3) { 689 if (msg->tx_len < 3) {
685 dev_err(dsi->dev, "wrong tx buf length %zu for long write\n", 690 DRM_DEV_ERROR(dsi->dev,
686 msg->tx_len); 691 "wrong tx buf length %zu for long write\n",
692 msg->tx_len);
687 return -EINVAL; 693 return -EINVAL;
688 } 694 }
689 695
@@ -704,8 +710,8 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
704 val, !(val & GEN_PLD_W_FULL), 1000, 710 val, !(val & GEN_PLD_W_FULL), 1000,
705 CMD_PKT_STATUS_TIMEOUT_US); 711 CMD_PKT_STATUS_TIMEOUT_US);
706 if (ret < 0) { 712 if (ret < 0) {
707 dev_err(dsi->dev, 713 DRM_DEV_ERROR(dsi->dev,
708 "failed to get available write payload FIFO\n"); 714 "failed to get available write payload FIFO\n");
709 return ret; 715 return ret;
710 } 716 }
711 } 717 }
@@ -731,8 +737,8 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
731 ret = dw_mipi_dsi_dcs_long_write(dsi, msg); 737 ret = dw_mipi_dsi_dcs_long_write(dsi, msg);
732 break; 738 break;
733 default: 739 default:
734 dev_err(dsi->dev, "unsupported message type 0x%02x\n", 740 DRM_DEV_ERROR(dsi->dev, "unsupported message type 0x%02x\n",
735 msg->type); 741 msg->type);
736 ret = -EINVAL; 742 ret = -EINVAL;
737 } 743 }
738 744
@@ -935,7 +941,7 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
935 return; 941 return;
936 942
937 if (clk_prepare_enable(dsi->pclk)) { 943 if (clk_prepare_enable(dsi->pclk)) {
938 dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__); 944 DRM_DEV_ERROR(dsi->dev, "Failed to enable pclk\n");
939 return; 945 return;
940 } 946 }
941 947
@@ -967,7 +973,7 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
967 return; 973 return;
968 974
969 if (clk_prepare_enable(dsi->pclk)) { 975 if (clk_prepare_enable(dsi->pclk)) {
970 dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__); 976 DRM_DEV_ERROR(dsi->dev, "Failed to enable pclk\n");
971 return; 977 return;
972 } 978 }
973 979
@@ -991,7 +997,7 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
991 */ 997 */
992 ret = clk_prepare_enable(dsi->grf_clk); 998 ret = clk_prepare_enable(dsi->grf_clk);
993 if (ret) { 999 if (ret) {
994 dev_err(dsi->dev, "Failed to enable grf_clk: %d\n", ret); 1000 DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
995 return; 1001 return;
996 } 1002 }
997 1003
@@ -1004,7 +1010,7 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
1004 1010
1005 dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_CMD_MODE); 1011 dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_CMD_MODE);
1006 if (drm_panel_prepare(dsi->panel)) 1012 if (drm_panel_prepare(dsi->panel))
1007 dev_err(dsi->dev, "failed to prepare panel\n"); 1013 DRM_DEV_ERROR(dsi->dev, "failed to prepare panel\n");
1008 1014
1009 dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_VID_MODE); 1015 dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_VID_MODE);
1010 drm_panel_enable(dsi->panel); 1016 drm_panel_enable(dsi->panel);
@@ -1017,7 +1023,8 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
1017 val = pdata->dsi0_en_bit << 16; 1023 val = pdata->dsi0_en_bit << 16;
1018 1024
1019 regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val); 1025 regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val);
1020 dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG"); 1026 DRM_DEV_DEBUG(dsi->dev,
1027 "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
1021 dsi->dpms_mode = DRM_MODE_DPMS_ON; 1028 dsi->dpms_mode = DRM_MODE_DPMS_ON;
1022 1029
1023 clk_disable_unprepare(dsi->grf_clk); 1030 clk_disable_unprepare(dsi->grf_clk);
@@ -1111,7 +1118,7 @@ static int dw_mipi_dsi_register(struct drm_device *drm,
1111 ret = drm_encoder_init(drm, &dsi->encoder, &dw_mipi_dsi_encoder_funcs, 1118 ret = drm_encoder_init(drm, &dsi->encoder, &dw_mipi_dsi_encoder_funcs,
1112 DRM_MODE_ENCODER_DSI, NULL); 1119 DRM_MODE_ENCODER_DSI, NULL);
1113 if (ret) { 1120 if (ret) {
1114 dev_err(dev, "Failed to initialize encoder with drm\n"); 1121 DRM_DEV_ERROR(dev, "Failed to initialize encoder with drm\n");
1115 return ret; 1122 return ret;
1116 } 1123 }
1117 1124
@@ -1133,7 +1140,7 @@ static int rockchip_mipi_parse_dt(struct dw_mipi_dsi *dsi)
1133 1140
1134 dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 1141 dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
1135 if (IS_ERR(dsi->grf_regmap)) { 1142 if (IS_ERR(dsi->grf_regmap)) {
1136 dev_err(dsi->dev, "Unable to get rockchip,grf\n"); 1143 DRM_DEV_ERROR(dsi->dev, "Unable to get rockchip,grf\n");
1137 return PTR_ERR(dsi->grf_regmap); 1144 return PTR_ERR(dsi->grf_regmap);
1138 } 1145 }
1139 1146
@@ -1205,14 +1212,15 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
1205 dsi->pllref_clk = devm_clk_get(dev, "ref"); 1212 dsi->pllref_clk = devm_clk_get(dev, "ref");
1206 if (IS_ERR(dsi->pllref_clk)) { 1213 if (IS_ERR(dsi->pllref_clk)) {
1207 ret = PTR_ERR(dsi->pllref_clk); 1214 ret = PTR_ERR(dsi->pllref_clk);
1208 dev_err(dev, "Unable to get pll reference clock: %d\n", ret); 1215 DRM_DEV_ERROR(dev,
1216 "Unable to get pll reference clock: %d\n", ret);
1209 return ret; 1217 return ret;
1210 } 1218 }
1211 1219
1212 dsi->pclk = devm_clk_get(dev, "pclk"); 1220 dsi->pclk = devm_clk_get(dev, "pclk");
1213 if (IS_ERR(dsi->pclk)) { 1221 if (IS_ERR(dsi->pclk)) {
1214 ret = PTR_ERR(dsi->pclk); 1222 ret = PTR_ERR(dsi->pclk);
1215 dev_err(dev, "Unable to get pclk: %d\n", ret); 1223 DRM_DEV_ERROR(dev, "Unable to get pclk: %d\n", ret);
1216 return ret; 1224 return ret;
1217 } 1225 }
1218 1226
@@ -1226,7 +1234,8 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
1226 if (ret == -ENOENT) { 1234 if (ret == -ENOENT) {
1227 apb_rst = NULL; 1235 apb_rst = NULL;
1228 } else { 1236 } else {
1229 dev_err(dev, "Unable to get reset control: %d\n", ret); 1237 DRM_DEV_ERROR(dev,
1238 "Unable to get reset control: %d\n", ret);
1230 return ret; 1239 return ret;
1231 } 1240 }
1232 } 1241 }
@@ -1234,7 +1243,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
1234 if (apb_rst) { 1243 if (apb_rst) {
1235 ret = clk_prepare_enable(dsi->pclk); 1244 ret = clk_prepare_enable(dsi->pclk);
1236 if (ret) { 1245 if (ret) {
1237 dev_err(dev, "%s: Failed to enable pclk\n", __func__); 1246 DRM_DEV_ERROR(dev, "Failed to enable pclk\n");
1238 return ret; 1247 return ret;
1239 } 1248 }
1240 1249
@@ -1249,7 +1258,8 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
1249 dsi->phy_cfg_clk = devm_clk_get(dev, "phy_cfg"); 1258 dsi->phy_cfg_clk = devm_clk_get(dev, "phy_cfg");
1250 if (IS_ERR(dsi->phy_cfg_clk)) { 1259 if (IS_ERR(dsi->phy_cfg_clk)) {
1251 ret = PTR_ERR(dsi->phy_cfg_clk); 1260 ret = PTR_ERR(dsi->phy_cfg_clk);
1252 dev_err(dev, "Unable to get phy_cfg_clk: %d\n", ret); 1261 DRM_DEV_ERROR(dev,
1262 "Unable to get phy_cfg_clk: %d\n", ret);
1253 return ret; 1263 return ret;
1254 } 1264 }
1255 } 1265 }
@@ -1258,20 +1268,20 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
1258 dsi->grf_clk = devm_clk_get(dev, "grf"); 1268 dsi->grf_clk = devm_clk_get(dev, "grf");
1259 if (IS_ERR(dsi->grf_clk)) { 1269 if (IS_ERR(dsi->grf_clk)) {
1260 ret = PTR_ERR(dsi->grf_clk); 1270 ret = PTR_ERR(dsi->grf_clk);
1261 dev_err(dev, "Unable to get grf_clk: %d\n", ret); 1271 DRM_DEV_ERROR(dev, "Unable to get grf_clk: %d\n", ret);
1262 return ret; 1272 return ret;
1263 } 1273 }
1264 } 1274 }
1265 1275
1266 ret = clk_prepare_enable(dsi->pllref_clk); 1276 ret = clk_prepare_enable(dsi->pllref_clk);
1267 if (ret) { 1277 if (ret) {
1268 dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__); 1278 DRM_DEV_ERROR(dev, "Failed to enable pllref_clk\n");
1269 return ret; 1279 return ret;
1270 } 1280 }
1271 1281
1272 ret = dw_mipi_dsi_register(drm, dsi); 1282 ret = dw_mipi_dsi_register(drm, dsi);
1273 if (ret) { 1283 if (ret) {
1274 dev_err(dev, "Failed to register mipi_dsi: %d\n", ret); 1284 DRM_DEV_ERROR(dev, "Failed to register mipi_dsi: %d\n", ret);
1275 goto err_pllref; 1285 goto err_pllref;
1276 } 1286 }
1277 1287
@@ -1281,7 +1291,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
1281 dsi->dsi_host.dev = dev; 1291 dsi->dsi_host.dev = dev;
1282 ret = mipi_dsi_host_register(&dsi->dsi_host); 1292 ret = mipi_dsi_host_register(&dsi->dsi_host);
1283 if (ret) { 1293 if (ret) {
1284 dev_err(dev, "Failed to register MIPI host: %d\n", ret); 1294 DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
1285 goto err_cleanup; 1295 goto err_cleanup;
1286 } 1296 }
1287 1297
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index ccd5d595ada7..1eb02a82fd91 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -168,7 +168,7 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
168 168
169 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 169 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
170 if (IS_ERR(hdmi->regmap)) { 170 if (IS_ERR(hdmi->regmap)) {
171 dev_err(hdmi->dev, "Unable to get rockchip,grf\n"); 171 DRM_DEV_ERROR(hdmi->dev, "Unable to get rockchip,grf\n");
172 return PTR_ERR(hdmi->regmap); 172 return PTR_ERR(hdmi->regmap);
173 } 173 }
174 174
@@ -178,7 +178,7 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
178 } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) { 178 } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
179 return -EPROBE_DEFER; 179 return -EPROBE_DEFER;
180 } else if (IS_ERR(hdmi->vpll_clk)) { 180 } else if (IS_ERR(hdmi->vpll_clk)) {
181 dev_err(hdmi->dev, "failed to get grf clock\n"); 181 DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
182 return PTR_ERR(hdmi->vpll_clk); 182 return PTR_ERR(hdmi->vpll_clk);
183 } 183 }
184 184
@@ -188,13 +188,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
188 } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) { 188 } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
189 return -EPROBE_DEFER; 189 return -EPROBE_DEFER;
190 } else if (IS_ERR(hdmi->grf_clk)) { 190 } else if (IS_ERR(hdmi->grf_clk)) {
191 dev_err(hdmi->dev, "failed to get grf clock\n"); 191 DRM_DEV_ERROR(hdmi->dev, "failed to get grf clock\n");
192 return PTR_ERR(hdmi->grf_clk); 192 return PTR_ERR(hdmi->grf_clk);
193 } 193 }
194 194
195 ret = clk_prepare_enable(hdmi->vpll_clk); 195 ret = clk_prepare_enable(hdmi->vpll_clk);
196 if (ret) { 196 if (ret) {
197 dev_err(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret); 197 DRM_DEV_ERROR(hdmi->dev,
198 "Failed to enable HDMI vpll: %d\n", ret);
198 return ret; 199 return ret;
199 } 200 }
200 201
@@ -259,17 +260,17 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
259 260
260 ret = clk_prepare_enable(hdmi->grf_clk); 261 ret = clk_prepare_enable(hdmi->grf_clk);
261 if (ret < 0) { 262 if (ret < 0) {
262 dev_err(hdmi->dev, "failed to enable grfclk %d\n", ret); 263 DRM_DEV_ERROR(hdmi->dev, "failed to enable grfclk %d\n", ret);
263 return; 264 return;
264 } 265 }
265 266
266 ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val); 267 ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
267 if (ret != 0) 268 if (ret != 0)
268 dev_err(hdmi->dev, "Could not write to GRF: %d\n", ret); 269 DRM_DEV_ERROR(hdmi->dev, "Could not write to GRF: %d\n", ret);
269 270
270 clk_disable_unprepare(hdmi->grf_clk); 271 clk_disable_unprepare(hdmi->grf_clk);
271 dev_dbg(hdmi->dev, "vop %s output to hdmi\n", 272 DRM_DEV_DEBUG(hdmi->dev, "vop %s output to hdmi\n",
272 ret ? "LIT" : "BIG"); 273 ret ? "LIT" : "BIG");
273} 274}
274 275
275static int 276static int
@@ -368,7 +369,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
368 369
369 ret = rockchip_hdmi_parse_dt(hdmi); 370 ret = rockchip_hdmi_parse_dt(hdmi);
370 if (ret) { 371 if (ret) {
371 dev_err(hdmi->dev, "Unable to parse OF data\n"); 372 DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n");
372 return ret; 373 return ret;
373 } 374 }
374 375
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7a251a54e792..ee584d87111f 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -224,7 +224,7 @@ static void inno_hdmi_set_pwr_mode(struct inno_hdmi *hdmi, int mode)
224 break; 224 break;
225 225
226 default: 226 default:
227 dev_err(hdmi->dev, "Unknown power mode %d\n", mode); 227 DRM_DEV_ERROR(hdmi->dev, "Unknown power mode %d\n", mode);
228 } 228 }
229} 229}
230 230
@@ -742,8 +742,9 @@ static int inno_hdmi_i2c_xfer(struct i2c_adapter *adap,
742 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY); 742 hdmi_writeb(hdmi, HDMI_INTERRUPT_STATUS1, m_INT_EDID_READY);
743 743
744 for (i = 0; i < num; i++) { 744 for (i = 0; i < num; i++) {
745 dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n", 745 DRM_DEV_DEBUG(hdmi->dev,
746 i + 1, num, msgs[i].len, msgs[i].flags); 746 "xfer: num: %d/%d, len: %d, flags: %#x\n",
747 i + 1, num, msgs[i].len, msgs[i].flags);
747 748
748 if (msgs[i].flags & I2C_M_RD) 749 if (msgs[i].flags & I2C_M_RD)
749 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]); 750 ret = inno_hdmi_i2c_read(hdmi, &msgs[i]);
@@ -806,7 +807,7 @@ static struct i2c_adapter *inno_hdmi_i2c_adapter(struct inno_hdmi *hdmi)
806 807
807 hdmi->i2c = i2c; 808 hdmi->i2c = i2c;
808 809
809 dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name); 810 DRM_DEV_INFO(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
810 811
811 return adap; 812 return adap;
812} 813}
@@ -838,13 +839,14 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
838 839
839 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk"); 840 hdmi->pclk = devm_clk_get(hdmi->dev, "pclk");
840 if (IS_ERR(hdmi->pclk)) { 841 if (IS_ERR(hdmi->pclk)) {
841 dev_err(hdmi->dev, "Unable to get HDMI pclk clk\n"); 842 DRM_DEV_ERROR(hdmi->dev, "Unable to get HDMI pclk clk\n");
842 return PTR_ERR(hdmi->pclk); 843 return PTR_ERR(hdmi->pclk);
843 } 844 }
844 845
845 ret = clk_prepare_enable(hdmi->pclk); 846 ret = clk_prepare_enable(hdmi->pclk);
846 if (ret) { 847 if (ret) {
847 dev_err(hdmi->dev, "Cannot enable HDMI pclk clock: %d\n", ret); 848 DRM_DEV_ERROR(hdmi->dev,
849 "Cannot enable HDMI pclk clock: %d\n", ret);
848 return ret; 850 return ret;
849 } 851 }
850 852
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ff3d0f5efbb1..76d63de5921d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -58,7 +58,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
58 58
59 ret = iommu_attach_device(private->domain, dev); 59 ret = iommu_attach_device(private->domain, dev);
60 if (ret) { 60 if (ret) {
61 dev_err(dev, "Failed to attach iommu device\n"); 61 DRM_DEV_ERROR(dev, "Failed to attach iommu device\n");
62 return ret; 62 return ret;
63 } 63 }
64 64
@@ -373,8 +373,9 @@ static int rockchip_drm_platform_of_probe(struct device *dev)
373 373
374 iommu = of_parse_phandle(port->parent, "iommus", 0); 374 iommu = of_parse_phandle(port->parent, "iommus", 0);
375 if (!iommu || !of_device_is_available(iommu->parent)) { 375 if (!iommu || !of_device_is_available(iommu->parent)) {
376 dev_dbg(dev, "no iommu attached for %pOF, using non-iommu buffers\n", 376 DRM_DEV_DEBUG(dev,
377 port->parent); 377 "no iommu attached for %pOF, using non-iommu buffers\n",
378 port->parent);
378 /* 379 /*
379 * if there is a crtc not support iommu, force set all 380 * if there is a crtc not support iommu, force set all
380 * crtc use non-iommu buffer. 381 * crtc use non-iommu buffer.
@@ -389,12 +390,13 @@ static int rockchip_drm_platform_of_probe(struct device *dev)
389 } 390 }
390 391
391 if (i == 0) { 392 if (i == 0) {
392 dev_err(dev, "missing 'ports' property\n"); 393 DRM_DEV_ERROR(dev, "missing 'ports' property\n");
393 return -ENODEV; 394 return -ENODEV;
394 } 395 }
395 396
396 if (!found) { 397 if (!found) {
397 dev_err(dev, "No available vop found for display-subsystem.\n"); 398 DRM_DEV_ERROR(dev,
399 "No available vop found for display-subsystem.\n");
398 return -ENODEV; 400 return -ENODEV;
399 } 401 }
400 402
@@ -453,6 +455,8 @@ static int __init rockchip_drm_init(void)
453 455
454 num_rockchip_sub_drivers = 0; 456 num_rockchip_sub_drivers = 0;
455 ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP); 457 ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP);
458 ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver,
459 CONFIG_ROCKCHIP_LVDS);
456 ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver, 460 ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver,
457 CONFIG_ROCKCHIP_ANALOGIX_DP); 461 CONFIG_ROCKCHIP_ANALOGIX_DP);
458 ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP); 462 ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index c7e96b82cf63..498dfbc52cec 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -69,5 +69,6 @@ extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
69extern struct platform_driver dw_mipi_dsi_driver; 69extern struct platform_driver dw_mipi_dsi_driver;
70extern struct platform_driver inno_hdmi_driver; 70extern struct platform_driver inno_hdmi_driver;
71extern struct platform_driver rockchip_dp_driver; 71extern struct platform_driver rockchip_dp_driver;
72extern struct platform_driver rockchip_lvds_driver;
72extern struct platform_driver vop_platform_driver; 73extern struct platform_driver vop_platform_driver;
73#endif /* _ROCKCHIP_DRM_DRV_H_ */ 74#endif /* _ROCKCHIP_DRM_DRV_H_ */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 70773041785b..cd2ace0c3caa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -100,8 +100,9 @@ rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cm
100 ret = drm_framebuffer_init(dev, &rockchip_fb->fb, 100 ret = drm_framebuffer_init(dev, &rockchip_fb->fb,
101 &rockchip_drm_fb_funcs); 101 &rockchip_drm_fb_funcs);
102 if (ret) { 102 if (ret) {
103 dev_err(dev->dev, "Failed to initialize framebuffer: %d\n", 103 DRM_DEV_ERROR(dev->dev,
104 ret); 104 "Failed to initialize framebuffer: %d\n",
105 ret);
105 kfree(rockchip_fb); 106 kfree(rockchip_fb);
106 return ERR_PTR(ret); 107 return ERR_PTR(ret);
107 } 108 }
@@ -134,7 +135,8 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
134 135
135 obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); 136 obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
136 if (!obj) { 137 if (!obj) {
137 dev_err(dev->dev, "Failed to lookup GEM object\n"); 138 DRM_DEV_ERROR(dev->dev,
139 "Failed to lookup GEM object\n");
138 ret = -ENXIO; 140 ret = -ENXIO;
139 goto err_gem_object_unreference; 141 goto err_gem_object_unreference;
140 } 142 }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index 724579ebf947..e6650553f5d6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -76,7 +76,7 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
76 76
77 fbi = drm_fb_helper_alloc_fbi(helper); 77 fbi = drm_fb_helper_alloc_fbi(helper);
78 if (IS_ERR(fbi)) { 78 if (IS_ERR(fbi)) {
79 dev_err(dev->dev, "Failed to create framebuffer info.\n"); 79 DRM_DEV_ERROR(dev->dev, "Failed to create framebuffer info.\n");
80 ret = PTR_ERR(fbi); 80 ret = PTR_ERR(fbi);
81 goto out; 81 goto out;
82 } 82 }
@@ -84,7 +84,8 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
84 helper->fb = rockchip_drm_framebuffer_init(dev, &mode_cmd, 84 helper->fb = rockchip_drm_framebuffer_init(dev, &mode_cmd,
85 private->fbdev_bo); 85 private->fbdev_bo);
86 if (IS_ERR(helper->fb)) { 86 if (IS_ERR(helper->fb)) {
87 dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); 87 DRM_DEV_ERROR(dev->dev,
88 "Failed to allocate DRM framebuffer.\n");
88 ret = PTR_ERR(helper->fb); 89 ret = PTR_ERR(helper->fb);
89 goto out; 90 goto out;
90 } 91 }
@@ -138,21 +139,24 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
138 139
139 ret = drm_fb_helper_init(dev, helper, ROCKCHIP_MAX_CONNECTOR); 140 ret = drm_fb_helper_init(dev, helper, ROCKCHIP_MAX_CONNECTOR);
140 if (ret < 0) { 141 if (ret < 0) {
141 dev_err(dev->dev, "Failed to initialize drm fb helper - %d.\n", 142 DRM_DEV_ERROR(dev->dev,
142 ret); 143 "Failed to initialize drm fb helper - %d.\n",
144 ret);
143 return ret; 145 return ret;
144 } 146 }
145 147
146 ret = drm_fb_helper_single_add_all_connectors(helper); 148 ret = drm_fb_helper_single_add_all_connectors(helper);
147 if (ret < 0) { 149 if (ret < 0) {
148 dev_err(dev->dev, "Failed to add connectors - %d.\n", ret); 150 DRM_DEV_ERROR(dev->dev,
151 "Failed to add connectors - %d.\n", ret);
149 goto err_drm_fb_helper_fini; 152 goto err_drm_fb_helper_fini;
150 } 153 }
151 154
152 ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); 155 ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP);
153 if (ret < 0) { 156 if (ret < 0) {
154 dev_err(dev->dev, "Failed to set initial hw config - %d.\n", 157 DRM_DEV_ERROR(dev->dev,
155 ret); 158 "Failed to set initial hw config - %d.\n",
159 ret);
156 goto err_drm_fb_helper_fini; 160 goto err_drm_fb_helper_fini;
157 } 161 }
158 162
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index bf9ed0e63973..19128b4dea54 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -160,7 +160,7 @@ static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
160 int offset, mask, shift; 160 int offset, mask, shift;
161 161
162 if (!reg || !reg->mask) { 162 if (!reg || !reg->mask) {
163 dev_dbg(vop->dev, "Warning: not support %s\n", reg_name); 163 DRM_DEV_DEBUG(vop->dev, "Warning: not support %s\n", reg_name);
164 return; 164 return;
165 } 165 }
166 166
@@ -499,7 +499,7 @@ static int vop_enable(struct drm_crtc *crtc)
499 499
500 ret = pm_runtime_get_sync(vop->dev); 500 ret = pm_runtime_get_sync(vop->dev);
501 if (ret < 0) { 501 if (ret < 0) {
502 dev_err(vop->dev, "failed to get pm runtime: %d\n", ret); 502 DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
503 return ret; 503 return ret;
504 } 504 }
505 505
@@ -523,7 +523,8 @@ static int vop_enable(struct drm_crtc *crtc)
523 */ 523 */
524 ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev); 524 ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
525 if (ret) { 525 if (ret) {
526 dev_err(vop->dev, "failed to attach dma mapping, %d\n", ret); 526 DRM_DEV_ERROR(vop->dev,
527 "failed to attach dma mapping, %d\n", ret);
527 goto err_disable_aclk; 528 goto err_disable_aclk;
528 } 529 }
529 530
@@ -1361,42 +1362,42 @@ static int vop_initial(struct vop *vop)
1361 1362
1362 vop->hclk = devm_clk_get(vop->dev, "hclk_vop"); 1363 vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
1363 if (IS_ERR(vop->hclk)) { 1364 if (IS_ERR(vop->hclk)) {
1364 dev_err(vop->dev, "failed to get hclk source\n"); 1365 DRM_DEV_ERROR(vop->dev, "failed to get hclk source\n");
1365 return PTR_ERR(vop->hclk); 1366 return PTR_ERR(vop->hclk);
1366 } 1367 }
1367 vop->aclk = devm_clk_get(vop->dev, "aclk_vop"); 1368 vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
1368 if (IS_ERR(vop->aclk)) { 1369 if (IS_ERR(vop->aclk)) {
1369 dev_err(vop->dev, "failed to get aclk source\n"); 1370 DRM_DEV_ERROR(vop->dev, "failed to get aclk source\n");
1370 return PTR_ERR(vop->aclk); 1371 return PTR_ERR(vop->aclk);
1371 } 1372 }
1372 vop->dclk = devm_clk_get(vop->dev, "dclk_vop"); 1373 vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
1373 if (IS_ERR(vop->dclk)) { 1374 if (IS_ERR(vop->dclk)) {
1374 dev_err(vop->dev, "failed to get dclk source\n"); 1375 DRM_DEV_ERROR(vop->dev, "failed to get dclk source\n");
1375 return PTR_ERR(vop->dclk); 1376 return PTR_ERR(vop->dclk);
1376 } 1377 }
1377 1378
1378 ret = pm_runtime_get_sync(vop->dev); 1379 ret = pm_runtime_get_sync(vop->dev);
1379 if (ret < 0) { 1380 if (ret < 0) {
1380 dev_err(vop->dev, "failed to get pm runtime: %d\n", ret); 1381 DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
1381 return ret; 1382 return ret;
1382 } 1383 }
1383 1384
1384 ret = clk_prepare(vop->dclk); 1385 ret = clk_prepare(vop->dclk);
1385 if (ret < 0) { 1386 if (ret < 0) {
1386 dev_err(vop->dev, "failed to prepare dclk\n"); 1387 DRM_DEV_ERROR(vop->dev, "failed to prepare dclk\n");
1387 goto err_put_pm_runtime; 1388 goto err_put_pm_runtime;
1388 } 1389 }
1389 1390
1390 /* Enable both the hclk and aclk to setup the vop */ 1391 /* Enable both the hclk and aclk to setup the vop */
1391 ret = clk_prepare_enable(vop->hclk); 1392 ret = clk_prepare_enable(vop->hclk);
1392 if (ret < 0) { 1393 if (ret < 0) {
1393 dev_err(vop->dev, "failed to prepare/enable hclk\n"); 1394 DRM_DEV_ERROR(vop->dev, "failed to prepare/enable hclk\n");
1394 goto err_unprepare_dclk; 1395 goto err_unprepare_dclk;
1395 } 1396 }
1396 1397
1397 ret = clk_prepare_enable(vop->aclk); 1398 ret = clk_prepare_enable(vop->aclk);
1398 if (ret < 0) { 1399 if (ret < 0) {
1399 dev_err(vop->dev, "failed to prepare/enable aclk\n"); 1400 DRM_DEV_ERROR(vop->dev, "failed to prepare/enable aclk\n");
1400 goto err_disable_hclk; 1401 goto err_disable_hclk;
1401 } 1402 }
1402 1403
@@ -1405,7 +1406,7 @@ static int vop_initial(struct vop *vop)
1405 */ 1406 */
1406 ahb_rst = devm_reset_control_get(vop->dev, "ahb"); 1407 ahb_rst = devm_reset_control_get(vop->dev, "ahb");
1407 if (IS_ERR(ahb_rst)) { 1408 if (IS_ERR(ahb_rst)) {
1408 dev_err(vop->dev, "failed to get ahb reset\n"); 1409 DRM_DEV_ERROR(vop->dev, "failed to get ahb reset\n");
1409 ret = PTR_ERR(ahb_rst); 1410 ret = PTR_ERR(ahb_rst);
1410 goto err_disable_aclk; 1411 goto err_disable_aclk;
1411 } 1412 }
@@ -1434,7 +1435,7 @@ static int vop_initial(struct vop *vop)
1434 */ 1435 */
1435 vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk"); 1436 vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk");
1436 if (IS_ERR(vop->dclk_rst)) { 1437 if (IS_ERR(vop->dclk_rst)) {
1437 dev_err(vop->dev, "failed to get dclk reset\n"); 1438 DRM_DEV_ERROR(vop->dev, "failed to get dclk reset\n");
1438 ret = PTR_ERR(vop->dclk_rst); 1439 ret = PTR_ERR(vop->dclk_rst);
1439 goto err_disable_aclk; 1440 goto err_disable_aclk;
1440 } 1441 }
@@ -1511,7 +1512,7 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
1511 vop_line_flag_irq_disable(vop); 1512 vop_line_flag_irq_disable(vop);
1512 1513
1513 if (jiffies_left == 0) { 1514 if (jiffies_left == 0) {
1514 dev_err(vop->dev, "Timeout waiting for IRQ\n"); 1515 DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
1515 return -ETIMEDOUT; 1516 return -ETIMEDOUT;
1516 } 1517 }
1517 1518
@@ -1558,7 +1559,7 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
1558 1559
1559 irq = platform_get_irq(pdev, 0); 1560 irq = platform_get_irq(pdev, 0);
1560 if (irq < 0) { 1561 if (irq < 0) {
1561 dev_err(dev, "cannot find irq for vop\n"); 1562 DRM_DEV_ERROR(dev, "cannot find irq for vop\n");
1562 return irq; 1563 return irq;
1563 } 1564 }
1564 vop->irq = (unsigned int)irq; 1565 vop->irq = (unsigned int)irq;
@@ -1584,7 +1585,8 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
1584 1585
1585 ret = vop_initial(vop); 1586 ret = vop_initial(vop);
1586 if (ret < 0) { 1587 if (ret < 0) {
1587 dev_err(&pdev->dev, "cannot initial vop dev - err %d\n", ret); 1588 DRM_DEV_ERROR(&pdev->dev,
1589 "cannot initial vop dev - err %d\n", ret);
1588 goto err_disable_pm_runtime; 1590 goto err_disable_pm_runtime;
1589 } 1591 }
1590 1592
diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
new file mode 100644
index 000000000000..c5fbe533796c
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -0,0 +1,581 @@
1/*
2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3 * Author:
4 * Mark Yao <mark.yao@rock-chips.com>
5 * Sandy Huang <hjc@rock-chips.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <drm/drmP.h>
18#include <drm/drm_atomic_helper.h>
19#include <drm/drm_crtc_helper.h>
20#include <drm/drm_dp_helper.h>
21#include <drm/drm_panel.h>
22#include <drm/drm_of.h>
23
24#include <linux/component.h>
25#include <linux/clk.h>
26#include <linux/mfd/syscon.h>
27#include <linux/of_graph.h>
28#include <linux/pm_runtime.h>
29#include <linux/regmap.h>
30#include <linux/reset.h>
31
32#include "rockchip_drm_drv.h"
33#include "rockchip_drm_vop.h"
34#include "rockchip_lvds.h"
35
36#define DISPLAY_OUTPUT_RGB 0
37#define DISPLAY_OUTPUT_LVDS 1
38#define DISPLAY_OUTPUT_DUAL_LVDS 2
39
40#define connector_to_lvds(c) \
41 container_of(c, struct rockchip_lvds, connector)
42
43#define encoder_to_lvds(c) \
44 container_of(c, struct rockchip_lvds, encoder)
45
46/**
47 * rockchip_lvds_soc_data - rockchip lvds Soc private data
48 * @ch1_offset: lvds channel 1 registe offset
49 * grf_soc_con6: general registe offset for LVDS contrl
50 * grf_soc_con7: general registe offset for LVDS contrl
51 * has_vop_sel: to indicate whether need to choose from different VOP.
52 */
53struct rockchip_lvds_soc_data {
54 u32 ch1_offset;
55 int grf_soc_con6;
56 int grf_soc_con7;
57 bool has_vop_sel;
58};
59
60struct rockchip_lvds {
61 struct device *dev;
62 void __iomem *regs;
63 struct regmap *grf;
64 struct clk *pclk;
65 const struct rockchip_lvds_soc_data *soc_data;
66 int output; /* rgb lvds or dual lvds output */
67 int format; /* vesa or jeida format */
68 struct drm_device *drm_dev;
69 struct drm_panel *panel;
70 struct drm_bridge *bridge;
71 struct drm_connector connector;
72 struct drm_encoder encoder;
73 struct dev_pin_info *pins;
74};
75
76static inline void lvds_writel(struct rockchip_lvds *lvds, u32 offset, u32 val)
77{
78 writel_relaxed(val, lvds->regs + offset);
79 if (lvds->output == DISPLAY_OUTPUT_LVDS)
80 return;
81 writel_relaxed(val, lvds->regs + offset + lvds->soc_data->ch1_offset);
82}
83
84static inline int lvds_name_to_format(const char *s)
85{
86 if (strncmp(s, "jeida-18", 8) == 0)
87 return LVDS_JEIDA_18;
88 else if (strncmp(s, "jeida-24", 8) == 0)
89 return LVDS_JEIDA_24;
90 else if (strncmp(s, "vesa-24", 7) == 0)
91 return LVDS_VESA_24;
92
93 return -EINVAL;
94}
95
96static inline int lvds_name_to_output(const char *s)
97{
98 if (strncmp(s, "rgb", 3) == 0)
99 return DISPLAY_OUTPUT_RGB;
100 else if (strncmp(s, "lvds", 4) == 0)
101 return DISPLAY_OUTPUT_LVDS;
102 else if (strncmp(s, "duallvds", 8) == 0)
103 return DISPLAY_OUTPUT_DUAL_LVDS;
104
105 return -EINVAL;
106}
107
108static int rockchip_lvds_poweron(struct rockchip_lvds *lvds)
109{
110 int ret;
111 u32 val;
112
113 ret = clk_enable(lvds->pclk);
114 if (ret < 0) {
115 DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
116 return ret;
117 }
118 ret = pm_runtime_get_sync(lvds->dev);
119 if (ret < 0) {
120 DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
121 clk_disable(lvds->pclk);
122 return ret;
123 }
124 val = RK3288_LVDS_CH0_REG0_LANE4_EN | RK3288_LVDS_CH0_REG0_LANE3_EN |
125 RK3288_LVDS_CH0_REG0_LANE2_EN | RK3288_LVDS_CH0_REG0_LANE1_EN |
126 RK3288_LVDS_CH0_REG0_LANE0_EN;
127 if (lvds->output == DISPLAY_OUTPUT_RGB) {
128 val |= RK3288_LVDS_CH0_REG0_TTL_EN |
129 RK3288_LVDS_CH0_REG0_LANECK_EN;
130 lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val);
131 lvds_writel(lvds, RK3288_LVDS_CH0_REG2,
132 RK3288_LVDS_PLL_FBDIV_REG2(0x46));
133 lvds_writel(lvds, RK3288_LVDS_CH0_REG4,
134 RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE |
135 RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE |
136 RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE |
137 RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE |
138 RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE |
139 RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE);
140 lvds_writel(lvds, RK3288_LVDS_CH0_REG5,
141 RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA |
142 RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA |
143 RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA |
144 RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA |
145 RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA |
146 RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA);
147 } else {
148 val |= RK3288_LVDS_CH0_REG0_LVDS_EN |
149 RK3288_LVDS_CH0_REG0_LANECK_EN;
150 lvds_writel(lvds, RK3288_LVDS_CH0_REG0, val);
151 lvds_writel(lvds, RK3288_LVDS_CH0_REG1,
152 RK3288_LVDS_CH0_REG1_LANECK_BIAS |
153 RK3288_LVDS_CH0_REG1_LANE4_BIAS |
154 RK3288_LVDS_CH0_REG1_LANE3_BIAS |
155 RK3288_LVDS_CH0_REG1_LANE2_BIAS |
156 RK3288_LVDS_CH0_REG1_LANE1_BIAS |
157 RK3288_LVDS_CH0_REG1_LANE0_BIAS);
158 lvds_writel(lvds, RK3288_LVDS_CH0_REG2,
159 RK3288_LVDS_CH0_REG2_RESERVE_ON |
160 RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE |
161 RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE |
162 RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE |
163 RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE |
164 RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE |
165 RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE |
166 RK3288_LVDS_PLL_FBDIV_REG2(0x46));
167 lvds_writel(lvds, RK3288_LVDS_CH0_REG4, 0x00);
168 lvds_writel(lvds, RK3288_LVDS_CH0_REG5, 0x00);
169 }
170 lvds_writel(lvds, RK3288_LVDS_CH0_REG3, RK3288_LVDS_PLL_FBDIV_REG3(0x46));
171 lvds_writel(lvds, RK3288_LVDS_CH0_REGD, RK3288_LVDS_PLL_PREDIV_REGD(0x0a));
172 lvds_writel(lvds, RK3288_LVDS_CH0_REG20, RK3288_LVDS_CH0_REG20_LSB);
173
174 lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE);
175 lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE);
176
177 return 0;
178}
179
180static void rockchip_lvds_poweroff(struct rockchip_lvds *lvds)
181{
182 int ret;
183 u32 val;
184
185 lvds_writel(lvds, RK3288_LVDS_CFG_REG21, RK3288_LVDS_CFG_REG21_TX_ENABLE);
186 lvds_writel(lvds, RK3288_LVDS_CFG_REGC, RK3288_LVDS_CFG_REGC_PLL_ENABLE);
187 val = LVDS_DUAL | LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN | LVDS_PWRDN;
188 val |= val << 16;
189 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val);
190 if (ret != 0)
191 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret);
192
193 pm_runtime_put(lvds->dev);
194 clk_disable(lvds->pclk);
195}
196
197static const struct drm_connector_funcs rockchip_lvds_connector_funcs = {
198 .fill_modes = drm_helper_probe_single_connector_modes,
199 .destroy = drm_connector_cleanup,
200 .reset = drm_atomic_helper_connector_reset,
201 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
202 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
203};
204
205static int rockchip_lvds_connector_get_modes(struct drm_connector *connector)
206{
207 struct rockchip_lvds *lvds = connector_to_lvds(connector);
208 struct drm_panel *panel = lvds->panel;
209
210 return drm_panel_get_modes(panel);
211}
212
213static const
214struct drm_connector_helper_funcs rockchip_lvds_connector_helper_funcs = {
215 .get_modes = rockchip_lvds_connector_get_modes,
216};
217
218static void rockchip_lvds_grf_config(struct drm_encoder *encoder,
219 struct drm_display_mode *mode)
220{
221 struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
222 u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0;
223 u8 pin_dclk = (mode->flags & DRM_MODE_FLAG_PCSYNC) ? 1 : 0;
224 u32 val;
225 int ret;
226
227 /* iomux to LCD data/sync mode */
228 if (lvds->output == DISPLAY_OUTPUT_RGB)
229 if (lvds->pins && !IS_ERR(lvds->pins->default_state))
230 pinctrl_select_state(lvds->pins->p,
231 lvds->pins->default_state);
232 val = lvds->format | LVDS_CH0_EN;
233 if (lvds->output == DISPLAY_OUTPUT_RGB)
234 val |= LVDS_TTL_EN | LVDS_CH1_EN;
235 else if (lvds->output == DISPLAY_OUTPUT_DUAL_LVDS)
236 val |= LVDS_DUAL | LVDS_CH1_EN;
237
238 if ((mode->htotal - mode->hsync_start) & 0x01)
239 val |= LVDS_START_PHASE_RST_1;
240
241 val |= (pin_dclk << 8) | (pin_hsync << 9);
242 val |= (0xffff << 16);
243 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con7, val);
244 if (ret != 0) {
245 DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret);
246 return;
247 }
248}
249
250static int rockchip_lvds_set_vop_source(struct rockchip_lvds *lvds,
251 struct drm_encoder *encoder)
252{
253 u32 val;
254 int ret;
255
256 if (!lvds->soc_data->has_vop_sel)
257 return 0;
258
259 ret = drm_of_encoder_active_endpoint_id(lvds->dev->of_node, encoder);
260 if (ret < 0)
261 return ret;
262
263 val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16;
264 if (ret)
265 val |= RK3288_LVDS_SOC_CON6_SEL_VOP_LIT;
266
267 ret = regmap_write(lvds->grf, lvds->soc_data->grf_soc_con6, val);
268 if (ret < 0)
269 return ret;
270
271 return 0;
272}
273
274static int
275rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder,
276 struct drm_crtc_state *crtc_state,
277 struct drm_connector_state *conn_state)
278{
279 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
280
281 s->output_mode = ROCKCHIP_OUT_MODE_P888;
282 s->output_type = DRM_MODE_CONNECTOR_LVDS;
283
284 return 0;
285}
286
287static void rockchip_lvds_encoder_enable(struct drm_encoder *encoder)
288{
289 struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
290 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
291 int ret;
292
293 drm_panel_prepare(lvds->panel);
294 ret = rockchip_lvds_poweron(lvds);
295 if (ret < 0) {
296 DRM_DEV_ERROR(lvds->dev, "failed to power on lvds: %d\n", ret);
297 drm_panel_unprepare(lvds->panel);
298 }
299 rockchip_lvds_grf_config(encoder, mode);
300 rockchip_lvds_set_vop_source(lvds, encoder);
301 drm_panel_enable(lvds->panel);
302}
303
304static void rockchip_lvds_encoder_disable(struct drm_encoder *encoder)
305{
306 struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
307
308 drm_panel_disable(lvds->panel);
309 rockchip_lvds_poweroff(lvds);
310 drm_panel_unprepare(lvds->panel);
311}
312
313static const
314struct drm_encoder_helper_funcs rockchip_lvds_encoder_helper_funcs = {
315 .enable = rockchip_lvds_encoder_enable,
316 .disable = rockchip_lvds_encoder_disable,
317 .atomic_check = rockchip_lvds_encoder_atomic_check,
318};
319
320static const struct drm_encoder_funcs rockchip_lvds_encoder_funcs = {
321 .destroy = drm_encoder_cleanup,
322};
323
324static const struct rockchip_lvds_soc_data rk3288_lvds_data = {
325 .ch1_offset = 0x100,
326 .grf_soc_con6 = 0x025c,
327 .grf_soc_con7 = 0x0260,
328 .has_vop_sel = true,
329};
330
331static const struct of_device_id rockchip_lvds_dt_ids[] = {
332 {
333 .compatible = "rockchip,rk3288-lvds",
334 .data = &rk3288_lvds_data
335 },
336 {}
337};
338MODULE_DEVICE_TABLE(of, rockchip_lvds_dt_ids);
339
340static int rockchip_lvds_bind(struct device *dev, struct device *master,
341 void *data)
342{
343 struct rockchip_lvds *lvds = dev_get_drvdata(dev);
344 struct drm_device *drm_dev = data;
345 struct drm_encoder *encoder;
346 struct drm_connector *connector;
347 struct device_node *remote = NULL;
348 struct device_node *port, *endpoint;
349 int ret;
350 const char *name;
351 u32 endpoint_id;
352
353 lvds->drm_dev = drm_dev;
354 port = of_graph_get_port_by_id(dev->of_node, 1);
355 if (!port) {
356 DRM_DEV_ERROR(dev,
357 "can't found port point, please init lvds panel port!\n");
358 return -EINVAL;
359 }
360 for_each_child_of_node(port, endpoint) {
361 of_property_read_u32(endpoint, "reg", &endpoint_id);
362 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, endpoint_id,
363 &lvds->panel, &lvds->bridge);
364 if (!ret)
365 break;
366 }
367 if (ret) {
368 DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n");
369 ret = -EPROBE_DEFER;
370 goto err_put_port;
371 }
372 if (lvds->panel)
373 remote = lvds->panel->dev->of_node;
374 else
375 remote = lvds->bridge->of_node;
376 if (of_property_read_string(dev->of_node, "rockchip,output", &name))
377 /* default set it as output rgb */
378 lvds->output = DISPLAY_OUTPUT_RGB;
379 else
380 lvds->output = lvds_name_to_output(name);
381
382 if (lvds->output < 0) {
383 DRM_DEV_ERROR(dev, "invalid output type [%s]\n", name);
384 ret = lvds->output;
385 goto err_put_remote;
386 }
387
388 if (of_property_read_string(remote, "data-mapping", &name))
389 /* default set it as format vesa 18 */
390 lvds->format = LVDS_VESA_18;
391 else
392 lvds->format = lvds_name_to_format(name);
393
394 if (lvds->format < 0) {
395 DRM_DEV_ERROR(dev, "invalid data-mapping format [%s]\n", name);
396 ret = lvds->format;
397 goto err_put_remote;
398 }
399
400 encoder = &lvds->encoder;
401 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
402 dev->of_node);
403
404 ret = drm_encoder_init(drm_dev, encoder, &rockchip_lvds_encoder_funcs,
405 DRM_MODE_ENCODER_LVDS, NULL);
406 if (ret < 0) {
407 DRM_DEV_ERROR(drm_dev->dev,
408 "failed to initialize encoder: %d\n", ret);
409 goto err_put_remote;
410 }
411
412 drm_encoder_helper_add(encoder, &rockchip_lvds_encoder_helper_funcs);
413
414 if (lvds->panel) {
415 connector = &lvds->connector;
416 connector->dpms = DRM_MODE_DPMS_OFF;
417 ret = drm_connector_init(drm_dev, connector,
418 &rockchip_lvds_connector_funcs,
419 DRM_MODE_CONNECTOR_LVDS);
420 if (ret < 0) {
421 DRM_DEV_ERROR(drm_dev->dev,
422 "failed to initialize connector: %d\n", ret);
423 goto err_free_encoder;
424 }
425
426 drm_connector_helper_add(connector,
427 &rockchip_lvds_connector_helper_funcs);
428
429 ret = drm_mode_connector_attach_encoder(connector, encoder);
430 if (ret < 0) {
431 DRM_DEV_ERROR(drm_dev->dev,
432 "failed to attach encoder: %d\n", ret);
433 goto err_free_connector;
434 }
435
436 ret = drm_panel_attach(lvds->panel, connector);
437 if (ret < 0) {
438 DRM_DEV_ERROR(drm_dev->dev,
439 "failed to attach panel: %d\n", ret);
440 goto err_free_connector;
441 }
442 } else {
443 lvds->bridge->encoder = encoder;
444 ret = drm_bridge_attach(encoder, lvds->bridge, NULL);
445 if (ret) {
446 DRM_DEV_ERROR(drm_dev->dev,
447 "failed to attach bridge: %d\n", ret);
448 goto err_free_encoder;
449 }
450 encoder->bridge = lvds->bridge;
451 }
452
453 pm_runtime_enable(dev);
454 of_node_put(remote);
455 of_node_put(port);
456
457 return 0;
458
459err_free_connector:
460 drm_connector_cleanup(connector);
461err_free_encoder:
462 drm_encoder_cleanup(encoder);
463err_put_remote:
464 of_node_put(remote);
465err_put_port:
466 of_node_put(port);
467
468 return ret;
469}
470
471static void rockchip_lvds_unbind(struct device *dev, struct device *master,
472 void *data)
473{
474 struct rockchip_lvds *lvds = dev_get_drvdata(dev);
475
476 rockchip_lvds_encoder_disable(&lvds->encoder);
477 if (lvds->panel)
478 drm_panel_detach(lvds->panel);
479 pm_runtime_disable(dev);
480 drm_connector_cleanup(&lvds->connector);
481 drm_encoder_cleanup(&lvds->encoder);
482}
483
484static const struct component_ops rockchip_lvds_component_ops = {
485 .bind = rockchip_lvds_bind,
486 .unbind = rockchip_lvds_unbind,
487};
488
489static int rockchip_lvds_probe(struct platform_device *pdev)
490{
491 struct device *dev = &pdev->dev;
492 struct rockchip_lvds *lvds;
493 const struct of_device_id *match;
494 struct resource *res;
495 int ret;
496
497 if (!dev->of_node)
498 return -ENODEV;
499
500 lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL);
501 if (!lvds)
502 return -ENOMEM;
503
504 lvds->dev = dev;
505 match = of_match_node(rockchip_lvds_dt_ids, dev->of_node);
506 if (!match)
507 return -ENODEV;
508 lvds->soc_data = match->data;
509
510 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
511 lvds->regs = devm_ioremap_resource(&pdev->dev, res);
512 if (IS_ERR(lvds->regs))
513 return PTR_ERR(lvds->regs);
514
515 lvds->pclk = devm_clk_get(&pdev->dev, "pclk_lvds");
516 if (IS_ERR(lvds->pclk)) {
517 DRM_DEV_ERROR(dev, "could not get pclk_lvds\n");
518 return PTR_ERR(lvds->pclk);
519 }
520
521 lvds->pins = devm_kzalloc(lvds->dev, sizeof(*lvds->pins),
522 GFP_KERNEL);
523 if (!lvds->pins)
524 return -ENOMEM;
525
526 lvds->pins->p = devm_pinctrl_get(lvds->dev);
527 if (IS_ERR(lvds->pins->p)) {
528 DRM_DEV_ERROR(dev, "no pinctrl handle\n");
529 devm_kfree(lvds->dev, lvds->pins);
530 lvds->pins = NULL;
531 } else {
532 lvds->pins->default_state =
533 pinctrl_lookup_state(lvds->pins->p, "lcdc");
534 if (IS_ERR(lvds->pins->default_state)) {
535 DRM_DEV_ERROR(dev, "no default pinctrl state\n");
536 devm_kfree(lvds->dev, lvds->pins);
537 lvds->pins = NULL;
538 }
539 }
540
541 lvds->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
542 "rockchip,grf");
543 if (IS_ERR(lvds->grf)) {
544 DRM_DEV_ERROR(dev, "missing rockchip,grf property\n");
545 return PTR_ERR(lvds->grf);
546 }
547
548 dev_set_drvdata(dev, lvds);
549
550 ret = clk_prepare(lvds->pclk);
551 if (ret < 0) {
552 DRM_DEV_ERROR(dev, "failed to prepare pclk_lvds\n");
553 return ret;
554 }
555 ret = component_add(&pdev->dev, &rockchip_lvds_component_ops);
556 if (ret < 0) {
557 DRM_DEV_ERROR(dev, "failed to add component\n");
558 clk_unprepare(lvds->pclk);
559 }
560
561 return ret;
562}
563
564static int rockchip_lvds_remove(struct platform_device *pdev)
565{
566 struct rockchip_lvds *lvds = dev_get_drvdata(&pdev->dev);
567
568 component_del(&pdev->dev, &rockchip_lvds_component_ops);
569 clk_unprepare(lvds->pclk);
570
571 return 0;
572}
573
574struct platform_driver rockchip_lvds_driver = {
575 .probe = rockchip_lvds_probe,
576 .remove = rockchip_lvds_remove,
577 .driver = {
578 .name = "rockchip-lvds",
579 .of_match_table = of_match_ptr(rockchip_lvds_dt_ids),
580 },
581};
diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.h b/drivers/gpu/drm/rockchip/rockchip_lvds.h
new file mode 100644
index 000000000000..15810b737809
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.h
@@ -0,0 +1,114 @@
1/*
2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3 * Author:
4 * Sandy Huang <hjc@rock-chips.com>
5 * Mark Yao <mark.yao@rock-chips.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _ROCKCHIP_LVDS_
18#define _ROCKCHIP_LVDS_
19
20#define RK3288_LVDS_CH0_REG0 0x00
21#define RK3288_LVDS_CH0_REG0_LVDS_EN BIT(7)
22#define RK3288_LVDS_CH0_REG0_TTL_EN BIT(6)
23#define RK3288_LVDS_CH0_REG0_LANECK_EN BIT(5)
24#define RK3288_LVDS_CH0_REG0_LANE4_EN BIT(4)
25#define RK3288_LVDS_CH0_REG0_LANE3_EN BIT(3)
26#define RK3288_LVDS_CH0_REG0_LANE2_EN BIT(2)
27#define RK3288_LVDS_CH0_REG0_LANE1_EN BIT(1)
28#define RK3288_LVDS_CH0_REG0_LANE0_EN BIT(0)
29
30#define RK3288_LVDS_CH0_REG1 0x04
31#define RK3288_LVDS_CH0_REG1_LANECK_BIAS BIT(5)
32#define RK3288_LVDS_CH0_REG1_LANE4_BIAS BIT(4)
33#define RK3288_LVDS_CH0_REG1_LANE3_BIAS BIT(3)
34#define RK3288_LVDS_CH0_REG1_LANE2_BIAS BIT(2)
35#define RK3288_LVDS_CH0_REG1_LANE1_BIAS BIT(1)
36#define RK3288_LVDS_CH0_REG1_LANE0_BIAS BIT(0)
37
38#define RK3288_LVDS_CH0_REG2 0x08
39#define RK3288_LVDS_CH0_REG2_RESERVE_ON BIT(7)
40#define RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE BIT(6)
41#define RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE BIT(5)
42#define RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE BIT(4)
43#define RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE BIT(3)
44#define RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE BIT(2)
45#define RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE BIT(1)
46#define RK3288_LVDS_CH0_REG2_PLL_FBDIV8 BIT(0)
47
48#define RK3288_LVDS_CH0_REG3 0x0c
49#define RK3288_LVDS_CH0_REG3_PLL_FBDIV_MASK 0xff
50
51#define RK3288_LVDS_CH0_REG4 0x10
52#define RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE BIT(5)
53#define RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE BIT(4)
54#define RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE BIT(3)
55#define RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE BIT(2)
56#define RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE BIT(1)
57#define RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE BIT(0)
58
59#define RK3288_LVDS_CH0_REG5 0x14
60#define RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA BIT(5)
61#define RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA BIT(4)
62#define RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA BIT(3)
63#define RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA BIT(2)
64#define RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA BIT(1)
65#define RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA BIT(0)
66
67#define RK3288_LVDS_CFG_REGC 0x30
68#define RK3288_LVDS_CFG_REGC_PLL_ENABLE 0x00
69#define RK3288_LVDS_CFG_REGC_PLL_DISABLE 0xff
70
71#define RK3288_LVDS_CH0_REGD 0x34
72#define RK3288_LVDS_CH0_REGD_PLL_PREDIV_MASK 0x1f
73
74#define RK3288_LVDS_CH0_REG20 0x80
75#define RK3288_LVDS_CH0_REG20_MSB 0x45
76#define RK3288_LVDS_CH0_REG20_LSB 0x44
77
78#define RK3288_LVDS_CFG_REG21 0x84
79#define RK3288_LVDS_CFG_REG21_TX_ENABLE 0x92
80#define RK3288_LVDS_CFG_REG21_TX_DISABLE 0x00
81#define RK3288_LVDS_CH1_OFFSET 0x100
82
83/* fbdiv value is split over 2 registers, with bit8 in reg2 */
84#define RK3288_LVDS_PLL_FBDIV_REG2(_fbd) \
85 (_fbd & BIT(8) ? RK3288_LVDS_CH0_REG2_PLL_FBDIV8 : 0)
86#define RK3288_LVDS_PLL_FBDIV_REG3(_fbd) \
87 (_fbd & RK3288_LVDS_CH0_REG3_PLL_FBDIV_MASK)
88#define RK3288_LVDS_PLL_PREDIV_REGD(_pd) \
89 (_pd & RK3288_LVDS_CH0_REGD_PLL_PREDIV_MASK)
90
91#define RK3288_LVDS_SOC_CON6_SEL_VOP_LIT BIT(3)
92
93#define LVDS_FMT_MASK (0x07 << 16)
94#define LVDS_MSB BIT(3)
95#define LVDS_DUAL BIT(4)
96#define LVDS_FMT_1 BIT(5)
97#define LVDS_TTL_EN BIT(6)
98#define LVDS_START_PHASE_RST_1 BIT(7)
99#define LVDS_DCLK_INV BIT(8)
100#define LVDS_CH0_EN BIT(11)
101#define LVDS_CH1_EN BIT(12)
102#define LVDS_PWRDN BIT(15)
103
104#define LVDS_24BIT (0 << 1)
105#define LVDS_18BIT (1 << 1)
106#define LVDS_FORMAT_VESA (0 << 0)
107#define LVDS_FORMAT_JEIDA (1 << 0)
108
109#define LVDS_VESA_24 0
110#define LVDS_JEIDA_24 1
111#define LVDS_VESA_18 2
112#define LVDS_JEIDA_18 3
113
114#endif /* _ROCKCHIP_LVDS_ */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 94de7b9f6fde..4a39049e901a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -533,7 +533,7 @@ static int vop_probe(struct platform_device *pdev)
533 struct device *dev = &pdev->dev; 533 struct device *dev = &pdev->dev;
534 534
535 if (!dev->of_node) { 535 if (!dev->of_node) {
536 dev_err(dev, "can't find vop devices\n"); 536 DRM_DEV_ERROR(dev, "can't find vop devices\n");
537 return -ENODEV; 537 return -ENODEV;
538 } 538 }
539 539
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index 1700c542cd93..9e9343101738 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -16,6 +16,7 @@
16#include <drm/drm_atomic_helper.h> 16#include <drm/drm_atomic_helper.h>
17#include <drm/drm_crtc_helper.h> 17#include <drm/drm_crtc_helper.h>
18#include <drm/drm_gem_cma_helper.h> 18#include <drm/drm_gem_cma_helper.h>
19#include <drm/drm_gem_framebuffer_helper.h>
19#include <drm/drm_fb_cma_helper.h> 20#include <drm/drm_fb_cma_helper.h>
20#include <drm/drm_of.h> 21#include <drm/drm_of.h>
21 22
@@ -145,7 +146,7 @@ static void sti_output_poll_changed(struct drm_device *ddev)
145} 146}
146 147
147static const struct drm_mode_config_funcs sti_mode_config_funcs = { 148static const struct drm_mode_config_funcs sti_mode_config_funcs = {
148 .fb_create = drm_fb_cma_create, 149 .fb_create = drm_gem_fb_create,
149 .output_poll_changed = sti_output_poll_changed, 150 .output_poll_changed = sti_output_poll_changed,
150 .atomic_check = sti_atomic_check, 151 .atomic_check = sti_atomic_check,
151 .atomic_commit = drm_atomic_helper_commit, 152 .atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index 852bf2293b05..83314aee65cb 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -463,11 +463,7 @@ static int sti_dvo_bind(struct device *dev, struct device *master, void *data)
463 bridge->driver_private = dvo; 463 bridge->driver_private = dvo;
464 bridge->funcs = &sti_dvo_bridge_funcs; 464 bridge->funcs = &sti_dvo_bridge_funcs;
465 bridge->of_node = dvo->dev.of_node; 465 bridge->of_node = dvo->dev.of_node;
466 err = drm_bridge_add(bridge); 466 drm_bridge_add(bridge);
467 if (err) {
468 DRM_ERROR("Failed to add bridge\n");
469 return err;
470 }
471 467
472 err = drm_bridge_attach(encoder, bridge, NULL); 468 err = drm_bridge_attach(encoder, bridge, NULL);
473 if (err) { 469 if (err) {
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index b333b37f3f89..c857663eafc2 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -17,6 +17,7 @@
17#include <drm/drm_crtc_helper.h> 17#include <drm/drm_crtc_helper.h>
18#include <drm/drm_fb_cma_helper.h> 18#include <drm/drm_fb_cma_helper.h>
19#include <drm/drm_gem_cma_helper.h> 19#include <drm/drm_gem_cma_helper.h>
20#include <drm/drm_gem_framebuffer_helper.h>
20 21
21#include "ltdc.h" 22#include "ltdc.h"
22 23
@@ -31,7 +32,7 @@ static void drv_output_poll_changed(struct drm_device *ddev)
31} 32}
32 33
33static const struct drm_mode_config_funcs drv_mode_config_funcs = { 34static const struct drm_mode_config_funcs drv_mode_config_funcs = {
34 .fb_create = drm_fb_cma_create, 35 .fb_create = drm_gem_fb_create,
35 .output_poll_changed = drv_output_poll_changed, 36 .output_poll_changed = drv_output_poll_changed,
36 .atomic_check = drm_atomic_helper_check, 37 .atomic_check = drm_atomic_helper_check,
37 .atomic_commit = drm_atomic_helper_commit, 38 .atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 568c5d0461ea..e5b6310240fe 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -113,11 +113,13 @@ static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)
113 113
114static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf) 114static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf)
115{ 115{
116 int divisor = idf * odf;
117
116 /* prevent from division by 0 */ 118 /* prevent from division by 0 */
117 if (idf * odf) 119 if (!divisor)
118 return DIV_ROUND_CLOSEST(clkin_khz * ndiv, idf * odf); 120 return 0;
119 121
120 return 0; 122 return DIV_ROUND_CLOSEST(clkin_khz * ndiv, divisor);
121} 123}
122 124
123static int dsi_pll_get_params(int clkin_khz, int clkout_khz, 125static int dsi_pll_get_params(int clkin_khz, int clkout_khz,
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index ace59651892f..a2012638d5f7 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -106,11 +106,6 @@ static int sun4i_drv_bind(struct device *dev)
106 goto free_drm; 106 goto free_drm;
107 } 107 }
108 108
109 /* drm_vblank_init calls kcalloc, which can fail */
110 ret = drm_vblank_init(drm, 1);
111 if (ret)
112 goto free_mem_region;
113
114 drm_mode_config_init(drm); 109 drm_mode_config_init(drm);
115 110
116 ret = component_bind_all(drm->dev, drm); 111 ret = component_bind_all(drm->dev, drm);
@@ -119,6 +114,11 @@ static int sun4i_drv_bind(struct device *dev)
119 goto cleanup_mode_config; 114 goto cleanup_mode_config;
120 } 115 }
121 116
117 /* drm_vblank_init calls kcalloc, which can fail */
118 ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
119 if (ret)
120 goto free_mem_region;
121
122 drm->irq_enabled = true; 122 drm->irq_enabled = true;
123 123
124 /* Remove early framebuffers (ie. simplefb) */ 124 /* Remove early framebuffers (ie. simplefb) */
@@ -200,11 +200,39 @@ static int compare_of(struct device *dev, void *data)
200 return dev->of_node == data; 200 return dev->of_node == data;
201} 201}
202 202
203/*
204 * The encoder drivers use drm_of_find_possible_crtcs to get upstream
205 * crtcs from the device tree using of_graph. For the results to be
206 * correct, encoders must be probed/bound after _all_ crtcs have been
207 * created. The existing code uses a depth first recursive traversal
208 * of the of_graph, which means the encoders downstream of the TCON
209 * get add right after the first TCON. The second TCON or CRTC will
210 * never be properly associated with encoders connected to it.
211 *
212 * Also, in a dual display pipeline setup, both frontends can feed
213 * either backend, and both backends can feed either TCON, we want
214 * all components of the same type to be added before the next type
215 * in the pipeline. Fortunately, the pipelines are perfectly symmetric,
216 * i.e. components of the same type are at the same depth when counted
217 * from the frontend. The only exception is the third pipeline in
218 * the A80 SoC, which we do not support anyway.
219 *
220 * Hence we can use a breadth first search traversal order to add
221 * components. We do not need to check for duplicates. The component
222 * matching system handles this for us.
223 */
224struct endpoint_list {
225 struct device_node *node;
226 struct list_head list;
227};
228
203static int sun4i_drv_add_endpoints(struct device *dev, 229static int sun4i_drv_add_endpoints(struct device *dev,
230 struct list_head *endpoints,
204 struct component_match **match, 231 struct component_match **match,
205 struct device_node *node) 232 struct device_node *node)
206{ 233{
207 struct device_node *port, *ep, *remote; 234 struct device_node *port, *ep, *remote;
235 struct endpoint_list *endpoint;
208 int count = 0; 236 int count = 0;
209 237
210 /* 238 /*
@@ -264,10 +292,15 @@ static int sun4i_drv_add_endpoints(struct device *dev,
264 } 292 }
265 } 293 }
266 294
267 /* Walk down our tree */ 295 /* Add downstream nodes to the queue */
268 count += sun4i_drv_add_endpoints(dev, match, remote); 296 endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
297 if (!endpoint) {
298 of_node_put(remote);
299 return -ENOMEM;
300 }
269 301
270 of_node_put(remote); 302 endpoint->node = remote;
303 list_add_tail(&endpoint->list, endpoints);
271 } 304 }
272 305
273 return count; 306 return count;
@@ -277,7 +310,9 @@ static int sun4i_drv_probe(struct platform_device *pdev)
277{ 310{
278 struct component_match *match = NULL; 311 struct component_match *match = NULL;
279 struct device_node *np = pdev->dev.of_node; 312 struct device_node *np = pdev->dev.of_node;
280 int i, count = 0; 313 struct endpoint_list *endpoint, *endpoint_temp;
314 int i, ret, count = 0;
315 LIST_HEAD(endpoints);
281 316
282 for (i = 0;; i++) { 317 for (i = 0;; i++) {
283 struct device_node *pipeline = of_parse_phandle(np, 318 struct device_node *pipeline = of_parse_phandle(np,
@@ -286,12 +321,31 @@ static int sun4i_drv_probe(struct platform_device *pdev)
286 if (!pipeline) 321 if (!pipeline)
287 break; 322 break;
288 323
289 count += sun4i_drv_add_endpoints(&pdev->dev, &match, 324 endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
290 pipeline); 325 if (!endpoint) {
291 of_node_put(pipeline); 326 ret = -ENOMEM;
327 goto err_free_endpoints;
328 }
292 329
293 DRM_DEBUG_DRIVER("Queued %d outputs on pipeline %d\n", 330 endpoint->node = pipeline;
294 count, i); 331 list_add_tail(&endpoint->list, &endpoints);
332 }
333
334 list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) {
335 /* process this endpoint */
336 ret = sun4i_drv_add_endpoints(&pdev->dev, &endpoints, &match,
337 endpoint->node);
338
339 /* sun4i_drv_add_endpoints can fail to allocate memory */
340 if (ret < 0)
341 goto err_free_endpoints;
342
343 count += ret;
344
345 /* delete and cleanup the current entry */
346 list_del(&endpoint->list);
347 of_node_put(endpoint->node);
348 kfree(endpoint);
295 } 349 }
296 350
297 if (count) 351 if (count)
@@ -300,6 +354,15 @@ static int sun4i_drv_probe(struct platform_device *pdev)
300 match); 354 match);
301 else 355 else
302 return 0; 356 return 0;
357
358err_free_endpoints:
359 list_for_each_entry_safe(endpoint, endpoint_temp, &endpoints, list) {
360 list_del(&endpoint->list);
361 of_node_put(endpoint->node);
362 kfree(endpoint);
363 }
364
365 return ret;
303} 366}
304 367
305static int sun4i_drv_remove(struct platform_device *pdev) 368static int sun4i_drv_remove(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index d9791292553e..e853dfe51389 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -463,42 +463,170 @@ static int sun4i_tcon_init_regmap(struct device *dev,
463 * function in fact searches the corresponding engine, and the ID is 463 * function in fact searches the corresponding engine, and the ID is
464 * requested via the get_id function of the engine. 464 * requested via the get_id function of the engine.
465 */ 465 */
466static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv, 466static struct sunxi_engine *
467 struct device_node *node) 467sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
468 struct device_node *node)
468{ 469{
469 struct device_node *port, *ep, *remote; 470 struct device_node *port, *ep, *remote;
470 struct sunxi_engine *engine; 471 struct sunxi_engine *engine = ERR_PTR(-EINVAL);
471 472
472 port = of_graph_get_port_by_id(node, 0); 473 port = of_graph_get_port_by_id(node, 0);
473 if (!port) 474 if (!port)
474 return ERR_PTR(-EINVAL); 475 return ERR_PTR(-EINVAL);
475 476
477 /*
478 * This only works if there is only one path from the TCON
479 * to any display engine. Otherwise the probe order of the
480 * TCONs and display engines is not guaranteed. They may
481 * either bind to the wrong one, or worse, bind to the same
482 * one if additional checks are not done.
483 *
484 * Bail out if there are multiple input connections.
485 */
486 if (of_get_available_child_count(port) != 1)
487 goto out_put_port;
488
489 /* Get the first connection without specifying an ID */
490 ep = of_get_next_available_child(port, NULL);
491 if (!ep)
492 goto out_put_port;
493
494 remote = of_graph_get_remote_port_parent(ep);
495 if (!remote)
496 goto out_put_ep;
497
498 /* does this node match any registered engines? */
499 list_for_each_entry(engine, &drv->engine_list, list)
500 if (remote == engine->node)
501 goto out_put_remote;
502
503 /* keep looking through upstream ports */
504 engine = sun4i_tcon_find_engine_traverse(drv, remote);
505
506out_put_remote:
507 of_node_put(remote);
508out_put_ep:
509 of_node_put(ep);
510out_put_port:
511 of_node_put(port);
512
513 return engine;
514}
515
516/*
517 * The device tree binding says that the remote endpoint ID of any
518 * connection between components, up to and including the TCON, of
519 * the display pipeline should be equal to the actual ID of the local
520 * component. Thus we can look at any one of the input connections of
521 * the TCONs, and use that connection's remote endpoint ID as our own.
522 *
523 * Since the user of this function already finds the input port,
524 * the port is passed in directly without further checks.
525 */
526static int sun4i_tcon_of_get_id_from_port(struct device_node *port)
527{
528 struct device_node *ep;
529 int ret = -EINVAL;
530
531 /* try finding an upstream endpoint */
476 for_each_available_child_of_node(port, ep) { 532 for_each_available_child_of_node(port, ep) {
477 remote = of_graph_get_remote_port_parent(ep); 533 struct device_node *remote;
534 u32 reg;
535
536 remote = of_graph_get_remote_endpoint(ep);
478 if (!remote) 537 if (!remote)
479 continue; 538 continue;
480 539
481 /* does this node match any registered engines? */ 540 ret = of_property_read_u32(remote, "reg", &reg);
482 list_for_each_entry(engine, &drv->engine_list, list) { 541 if (ret)
483 if (remote == engine->node) { 542 continue;
484 of_node_put(remote);
485 of_node_put(port);
486 return engine;
487 }
488 }
489 543
490 /* keep looking through upstream ports */ 544 ret = reg;
491 engine = sun4i_tcon_find_engine(drv, remote);
492 if (!IS_ERR(engine)) {
493 of_node_put(remote);
494 of_node_put(port);
495 return engine;
496 }
497 } 545 }
498 546
547 return ret;
548}
549
550/*
551 * Once we know the TCON's id, we can look through the list of
552 * engines to find a matching one. We assume all engines have
553 * been probed and added to the list.
554 */
555static struct sunxi_engine *sun4i_tcon_get_engine_by_id(struct sun4i_drv *drv,
556 int id)
557{
558 struct sunxi_engine *engine;
559
560 list_for_each_entry(engine, &drv->engine_list, list)
561 if (engine->id == id)
562 return engine;
563
499 return ERR_PTR(-EINVAL); 564 return ERR_PTR(-EINVAL);
500} 565}
501 566
567/*
568 * On SoCs with the old display pipeline design (Display Engine 1.0),
569 * we assumed the TCON was always tied to just one backend. However
570 * this proved not to be the case. On the A31, the TCON can select
571 * either backend as its source. On the A20 (and likely on the A10),
572 * the backend can choose which TCON to output to.
573 *
574 * The device tree binding says that the remote endpoint ID of any
575 * connection between components, up to and including the TCON, of
576 * the display pipeline should be equal to the actual ID of the local
577 * component. Thus we should be able to look at any one of the input
578 * connections of the TCONs, and use that connection's remote endpoint
579 * ID as our own.
580 *
581 * However the connections between the backend and TCON were assumed
582 * to be always singular, and their endpoit IDs were all incorrectly
583 * set to 0. This means for these old device trees, we cannot just look
584 * up the remote endpoint ID of a TCON input endpoint. TCON1 would be
585 * incorrectly identified as TCON0.
586 *
587 * This function first checks if the TCON node has 2 input endpoints.
588 * If so, then the device tree is a corrected version, and it will use
589 * sun4i_tcon_of_get_id() and sun4i_tcon_get_engine_by_id() from above
590 * to fetch the ID and engine directly. If not, then it is likely an
591 * old device trees, where the endpoint IDs were incorrect, but did not
592 * have endpoint connections between the backend and TCON across
593 * different display pipelines. It will fall back to the old method of
594 * traversing the of_graph to try and find a matching engine by device
595 * node.
596 *
597 * In the case of single display pipeline device trees, either method
598 * works.
599 */
600static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv,
601 struct device_node *node)
602{
603 struct device_node *port;
604 struct sunxi_engine *engine;
605
606 port = of_graph_get_port_by_id(node, 0);
607 if (!port)
608 return ERR_PTR(-EINVAL);
609
610 /*
611 * Is this a corrected device tree with cross pipeline
612 * connections between the backend and TCON?
613 */
614 if (of_get_child_count(port) > 1) {
615 /* Get our ID directly from an upstream endpoint */
616 int id = sun4i_tcon_of_get_id_from_port(port);
617
618 /* Get our engine by matching our ID */
619 engine = sun4i_tcon_get_engine_by_id(drv, id);
620
621 of_node_put(port);
622 return engine;
623 }
624
625 /* Fallback to old method by traversing input endpoints */
626 of_node_put(port);
627 return sun4i_tcon_find_engine_traverse(drv, node);
628}
629
502static int sun4i_tcon_bind(struct device *dev, struct device *master, 630static int sun4i_tcon_bind(struct device *dev, struct device *master,
503 void *data) 631 void *data)
504{ 632{
@@ -530,10 +658,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
530 } 658 }
531 659
532 /* Make sure our TCON is reset */ 660 /* Make sure our TCON is reset */
533 if (!reset_control_status(tcon->lcd_rst)) 661 ret = reset_control_reset(tcon->lcd_rst);
534 reset_control_assert(tcon->lcd_rst);
535
536 ret = reset_control_deassert(tcon->lcd_rst);
537 if (ret) { 662 if (ret) {
538 dev_err(dev, "Couldn't deassert our reset line\n"); 663 dev_err(dev, "Couldn't deassert our reset line\n");
539 return ret; 664 return ret;
@@ -574,6 +699,25 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
574 if (ret < 0) 699 if (ret < 0)
575 goto err_free_clocks; 700 goto err_free_clocks;
576 701
702 if (tcon->quirks->needs_de_be_mux) {
703 /*
704 * We assume there is no dynamic muxing of backends
705 * and TCONs, so we select the backend with same ID.
706 *
707 * While dynamic selection might be interesting, since
708 * the CRTC is tied to the TCON, while the layers are
709 * tied to the backends, this means, we will need to
710 * switch between groups of layers. There might not be
711 * a way to represent this constraint in DRM.
712 */
713 regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
714 SUN4I_TCON0_CTL_SRC_SEL_MASK,
715 tcon->id);
716 regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
717 SUN4I_TCON1_CTL_SRC_SEL_MASK,
718 tcon->id);
719 }
720
577 list_add_tail(&tcon->list, &drv->tcon_list); 721 list_add_tail(&tcon->list, &drv->tcon_list);
578 722
579 return 0; 723 return 0;
@@ -629,11 +773,13 @@ static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
629}; 773};
630 774
631static const struct sun4i_tcon_quirks sun6i_a31_quirks = { 775static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
632 .has_channel_1 = true, 776 .has_channel_1 = true,
777 .needs_de_be_mux = true,
633}; 778};
634 779
635static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { 780static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
636 .has_channel_1 = true, 781 .has_channel_1 = true,
782 .needs_de_be_mux = true,
637}; 783};
638 784
639static const struct sun4i_tcon_quirks sun8i_a33_quirks = { 785static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 552c88ec16be..5a219d1ccc26 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -37,6 +37,7 @@
37#define SUN4I_TCON0_CTL_TCON_ENABLE BIT(31) 37#define SUN4I_TCON0_CTL_TCON_ENABLE BIT(31)
38#define SUN4I_TCON0_CTL_CLK_DELAY_MASK GENMASK(8, 4) 38#define SUN4I_TCON0_CTL_CLK_DELAY_MASK GENMASK(8, 4)
39#define SUN4I_TCON0_CTL_CLK_DELAY(delay) ((delay << 4) & SUN4I_TCON0_CTL_CLK_DELAY_MASK) 39#define SUN4I_TCON0_CTL_CLK_DELAY(delay) ((delay << 4) & SUN4I_TCON0_CTL_CLK_DELAY_MASK)
40#define SUN4I_TCON0_CTL_SRC_SEL_MASK GENMASK(2, 0)
40 41
41#define SUN4I_TCON0_DCLK_REG 0x44 42#define SUN4I_TCON0_DCLK_REG 0x44
42#define SUN4I_TCON0_DCLK_GATE_BIT (31) 43#define SUN4I_TCON0_DCLK_GATE_BIT (31)
@@ -85,6 +86,7 @@
85#define SUN4I_TCON1_CTL_INTERLACE_ENABLE BIT(20) 86#define SUN4I_TCON1_CTL_INTERLACE_ENABLE BIT(20)
86#define SUN4I_TCON1_CTL_CLK_DELAY_MASK GENMASK(8, 4) 87#define SUN4I_TCON1_CTL_CLK_DELAY_MASK GENMASK(8, 4)
87#define SUN4I_TCON1_CTL_CLK_DELAY(delay) ((delay << 4) & SUN4I_TCON1_CTL_CLK_DELAY_MASK) 88#define SUN4I_TCON1_CTL_CLK_DELAY(delay) ((delay << 4) & SUN4I_TCON1_CTL_CLK_DELAY_MASK)
89#define SUN4I_TCON1_CTL_SRC_SEL_MASK GENMASK(1, 0)
88 90
89#define SUN4I_TCON1_BASIC0_REG 0x94 91#define SUN4I_TCON1_BASIC0_REG 0x94
90#define SUN4I_TCON1_BASIC0_X(width) ((((width) - 1) & 0xfff) << 16) 92#define SUN4I_TCON1_BASIC0_X(width) ((((width) - 1) & 0xfff) << 16)
@@ -146,6 +148,7 @@
146struct sun4i_tcon_quirks { 148struct sun4i_tcon_quirks {
147 bool has_unknown_mux; /* sun5i has undocumented mux */ 149 bool has_unknown_mux; /* sun5i has undocumented mux */
148 bool has_channel_1; /* a33 does not have channel 1 */ 150 bool has_channel_1; /* a33 does not have channel 1 */
151 bool needs_de_be_mux; /* sun6i needs mux to select backend */
149}; 152};
150 153
151struct sun4i_tcon { 154struct sun4i_tcon {
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index b0d70f943cec..146ac9a5a2fd 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -23,6 +23,7 @@
23#include <drm/drm_atomic.h> 23#include <drm/drm_atomic.h>
24#include <drm/drm_atomic_helper.h> 24#include <drm/drm_atomic_helper.h>
25#include <drm/drm_fb_helper.h> 25#include <drm/drm_fb_helper.h>
26#include <drm/drm_gem_framebuffer_helper.h>
26 27
27#include "tilcdc_drv.h" 28#include "tilcdc_drv.h"
28#include "tilcdc_regs.h" 29#include "tilcdc_regs.h"
@@ -65,7 +66,7 @@ static struct of_device_id tilcdc_of_match[];
65static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev, 66static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev,
66 struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd) 67 struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd)
67{ 68{
68 return drm_fb_cma_create(dev, file_priv, mode_cmd); 69 return drm_gem_fb_create(dev, file_priv, mode_cmd);
69} 70}
70 71
71static void tilcdc_fb_output_poll_changed(struct drm_device *dev) 72static void tilcdc_fb_output_poll_changed(struct drm_device *dev)
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index 7e5bb7d6f655..7fd26912f2ba 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -163,7 +163,6 @@ MODULE_DEVICE_TABLE(spi, mi0283qt_id);
163static int mi0283qt_probe(struct spi_device *spi) 163static int mi0283qt_probe(struct spi_device *spi)
164{ 164{
165 struct device *dev = &spi->dev; 165 struct device *dev = &spi->dev;
166 struct tinydrm_device *tdev;
167 struct mipi_dbi *mipi; 166 struct mipi_dbi *mipi;
168 struct gpio_desc *dc; 167 struct gpio_desc *dc;
169 u32 rotation = 0; 168 u32 rotation = 0;
@@ -215,20 +214,9 @@ static int mi0283qt_probe(struct spi_device *spi)
215 return ret; 214 return ret;
216 } 215 }
217 216
218 tdev = &mipi->tinydrm;
219
220 ret = devm_tinydrm_register(tdev);
221 if (ret)
222 return ret;
223
224 spi_set_drvdata(spi, mipi); 217 spi_set_drvdata(spi, mipi);
225 218
226 DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n", 219 return devm_tinydrm_register(&mipi->tinydrm);
227 tdev->drm->driver->name, dev_name(dev),
228 spi->max_speed_hz / 1000000,
229 tdev->drm->primary->index);
230
231 return 0;
232} 220}
233 221
234static void mi0283qt_shutdown(struct spi_device *spi) 222static void mi0283qt_shutdown(struct spi_device *spi)
diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index 2caeabcd3458..f0dedc244944 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -842,6 +842,8 @@ int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
842 return -ENOMEM; 842 return -ENOMEM;
843 } 843 }
844 844
845 DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000);
846
845 return 0; 847 return 0;
846} 848}
847EXPORT_SYMBOL(mipi_dbi_spi_init); 849EXPORT_SYMBOL(mipi_dbi_spi_init);
diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c
index 30dc97b3ff21..5fbe14715c83 100644
--- a/drivers/gpu/drm/tinydrm/repaper.c
+++ b/drivers/gpu/drm/tinydrm/repaper.c
@@ -1078,19 +1078,11 @@ static int repaper_probe(struct spi_device *spi)
1078 return ret; 1078 return ret;
1079 1079
1080 drm_mode_config_reset(tdev->drm); 1080 drm_mode_config_reset(tdev->drm);
1081
1082 ret = devm_tinydrm_register(tdev);
1083 if (ret)
1084 return ret;
1085
1086 spi_set_drvdata(spi, tdev); 1081 spi_set_drvdata(spi, tdev);
1087 1082
1088 DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n", 1083 DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000);
1089 tdev->drm->driver->name, dev_name(dev),
1090 spi->max_speed_hz / 1000000,
1091 tdev->drm->primary->index);
1092 1084
1093 return 0; 1085 return devm_tinydrm_register(tdev);
1094} 1086}
1095 1087
1096static void repaper_shutdown(struct spi_device *spi) 1088static void repaper_shutdown(struct spi_device *spi)
diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c
index b439956a07f4..07b4d312784c 100644
--- a/drivers/gpu/drm/tinydrm/st7586.c
+++ b/drivers/gpu/drm/tinydrm/st7586.c
@@ -343,7 +343,6 @@ MODULE_DEVICE_TABLE(spi, st7586_id);
343static int st7586_probe(struct spi_device *spi) 343static int st7586_probe(struct spi_device *spi)
344{ 344{
345 struct device *dev = &spi->dev; 345 struct device *dev = &spi->dev;
346 struct tinydrm_device *tdev;
347 struct mipi_dbi *mipi; 346 struct mipi_dbi *mipi;
348 struct gpio_desc *a0; 347 struct gpio_desc *a0;
349 u32 rotation = 0; 348 u32 rotation = 0;
@@ -388,20 +387,9 @@ static int st7586_probe(struct spi_device *spi)
388 if (ret) 387 if (ret)
389 return ret; 388 return ret;
390 389
391 tdev = &mipi->tinydrm;
392
393 ret = devm_tinydrm_register(tdev);
394 if (ret)
395 return ret;
396
397 spi_set_drvdata(spi, mipi); 390 spi_set_drvdata(spi, mipi);
398 391
399 DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n", 392 return devm_tinydrm_register(&mipi->tinydrm);
400 tdev->drm->driver->name, dev_name(dev),
401 spi->max_speed_hz / 1000000,
402 tdev->drm->primary->index);
403
404 return 0;
405} 393}
406 394
407static void st7586_shutdown(struct spi_device *spi) 395static void st7586_shutdown(struct spi_device *spi)
diff --git a/drivers/gpu/drm/tve200/Kconfig b/drivers/gpu/drm/tve200/Kconfig
new file mode 100644
index 000000000000..c5f03bf4570c
--- /dev/null
+++ b/drivers/gpu/drm/tve200/Kconfig
@@ -0,0 +1,16 @@
1config DRM_TVE200
2 tristate "DRM Support for Faraday TV Encoder TVE200"
3 depends on DRM
4 depends on CMA
5 depends on ARM || COMPILE_TEST
6 depends on OF
7 select DRM_BRIDGE
8 select DRM_PANEL_BRIDGE
9 select DRM_KMS_HELPER
10 select DRM_KMS_CMA_HELPER
11 select DRM_GEM_CMA_HELPER
12 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
13 help
14 Choose this option for DRM support for the Faraday TV Encoder
15 TVE200 Controller.
16 If M is selected the module will be called tve200_drm.
diff --git a/drivers/gpu/drm/tve200/Makefile b/drivers/gpu/drm/tve200/Makefile
new file mode 100644
index 000000000000..6b7a6a1dcbf8
--- /dev/null
+++ b/drivers/gpu/drm/tve200/Makefile
@@ -0,0 +1,4 @@
1tve200_drm-y += tve200_display.o \
2 tve200_drv.o
3
4obj-$(CONFIG_DRM_TVE200) += tve200_drm.o
diff --git a/drivers/gpu/drm/tve200/tve200_display.c b/drivers/gpu/drm/tve200/tve200_display.c
new file mode 100644
index 000000000000..18457de47bbc
--- /dev/null
+++ b/drivers/gpu/drm/tve200/tve200_display.c
@@ -0,0 +1,337 @@
1/*
2 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
3 * Parts of this file were based on sources as follows:
4 *
5 * Copyright (C) 2006-2008 Intel Corporation
6 * Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com>
7 * Copyright (C) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
9 * Copyright (C) 2017 Eric Anholt
10 *
11 * This program is free software and is provided to you under the terms of the
12 * GNU General Public License version 2 as published by the Free Software
13 * Foundation, and any use by you of this program is subject to the terms of
14 * such GNU licence.
15 */
16#include <linux/clk.h>
17#include <linux/version.h>
18#include <linux/dma-buf.h>
19#include <linux/of_graph.h>
20
21#include <drm/drmP.h>
22#include <drm/drm_panel.h>
23#include <drm/drm_gem_cma_helper.h>
24#include <drm/drm_fb_cma_helper.h>
25
26#include "tve200_drm.h"
27
28irqreturn_t tve200_irq(int irq, void *data)
29{
30 struct tve200_drm_dev_private *priv = data;
31 u32 stat;
32 u32 val;
33
34 stat = readl(priv->regs + TVE200_INT_STAT);
35
36 if (!stat)
37 return IRQ_NONE;
38
39 /*
40 * Vblank IRQ
41 *
42 * The hardware is a bit tilted: the line stays high after clearing
43 * the vblank IRQ, firing many more interrupts. We counter this
44 * by toggling the IRQ back and forth from firing at vblank and
45 * firing at start of active image, which works around the problem
46 * since those occur strictly in sequence, and we get two IRQs for each
47 * frame, one at start of Vblank (that we make call into the CRTC) and
48 * another one at the start of the image (that we discard).
49 */
50 if (stat & TVE200_INT_V_STATUS) {
51 val = readl(priv->regs + TVE200_CTRL);
52 /* We have an actual start of vsync */
53 if (!(val & TVE200_VSTSTYPE_BITS)) {
54 drm_crtc_handle_vblank(&priv->pipe.crtc);
55 /* Toggle trigger to start of active image */
56 val |= TVE200_VSTSTYPE_VAI;
57 } else {
58 /* Toggle trigger back to start of vsync */
59 val &= ~TVE200_VSTSTYPE_BITS;
60 }
61 writel(val, priv->regs + TVE200_CTRL);
62 } else
63 dev_err(priv->drm->dev, "stray IRQ %08x\n", stat);
64
65 /* Clear the interrupt once done */
66 writel(stat, priv->regs + TVE200_INT_CLR);
67
68 return IRQ_HANDLED;
69}
70
71static int tve200_display_check(struct drm_simple_display_pipe *pipe,
72 struct drm_plane_state *pstate,
73 struct drm_crtc_state *cstate)
74{
75 const struct drm_display_mode *mode = &cstate->mode;
76 struct drm_framebuffer *old_fb = pipe->plane.state->fb;
77 struct drm_framebuffer *fb = pstate->fb;
78
79 /*
80 * We support these specific resolutions and nothing else.
81 */
82 if (!(mode->hdisplay == 352 && mode->vdisplay == 240) && /* SIF(525) */
83 !(mode->hdisplay == 352 && mode->vdisplay == 288) && /* CIF(625) */
84 !(mode->hdisplay == 640 && mode->vdisplay == 480) && /* VGA */
85 !(mode->hdisplay == 720 && mode->vdisplay == 480) && /* D1 */
86 !(mode->hdisplay == 720 && mode->vdisplay == 576)) { /* D1 */
87 DRM_DEBUG_KMS("unsupported display mode (%u x %u)\n",
88 mode->hdisplay, mode->vdisplay);
89 return -EINVAL;
90 }
91
92 if (fb) {
93 u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0);
94
95 /* FB base address must be dword aligned. */
96 if (offset & 3) {
97 DRM_DEBUG_KMS("FB not 32-bit aligned\n");
98 return -EINVAL;
99 }
100
101 /*
102 * There's no pitch register, the mode's hdisplay
103 * controls this.
104 */
105 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) {
106 DRM_DEBUG_KMS("can't handle pitches\n");
107 return -EINVAL;
108 }
109
110 /*
111 * We can't change the FB format in a flicker-free
112 * manner (and only update it during CRTC enable).
113 */
114 if (old_fb && old_fb->format != fb->format)
115 cstate->mode_changed = true;
116 }
117
118 return 0;
119}
120
121static void tve200_display_enable(struct drm_simple_display_pipe *pipe,
122 struct drm_crtc_state *cstate)
123{
124 struct drm_crtc *crtc = &pipe->crtc;
125 struct drm_plane *plane = &pipe->plane;
126 struct drm_device *drm = crtc->dev;
127 struct tve200_drm_dev_private *priv = drm->dev_private;
128 const struct drm_display_mode *mode = &cstate->mode;
129 struct drm_framebuffer *fb = plane->state->fb;
130 struct drm_connector *connector = priv->connector;
131 u32 format = fb->format->format;
132 u32 ctrl1 = 0;
133
134 clk_prepare_enable(priv->clk);
135
136 /* Function 1 */
137 ctrl1 |= TVE200_CTRL_CSMODE;
138 /* Interlace mode for CCIR656: parameterize? */
139 ctrl1 |= TVE200_CTRL_NONINTERLACE;
140 /* 32 words per burst */
141 ctrl1 |= TVE200_CTRL_BURST_32_WORDS;
142 /* 16 retries */
143 ctrl1 |= TVE200_CTRL_RETRYCNT_16;
144 /* NTSC mode: parametrize? */
145 ctrl1 |= TVE200_CTRL_NTSC;
146
147 /* Vsync IRQ at start of Vsync at first */
148 ctrl1 |= TVE200_VSTSTYPE_VSYNC;
149
150 if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
151 ctrl1 |= TVE200_CTRL_TVCLKP;
152
153 if ((mode->hdisplay == 352 && mode->vdisplay == 240) || /* SIF(525) */
154 (mode->hdisplay == 352 && mode->vdisplay == 288)) { /* CIF(625) */
155 ctrl1 |= TVE200_CTRL_IPRESOL_CIF;
156 dev_info(drm->dev, "CIF mode\n");
157 } else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
158 ctrl1 |= TVE200_CTRL_IPRESOL_VGA;
159 dev_info(drm->dev, "VGA mode\n");
160 } else if ((mode->hdisplay == 720 && mode->vdisplay == 480) ||
161 (mode->hdisplay == 720 && mode->vdisplay == 576)) {
162 ctrl1 |= TVE200_CTRL_IPRESOL_D1;
163 dev_info(drm->dev, "D1 mode\n");
164 }
165
166 if (format & DRM_FORMAT_BIG_ENDIAN) {
167 ctrl1 |= TVE200_CTRL_BBBP;
168 format &= ~DRM_FORMAT_BIG_ENDIAN;
169 }
170
171 switch (format) {
172 case DRM_FORMAT_XRGB8888:
173 ctrl1 |= TVE200_IPDMOD_RGB888;
174 break;
175 case DRM_FORMAT_RGB565:
176 ctrl1 |= TVE200_IPDMOD_RGB565;
177 break;
178 case DRM_FORMAT_XRGB1555:
179 ctrl1 |= TVE200_IPDMOD_RGB555;
180 break;
181 case DRM_FORMAT_XBGR8888:
182 ctrl1 |= TVE200_IPDMOD_RGB888 | TVE200_BGR;
183 break;
184 case DRM_FORMAT_BGR565:
185 ctrl1 |= TVE200_IPDMOD_RGB565 | TVE200_BGR;
186 break;
187 case DRM_FORMAT_XBGR1555:
188 ctrl1 |= TVE200_IPDMOD_RGB555 | TVE200_BGR;
189 break;
190 case DRM_FORMAT_YUYV:
191 ctrl1 |= TVE200_IPDMOD_YUV422;
192 ctrl1 |= TVE200_CTRL_YCBCRODR_CR0Y1CB0Y0;
193 break;
194 case DRM_FORMAT_YVYU:
195 ctrl1 |= TVE200_IPDMOD_YUV422;
196 ctrl1 |= TVE200_CTRL_YCBCRODR_CB0Y1CR0Y0;
197 break;
198 case DRM_FORMAT_UYVY:
199 ctrl1 |= TVE200_IPDMOD_YUV422;
200 ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CR0Y0CB0;
201 break;
202 case DRM_FORMAT_VYUY:
203 ctrl1 |= TVE200_IPDMOD_YUV422;
204 ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CB0Y0CR0;
205 break;
206 case DRM_FORMAT_YUV420:
207 ctrl1 |= TVE200_CTRL_YUV420;
208 ctrl1 |= TVE200_IPDMOD_YUV420;
209 break;
210 default:
211 dev_err(drm->dev, "Unknown FB format 0x%08x\n",
212 fb->format->format);
213 break;
214 }
215
216 ctrl1 |= TVE200_TVEEN;
217
218 /* Turn it on */
219 writel(ctrl1, priv->regs + TVE200_CTRL);
220
221 drm_crtc_vblank_on(crtc);
222}
223
224void tve200_display_disable(struct drm_simple_display_pipe *pipe)
225{
226 struct drm_crtc *crtc = &pipe->crtc;
227 struct drm_device *drm = crtc->dev;
228 struct tve200_drm_dev_private *priv = drm->dev_private;
229
230 drm_crtc_vblank_off(crtc);
231
232 /* Disable and Power Down */
233 writel(0, priv->regs + TVE200_CTRL);
234
235 clk_disable_unprepare(priv->clk);
236}
237
238static void tve200_display_update(struct drm_simple_display_pipe *pipe,
239 struct drm_plane_state *old_pstate)
240{
241 struct drm_crtc *crtc = &pipe->crtc;
242 struct drm_device *drm = crtc->dev;
243 struct tve200_drm_dev_private *priv = drm->dev_private;
244 struct drm_pending_vblank_event *event = crtc->state->event;
245 struct drm_plane *plane = &pipe->plane;
246 struct drm_plane_state *pstate = plane->state;
247 struct drm_framebuffer *fb = pstate->fb;
248
249 if (fb) {
250 /* For RGB, the Y component is used as base address */
251 writel(drm_fb_cma_get_gem_addr(fb, pstate, 0),
252 priv->regs + TVE200_Y_FRAME_BASE_ADDR);
253
254 /* For three plane YUV we need two more addresses */
255 if (fb->format->format == DRM_FORMAT_YUV420) {
256 writel(drm_fb_cma_get_gem_addr(fb, pstate, 1),
257 priv->regs + TVE200_U_FRAME_BASE_ADDR);
258 writel(drm_fb_cma_get_gem_addr(fb, pstate, 2),
259 priv->regs + TVE200_V_FRAME_BASE_ADDR);
260 }
261 }
262
263 if (event) {
264 crtc->state->event = NULL;
265
266 spin_lock_irq(&crtc->dev->event_lock);
267 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
268 drm_crtc_arm_vblank_event(crtc, event);
269 else
270 drm_crtc_send_vblank_event(crtc, event);
271 spin_unlock_irq(&crtc->dev->event_lock);
272 }
273}
274
275int tve200_enable_vblank(struct drm_device *drm, unsigned int crtc)
276{
277 struct tve200_drm_dev_private *priv = drm->dev_private;
278
279 writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN);
280 return 0;
281}
282
283void tve200_disable_vblank(struct drm_device *drm, unsigned int crtc)
284{
285 struct tve200_drm_dev_private *priv = drm->dev_private;
286
287 writel(0, priv->regs + TVE200_INT_EN);
288}
289
290static int tve200_display_prepare_fb(struct drm_simple_display_pipe *pipe,
291 struct drm_plane_state *plane_state)
292{
293 return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
294}
295
296const struct drm_simple_display_pipe_funcs tve200_display_funcs = {
297 .check = tve200_display_check,
298 .enable = tve200_display_enable,
299 .disable = tve200_display_disable,
300 .update = tve200_display_update,
301 .prepare_fb = tve200_display_prepare_fb,
302};
303
304int tve200_display_init(struct drm_device *drm)
305{
306 struct tve200_drm_dev_private *priv = drm->dev_private;
307 int ret;
308 static const u32 formats[] = {
309 DRM_FORMAT_XRGB8888,
310 DRM_FORMAT_XBGR8888,
311 DRM_FORMAT_RGB565,
312 DRM_FORMAT_BGR565,
313 DRM_FORMAT_XRGB1555,
314 DRM_FORMAT_XBGR1555,
315 /*
316 * The controller actually supports any YCbCr ordering,
317 * for packed YCbCr. This just lists the orderings that
318 * DRM supports.
319 */
320 DRM_FORMAT_YUYV,
321 DRM_FORMAT_YVYU,
322 DRM_FORMAT_UYVY,
323 DRM_FORMAT_VYUY,
324 /* This uses three planes */
325 DRM_FORMAT_YUV420,
326 };
327
328 ret = drm_simple_display_pipe_init(drm, &priv->pipe,
329 &tve200_display_funcs,
330 formats, ARRAY_SIZE(formats),
331 NULL,
332 priv->connector);
333 if (ret)
334 return ret;
335
336 return 0;
337}
diff --git a/drivers/gpu/drm/tve200/tve200_drm.h b/drivers/gpu/drm/tve200/tve200_drm.h
new file mode 100644
index 000000000000..628b79324c48
--- /dev/null
+++ b/drivers/gpu/drm/tve200/tve200_drm.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
3 * Parts of this file were based on sources as follows:
4 *
5 * Copyright (C) 2006-2008 Intel Corporation
6 * Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com>
7 * Copyright (C) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
9 * Copyright (C) 2017 Eric Anholt
10 *
11 * This program is free software and is provided to you under the terms of the
12 * GNU General Public License version 2 as published by the Free Software
13 * Foundation, and any use by you of this program is subject to the terms of
14 * such GNU licence.
15 */
16
17#ifndef _TVE200_DRM_H_
18#define _TVE200_DRM_H_
19
20/* Bits 2-31 are valid physical base addresses */
21#define TVE200_Y_FRAME_BASE_ADDR 0x00
22#define TVE200_U_FRAME_BASE_ADDR 0x04
23#define TVE200_V_FRAME_BASE_ADDR 0x08
24
25#define TVE200_INT_EN 0x0C
26#define TVE200_INT_CLR 0x10
27#define TVE200_INT_STAT 0x14
28#define TVE200_INT_BUS_ERR BIT(7)
29#define TVE200_INT_V_STATUS BIT(6) /* vertical blank */
30#define TVE200_INT_V_NEXT_FRAME BIT(5)
31#define TVE200_INT_U_NEXT_FRAME BIT(4)
32#define TVE200_INT_Y_NEXT_FRAME BIT(3)
33#define TVE200_INT_V_FIFO_UNDERRUN BIT(2)
34#define TVE200_INT_U_FIFO_UNDERRUN BIT(1)
35#define TVE200_INT_Y_FIFO_UNDERRUN BIT(0)
36#define TVE200_FIFO_UNDERRUNS (TVE200_INT_V_FIFO_UNDERRUN | \
37 TVE200_INT_U_FIFO_UNDERRUN | \
38 TVE200_INT_Y_FIFO_UNDERRUN)
39
40#define TVE200_CTRL 0x18
41#define TVE200_CTRL_YUV420 BIT(31)
42#define TVE200_CTRL_CSMODE BIT(30)
43#define TVE200_CTRL_NONINTERLACE BIT(28) /* 0 = non-interlace CCIR656 */
44#define TVE200_CTRL_TVCLKP BIT(27) /* Inverted clock phase */
45/* Bits 24..26 define the burst size after arbitration on the bus */
46#define TVE200_CTRL_BURST_4_WORDS (0 << 24)
47#define TVE200_CTRL_BURST_8_WORDS (1 << 24)
48#define TVE200_CTRL_BURST_16_WORDS (2 << 24)
49#define TVE200_CTRL_BURST_32_WORDS (3 << 24)
50#define TVE200_CTRL_BURST_64_WORDS (4 << 24)
51#define TVE200_CTRL_BURST_128_WORDS (5 << 24)
52#define TVE200_CTRL_BURST_256_WORDS (6 << 24)
53#define TVE200_CTRL_BURST_0_WORDS (7 << 24) /* ? */
54/*
55 * Bits 16..23 is the retry count*16 before issueing a new AHB transfer
56 * on the AHB bus.
57 */
58#define TVE200_CTRL_RETRYCNT_MASK GENMASK(23, 16)
59#define TVE200_CTRL_RETRYCNT_16 (1 << 16)
60#define TVE200_CTRL_BBBP BIT(15) /* 0 = little-endian */
61/* Bits 12..14 define the YCbCr ordering */
62#define TVE200_CTRL_YCBCRODR_CB0Y0CR0Y1 (0 << 12)
63#define TVE200_CTRL_YCBCRODR_Y0CB0Y1CR0 (1 << 12)
64#define TVE200_CTRL_YCBCRODR_CR0Y0CB0Y1 (2 << 12)
65#define TVE200_CTRL_YCBCRODR_Y1CB0Y0CR0 (3 << 12)
66#define TVE200_CTRL_YCBCRODR_CR0Y1CB0Y0 (4 << 12)
67#define TVE200_CTRL_YCBCRODR_Y1CR0Y0CB0 (5 << 12)
68#define TVE200_CTRL_YCBCRODR_CB0Y1CR0Y0 (6 << 12)
69#define TVE200_CTRL_YCBCRODR_Y0CR0Y1CB0 (7 << 12)
70/* Bits 10..11 define the input resolution (framebuffer size) */
71#define TVE200_CTRL_IPRESOL_CIF (0 << 10)
72#define TVE200_CTRL_IPRESOL_VGA (1 << 10)
73#define TVE200_CTRL_IPRESOL_D1 (2 << 10)
74#define TVE200_CTRL_NTSC BIT(9) /* 0 = PAL, 1 = NTSC */
75#define TVE200_CTRL_INTERLACE BIT(8) /* 1 = interlace, only for D1 */
76#define TVE200_IPDMOD_RGB555 (0 << 6) /* TVE200_CTRL_YUV420 = 0 */
77#define TVE200_IPDMOD_RGB565 (1 << 6)
78#define TVE200_IPDMOD_RGB888 (2 << 6)
79#define TVE200_IPDMOD_YUV420 (2 << 6) /* TVE200_CTRL_YUV420 = 1 */
80#define TVE200_IPDMOD_YUV422 (3 << 6)
81/* Bits 4 & 5 define when to fire the vblank IRQ */
82#define TVE200_VSTSTYPE_VSYNC (0 << 4) /* start of vsync */
83#define TVE200_VSTSTYPE_VBP (1 << 4) /* start of v back porch */
84#define TVE200_VSTSTYPE_VAI (2 << 4) /* start of v active image */
85#define TVE200_VSTSTYPE_VFP (3 << 4) /* start of v front porch */
86#define TVE200_VSTSTYPE_BITS (BIT(4) | BIT(5))
87#define TVE200_BGR BIT(1) /* 0 = RGB, 1 = BGR */
88#define TVE200_TVEEN BIT(0) /* Enable TVE block */
89
90#define TVE200_CTRL_2 0x1c
91#define TVE200_CTRL_3 0x20
92
93#define TVE200_CTRL_4 0x24
94#define TVE200_CTRL_4_RESET BIT(0) /* triggers reset of TVE200 */
95
96#include <drm/drm_gem.h>
97#include <drm/drm_simple_kms_helper.h>
98
99struct tve200_drm_dev_private {
100 struct drm_device *drm;
101
102 struct drm_connector *connector;
103 struct drm_panel *panel;
104 struct drm_bridge *bridge;
105 struct drm_simple_display_pipe pipe;
106 struct drm_fbdev_cma *fbdev;
107
108 void *regs;
109 struct clk *pclk;
110 struct clk *clk;
111};
112
113#define to_tve200_connector(x) \
114 container_of(x, struct tve200_drm_connector, connector)
115
116int tve200_display_init(struct drm_device *dev);
117int tve200_enable_vblank(struct drm_device *drm, unsigned int crtc);
118void tve200_disable_vblank(struct drm_device *drm, unsigned int crtc);
119irqreturn_t tve200_irq(int irq, void *data);
120int tve200_connector_init(struct drm_device *dev);
121int tve200_encoder_init(struct drm_device *dev);
122int tve200_dumb_create(struct drm_file *file_priv,
123 struct drm_device *dev,
124 struct drm_mode_create_dumb *args);
125
126#endif /* _TVE200_DRM_H_ */
diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c
new file mode 100644
index 000000000000..eae38b669f0a
--- /dev/null
+++ b/drivers/gpu/drm/tve200/tve200_drv.c
@@ -0,0 +1,302 @@
1/*
2 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
3 * Parts of this file were based on sources as follows:
4 *
5 * Copyright (C) 2006-2008 Intel Corporation
6 * Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com>
7 * Copyright (C) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
9 * Copyright (C) 2017 Eric Anholt
10 *
11 * This program is free software and is provided to you under the terms of the
12 * GNU General Public License version 2 as published by the Free Software
13 * Foundation, and any use by you of this program is subject to the terms of
14 * such GNU licence.
15 */
16
17/**
18 * DOC: Faraday TV Encoder TVE200 DRM Driver
19 *
20 * The Faraday TV Encoder TVE200 is also known as the Gemini TV Interface
21 * Controller (TVC) and is found in the Gemini Chipset from Storlink
22 * Semiconductor (later Storm Semiconductor, later Cortina Systems)
23 * but also in the Grain Media GM8180 chipset. On the Gemini the module
24 * is connected to 8 data lines and a single clock line, comprising an
25 * 8-bit BT.656 interface.
26 *
27 * This is a very basic YUV display driver. The datasheet specifies that
28 * it supports the ITU BT.656 standard. It requires a 27 MHz clock which is
29 * the hallmark of any TV encoder supporting both PAL and NTSC.
30 *
31 * This driver exposes a standard KMS interface for this TV encoder.
32 */
33
34#include <linux/clk.h>
35#include <linux/dma-buf.h>
36#include <linux/irq.h>
37#include <linux/io.h>
38#include <linux/module.h>
39#include <linux/platform_device.h>
40#include <linux/shmem_fs.h>
41#include <linux/slab.h>
42#include <linux/version.h>
43
44#include <drm/drmP.h>
45#include <drm/drm_atomic_helper.h>
46#include <drm/drm_crtc_helper.h>
47#include <drm/drm_gem_cma_helper.h>
48#include <drm/drm_fb_cma_helper.h>
49#include <drm/drm_panel.h>
50#include <drm/drm_of.h>
51#include <drm/drm_bridge.h>
52
53#include "tve200_drm.h"
54
55#define DRIVER_DESC "DRM module for Faraday TVE200"
56
57static const struct drm_mode_config_funcs mode_config_funcs = {
58 .fb_create = drm_fb_cma_create,
59 .atomic_check = drm_atomic_helper_check,
60 .atomic_commit = drm_atomic_helper_commit,
61};
62
63static int tve200_modeset_init(struct drm_device *dev)
64{
65 struct drm_mode_config *mode_config;
66 struct tve200_drm_dev_private *priv = dev->dev_private;
67 struct drm_panel *panel;
68 struct drm_bridge *bridge;
69 int ret = 0;
70
71 drm_mode_config_init(dev);
72 mode_config = &dev->mode_config;
73 mode_config->funcs = &mode_config_funcs;
74 mode_config->min_width = 352;
75 mode_config->max_width = 720;
76 mode_config->min_height = 240;
77 mode_config->max_height = 576;
78
79 ret = drm_of_find_panel_or_bridge(dev->dev->of_node,
80 0, 0, &panel, &bridge);
81 if (ret && ret != -ENODEV)
82 return ret;
83 if (panel) {
84 bridge = drm_panel_bridge_add(panel,
85 DRM_MODE_CONNECTOR_Unknown);
86 if (IS_ERR(bridge)) {
87 ret = PTR_ERR(bridge);
88 goto out_bridge;
89 }
90 } else {
91 /*
92 * TODO: when we are using a different bridge than a panel
93 * (such as a dumb VGA connector) we need to devise a different
94 * method to get the connector out of the bridge.
95 */
96 dev_err(dev->dev, "the bridge is not a panel\n");
97 goto out_bridge;
98 }
99
100 ret = tve200_display_init(dev);
101 if (ret) {
102 dev_err(dev->dev, "failed to init display\n");
103 goto out_bridge;
104 }
105
106 ret = drm_simple_display_pipe_attach_bridge(&priv->pipe,
107 bridge);
108 if (ret) {
109 dev_err(dev->dev, "failed to attach bridge\n");
110 goto out_bridge;
111 }
112
113 priv->panel = panel;
114 priv->connector = panel->connector;
115 priv->bridge = bridge;
116
117 dev_info(dev->dev, "attached to panel %s\n",
118 dev_name(panel->dev));
119
120 ret = drm_vblank_init(dev, 1);
121 if (ret) {
122 dev_err(dev->dev, "failed to init vblank\n");
123 goto out_bridge;
124 }
125
126 drm_mode_config_reset(dev);
127
128 /*
129 * Passing in 16 here will make the RGB656 mode the default
130 * Passing in 32 will use XRGB8888 mode
131 */
132 priv->fbdev = drm_fbdev_cma_init(dev, 16,
133 dev->mode_config.num_connector);
134 drm_kms_helper_poll_init(dev);
135
136 goto finish;
137
138out_bridge:
139 if (panel)
140 drm_panel_bridge_remove(bridge);
141 drm_mode_config_cleanup(dev);
142finish:
143 return ret;
144}
145
146DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
147
148static void tve200_lastclose(struct drm_device *dev)
149{
150 struct tve200_drm_dev_private *priv = dev->dev_private;
151
152 drm_fbdev_cma_restore_mode(priv->fbdev);
153}
154
155static struct drm_driver tve200_drm_driver = {
156 .driver_features =
157 DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
158 .lastclose = tve200_lastclose,
159 .ioctls = NULL,
160 .fops = &drm_fops,
161 .name = "tve200",
162 .desc = DRIVER_DESC,
163 .date = "20170703",
164 .major = 1,
165 .minor = 0,
166 .patchlevel = 0,
167 .dumb_create = drm_gem_cma_dumb_create,
168 .gem_free_object_unlocked = drm_gem_cma_free_object,
169 .gem_vm_ops = &drm_gem_cma_vm_ops,
170
171 .enable_vblank = tve200_enable_vblank,
172 .disable_vblank = tve200_disable_vblank,
173
174 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
175 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
176 .gem_prime_import = drm_gem_prime_import,
177 .gem_prime_export = drm_gem_prime_export,
178 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
179 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
180 .gem_prime_vmap = drm_gem_cma_prime_vmap,
181 .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
182 .gem_prime_mmap = drm_gem_cma_prime_mmap,
183};
184
185static int tve200_probe(struct platform_device *pdev)
186{
187 struct device *dev = &pdev->dev;
188 struct tve200_drm_dev_private *priv;
189 struct drm_device *drm;
190 struct resource *res;
191 int irq;
192 int ret;
193
194 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
195 if (!priv)
196 return -ENOMEM;
197
198 drm = drm_dev_alloc(&tve200_drm_driver, dev);
199 if (IS_ERR(drm))
200 return PTR_ERR(drm);
201 platform_set_drvdata(pdev, drm);
202 priv->drm = drm;
203 drm->dev_private = priv;
204
205 /* Clock the silicon so we can access the registers */
206 priv->pclk = devm_clk_get(dev, "PCLK");
207 if (IS_ERR(priv->pclk)) {
208 dev_err(dev, "unable to get PCLK\n");
209 ret = PTR_ERR(priv->pclk);
210 goto dev_unref;
211 }
212 ret = clk_prepare_enable(priv->pclk);
213 if (ret) {
214 dev_err(dev, "failed to enable PCLK\n");
215 goto dev_unref;
216 }
217
218 /* This clock is for the pixels (27MHz) */
219 priv->clk = devm_clk_get(dev, "TVE");
220 if (IS_ERR(priv->clk)) {
221 dev_err(dev, "unable to get TVE clock\n");
222 ret = PTR_ERR(priv->clk);
223 goto clk_disable;
224 }
225
226 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
227 priv->regs = devm_ioremap_resource(dev, res);
228 if (!priv->regs) {
229 dev_err(dev, "%s failed mmio\n", __func__);
230 ret = -EINVAL;
231 goto clk_disable;
232 }
233
234 irq = platform_get_irq(pdev, 0);
235 if (!irq) {
236 ret = -EINVAL;
237 goto clk_disable;
238 }
239
240 /* turn off interrupts before requesting the irq */
241 writel(0, priv->regs + TVE200_INT_EN);
242
243 ret = devm_request_irq(dev, irq, tve200_irq, 0, "tve200", priv);
244 if (ret) {
245 dev_err(dev, "failed to request irq %d\n", ret);
246 goto clk_disable;
247 }
248
249 ret = tve200_modeset_init(drm);
250 if (ret)
251 goto clk_disable;
252
253 ret = drm_dev_register(drm, 0);
254 if (ret < 0)
255 goto clk_disable;
256
257 return 0;
258
259clk_disable:
260 clk_disable_unprepare(priv->pclk);
261dev_unref:
262 drm_dev_unref(drm);
263 return ret;
264}
265
266static int tve200_remove(struct platform_device *pdev)
267{
268 struct drm_device *drm = platform_get_drvdata(pdev);
269 struct tve200_drm_dev_private *priv = drm->dev_private;
270
271 drm_dev_unregister(drm);
272 if (priv->fbdev)
273 drm_fbdev_cma_fini(priv->fbdev);
274 if (priv->panel)
275 drm_panel_bridge_remove(priv->bridge);
276 drm_mode_config_cleanup(drm);
277 clk_disable_unprepare(priv->pclk);
278 drm_dev_unref(drm);
279
280 return 0;
281}
282
283static const struct of_device_id tve200_of_match[] = {
284 {
285 .compatible = "faraday,tve200",
286 },
287 {},
288};
289
290static struct platform_driver tve200_driver = {
291 .driver = {
292 .name = "tve200",
293 .of_match_table = of_match_ptr(tve200_of_match),
294 },
295 .probe = tve200_probe,
296 .remove = tve200_remove,
297};
298module_platform_driver(tve200_driver);
299
300MODULE_DESCRIPTION(DRIVER_DESC);
301MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
302MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index 25bd5d30415d..719a771f3d5c 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -24,5 +24,3 @@ vc4-y := \
24vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o 24vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
25 25
26obj-$(CONFIG_DRM_VC4) += vc4.o 26obj-$(CONFIG_DRM_VC4) += vc4.o
27
28CFLAGS_vc4_trace_points.o := -I$(src)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 937da8dd65b8..fa37a1c07cf6 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -309,16 +309,13 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
309static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev, 309static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
310 struct drm_encoder *encoder) 310 struct drm_encoder *encoder)
311{ 311{
312 struct drm_connector *connector = NULL; 312 struct drm_connector *connector;
313 struct vc4_hdmi_connector *hdmi_connector; 313 struct vc4_hdmi_connector *hdmi_connector;
314 int ret = 0;
315 314
316 hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector), 315 hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
317 GFP_KERNEL); 316 GFP_KERNEL);
318 if (!hdmi_connector) { 317 if (!hdmi_connector)
319 ret = -ENOMEM; 318 return ERR_PTR(-ENOMEM);
320 goto fail;
321 }
322 connector = &hdmi_connector->base; 319 connector = &hdmi_connector->base;
323 320
324 hdmi_connector->encoder = encoder; 321 hdmi_connector->encoder = encoder;
@@ -336,12 +333,6 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
336 drm_mode_connector_attach_encoder(connector, encoder); 333 drm_mode_connector_attach_encoder(connector, encoder);
337 334
338 return connector; 335 return connector;
339
340 fail:
341 if (connector)
342 vc4_hdmi_connector_destroy(connector);
343
344 return ERR_PTR(ret);
345} 336}
346 337
347static void vc4_hdmi_encoder_destroy(struct drm_encoder *encoder) 338static void vc4_hdmi_encoder_destroy(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/vc4/vc4_trace.h b/drivers/gpu/drm/vc4/vc4_trace.h
index ad7b1ea720c2..deafb32923e1 100644
--- a/drivers/gpu/drm/vc4/vc4_trace.h
+++ b/drivers/gpu/drm/vc4/vc4_trace.h
@@ -59,5 +59,5 @@ TRACE_EVENT(vc4_wait_for_seqno_end,
59 59
60/* This part must be outside protection */ 60/* This part must be outside protection */
61#undef TRACE_INCLUDE_PATH 61#undef TRACE_INCLUDE_PATH
62#define TRACE_INCLUDE_PATH . 62#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/vc4
63#include <trace/define_trace.h> 63#include <trace/define_trace.h>
diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
index 45244828fc1f..e8b8266c0cde 100644
--- a/drivers/gpu/drm/zte/zx_drm_drv.c
+++ b/drivers/gpu/drm/zte/zx_drm_drv.c
@@ -22,6 +22,7 @@
22#include <drm/drm_fb_cma_helper.h> 22#include <drm/drm_fb_cma_helper.h>
23#include <drm/drm_fb_helper.h> 23#include <drm/drm_fb_helper.h>
24#include <drm/drm_gem_cma_helper.h> 24#include <drm/drm_gem_cma_helper.h>
25#include <drm/drm_gem_framebuffer_helper.h>
25#include <drm/drm_of.h> 26#include <drm/drm_of.h>
26#include <drm/drmP.h> 27#include <drm/drmP.h>
27 28
@@ -40,7 +41,7 @@ static void zx_drm_fb_output_poll_changed(struct drm_device *drm)
40} 41}
41 42
42static const struct drm_mode_config_funcs zx_drm_mode_config_funcs = { 43static const struct drm_mode_config_funcs zx_drm_mode_config_funcs = {
43 .fb_create = drm_fb_cma_create, 44 .fb_create = drm_gem_fb_create,
44 .output_poll_changed = zx_drm_fb_output_poll_changed, 45 .output_poll_changed = zx_drm_fb_output_poll_changed,
45 .atomic_check = drm_atomic_helper_check, 46 .atomic_check = drm_atomic_helper_check,
46 .atomic_commit = drm_atomic_helper_commit, 47 .atomic_commit = drm_atomic_helper_commit,
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 8a5808eb5628..5834580d75bc 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -144,7 +144,6 @@ struct __drm_planes_state {
144struct __drm_crtcs_state { 144struct __drm_crtcs_state {
145 struct drm_crtc *ptr; 145 struct drm_crtc *ptr;
146 struct drm_crtc_state *state, *old_state, *new_state; 146 struct drm_crtc_state *state, *old_state, *new_state;
147 struct drm_crtc_commit *commit;
148 s32 __user *out_fence_ptr; 147 s32 __user *out_fence_ptr;
149 unsigned last_vblank_count; 148 unsigned last_vblank_count;
150}; 149};
@@ -237,6 +236,18 @@ struct drm_atomic_state {
237 struct drm_modeset_acquire_ctx *acquire_ctx; 236 struct drm_modeset_acquire_ctx *acquire_ctx;
238 237
239 /** 238 /**
239 * @fake_commit:
240 *
241 * Used for signaling unbound planes/connectors.
242 * When a connector or plane is not bound to any CRTC, it's still important
243 * to preserve linearity to prevent the atomic states from being freed to early.
244 *
245 * This commit (if set) is not bound to any crtc, but will be completed when
246 * drm_atomic_helper_commit_hw_done() is called.
247 */
248 struct drm_crtc_commit *fake_commit;
249
250 /**
240 * @commit_work: 251 * @commit_work:
241 * 252 *
242 * Work item which can be used by the driver or helpers to execute the 253 * Work item which can be used by the driver or helpers to execute the
@@ -252,10 +263,14 @@ void __drm_crtc_commit_free(struct kref *kref);
252 * @commit: CRTC commit 263 * @commit: CRTC commit
253 * 264 *
254 * Increases the reference of @commit. 265 * Increases the reference of @commit.
266 *
267 * Returns:
268 * The pointer to @commit, with reference increased.
255 */ 269 */
256static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit) 270static inline struct drm_crtc_commit *drm_crtc_commit_get(struct drm_crtc_commit *commit)
257{ 271{
258 kref_get(&commit->ref); 272 kref_get(&commit->ref);
273 return commit;
259} 274}
260 275
261/** 276/**
@@ -555,31 +570,6 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
555void drm_state_dump(struct drm_device *dev, struct drm_printer *p); 570void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
556 571
557/** 572/**
558 * for_each_connector_in_state - iterate over all connectors in an atomic update
559 * @__state: &struct drm_atomic_state pointer
560 * @connector: &struct drm_connector iteration cursor
561 * @connector_state: &struct drm_connector_state iteration cursor
562 * @__i: int iteration cursor, for macro-internal use
563 *
564 * This iterates over all connectors in an atomic update. Note that before the
565 * software state is committed (by calling drm_atomic_helper_swap_state(), this
566 * points to the new state, while afterwards it points to the old state. Due to
567 * this tricky confusion this macro is deprecated.
568 *
569 * FIXME:
570 *
571 * Replace all usage of this with one of the explicit iterators below and then
572 * remove this macro.
573 */
574#define for_each_connector_in_state(__state, connector, connector_state, __i) \
575 for ((__i) = 0; \
576 (__i) < (__state)->num_connector && \
577 ((connector) = (__state)->connectors[__i].ptr, \
578 (connector_state) = (__state)->connectors[__i].state, 1); \
579 (__i)++) \
580 for_each_if (connector)
581
582/**
583 * for_each_oldnew_connector_in_state - iterate over all connectors in an atomic update 573 * for_each_oldnew_connector_in_state - iterate over all connectors in an atomic update
584 * @__state: &struct drm_atomic_state pointer 574 * @__state: &struct drm_atomic_state pointer
585 * @connector: &struct drm_connector iteration cursor 575 * @connector: &struct drm_connector iteration cursor
@@ -643,31 +633,6 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
643 for_each_if (connector) 633 for_each_if (connector)
644 634
645/** 635/**
646 * for_each_crtc_in_state - iterate over all connectors in an atomic update
647 * @__state: &struct drm_atomic_state pointer
648 * @crtc: &struct drm_crtc iteration cursor
649 * @crtc_state: &struct drm_crtc_state iteration cursor
650 * @__i: int iteration cursor, for macro-internal use
651 *
652 * This iterates over all CRTCs in an atomic update. Note that before the
653 * software state is committed (by calling drm_atomic_helper_swap_state(), this
654 * points to the new state, while afterwards it points to the old state. Due to
655 * this tricky confusion this macro is deprecated.
656 *
657 * FIXME:
658 *
659 * Replace all usage of this with one of the explicit iterators below and then
660 * remove this macro.
661 */
662#define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \
663 for ((__i) = 0; \
664 (__i) < (__state)->dev->mode_config.num_crtc && \
665 ((crtc) = (__state)->crtcs[__i].ptr, \
666 (crtc_state) = (__state)->crtcs[__i].state, 1); \
667 (__i)++) \
668 for_each_if (crtc_state)
669
670/**
671 * for_each_oldnew_crtc_in_state - iterate over all CRTCs in an atomic update 636 * for_each_oldnew_crtc_in_state - iterate over all CRTCs in an atomic update
672 * @__state: &struct drm_atomic_state pointer 637 * @__state: &struct drm_atomic_state pointer
673 * @crtc: &struct drm_crtc iteration cursor 638 * @crtc: &struct drm_crtc iteration cursor
@@ -727,31 +692,6 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
727 for_each_if (crtc) 692 for_each_if (crtc)
728 693
729/** 694/**
730 * for_each_plane_in_state - iterate over all planes in an atomic update
731 * @__state: &struct drm_atomic_state pointer
732 * @plane: &struct drm_plane iteration cursor
733 * @plane_state: &struct drm_plane_state iteration cursor
734 * @__i: int iteration cursor, for macro-internal use
735 *
736 * This iterates over all planes in an atomic update. Note that before the
737 * software state is committed (by calling drm_atomic_helper_swap_state(), this
738 * points to the new state, while afterwards it points to the old state. Due to
739 * this tricky confusion this macro is deprecated.
740 *
741 * FIXME:
742 *
743 * Replace all usage of this with one of the explicit iterators below and then
744 * remove this macro.
745 */
746#define for_each_plane_in_state(__state, plane, plane_state, __i) \
747 for ((__i) = 0; \
748 (__i) < (__state)->dev->mode_config.num_total_plane && \
749 ((plane) = (__state)->planes[__i].ptr, \
750 (plane_state) = (__state)->planes[__i].state, 1); \
751 (__i)++) \
752 for_each_if (plane_state)
753
754/**
755 * for_each_oldnew_plane_in_state - iterate over all planes in an atomic update 695 * for_each_oldnew_plane_in_state - iterate over all planes in an atomic update
756 * @__state: &struct drm_atomic_state pointer 696 * @__state: &struct drm_atomic_state pointer
757 * @plane: &struct drm_plane iteration cursor 697 * @plane: &struct drm_plane iteration cursor
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 6522d4cbc9d9..682d01ba920c 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -245,7 +245,7 @@ struct drm_bridge {
245 void *driver_private; 245 void *driver_private;
246}; 246};
247 247
248int drm_bridge_add(struct drm_bridge *bridge); 248void drm_bridge_add(struct drm_bridge *bridge);
249void drm_bridge_remove(struct drm_bridge *bridge); 249void drm_bridge_remove(struct drm_bridge *bridge);
250struct drm_bridge *of_drm_find_bridge(struct device_node *np); 250struct drm_bridge *of_drm_find_bridge(struct device_node *np);
251int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, 251int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ea8da401c93c..b34904dc8b9b 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -347,6 +347,13 @@ struct drm_connector_state {
347 347
348 struct drm_atomic_state *state; 348 struct drm_atomic_state *state;
349 349
350 /**
351 * @commit: Tracks the pending commit to prevent use-after-free conditions.
352 *
353 * Is only set when @crtc is NULL.
354 */
355 struct drm_crtc_commit *commit;
356
350 struct drm_tv_connector_state tv; 357 struct drm_tv_connector_state tv;
351 358
352 /** 359 /**
@@ -888,8 +895,7 @@ struct drm_connector {
888 * This is protected by @drm_mode_config.connection_mutex. Note that 895 * This is protected by @drm_mode_config.connection_mutex. Note that
889 * nonblocking atomic commits access the current connector state without 896 * nonblocking atomic commits access the current connector state without
890 * taking locks. Either by going through the &struct drm_atomic_state 897 * taking locks. Either by going through the &struct drm_atomic_state
891 * pointers, see for_each_connector_in_state(), 898 * pointers, see for_each_oldnew_connector_in_state(),
892 * for_each_oldnew_connector_in_state(),
893 * for_each_old_connector_in_state() and 899 * for_each_old_connector_in_state() and
894 * for_each_new_connector_in_state(). Or through careful ordering of 900 * for_each_new_connector_in_state(). Or through careful ordering of
895 * atomic commit operations as implemented in the atomic helpers, see 901 * atomic commit operations as implemented in the atomic helpers, see
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 1a642020e306..80c97210eda5 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -253,6 +253,15 @@ struct drm_crtc_state {
253 */ 253 */
254 struct drm_pending_vblank_event *event; 254 struct drm_pending_vblank_event *event;
255 255
256 /**
257 * @commit:
258 *
259 * This tracks how the commit for this update proceeds through the
260 * various phases. This is never cleared, except when we destroy the
261 * state, so that subsequent commits can synchronize with previous ones.
262 */
263 struct drm_crtc_commit *commit;
264
256 struct drm_atomic_state *state; 265 struct drm_atomic_state *state;
257}; 266};
258 267
@@ -797,10 +806,10 @@ struct drm_crtc {
797 * This is protected by @mutex. Note that nonblocking atomic commits 806 * This is protected by @mutex. Note that nonblocking atomic commits
798 * access the current CRTC state without taking locks. Either by going 807 * access the current CRTC state without taking locks. Either by going
799 * through the &struct drm_atomic_state pointers, see 808 * through the &struct drm_atomic_state pointers, see
800 * for_each_crtc_in_state(), for_each_oldnew_crtc_in_state(), 809 * for_each_oldnew_crtc_in_state(), for_each_old_crtc_in_state() and
801 * for_each_old_crtc_in_state() and for_each_new_crtc_in_state(). Or 810 * for_each_new_crtc_in_state(). Or through careful ordering of atomic
802 * through careful ordering of atomic commit operations as implemented 811 * commit operations as implemented in the atomic helpers, see
803 * in the atomic helpers, see &struct drm_crtc_commit. 812 * &struct drm_crtc_commit.
804 */ 813 */
805 struct drm_crtc_state *state; 814 struct drm_crtc_state *state;
806 815
@@ -808,10 +817,16 @@ struct drm_crtc {
808 * @commit_list: 817 * @commit_list:
809 * 818 *
810 * List of &drm_crtc_commit structures tracking pending commits. 819 * List of &drm_crtc_commit structures tracking pending commits.
811 * Protected by @commit_lock. This list doesn't hold its own full 820 * Protected by @commit_lock. This list holds its own full reference,
812 * reference, but burrows it from the ongoing commit. Commit entries 821 * as does the ongoing commit.
813 * must be removed from this list once the commit is fully completed, 822 *
814 * but before it's correspoding &drm_atomic_state gets destroyed. 823 * "Note that the commit for a state change is also tracked in
824 * &drm_crtc_state.commit. For accessing the immediately preceding
825 * commit in an atomic update it is recommended to just use that
826 * pointer in the old CRTC state, since accessing that doesn't need
827 * any locking or list-walking. @commit_list should only be used to
828 * stall for framebuffer cleanup that's signalled through
829 * &drm_crtc_commit.cleanup_done."
815 */ 830 */
816 struct list_head commit_list; 831 struct list_head commit_list;
817 832
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index b17476a6909c..11c39f15f1b3 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -738,6 +738,11 @@
738#define DP_RECEIVER_ALPM_STATUS 0x200b /* eDP 1.4 */ 738#define DP_RECEIVER_ALPM_STATUS 0x200b /* eDP 1.4 */
739# define DP_ALPM_LOCK_TIMEOUT_ERROR (1 << 0) 739# define DP_ALPM_LOCK_TIMEOUT_ERROR (1 << 0)
740 740
741#define DP_LANE0_1_STATUS_ESI 0x200c /* status same as 0x202 */
742#define DP_LANE2_3_STATUS_ESI 0x200d /* status same as 0x203 */
743#define DP_LANE_ALIGN_STATUS_UPDATED_ESI 0x200e /* status same as 0x204 */
744#define DP_SINK_STATUS_ESI 0x200f /* status same as 0x205 */
745
741#define DP_DPRX_FEATURE_ENUMERATION_LIST 0x2210 /* DP 1.3 */ 746#define DP_DPRX_FEATURE_ENUMERATION_LIST 0x2210 /* DP 1.3 */
742# define DP_GTC_CAP (1 << 0) /* DP 1.3 */ 747# define DP_GTC_CAP (1 << 0) /* DP 1.3 */
743# define DP_SST_SPLIT_SDP_CAP (1 << 1) /* DP 1.4 */ 748# define DP_SST_SPLIT_SDP_CAP (1 << 1) /* DP 1.4 */
@@ -871,6 +876,18 @@ void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
871u8 drm_dp_link_rate_to_bw_code(int link_rate); 876u8 drm_dp_link_rate_to_bw_code(int link_rate);
872int drm_dp_bw_code_to_link_rate(u8 link_bw); 877int drm_dp_bw_code_to_link_rate(u8 link_bw);
873 878
879#define DP_SDP_AUDIO_TIMESTAMP 0x01
880#define DP_SDP_AUDIO_STREAM 0x02
881#define DP_SDP_EXTENSION 0x04 /* DP 1.1 */
882#define DP_SDP_AUDIO_COPYMANAGEMENT 0x05 /* DP 1.2 */
883#define DP_SDP_ISRC 0x06 /* DP 1.2 */
884#define DP_SDP_VSC 0x07 /* DP 1.2 */
885#define DP_SDP_CAMERA_GENERIC(i) (0x08 + (i)) /* 0-7, DP 1.3 */
886#define DP_SDP_PPS 0x10 /* DP 1.4 */
887#define DP_SDP_VSC_EXT_VESA 0x20 /* DP 1.4 */
888#define DP_SDP_VSC_EXT_CEA 0x21 /* DP 1.4 */
889/* 0x80+ CEA-861 infoframe types */
890
874struct edp_sdp_header { 891struct edp_sdp_header {
875 u8 HB0; /* Secondary Data Packet ID */ 892 u8 HB0; /* Secondary Data Packet ID */
876 u8 HB1; /* Secondary Data Packet Type */ 893 u8 HB1; /* Secondary Data Packet Type */
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index d55abb75f29a..7f78d26a0766 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -631,5 +631,7 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
631int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state, 631int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
632 struct drm_dp_mst_topology_mgr *mgr, 632 struct drm_dp_mst_topology_mgr *mgr,
633 int slots); 633 int slots);
634int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
635 struct drm_dp_mst_port *port, bool power_up);
634 636
635#endif 637#endif
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 1e1908a6b1d6..6f35909b8add 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -341,6 +341,8 @@ int drm_av_sync_delay(struct drm_connector *connector,
341 341
342#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE 342#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
343struct edid *drm_load_edid_firmware(struct drm_connector *connector); 343struct edid *drm_load_edid_firmware(struct drm_connector *connector);
344int __drm_set_edid_firmware_path(const char *path);
345int __drm_get_edid_firmware_path(char *buf, size_t bufsize);
344#else 346#else
345static inline struct edid * 347static inline struct edid *
346drm_load_edid_firmware(struct drm_connector *connector) 348drm_load_edid_firmware(struct drm_connector *connector)
diff --git a/include/drm/drm_gem_framebuffer_helper.h b/include/drm/drm_gem_framebuffer_helper.h
index db9cfa07235e..5ca7cdc3f527 100644
--- a/include/drm/drm_gem_framebuffer_helper.h
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -2,8 +2,8 @@
2#define __DRM_GEM_FB_HELPER_H__ 2#define __DRM_GEM_FB_HELPER_H__
3 3
4struct drm_device; 4struct drm_device;
5struct drm_file;
6struct drm_fb_helper_surface_size; 5struct drm_fb_helper_surface_size;
6struct drm_file;
7struct drm_framebuffer; 7struct drm_framebuffer;
8struct drm_framebuffer_funcs; 8struct drm_framebuffer_funcs;
9struct drm_gem_object; 9struct drm_gem_object;
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index c55cf3ff6847..16646c44b7df 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -314,7 +314,7 @@ struct drm_crtc_helper_funcs {
314 * implementation in drm_atomic_helper_check(). 314 * implementation in drm_atomic_helper_check().
315 * 315 *
316 * When using drm_atomic_helper_check_planes() this hook is called 316 * When using drm_atomic_helper_check_planes() this hook is called
317 * after the &drm_plane_helper_funcs.atomc_check hook for planes, which 317 * after the &drm_plane_helper_funcs.atomic_check hook for planes, which
318 * allows drivers to assign shared resources requested by planes in this 318 * allows drivers to assign shared resources requested by planes in this
319 * callback here. For more complicated dependencies the driver can call 319 * callback here. For more complicated dependencies the driver can call
320 * the provided check helpers multiple times until the computed state 320 * the provided check helpers multiple times until the computed state
diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h
index 4b27c2bb955c..a685d1bb21f2 100644
--- a/include/drm/drm_modeset_lock.h
+++ b/include/drm/drm_modeset_lock.h
@@ -34,6 +34,7 @@ struct drm_modeset_lock;
34 * @contended: used internally for -EDEADLK handling 34 * @contended: used internally for -EDEADLK handling
35 * @locked: list of held locks 35 * @locked: list of held locks
36 * @trylock_only: trylock mode used in atomic contexts/panic notifiers 36 * @trylock_only: trylock mode used in atomic contexts/panic notifiers
37 * @interruptible: whether interruptible locking should be used.
37 * 38 *
38 * Each thread competing for a set of locks must use one acquire 39 * Each thread competing for a set of locks must use one acquire
39 * ctx. And if any lock fxn returns -EDEADLK, it must backoff and 40 * ctx. And if any lock fxn returns -EDEADLK, it must backoff and
@@ -59,6 +60,9 @@ struct drm_modeset_acquire_ctx {
59 * Trylock mode, use only for panic handlers! 60 * Trylock mode, use only for panic handlers!
60 */ 61 */
61 bool trylock_only; 62 bool trylock_only;
63
64 /* Perform interruptible waits on this context. */
65 bool interruptible;
62}; 66};
63 67
64/** 68/**
@@ -82,12 +86,13 @@ struct drm_modeset_lock {
82 struct list_head head; 86 struct list_head head;
83}; 87};
84 88
89#define DRM_MODESET_ACQUIRE_INTERRUPTIBLE BIT(0)
90
85void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx, 91void drm_modeset_acquire_init(struct drm_modeset_acquire_ctx *ctx,
86 uint32_t flags); 92 uint32_t flags);
87void drm_modeset_acquire_fini(struct drm_modeset_acquire_ctx *ctx); 93void drm_modeset_acquire_fini(struct drm_modeset_acquire_ctx *ctx);
88void drm_modeset_drop_locks(struct drm_modeset_acquire_ctx *ctx); 94void drm_modeset_drop_locks(struct drm_modeset_acquire_ctx *ctx);
89void drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx); 95int drm_modeset_backoff(struct drm_modeset_acquire_ctx *ctx);
90int drm_modeset_backoff_interruptible(struct drm_modeset_acquire_ctx *ctx);
91 96
92void drm_modeset_lock_init(struct drm_modeset_lock *lock); 97void drm_modeset_lock_init(struct drm_modeset_lock *lock);
93 98
@@ -111,8 +116,7 @@ static inline bool drm_modeset_is_locked(struct drm_modeset_lock *lock)
111 116
112int drm_modeset_lock(struct drm_modeset_lock *lock, 117int drm_modeset_lock(struct drm_modeset_lock *lock,
113 struct drm_modeset_acquire_ctx *ctx); 118 struct drm_modeset_acquire_ctx *ctx);
114int drm_modeset_lock_interruptible(struct drm_modeset_lock *lock, 119int __must_check drm_modeset_lock_single_interruptible(struct drm_modeset_lock *lock);
115 struct drm_modeset_acquire_ctx *ctx);
116void drm_modeset_unlock(struct drm_modeset_lock *lock); 120void drm_modeset_unlock(struct drm_modeset_lock *lock);
117 121
118struct drm_device; 122struct drm_device;
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 73f90f9d057f..82a217bd77f0 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -123,6 +123,14 @@ struct drm_plane_state {
123 */ 123 */
124 bool visible; 124 bool visible;
125 125
126 /**
127 * @commit: Tracks the pending commit to prevent use-after-free conditions,
128 * and for async plane updates.
129 *
130 * May be NULL.
131 */
132 struct drm_crtc_commit *commit;
133
126 struct drm_atomic_state *state; 134 struct drm_atomic_state *state;
127}; 135};
128 136
@@ -531,10 +539,10 @@ struct drm_plane {
531 * This is protected by @mutex. Note that nonblocking atomic commits 539 * This is protected by @mutex. Note that nonblocking atomic commits
532 * access the current plane state without taking locks. Either by going 540 * access the current plane state without taking locks. Either by going
533 * through the &struct drm_atomic_state pointers, see 541 * through the &struct drm_atomic_state pointers, see
534 * for_each_plane_in_state(), for_each_oldnew_plane_in_state(), 542 * for_each_oldnew_plane_in_state(), for_each_old_plane_in_state() and
535 * for_each_old_plane_in_state() and for_each_new_plane_in_state(). Or 543 * for_each_new_plane_in_state(). Or through careful ordering of atomic
536 * through careful ordering of atomic commit operations as implemented 544 * commit operations as implemented in the atomic helpers, see
537 * in the atomic helpers, see &struct drm_crtc_commit. 545 * &struct drm_crtc_commit.
538 */ 546 */
539 struct drm_plane_state *state; 547 struct drm_plane_state *state;
540 548
diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h
index 0ad87c434ae6..790ca021203a 100644
--- a/include/linux/sync_file.h
+++ b/include/linux/sync_file.h
@@ -25,8 +25,12 @@
25 * @file: file representing this fence 25 * @file: file representing this fence
26 * @sync_file_list: membership in global file list 26 * @sync_file_list: membership in global file list
27 * @wq: wait queue for fence signaling 27 * @wq: wait queue for fence signaling
28 * @flags: flags for the sync_file
28 * @fence: fence with the fences in the sync_file 29 * @fence: fence with the fences in the sync_file
29 * @cb: fence callback information 30 * @cb: fence callback information
31 *
32 * flags:
33 * POLL_ENABLED: whether userspace is currently poll()'ing or not
30 */ 34 */
31struct sync_file { 35struct sync_file {
32 struct file *file; 36 struct file *file;
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 54fc38c3c3f1..34b6bb34b002 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -749,9 +749,9 @@ struct drm_format_modifier {
749 * If the number formats grew to 128, and formats 98-102 are 749 * If the number formats grew to 128, and formats 98-102 are
750 * supported with the modifier: 750 * supported with the modifier:
751 * 751 *
752 * 0x0000003c00000000 0000000000000000 752 * 0x0000007c00000000 0000000000000000
753 * ^ 753 * ^
754 * |__offset = 64, formats = 0x3c00000000 754 * |__offset = 64, formats = 0x7c00000000
755 * 755 *
756 */ 756 */
757 __u64 formats; 757 __u64 formats;