aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt24
-rw-r--r--Documentation/devicetree/bindings/display/panel/auo,g104sn02.txt12
-rw-r--r--Documentation/devicetree/bindings/display/panel/display-timing.txt5
-rw-r--r--Documentation/devicetree/bindings/display/panel/koe,tx31d200vm0baa.txt25
-rw-r--r--Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt2
-rw-r--r--Documentation/devicetree/bindings/display/panel/raydium,rm68200.txt25
-rw-r--r--Documentation/devicetree/bindings/display/panel/simple-panel.txt4
-rw-r--r--Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt39
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/gpu/drivers.rst21
-rw-r--r--Documentation/gpu/drm-kms.rst3
-rw-r--r--Documentation/gpu/index.rst9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c2
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c151
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.h11
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c38
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c9
-rw-r--r--drivers/gpu/drm/drm_atomic.c42
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c2
-rw-r--r--drivers/gpu/drm/drm_bufs.c16
-rw-r--r--drivers/gpu/drm/drm_edid.c3
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c2
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c5
-rw-r--r--drivers/gpu/drm/drm_modes.c34
-rw-r--r--drivers/gpu/drm/drm_plane.c2
-rw-r--r--drivers/gpu/drm/drm_print.c65
-rw-r--r--drivers/gpu/drm/drm_property.c1
-rw-r--r--drivers/gpu/drm/etnaviv/Kconfig1
-rw-r--r--drivers/gpu/drm/etnaviv/Makefile4
-rw-r--r--drivers/gpu/drm/etnaviv/common.xml.h281
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_buffer.c18
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.c52
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.h8
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_dump.c21
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem.h5
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c68
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c406
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.h54
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_hwdb.c65
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_iommu.c2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c78
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_mmu.c4
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_sched.c170
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_sched.h35
-rw-r--r--drivers/gpu/drm/etnaviv/state.xml.h256
-rw-r--r--drivers/gpu/drm/etnaviv/state_3d.xml.h5
-rw-r--r--drivers/gpu/drm/etnaviv/state_blt.xml.h52
-rw-r--r--drivers/gpu/drm/etnaviv/state_hi.xml.h150
-rw-r--r--drivers/gpu/drm/i915/intel_color.c32
-rw-r--r--drivers/gpu/drm/i915/intel_display.c15
-rw-r--r--drivers/gpu/drm/meson/meson_drv.c37
-rw-r--r--drivers/gpu/drm/meson/meson_dw_hdmi.c22
-rw-r--r--drivers/gpu/drm/meson/meson_vclk.c219
-rw-r--r--drivers/gpu/drm/meson/meson_venc.c347
-rw-r--r--drivers/gpu/drm/meson/meson_venc.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c46
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/panel/Kconfig9
-rw-r--r--drivers/gpu/drm/panel/Makefile1
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9322.c4
-rw-r--r--drivers/gpu/drm/panel/panel-lvds.c2
-rw-r--r--drivers/gpu/drm/panel/panel-orisetech-otm8009a.c21
-rw-r--r--drivers/gpu/drm/panel/panel-raydium-rm68200.c448
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c82
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_dumb.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c6
-rw-r--r--drivers/gpu/drm/qxl/qxl_gem.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_ioctl.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c2
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c33
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c7
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c74
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.c154
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.h18
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c12
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c4
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_lvds.c55
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_rgb.c8
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.c52
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.h1
-rw-r--r--drivers/gpu/drm/sun4i/sun6i_drc.c1
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c25
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h60
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c68
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h1
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c4
-rw-r--r--drivers/gpu/vga/vga_switcheroo.c152
-rw-r--r--drivers/pci/pci-driver.c17
-rw-r--r--drivers/pci/pci.c8
-rw-r--r--drivers/pci/quirks.c39
-rw-r--r--include/drm/bridge/analogix_dp.h2
-rw-r--r--include/drm/drm_color_mgmt.h12
-rw-r--r--include/drm/drm_dp_helper.h1
-rw-r--r--include/drm/drm_mode_object.h24
-rw-r--r--include/drm/drm_print.h119
-rw-r--r--include/drm/drm_property.h2
-rw-r--r--include/linux/pci.h2
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/vga_switcheroo.h6
-rw-r--r--include/sound/hdaudio.h3
-rw-r--r--include/uapi/drm/etnaviv_drm.h6
-rw-r--r--scripts/coccinelle/api/drm-get-put.cocci10
-rw-r--r--sound/pci/hda/hda_intel.c36
-rw-r--r--sound/pci/hda/hda_intel.h3
108 files changed, 3528 insertions, 1097 deletions
diff --git a/Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt b/Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt
index 05176f1ae108..8def11b16a24 100644
--- a/Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt
+++ b/Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt
@@ -1,23 +1,3 @@
1Etnaviv DRM master device
2=========================
3
4The Etnaviv DRM master device is a virtual device needed to list all
5Vivante GPU cores that comprise the GPU subsystem.
6
7Required properties:
8- compatible: Should be one of
9 "fsl,imx-gpu-subsystem"
10 "marvell,dove-gpu-subsystem"
11- cores: Should contain a list of phandles pointing to Vivante GPU devices
12
13example:
14
15gpu-subsystem {
16 compatible = "fsl,imx-gpu-subsystem";
17 cores = <&gpu_2d>, <&gpu_3d>;
18};
19
20
21Vivante GPU core devices 1Vivante GPU core devices
22======================== 2========================
23 3
@@ -32,7 +12,9 @@ Required properties:
32- clocks: should contain one clock for entry in clock-names 12- clocks: should contain one clock for entry in clock-names
33 see Documentation/devicetree/bindings/clock/clock-bindings.txt 13 see Documentation/devicetree/bindings/clock/clock-bindings.txt
34- clock-names: 14- clock-names:
35 - "bus": AXI/register clock 15 - "bus": AXI/master interface clock
16 - "reg": AHB/slave interface clock
17 (only required if GPU can gate slave interface independently)
36 - "core": GPU core clock 18 - "core": GPU core clock
37 - "shader": Shader clock (only required if GPU has feature PIPE_3D) 19 - "shader": Shader clock (only required if GPU has feature PIPE_3D)
38 20
diff --git a/Documentation/devicetree/bindings/display/panel/auo,g104sn02.txt b/Documentation/devicetree/bindings/display/panel/auo,g104sn02.txt
new file mode 100644
index 000000000000..85626edf63e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/auo,g104sn02.txt
@@ -0,0 +1,12 @@
1AU Optronics Corporation 10.4" (800x600) color TFT LCD panel
2
3Required properties:
4- compatible: should be "auo,g104sn02"
5- power-supply: as specified in the base binding
6
7Optional properties:
8- backlight: as specified in the base binding
9- enable-gpios: as specified in the base binding
10
11This binding is compatible with the simple-panel binding, which is specified
12in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/display-timing.txt b/Documentation/devicetree/bindings/display/panel/display-timing.txt
index 58fa3e48481d..78222ced1874 100644
--- a/Documentation/devicetree/bindings/display/panel/display-timing.txt
+++ b/Documentation/devicetree/bindings/display/panel/display-timing.txt
@@ -80,6 +80,11 @@ The parameters are defined as:
80 | | v | | | 80 | | v | | |
81 +----------+-------------------------------------+----------+-------+ 81 +----------+-------------------------------------+----------+-------+
82 82
83Note: In addition to being used as subnode(s) of display-timings, the timing
84 subnode may also be used on its own. This is appropriate if only one mode
85 need be conveyed. In this case, the node should be named 'panel-timing'.
86
87
83Example: 88Example:
84 89
85 display-timings { 90 display-timings {
diff --git a/Documentation/devicetree/bindings/display/panel/koe,tx31d200vm0baa.txt b/Documentation/devicetree/bindings/display/panel/koe,tx31d200vm0baa.txt
new file mode 100644
index 000000000000..6a036ede3e28
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/koe,tx31d200vm0baa.txt
@@ -0,0 +1,25 @@
1Kaohsiung Opto-Electronics. TX31D200VM0BAA 12.3" HSXGA LVDS panel
2
3This binding is compatible with the simple-panel binding, which is specified
4in simple-panel.txt in this directory.
5
6Required properties:
7- compatible: should be "koe,tx31d200vm0baa"
8
9Optional properties:
10- backlight: phandle of the backlight device attached to the panel
11
12Optional nodes:
13- Video port for LVDS panel input.
14
15Example:
16 panel {
17 compatible = "koe,tx31d200vm0baa";
18 backlight = <&backlight_lvds>;
19
20 port {
21 panel_in: endpoint {
22 remote-endpoint = <&lvds0_out>;
23 };
24 };
25 };
diff --git a/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
index 6862028e7b2e..203b03eefb68 100644
--- a/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
+++ b/Documentation/devicetree/bindings/display/panel/orisetech,otm8009a.txt
@@ -9,6 +9,7 @@ Required properties:
9 9
10Optional properties: 10Optional properties:
11 - reset-gpios: a GPIO spec for the reset pin (active low). 11 - reset-gpios: a GPIO spec for the reset pin (active low).
12 - power-supply: phandle of the regulator that provides the supply voltage.
12 13
13Example: 14Example:
14&dsi { 15&dsi {
@@ -17,5 +18,6 @@ Example:
17 compatible = "orisetech,otm8009a"; 18 compatible = "orisetech,otm8009a";
18 reg = <0>; 19 reg = <0>;
19 reset-gpios = <&gpioh 7 GPIO_ACTIVE_LOW>; 20 reset-gpios = <&gpioh 7 GPIO_ACTIVE_LOW>;
21 power-supply = <&v1v8>;
20 }; 22 };
21}; 23};
diff --git a/Documentation/devicetree/bindings/display/panel/raydium,rm68200.txt b/Documentation/devicetree/bindings/display/panel/raydium,rm68200.txt
new file mode 100644
index 000000000000..cbb79ef3bfc9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/raydium,rm68200.txt
@@ -0,0 +1,25 @@
1Raydium Semiconductor Corporation RM68200 5.5" 720p MIPI-DSI TFT LCD panel
2
3The Raydium Semiconductor Corporation RM68200 is a 5.5" 720x1280 TFT LCD
4panel connected using a MIPI-DSI video interface.
5
6Required properties:
7 - compatible: "raydium,rm68200"
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 - power-supply: phandle of the regulator that provides the supply voltage.
13 - backlight: phandle of the backlight device attached to the panel.
14
15Example:
16&dsi {
17 ...
18 panel@0 {
19 compatible = "raydium,rm68200";
20 reg = <0>;
21 reset-gpios = <&gpiof 15 GPIO_ACTIVE_LOW>;
22 power-supply = <&v1v8>;
23 backlight = <&pwm_backlight>;
24 };
25};
diff --git a/Documentation/devicetree/bindings/display/panel/simple-panel.txt b/Documentation/devicetree/bindings/display/panel/simple-panel.txt
index 16d8ff088b7d..45a457ad38f0 100644
--- a/Documentation/devicetree/bindings/display/panel/simple-panel.txt
+++ b/Documentation/devicetree/bindings/display/panel/simple-panel.txt
@@ -1,4 +1,8 @@
1Simple display panel 1Simple display panel
2====================
3
4panel node
5----------
2 6
3Required properties: 7Required properties:
4- power-supply: See panel-common.txt 8- power-supply: See panel-common.txt
diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 8bdef4920edc..3346c1e2a7a0 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -146,13 +146,16 @@ Required properties:
146 * allwinner,sun8i-a83t-tcon-lcd 146 * allwinner,sun8i-a83t-tcon-lcd
147 * allwinner,sun8i-a83t-tcon-tv 147 * allwinner,sun8i-a83t-tcon-tv
148 * allwinner,sun8i-v3s-tcon 148 * allwinner,sun8i-v3s-tcon
149 * allwinner,sun9i-a80-tcon-lcd
150 * allwinner,sun9i-a80-tcon-tv
149 - reg: base address and size of memory-mapped region 151 - reg: base address and size of memory-mapped region
150 - interrupts: interrupt associated to this IP 152 - interrupts: interrupt associated to this IP
151 - clocks: phandles to the clocks feeding the TCON. 153 - clocks: phandles to the clocks feeding the TCON.
152 - 'ahb': the interface clocks 154 - 'ahb': the interface clocks
153 - 'tcon-ch0': The clock driving the TCON channel 0, except for A83T TV TCON 155 - 'tcon-ch0': The clock driving the TCON channel 0, if supported
154 - resets: phandles to the reset controllers driving the encoder 156 - resets: phandles to the reset controllers driving the encoder
155 - "lcd": the reset line for the TCON channel 0 157 - "lcd": the reset line for the TCON
158 - "edp": the reset line for the eDP block (A80 only)
156 159
157 - clock-names: the clock names mentioned above 160 - clock-names: the clock names mentioned above
158 - reset-names: the reset names mentioned above 161 - reset-names: the reset names mentioned above
@@ -171,7 +174,9 @@ Required properties:
171 channel the endpoint is associated to. If that property is not 174 channel the endpoint is associated to. If that property is not
172 present, the endpoint number will be used as the channel number. 175 present, the endpoint number will be used as the channel number.
173 176
174On SoCs other than the A33 and V3s, there is one more clock required: 177For TCONs with channel 0, there is one more clock required:
178 - 'tcon-ch0': The clock driving the TCON channel 0
179For TCONs with channel 1, there is one more clock required:
175 - 'tcon-ch1': The clock driving the TCON channel 1 180 - 'tcon-ch1': The clock driving the TCON channel 1
176 181
177When TCON support LVDS (all TCONs except TV TCON on A83T and those found 182When TCON support LVDS (all TCONs except TV TCON on A83T and those found
@@ -186,7 +191,7 @@ DRC
186--- 191---
187 192
188The DRC (Dynamic Range Controller), found in the latest Allwinner SoCs 193The DRC (Dynamic Range Controller), found in the latest Allwinner SoCs
189(A31, A23, A33), allows to dynamically adjust pixel 194(A31, A23, A33, A80), allows to dynamically adjust pixel
190brightness/contrast based on histogram measurements for LCD content 195brightness/contrast based on histogram measurements for LCD content
191adaptive backlight control. 196adaptive backlight control.
192 197
@@ -196,6 +201,7 @@ Required properties:
196 * allwinner,sun6i-a31-drc 201 * allwinner,sun6i-a31-drc
197 * allwinner,sun6i-a31s-drc 202 * allwinner,sun6i-a31s-drc
198 * allwinner,sun8i-a33-drc 203 * allwinner,sun8i-a33-drc
204 * allwinner,sun9i-a80-drc
199 - reg: base address and size of the memory-mapped region. 205 - reg: base address and size of the memory-mapped region.
200 - interrupts: interrupt associated to this IP 206 - interrupts: interrupt associated to this IP
201 - clocks: phandles to the clocks feeding the DRC 207 - clocks: phandles to the clocks feeding the DRC
@@ -222,6 +228,7 @@ Required properties:
222 * allwinner,sun6i-a31-display-backend 228 * allwinner,sun6i-a31-display-backend
223 * allwinner,sun7i-a20-display-backend 229 * allwinner,sun7i-a20-display-backend
224 * allwinner,sun8i-a33-display-backend 230 * allwinner,sun8i-a33-display-backend
231 * allwinner,sun9i-a80-display-backend
225 - reg: base address and size of the memory-mapped region. 232 - reg: base address and size of the memory-mapped region.
226 - interrupts: interrupt associated to this IP 233 - interrupts: interrupt associated to this IP
227 - clocks: phandles to the clocks feeding the frontend and backend 234 - clocks: phandles to the clocks feeding the frontend and backend
@@ -243,6 +250,28 @@ On the A33, some additional properties are required:
243 - resets and reset-names need to have a phandle to the SAT bus 250 - resets and reset-names need to have a phandle to the SAT bus
244 resets, whose name will be "sat" 251 resets, whose name will be "sat"
245 252
253DEU
254---
255
256The DEU (Detail Enhancement Unit), found in the Allwinner A80 SoC,
257can sharpen the display content in both luma and chroma channels.
258
259Required properties:
260 - compatible: value must be one of:
261 * allwinner,sun9i-a80-deu
262 - reg: base address and size of the memory-mapped region.
263 - interrupts: interrupt associated to this IP
264 - clocks: phandles to the clocks feeding the DEU
265 * ahb: the DEU interface clock
266 * mod: the DEU module clock
267 * ram: the DEU DRAM clock
268 - clock-names: the clock names mentioned above
269 - resets: phandles to the reset line driving the DEU
270
271- ports: A ports node with endpoint definitions as defined in
272 Documentation/devicetree/bindings/media/video-interfaces.txt. The
273 first port should be the input endpoints, the second one the outputs
274
246Display Engine Frontend 275Display Engine Frontend
247----------------------- 276-----------------------
248 277
@@ -256,6 +285,7 @@ Required properties:
256 * allwinner,sun6i-a31-display-frontend 285 * allwinner,sun6i-a31-display-frontend
257 * allwinner,sun7i-a20-display-frontend 286 * allwinner,sun7i-a20-display-frontend
258 * allwinner,sun8i-a33-display-frontend 287 * allwinner,sun8i-a33-display-frontend
288 * allwinner,sun9i-a80-display-frontend
259 - reg: base address and size of the memory-mapped region. 289 - reg: base address and size of the memory-mapped region.
260 - interrupts: interrupt associated to this IP 290 - interrupts: interrupt associated to this IP
261 - clocks: phandles to the clocks feeding the frontend and backend 291 - clocks: phandles to the clocks feeding the frontend and backend
@@ -312,6 +342,7 @@ Required properties:
312 * allwinner,sun8i-a83t-display-engine 342 * allwinner,sun8i-a83t-display-engine
313 * allwinner,sun8i-h3-display-engine 343 * allwinner,sun8i-h3-display-engine
314 * allwinner,sun8i-v3s-display-engine 344 * allwinner,sun8i-v3s-display-engine
345 * allwinner,sun9i-a80-display-engine
315 346
316 - allwinner,pipelines: list of phandle to the display engine 347 - allwinner,pipelines: list of phandle to the display engine
317 frontends (DE 1.0) or mixers (DE 2.0) available. 348 frontends (DE 1.0) or mixers (DE 2.0) available.
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index ae850d6c0ad3..12e8b3e576b0 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -104,6 +104,7 @@ eeti eGalax_eMPIA Technology Inc
104elan Elan Microelectronic Corp. 104elan Elan Microelectronic Corp.
105embest Shenzhen Embest Technology Co., Ltd. 105embest Shenzhen Embest Technology Co., Ltd.
106emmicro EM Microelectronic 106emmicro EM Microelectronic
107emtrion emtrion GmbH
107energymicro Silicon Laboratories (formerly Energy Micro AS) 108energymicro Silicon Laboratories (formerly Energy Micro AS)
108engicam Engicam S.r.l. 109engicam Engicam S.r.l.
109epcos EPCOS AG 110epcos EPCOS AG
diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst
new file mode 100644
index 000000000000..e8c84419a2a1
--- /dev/null
+++ b/Documentation/gpu/drivers.rst
@@ -0,0 +1,21 @@
1========================
2GPU Driver Documentation
3========================
4
5.. toctree::
6
7 i915
8 meson
9 pl111
10 tegra
11 tinydrm
12 tve200
13 vc4
14 bridge/dw-hdmi
15
16.. only:: subproject and html
17
18 Indices
19 =======
20
21 * :ref:`genindex`
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 56a3780e39b8..1dffd1ac4cd4 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -286,6 +286,9 @@ Atomic Mode Setting Function Reference
286.. kernel-doc:: drivers/gpu/drm/drm_atomic.c 286.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
287 :export: 287 :export:
288 288
289.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
290 :internal:
291
289CRTC Abstraction 292CRTC Abstraction
290================ 293================
291 294
diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst
index c36586dad29d..00288f34c5a6 100644
--- a/Documentation/gpu/index.rst
+++ b/Documentation/gpu/index.rst
@@ -10,16 +10,9 @@ Linux GPU Driver Developer's Guide
10 drm-kms 10 drm-kms
11 drm-kms-helpers 11 drm-kms-helpers
12 drm-uapi 12 drm-uapi
13 i915 13 drivers
14 meson
15 pl111
16 tegra
17 tinydrm
18 tve200
19 vc4
20 vga-switcheroo 14 vga-switcheroo
21 vgaarbiter 15 vgaarbiter
22 bridge/dw-hdmi
23 todo 16 todo
24 17
25.. only:: subproject and html 18.. only:: subproject and html
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index e6709362994a..2337d4bfd85c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -738,7 +738,6 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
738 738
739 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 739 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
740 drm_kms_helper_poll_disable(drm_dev); 740 drm_kms_helper_poll_disable(drm_dev);
741 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
742 741
743 ret = amdgpu_device_suspend(drm_dev, false, false); 742 ret = amdgpu_device_suspend(drm_dev, false, false);
744 pci_save_state(pdev); 743 pci_save_state(pdev);
@@ -775,7 +774,6 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
775 774
776 ret = amdgpu_device_resume(drm_dev, false, false); 775 ret = amdgpu_device_resume(drm_dev, false, false);
777 drm_kms_helper_poll_enable(drm_dev); 776 drm_kms_helper_poll_enable(drm_dev);
778 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
779 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; 777 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
780 return 0; 778 return 0;
781} 779}
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index a693ab3078f0..5c52307146c7 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -15,6 +15,7 @@
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/iopoll.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
19#include <linux/of.h> 20#include <linux/of.h>
20#include <linux/of_gpio.h> 21#include <linux/of_gpio.h>
@@ -35,6 +36,8 @@
35 36
36#define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) 37#define to_dp(nm) container_of(nm, struct analogix_dp_device, nm)
37 38
39static const bool verify_fast_training;
40
38struct bridge_init { 41struct bridge_init {
39 struct i2c_client *client; 42 struct i2c_client *client;
40 struct device_node *node; 43 struct device_node *node;
@@ -98,18 +101,18 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
98 return 0; 101 return 0;
99} 102}
100 103
101int analogix_dp_psr_supported(struct analogix_dp_device *dp) 104int analogix_dp_psr_enabled(struct analogix_dp_device *dp)
102{ 105{
103 106
104 return dp->psr_support; 107 return dp->psr_enable;
105} 108}
106EXPORT_SYMBOL_GPL(analogix_dp_psr_supported); 109EXPORT_SYMBOL_GPL(analogix_dp_psr_enabled);
107 110
108int analogix_dp_enable_psr(struct analogix_dp_device *dp) 111int analogix_dp_enable_psr(struct analogix_dp_device *dp)
109{ 112{
110 struct edp_vsc_psr psr_vsc; 113 struct edp_vsc_psr psr_vsc;
111 114
112 if (!dp->psr_support) 115 if (!dp->psr_enable)
113 return 0; 116 return 0;
114 117
115 /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ 118 /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
@@ -122,8 +125,7 @@ int analogix_dp_enable_psr(struct analogix_dp_device *dp)
122 psr_vsc.DB0 = 0; 125 psr_vsc.DB0 = 0;
123 psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; 126 psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
124 127
125 analogix_dp_send_psr_spd(dp, &psr_vsc); 128 return analogix_dp_send_psr_spd(dp, &psr_vsc, true);
126 return 0;
127} 129}
128EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); 130EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
129 131
@@ -132,7 +134,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
132 struct edp_vsc_psr psr_vsc; 134 struct edp_vsc_psr psr_vsc;
133 int ret; 135 int ret;
134 136
135 if (!dp->psr_support) 137 if (!dp->psr_enable)
136 return 0; 138 return 0;
137 139
138 /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ 140 /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
@@ -149,8 +151,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
149 if (ret != 1) 151 if (ret != 1)
150 dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret); 152 dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
151 153
152 analogix_dp_send_psr_spd(dp, &psr_vsc); 154 return analogix_dp_send_psr_spd(dp, &psr_vsc, false);
153 return 0;
154} 155}
155EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); 156EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
156 157
@@ -530,7 +531,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
530{ 531{
531 int lane, lane_count, retval; 532 int lane, lane_count, retval;
532 u32 reg; 533 u32 reg;
533 u8 link_align, link_status[2], adjust_request[2]; 534 u8 link_align, link_status[2], adjust_request[2], spread;
534 535
535 usleep_range(400, 401); 536 usleep_range(400, 401);
536 537
@@ -573,6 +574,20 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
573 dev_dbg(dp->dev, "final lane count = %.2x\n", 574 dev_dbg(dp->dev, "final lane count = %.2x\n",
574 dp->link_train.lane_count); 575 dp->link_train.lane_count);
575 576
577 retval = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD,
578 &spread);
579 if (retval != 1) {
580 dev_err(dp->dev, "failed to read downspread %d\n",
581 retval);
582 dp->fast_train_support = false;
583 } else {
584 dp->fast_train_support =
585 (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
586 true : false;
587 }
588 dev_dbg(dp->dev, "fast link training %s\n",
589 dp->fast_train_support ? "supported" : "unsupported");
590
576 /* set enhanced mode if available */ 591 /* set enhanced mode if available */
577 analogix_dp_set_enhanced_mode(dp); 592 analogix_dp_set_enhanced_mode(dp);
578 dp->link_train.lt_state = FINISHED; 593 dp->link_train.lt_state = FINISHED;
@@ -629,10 +644,12 @@ static void analogix_dp_get_max_rx_lane_count(struct analogix_dp_device *dp,
629 *lane_count = DPCD_MAX_LANE_COUNT(data); 644 *lane_count = DPCD_MAX_LANE_COUNT(data);
630} 645}
631 646
632static void analogix_dp_init_training(struct analogix_dp_device *dp, 647static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
633 enum link_lane_count_type max_lane, 648 u32 max_lanes, u32 max_rate)
634 int max_rate)
635{ 649{
650 int retval = 0;
651 bool training_finished = false;
652
636 /* 653 /*
637 * MACRO_RST must be applied after the PLL_LOCK to avoid 654 * MACRO_RST must be applied after the PLL_LOCK to avoid
638 * the DP inter pair skew issue for at least 10 us 655 * the DP inter pair skew issue for at least 10 us
@@ -658,18 +675,13 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
658 } 675 }
659 676
660 /* Setup TX lane count & rate */ 677 /* Setup TX lane count & rate */
661 if (dp->link_train.lane_count > max_lane) 678 if (dp->link_train.lane_count > max_lanes)
662 dp->link_train.lane_count = max_lane; 679 dp->link_train.lane_count = max_lanes;
663 if (dp->link_train.link_rate > max_rate) 680 if (dp->link_train.link_rate > max_rate)
664 dp->link_train.link_rate = max_rate; 681 dp->link_train.link_rate = max_rate;
665 682
666 /* All DP analog module power up */ 683 /* All DP analog module power up */
667 analogix_dp_set_analog_power_down(dp, POWER_ALL, 0); 684 analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
668}
669
670static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
671{
672 int retval = 0, training_finished = 0;
673 685
674 dp->link_train.lt_state = START; 686 dp->link_train.lt_state = START;
675 687
@@ -704,22 +716,88 @@ static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
704 return retval; 716 return retval;
705} 717}
706 718
707static int analogix_dp_set_link_train(struct analogix_dp_device *dp, 719static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
708 u32 count, u32 bwtype)
709{ 720{
710 int i; 721 int i, ret;
711 int retval; 722 u8 link_align, link_status[2];
723 enum pll_status status;
712 724
713 for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) { 725 analogix_dp_reset_macro(dp);
714 analogix_dp_init_training(dp, count, bwtype); 726
715 retval = analogix_dp_sw_link_training(dp); 727 analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
716 if (retval == 0) 728 analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
717 break;
718 729
719 usleep_range(100, 110); 730 for (i = 0; i < dp->link_train.lane_count; i++) {
731 analogix_dp_set_lane_link_training(dp,
732 dp->link_train.training_lane[i], i);
720 } 733 }
721 734
722 return retval; 735 ret = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status,
736 status != PLL_UNLOCKED, 120,
737 120 * DP_TIMEOUT_LOOP_COUNT);
738 if (ret) {
739 DRM_DEV_ERROR(dp->dev, "Wait for pll lock failed %d\n", ret);
740 return ret;
741 }
742
743 /* source Set training pattern 1 */
744 analogix_dp_set_training_pattern(dp, TRAINING_PTN1);
745 /* From DP spec, pattern must be on-screen for a minimum 500us */
746 usleep_range(500, 600);
747
748 analogix_dp_set_training_pattern(dp, TRAINING_PTN2);
749 /* From DP spec, pattern must be on-screen for a minimum 500us */
750 usleep_range(500, 600);
751
752 /* TODO: enhanced_mode?*/
753 analogix_dp_set_training_pattern(dp, DP_NONE);
754
755 /*
756 * Useful for debugging issues with fast link training, disable for more
757 * speed
758 */
759 if (verify_fast_training) {
760 ret = drm_dp_dpcd_readb(&dp->aux, DP_LANE_ALIGN_STATUS_UPDATED,
761 &link_align);
762 if (ret < 0) {
763 DRM_DEV_ERROR(dp->dev, "Read align status failed %d\n",
764 ret);
765 return ret;
766 }
767
768 ret = drm_dp_dpcd_read(&dp->aux, DP_LANE0_1_STATUS, link_status,
769 2);
770 if (ret < 0) {
771 DRM_DEV_ERROR(dp->dev, "Read link status failed %d\n",
772 ret);
773 return ret;
774 }
775
776 if (analogix_dp_clock_recovery_ok(link_status,
777 dp->link_train.lane_count)) {
778 DRM_DEV_ERROR(dp->dev, "Clock recovery failed\n");
779 analogix_dp_reduce_link_rate(dp);
780 return -EIO;
781 }
782
783 if (analogix_dp_channel_eq_ok(link_status, link_align,
784 dp->link_train.lane_count)) {
785 DRM_DEV_ERROR(dp->dev, "Channel EQ failed\n");
786 analogix_dp_reduce_link_rate(dp);
787 return -EIO;
788 }
789 }
790
791 return 0;
792}
793
794static int analogix_dp_train_link(struct analogix_dp_device *dp)
795{
796 if (dp->fast_train_support)
797 return analogix_dp_fast_link_train(dp);
798
799 return analogix_dp_full_link_train(dp, dp->video_info.max_lane_count,
800 dp->video_info.max_link_rate);
723} 801}
724 802
725static int analogix_dp_config_video(struct analogix_dp_device *dp) 803static int analogix_dp_config_video(struct analogix_dp_device *dp)
@@ -848,10 +926,10 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
848 DRM_ERROR("failed to disable the panel\n"); 926 DRM_ERROR("failed to disable the panel\n");
849 } 927 }
850 928
851 ret = analogix_dp_set_link_train(dp, dp->video_info.max_lane_count, 929 ret = readx_poll_timeout(analogix_dp_train_link, dp, ret, !ret, 100,
852 dp->video_info.max_link_rate); 930 DP_TIMEOUT_TRAINING_US * 5);
853 if (ret) { 931 if (ret) {
854 dev_err(dp->dev, "unable to do link train\n"); 932 dev_err(dp->dev, "unable to do link train, ret=%d\n", ret);
855 return; 933 return;
856 } 934 }
857 935
@@ -873,8 +951,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
873 /* Enable video */ 951 /* Enable video */
874 analogix_dp_start_video(dp); 952 analogix_dp_start_video(dp);
875 953
876 dp->psr_support = analogix_dp_detect_sink_psr(dp); 954 dp->psr_enable = analogix_dp_detect_sink_psr(dp);
877 if (dp->psr_support) 955 if (dp->psr_enable)
878 analogix_dp_enable_sink_psr(dp); 956 analogix_dp_enable_sink_psr(dp);
879} 957}
880 958
@@ -1119,6 +1197,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
1119 if (ret) 1197 if (ret)
1120 DRM_ERROR("failed to setup the panel ret = %d\n", ret); 1198 DRM_ERROR("failed to setup the panel ret = %d\n", ret);
1121 1199
1200 dp->psr_enable = false;
1122 dp->dpms_mode = DRM_MODE_DPMS_OFF; 1201 dp->dpms_mode = DRM_MODE_DPMS_OFF;
1123} 1202}
1124 1203
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 5c6a28806129..6a96ef7e6934 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -20,6 +20,10 @@
20#define MAX_CR_LOOP 5 20#define MAX_CR_LOOP 5
21#define MAX_EQ_LOOP 5 21#define MAX_EQ_LOOP 5
22 22
23/* Training takes 22ms if AUX channel comm fails. Use this as retry interval */
24#define DP_TIMEOUT_TRAINING_US 22000
25#define DP_TIMEOUT_PSR_LOOP_MS 300
26
23/* DP_MAX_LANE_COUNT */ 27/* DP_MAX_LANE_COUNT */
24#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) 28#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
25#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) 29#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
@@ -168,7 +172,8 @@ struct analogix_dp_device {
168 int dpms_mode; 172 int dpms_mode;
169 int hpd_gpio; 173 int hpd_gpio;
170 bool force_hpd; 174 bool force_hpd;
171 bool psr_support; 175 bool psr_enable;
176 bool fast_train_support;
172 177
173 struct mutex panel_lock; 178 struct mutex panel_lock;
174 bool panel_is_modeset; 179 bool panel_is_modeset;
@@ -247,8 +252,8 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
247void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); 252void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
248void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); 253void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
249void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); 254void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
250void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, 255int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
251 struct edp_vsc_psr *vsc); 256 struct edp_vsc_psr *vsc, bool blocking);
252ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, 257ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
253 struct drm_dp_aux_msg *msg); 258 struct drm_dp_aux_msg *msg);
254 259
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 303083ad28e3..9df2f3ef000c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -10,10 +10,11 @@
10 * option) any later version. 10 * option) any later version.
11 */ 11 */
12 12
13#include <linux/device.h>
14#include <linux/io.h>
15#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/device.h>
16#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/io.h>
17#include <linux/iopoll.h>
17 18
18#include <drm/bridge/analogix_dp.h> 19#include <drm/bridge/analogix_dp.h>
19 20
@@ -992,10 +993,25 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)
992 writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON); 993 writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
993} 994}
994 995
995void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, 996static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
996 struct edp_vsc_psr *vsc) 997{
998 ssize_t val;
999 u8 status;
1000
1001 val = drm_dp_dpcd_readb(&dp->aux, DP_PSR_STATUS, &status);
1002 if (val < 0) {
1003 dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
1004 return val;
1005 }
1006 return status;
1007}
1008
1009int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
1010 struct edp_vsc_psr *vsc, bool blocking)
997{ 1011{
998 unsigned int val; 1012 unsigned int val;
1013 int ret;
1014 ssize_t psr_status;
999 1015
1000 /* don't send info frame */ 1016 /* don't send info frame */
1001 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 1017 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
@@ -1036,6 +1052,20 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
1036 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 1052 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1037 val |= IF_EN; 1053 val |= IF_EN;
1038 writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 1054 writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1055
1056 if (!blocking)
1057 return 0;
1058
1059 ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
1060 psr_status >= 0 &&
1061 ((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
1062 (!vsc->DB1 && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
1063 DP_TIMEOUT_PSR_LOOP_MS * 1000);
1064 if (ret) {
1065 dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
1066 return ret;
1067 }
1068 return 0;
1039} 1069}
1040 1070
1041ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, 1071ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 53ebbe2904b6..ec8d0006ef7c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -147,7 +147,6 @@ struct dw_hdmi {
147 int vic; 147 int vic;
148 148
149 u8 edid[HDMI_EDID_LEN]; 149 u8 edid[HDMI_EDID_LEN];
150 bool cable_plugin;
151 150
152 struct { 151 struct {
153 const struct dw_hdmi_phy_ops *ops; 152 const struct dw_hdmi_phy_ops *ops;
@@ -1679,12 +1678,6 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
1679 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); 1678 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
1680} 1679}
1681 1680
1682static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi)
1683{
1684 hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
1685 hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
1686}
1687
1688static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) 1681static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
1689{ 1682{
1690 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, 1683 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
@@ -1774,8 +1767,6 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
1774 hdmi_tx_hdcp_config(hdmi); 1767 hdmi_tx_hdcp_config(hdmi);
1775 1768
1776 dw_hdmi_clear_overflow(hdmi); 1769 dw_hdmi_clear_overflow(hdmi);
1777 if (hdmi->cable_plugin && hdmi->sink_is_hdmi)
1778 hdmi_enable_overflow_interrupts(hdmi);
1779 1770
1780 return 0; 1771 return 0;
1781} 1772}
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 34b7d420e555..7d25c42f22db 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -391,8 +391,7 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
391 if (blob) { 391 if (blob) {
392 if (blob->length != sizeof(struct drm_mode_modeinfo) || 392 if (blob->length != sizeof(struct drm_mode_modeinfo) ||
393 drm_mode_convert_umode(state->crtc->dev, &state->mode, 393 drm_mode_convert_umode(state->crtc->dev, &state->mode,
394 (const struct drm_mode_modeinfo *) 394 blob->data))
395 blob->data))
396 return -EINVAL; 395 return -EINVAL;
397 396
398 state->mode_blob = drm_property_blob_get(blob); 397 state->mode_blob = drm_property_blob_get(blob);
@@ -409,11 +408,36 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
409} 408}
410EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); 409EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
411 410
411/**
412 * drm_atomic_replace_property_blob_from_id - lookup the new blob and replace the old one with it
413 * @dev: DRM device
414 * @blob: a pointer to the member blob to be replaced
415 * @blob_id: ID of the new blob
416 * @expected_size: total expected size of the blob data (in bytes)
417 * @expected_elem_size: expected element size of the blob data (in bytes)
418 * @replaced: did the blob get replaced?
419 *
420 * Replace @blob with another blob with the ID @blob_id. If @blob_id is zero
421 * @blob becomes NULL.
422 *
423 * If @expected_size is positive the new blob length is expected to be equal
424 * to @expected_size bytes. If @expected_elem_size is positive the new blob
425 * length is expected to be a multiple of @expected_elem_size bytes. Otherwise
426 * an error is returned.
427 *
428 * @replaced will indicate to the caller whether the blob was replaced or not.
429 * If the old and new blobs were in fact the same blob @replaced will be false
430 * otherwise it will be true.
431 *
432 * RETURNS:
433 * Zero on success, error code on failure.
434 */
412static int 435static int
413drm_atomic_replace_property_blob_from_id(struct drm_device *dev, 436drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
414 struct drm_property_blob **blob, 437 struct drm_property_blob **blob,
415 uint64_t blob_id, 438 uint64_t blob_id,
416 ssize_t expected_size, 439 ssize_t expected_size,
440 ssize_t expected_elem_size,
417 bool *replaced) 441 bool *replaced)
418{ 442{
419 struct drm_property_blob *new_blob = NULL; 443 struct drm_property_blob *new_blob = NULL;
@@ -423,7 +447,13 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
423 if (new_blob == NULL) 447 if (new_blob == NULL)
424 return -EINVAL; 448 return -EINVAL;
425 449
426 if (expected_size > 0 && expected_size != new_blob->length) { 450 if (expected_size > 0 &&
451 new_blob->length != expected_size) {
452 drm_property_blob_put(new_blob);
453 return -EINVAL;
454 }
455 if (expected_elem_size > 0 &&
456 new_blob->length % expected_elem_size != 0) {
427 drm_property_blob_put(new_blob); 457 drm_property_blob_put(new_blob);
428 return -EINVAL; 458 return -EINVAL;
429 } 459 }
@@ -471,7 +501,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
471 ret = drm_atomic_replace_property_blob_from_id(dev, 501 ret = drm_atomic_replace_property_blob_from_id(dev,
472 &state->degamma_lut, 502 &state->degamma_lut,
473 val, 503 val,
474 -1, 504 -1, sizeof(struct drm_color_lut),
475 &replaced); 505 &replaced);
476 state->color_mgmt_changed |= replaced; 506 state->color_mgmt_changed |= replaced;
477 return ret; 507 return ret;
@@ -479,7 +509,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
479 ret = drm_atomic_replace_property_blob_from_id(dev, 509 ret = drm_atomic_replace_property_blob_from_id(dev,
480 &state->ctm, 510 &state->ctm,
481 val, 511 val,
482 sizeof(struct drm_color_ctm), 512 sizeof(struct drm_color_ctm), -1,
483 &replaced); 513 &replaced);
484 state->color_mgmt_changed |= replaced; 514 state->color_mgmt_changed |= replaced;
485 return ret; 515 return ret;
@@ -487,7 +517,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
487 ret = drm_atomic_replace_property_blob_from_id(dev, 517 ret = drm_atomic_replace_property_blob_from_id(dev,
488 &state->gamma_lut, 518 &state->gamma_lut,
489 val, 519 val,
490 -1, 520 -1, sizeof(struct drm_color_lut),
491 &replaced); 521 &replaced);
492 state->color_mgmt_changed |= replaced; 522 state->color_mgmt_changed |= replaced;
493 return ret; 523 return ret;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 00c78c1c9681..c35654591c12 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3818,7 +3818,7 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
3818 } 3818 }
3819 3819
3820 /* Prepare GAMMA_LUT with the legacy values. */ 3820 /* Prepare GAMMA_LUT with the legacy values. */
3821 blob_data = (struct drm_color_lut *) blob->data; 3821 blob_data = blob->data;
3822 for (i = 0; i < size; i++) { 3822 for (i = 0; i < size; i++) {
3823 blob_data[i].red = red[i]; 3823 blob_data[i].red = red[i];
3824 blob_data[i].green = green[i]; 3824 blob_data[i].green = green[i];
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 1ee84dd802d4..ba8cfe65c65b 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -129,10 +129,10 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
129 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where 129 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
130 * applicable and if supported by the kernel. 130 * applicable and if supported by the kernel.
131 */ 131 */
132static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, 132static int drm_addmap_core(struct drm_device *dev, resource_size_t offset,
133 unsigned int size, enum drm_map_type type, 133 unsigned int size, enum drm_map_type type,
134 enum drm_map_flags flags, 134 enum drm_map_flags flags,
135 struct drm_map_list ** maplist) 135 struct drm_map_list **maplist)
136{ 136{
137 struct drm_local_map *map; 137 struct drm_local_map *map;
138 struct drm_map_list *list; 138 struct drm_map_list *list;
@@ -224,7 +224,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
224 case _DRM_SHM: 224 case _DRM_SHM:
225 list = drm_find_matching_map(dev, map); 225 list = drm_find_matching_map(dev, map);
226 if (list != NULL) { 226 if (list != NULL) {
227 if(list->map->size != map->size) { 227 if (list->map->size != map->size) {
228 DRM_DEBUG("Matching maps of type %d with " 228 DRM_DEBUG("Matching maps of type %d with "
229 "mismatched sizes, (%ld vs %ld)\n", 229 "mismatched sizes, (%ld vs %ld)\n",
230 map->type, map->size, list->map->size); 230 map->type, map->size, list->map->size);
@@ -361,7 +361,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
361 return 0; 361 return 0;
362} 362}
363 363
364int drm_legacy_addmap(struct drm_device * dev, resource_size_t offset, 364int drm_legacy_addmap(struct drm_device *dev, resource_size_t offset,
365 unsigned int size, enum drm_map_type type, 365 unsigned int size, enum drm_map_type type,
366 enum drm_map_flags flags, struct drm_local_map **map_ptr) 366 enum drm_map_flags flags, struct drm_local_map **map_ptr)
367{ 367{
@@ -637,8 +637,8 @@ int drm_legacy_rmmap_ioctl(struct drm_device *dev, void *data,
637 * 637 *
638 * Frees any pages and buffers associated with the given entry. 638 * Frees any pages and buffers associated with the given entry.
639 */ 639 */
640static void drm_cleanup_buf_error(struct drm_device * dev, 640static void drm_cleanup_buf_error(struct drm_device *dev,
641 struct drm_buf_entry * entry) 641 struct drm_buf_entry *entry)
642{ 642{
643 int i; 643 int i;
644 644
@@ -1446,8 +1446,8 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data,
1446int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p, 1446int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p,
1447 void __user **v, 1447 void __user **v,
1448 int (*f)(void *, int, unsigned long, 1448 int (*f)(void *, int, unsigned long,
1449 struct drm_buf *), 1449 struct drm_buf *),
1450 struct drm_file *file_priv) 1450 struct drm_file *file_priv)
1451{ 1451{
1452 struct drm_device_dma *dma = dev->dma; 1452 struct drm_device_dma *dma = dev->dma;
1453 int retcode = 0; 1453 int retcode = 0;
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a797bbf1cab8..49147b2aa288 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1554,8 +1554,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
1554 struct edid *override = NULL; 1554 struct edid *override = NULL;
1555 1555
1556 if (connector->override_edid) 1556 if (connector->override_edid)
1557 override = drm_edid_duplicate((const struct edid *) 1557 override = drm_edid_duplicate(connector->edid_blob_ptr->data);
1558 connector->edid_blob_ptr->data);
1559 1558
1560 if (!override) 1559 if (!override)
1561 override = drm_load_edid_firmware(connector); 1560 override = drm_load_edid_firmware(connector);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 035784ddd133..0646b108030b 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1351,7 +1351,7 @@ static struct drm_property_blob *setcmap_new_gamma_lut(struct drm_crtc *crtc,
1351 if (IS_ERR(gamma_lut)) 1351 if (IS_ERR(gamma_lut))
1352 return gamma_lut; 1352 return gamma_lut;
1353 1353
1354 lut = (struct drm_color_lut *)gamma_lut->data; 1354 lut = gamma_lut->data;
1355 if (cmap->start || cmap->len != size) { 1355 if (cmap->start || cmap->len != size) {
1356 u16 *r = crtc->gamma_store; 1356 u16 *r = crtc->gamma_store;
1357 u16 *g = r + crtc->gamma_size; 1357 u16 *g = r + crtc->gamma_size;
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 5a13ff29f4f0..0eebe8ba8a2c 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -158,9 +158,10 @@ static int framebuffer_check(struct drm_device *dev,
158 info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN); 158 info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
159 if (!info) { 159 if (!info) {
160 struct drm_format_name_buf format_name; 160 struct drm_format_name_buf format_name;
161
161 DRM_DEBUG_KMS("bad framebuffer format %s\n", 162 DRM_DEBUG_KMS("bad framebuffer format %s\n",
162 drm_get_format_name(r->pixel_format, 163 drm_get_format_name(r->pixel_format,
163 &format_name)); 164 &format_name));
164 return -EINVAL; 165 return -EINVAL;
165 } 166 }
166 167
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 5a8033fda4e3..f6b7c0e36a1a 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -773,24 +773,23 @@ EXPORT_SYMBOL(drm_mode_hsync);
773int drm_mode_vrefresh(const struct drm_display_mode *mode) 773int drm_mode_vrefresh(const struct drm_display_mode *mode)
774{ 774{
775 int refresh = 0; 775 int refresh = 0;
776 unsigned int calc_val;
777 776
778 if (mode->vrefresh > 0) 777 if (mode->vrefresh > 0)
779 refresh = mode->vrefresh; 778 refresh = mode->vrefresh;
780 else if (mode->htotal > 0 && mode->vtotal > 0) { 779 else if (mode->htotal > 0 && mode->vtotal > 0) {
781 int vtotal; 780 unsigned int num, den;
782 vtotal = mode->vtotal; 781
783 /* work out vrefresh the value will be x1000 */ 782 num = mode->clock * 1000;
784 calc_val = (mode->clock * 1000); 783 den = mode->htotal * mode->vtotal;
785 calc_val /= mode->htotal;
786 refresh = (calc_val + vtotal / 2) / vtotal;
787 784
788 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 785 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
789 refresh *= 2; 786 num *= 2;
790 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 787 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
791 refresh /= 2; 788 den *= 2;
792 if (mode->vscan > 1) 789 if (mode->vscan > 1)
793 refresh /= mode->vscan; 790 den *= mode->vscan;
791
792 refresh = DIV_ROUND_CLOSEST(num, den);
794 } 793 }
795 return refresh; 794 return refresh;
796} 795}
@@ -1596,12 +1595,8 @@ int drm_mode_convert_umode(struct drm_device *dev,
1596 struct drm_display_mode *out, 1595 struct drm_display_mode *out,
1597 const struct drm_mode_modeinfo *in) 1596 const struct drm_mode_modeinfo *in)
1598{ 1597{
1599 int ret = -EINVAL; 1598 if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
1600 1599 return -ERANGE;
1601 if (in->clock > INT_MAX || in->vrefresh > INT_MAX) {
1602 ret = -ERANGE;
1603 goto out;
1604 }
1605 1600
1606 out->clock = in->clock; 1601 out->clock = in->clock;
1607 out->hdisplay = in->hdisplay; 1602 out->hdisplay = in->hdisplay;
@@ -1622,14 +1617,11 @@ int drm_mode_convert_umode(struct drm_device *dev,
1622 1617
1623 out->status = drm_mode_validate_driver(dev, out); 1618 out->status = drm_mode_validate_driver(dev, out);
1624 if (out->status != MODE_OK) 1619 if (out->status != MODE_OK)
1625 goto out; 1620 return -EINVAL;
1626 1621
1627 drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V); 1622 drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
1628 1623
1629 ret = 0; 1624 return 0;
1630
1631out:
1632 return ret;
1633} 1625}
1634 1626
1635/** 1627/**
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index a5d1fc7e8a37..6d2a6e428a3e 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -104,7 +104,7 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane
104 if (IS_ERR(blob)) 104 if (IS_ERR(blob))
105 return -1; 105 return -1;
106 106
107 blob_data = (struct drm_format_modifier_blob *)blob->data; 107 blob_data = blob->data;
108 blob_data->version = FORMAT_BLOB_CURRENT; 108 blob_data->version = FORMAT_BLOB_CURRENT;
109 blob_data->count_formats = plane->format_count; 109 blob_data->count_formats = plane->format_count;
110 blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); 110 blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 781518fd88e3..b25f98f33f6c 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -63,16 +63,34 @@ void drm_printf(struct drm_printer *p, const char *f, ...)
63} 63}
64EXPORT_SYMBOL(drm_printf); 64EXPORT_SYMBOL(drm_printf);
65 65
66#define DRM_PRINTK_FMT "[" DRM_NAME ":%s]%s %pV"
67
68void drm_dev_printk(const struct device *dev, const char *level, 66void drm_dev_printk(const struct device *dev, const char *level,
69 unsigned int category, const char *function_name, 67 const char *format, ...)
70 const char *prefix, const char *format, ...)
71{ 68{
72 struct va_format vaf; 69 struct va_format vaf;
73 va_list args; 70 va_list args;
74 71
75 if (category != DRM_UT_NONE && !(drm_debug & category)) 72 va_start(args, format);
73 vaf.fmt = format;
74 vaf.va = &args;
75
76 if (dev)
77 dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV",
78 __builtin_return_address(0), &vaf);
79 else
80 printk("%s" "[" DRM_NAME ":%ps] %pV",
81 level, __builtin_return_address(0), &vaf);
82
83 va_end(args);
84}
85EXPORT_SYMBOL(drm_dev_printk);
86
87void drm_dev_dbg(const struct device *dev, unsigned int category,
88 const char *format, ...)
89{
90 struct va_format vaf;
91 va_list args;
92
93 if (!(drm_debug & category))
76 return; 94 return;
77 95
78 va_start(args, format); 96 va_start(args, format);
@@ -80,32 +98,47 @@ void drm_dev_printk(const struct device *dev, const char *level,
80 vaf.va = &args; 98 vaf.va = &args;
81 99
82 if (dev) 100 if (dev)
83 dev_printk(level, dev, DRM_PRINTK_FMT, function_name, prefix, 101 dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
84 &vaf); 102 __builtin_return_address(0), &vaf);
85 else 103 else
86 printk("%s" DRM_PRINTK_FMT, level, function_name, prefix, &vaf); 104 printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
105 __builtin_return_address(0), &vaf);
87 106
88 va_end(args); 107 va_end(args);
89} 108}
90EXPORT_SYMBOL(drm_dev_printk); 109EXPORT_SYMBOL(drm_dev_dbg);
91 110
92void drm_printk(const char *level, unsigned int category, 111void drm_dbg(unsigned int category, const char *format, ...)
93 const char *format, ...)
94{ 112{
95 struct va_format vaf; 113 struct va_format vaf;
96 va_list args; 114 va_list args;
97 115
98 if (category != DRM_UT_NONE && !(drm_debug & category)) 116 if (!(drm_debug & category))
99 return; 117 return;
100 118
101 va_start(args, format); 119 va_start(args, format);
102 vaf.fmt = format; 120 vaf.fmt = format;
103 vaf.va = &args; 121 vaf.va = &args;
104 122
105 printk("%s" "[" DRM_NAME ":%ps]%s %pV", 123 printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
106 level, __builtin_return_address(0), 124 __builtin_return_address(0), &vaf);
107 strcmp(level, KERN_ERR) == 0 ? " *ERROR*" : "", &vaf); 125
126 va_end(args);
127}
128EXPORT_SYMBOL(drm_dbg);
129
130void drm_err(const char *format, ...)
131{
132 struct va_format vaf;
133 va_list args;
134
135 va_start(args, format);
136 vaf.fmt = format;
137 vaf.va = &args;
138
139 printk(KERN_ERR "[" DRM_NAME ":%ps] *ERROR* %pV",
140 __builtin_return_address(0), &vaf);
108 141
109 va_end(args); 142 va_end(args);
110} 143}
111EXPORT_SYMBOL(drm_printk); 144EXPORT_SYMBOL(drm_err);
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 6ac6ee41a6a3..8f4672daac7f 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -567,6 +567,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
567 /* This must be explicitly initialised, so we can safely call list_del 567 /* This must be explicitly initialised, so we can safely call list_del
568 * on it in the removal handler, even if it isn't in a file list. */ 568 * on it in the removal handler, even if it isn't in a file list. */
569 INIT_LIST_HEAD(&blob->head_file); 569 INIT_LIST_HEAD(&blob->head_file);
570 blob->data = (void *)blob + sizeof(*blob);
570 blob->length = length; 571 blob->length = length;
571 blob->dev = dev; 572 blob->dev = dev;
572 573
diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig
index 3f58b4077767..e5bfeca361bd 100644
--- a/drivers/gpu/drm/etnaviv/Kconfig
+++ b/drivers/gpu/drm/etnaviv/Kconfig
@@ -11,6 +11,7 @@ config DRM_ETNAVIV
11 select WANT_DEV_COREDUMP 11 select WANT_DEV_COREDUMP
12 select CMA if HAVE_DMA_CONTIGUOUS 12 select CMA if HAVE_DMA_CONTIGUOUS
13 select DMA_CMA if HAVE_DMA_CONTIGUOUS 13 select DMA_CMA if HAVE_DMA_CONTIGUOUS
14 select DRM_SCHED
14 help 15 help
15 DRM driver for Vivante GPUs. 16 DRM driver for Vivante GPUs.
16 17
diff --git a/drivers/gpu/drm/etnaviv/Makefile b/drivers/gpu/drm/etnaviv/Makefile
index 1281c8d4fae5..46e5ffad69a6 100644
--- a/drivers/gpu/drm/etnaviv/Makefile
+++ b/drivers/gpu/drm/etnaviv/Makefile
@@ -9,9 +9,11 @@ etnaviv-y := \
9 etnaviv_gem_submit.o \ 9 etnaviv_gem_submit.o \
10 etnaviv_gem.o \ 10 etnaviv_gem.o \
11 etnaviv_gpu.o \ 11 etnaviv_gpu.o \
12 etnaviv_hwdb.o \
12 etnaviv_iommu_v2.o \ 13 etnaviv_iommu_v2.o \
13 etnaviv_iommu.o \ 14 etnaviv_iommu.o \
14 etnaviv_mmu.o \ 15 etnaviv_mmu.o \
15 etnaviv_perfmon.o 16 etnaviv_perfmon.o \
17 etnaviv_sched.o
16 18
17obj-$(CONFIG_DRM_ETNAVIV) += etnaviv.o 19obj-$(CONFIG_DRM_ETNAVIV) += etnaviv.o
diff --git a/drivers/gpu/drm/etnaviv/common.xml.h b/drivers/gpu/drm/etnaviv/common.xml.h
index 207f45c999c3..001faea80fef 100644
--- a/drivers/gpu/drm/etnaviv/common.xml.h
+++ b/drivers/gpu/drm/etnaviv/common.xml.h
@@ -8,15 +8,12 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
8git clone git://0x04.net/rules-ng-ng 8git clone git://0x04.net/rules-ng-ng
9 9
10The rules-ng-ng source files this header was generated from are: 10The rules-ng-ng source files this header was generated from are:
11- state.xml ( 19930 bytes, from 2017-03-09 15:43:43) 11- texdesc_3d.xml ( 3183 bytes, from 2017-12-18 16:51:59)
12- common.xml ( 23473 bytes, from 2017-03-09 15:43:43) 12- copyright.xml ( 1597 bytes, from 2016-12-08 16:37:56)
13- state_hi.xml ( 26403 bytes, from 2017-03-09 15:43:43) 13- common.xml ( 35468 bytes, from 2018-01-22 13:48:54)
14- copyright.xml ( 1597 bytes, from 2016-12-08 16:37:56) 14- common_3d.xml ( 14615 bytes, from 2017-12-18 16:51:59)
15- state_2d.xml ( 51552 bytes, from 2016-12-08 16:37:56)
16- state_3d.xml ( 66957 bytes, from 2017-03-09 15:43:43)
17- state_vg.xml ( 5975 bytes, from 2016-12-08 16:37:56)
18 15
19Copyright (C) 2012-2017 by the following authors: 16Copyright (C) 2012-2018 by the following authors:
20- Wladimir J. van der Laan <laanwj@gmail.com> 17- Wladimir J. van der Laan <laanwj@gmail.com>
21- Christian Gmeiner <christian.gmeiner@gmail.com> 18- Christian Gmeiner <christian.gmeiner@gmail.com>
22- Lucas Stach <l.stach@pengutronix.de> 19- Lucas Stach <l.stach@pengutronix.de>
@@ -49,12 +46,7 @@ DEALINGS IN THE SOFTWARE.
49#define SYNC_RECIPIENT_RA 0x00000005 46#define SYNC_RECIPIENT_RA 0x00000005
50#define SYNC_RECIPIENT_PE 0x00000007 47#define SYNC_RECIPIENT_PE 0x00000007
51#define SYNC_RECIPIENT_DE 0x0000000b 48#define SYNC_RECIPIENT_DE 0x0000000b
52#define SYNC_RECIPIENT_VG 0x0000000f 49#define SYNC_RECIPIENT_BLT 0x00000010
53#define SYNC_RECIPIENT_TESSELATOR 0x00000010
54#define SYNC_RECIPIENT_VG2 0x00000011
55#define SYNC_RECIPIENT_TESSELATOR2 0x00000012
56#define SYNC_RECIPIENT_VG3 0x00000013
57#define SYNC_RECIPIENT_TESSELATOR3 0x00000014
58#define ENDIAN_MODE_NO_SWAP 0x00000000 50#define ENDIAN_MODE_NO_SWAP 0x00000000
59#define ENDIAN_MODE_SWAP_16 0x00000001 51#define ENDIAN_MODE_SWAP_16 0x00000001
60#define ENDIAN_MODE_SWAP_32 0x00000002 52#define ENDIAN_MODE_SWAP_32 0x00000002
@@ -77,6 +69,7 @@ DEALINGS IN THE SOFTWARE.
77#define chipModel_GC800 0x00000800 69#define chipModel_GC800 0x00000800
78#define chipModel_GC860 0x00000860 70#define chipModel_GC860 0x00000860
79#define chipModel_GC880 0x00000880 71#define chipModel_GC880 0x00000880
72#define chipModel_GC900 0x00000900
80#define chipModel_GC1000 0x00001000 73#define chipModel_GC1000 0x00001000
81#define chipModel_GC1500 0x00001500 74#define chipModel_GC1500 0x00001500
82#define chipModel_GC2000 0x00002000 75#define chipModel_GC2000 0x00002000
@@ -88,6 +81,12 @@ DEALINGS IN THE SOFTWARE.
88#define chipModel_GC5000 0x00005000 81#define chipModel_GC5000 0x00005000
89#define chipModel_GC5200 0x00005200 82#define chipModel_GC5200 0x00005200
90#define chipModel_GC6400 0x00006400 83#define chipModel_GC6400 0x00006400
84#define chipModel_GC7000 0x00007000
85#define chipModel_GC7400 0x00007400
86#define chipModel_GC8000 0x00008000
87#define chipModel_GC8100 0x00008100
88#define chipModel_GC8200 0x00008200
89#define chipModel_GC8400 0x00008400
91#define RGBA_BITS_R 0x00000001 90#define RGBA_BITS_R 0x00000001
92#define RGBA_BITS_G 0x00000002 91#define RGBA_BITS_G 0x00000002
93#define RGBA_BITS_B 0x00000004 92#define RGBA_BITS_B 0x00000004
@@ -203,7 +202,7 @@ DEALINGS IN THE SOFTWARE.
203#define chipMinorFeatures2_RGB888 0x00001000 202#define chipMinorFeatures2_RGB888 0x00001000
204#define chipMinorFeatures2_TX__YUV_ASSEMBLER 0x00002000 203#define chipMinorFeatures2_TX__YUV_ASSEMBLER 0x00002000
205#define chipMinorFeatures2_DYNAMIC_FREQUENCY_SCALING 0x00004000 204#define chipMinorFeatures2_DYNAMIC_FREQUENCY_SCALING 0x00004000
206#define chipMinorFeatures2_EXTRA_TEXTURE_STATE 0x00008000 205#define chipMinorFeatures2_TX_FILTER 0x00008000
207#define chipMinorFeatures2_FULL_DIRECTFB 0x00010000 206#define chipMinorFeatures2_FULL_DIRECTFB 0x00010000
208#define chipMinorFeatures2_2D_TILING 0x00020000 207#define chipMinorFeatures2_2D_TILING 0x00020000
209#define chipMinorFeatures2_THREAD_WALKER_IN_PS 0x00040000 208#define chipMinorFeatures2_THREAD_WALKER_IN_PS 0x00040000
@@ -242,36 +241,36 @@ DEALINGS IN THE SOFTWARE.
242#define chipMinorFeatures3_TX_ENHANCEMENTS1 0x00080000 241#define chipMinorFeatures3_TX_ENHANCEMENTS1 0x00080000
243#define chipMinorFeatures3_SH_ENHANCEMENTS1 0x00100000 242#define chipMinorFeatures3_SH_ENHANCEMENTS1 0x00100000
244#define chipMinorFeatures3_SH_ENHANCEMENTS2 0x00200000 243#define chipMinorFeatures3_SH_ENHANCEMENTS2 0x00200000
245#define chipMinorFeatures3_UNK22 0x00400000 244#define chipMinorFeatures3_PE_ENHANCEMENTS1 0x00400000
246#define chipMinorFeatures3_2D_FC_SOURCE 0x00800000 245#define chipMinorFeatures3_2D_FC_SOURCE 0x00800000
247#define chipMinorFeatures3_UNK24 0x01000000 246#define chipMinorFeatures3_BUG_FIXES_14 0x01000000
248#define chipMinorFeatures3_UNK25 0x02000000 247#define chipMinorFeatures3_POWER_OPTIMIZATIONS_0 0x02000000
249#define chipMinorFeatures3_NEW_HZ 0x04000000 248#define chipMinorFeatures3_NEW_HZ 0x04000000
250#define chipMinorFeatures3_UNK27 0x08000000 249#define chipMinorFeatures3_PE_DITHER_FIX 0x08000000
251#define chipMinorFeatures3_UNK28 0x10000000 250#define chipMinorFeatures3_DE_ENHANCEMENTS3 0x10000000
252#define chipMinorFeatures3_SH_ENHANCEMENTS3 0x20000000 251#define chipMinorFeatures3_SH_ENHANCEMENTS3 0x20000000
253#define chipMinorFeatures3_UNK30 0x40000000 252#define chipMinorFeatures3_SH_ENHANCEMENTS4 0x40000000
254#define chipMinorFeatures3_UNK31 0x80000000 253#define chipMinorFeatures3_TX_ENHANCEMENTS2 0x80000000
255#define chipMinorFeatures4_UNK0 0x00000001 254#define chipMinorFeatures4_FE_ENHANCEMENTS1 0x00000001
256#define chipMinorFeatures4_PE_ENHANCEMENTS2 0x00000002 255#define chipMinorFeatures4_PE_ENHANCEMENTS2 0x00000002
257#define chipMinorFeatures4_FRUSTUM_CLIP_FIX 0x00000004 256#define chipMinorFeatures4_FRUSTUM_CLIP_FIX 0x00000004
258#define chipMinorFeatures4_UNK3 0x00000008 257#define chipMinorFeatures4_DE_NO_GAMMA 0x00000008
259#define chipMinorFeatures4_UNK4 0x00000010 258#define chipMinorFeatures4_PA_ENHANCEMENTS_2 0x00000010
260#define chipMinorFeatures4_2D_GAMMA 0x00000020 259#define chipMinorFeatures4_2D_GAMMA 0x00000020
261#define chipMinorFeatures4_SINGLE_BUFFER 0x00000040 260#define chipMinorFeatures4_SINGLE_BUFFER 0x00000040
262#define chipMinorFeatures4_UNK7 0x00000080 261#define chipMinorFeatures4_HI_ENHANCEMENTS_1 0x00000080
263#define chipMinorFeatures4_UNK8 0x00000100 262#define chipMinorFeatures4_TX_ENHANCEMENTS_3 0x00000100
264#define chipMinorFeatures4_UNK9 0x00000200 263#define chipMinorFeatures4_SH_ENHANCEMENTS_5 0x00000200
265#define chipMinorFeatures4_UNK10 0x00000400 264#define chipMinorFeatures4_FE_ENHANCEMENTS_2 0x00000400
266#define chipMinorFeatures4_TX_LERP_PRECISION_FIX 0x00000800 265#define chipMinorFeatures4_TX_LERP_PRECISION_FIX 0x00000800
267#define chipMinorFeatures4_2D_COLOR_SPACE_CONVERSION 0x00001000 266#define chipMinorFeatures4_2D_COLOR_SPACE_CONVERSION 0x00001000
268#define chipMinorFeatures4_TEXTURE_ASTC 0x00002000 267#define chipMinorFeatures4_TEXTURE_ASTC 0x00002000
269#define chipMinorFeatures4_UNK14 0x00004000 268#define chipMinorFeatures4_PE_ENHANCEMENTS_4 0x00004000
270#define chipMinorFeatures4_UNK15 0x00008000 269#define chipMinorFeatures4_MC_ENHANCEMENTS_1 0x00008000
271#define chipMinorFeatures4_HALTI2 0x00010000 270#define chipMinorFeatures4_HALTI2 0x00010000
272#define chipMinorFeatures4_UNK17 0x00020000 271#define chipMinorFeatures4_2D_MIRROR_EXTENSION 0x00020000
273#define chipMinorFeatures4_SMALL_MSAA 0x00040000 272#define chipMinorFeatures4_SMALL_MSAA 0x00040000
274#define chipMinorFeatures4_UNK19 0x00080000 273#define chipMinorFeatures4_BUG_FIXES_17 0x00080000
275#define chipMinorFeatures4_NEW_RA 0x00100000 274#define chipMinorFeatures4_NEW_RA 0x00100000
276#define chipMinorFeatures4_2D_OPF_YUV_OUTPUT 0x00200000 275#define chipMinorFeatures4_2D_OPF_YUV_OUTPUT 0x00200000
277#define chipMinorFeatures4_2D_MULTI_SOURCE_BLT_EX2 0x00400000 276#define chipMinorFeatures4_2D_MULTI_SOURCE_BLT_EX2 0x00400000
@@ -280,41 +279,207 @@ DEALINGS IN THE SOFTWARE.
280#define chipMinorFeatures4_BUG_FIXES18 0x02000000 279#define chipMinorFeatures4_BUG_FIXES18 0x02000000
281#define chipMinorFeatures4_2D_COMPRESSION 0x04000000 280#define chipMinorFeatures4_2D_COMPRESSION 0x04000000
282#define chipMinorFeatures4_PROBE 0x08000000 281#define chipMinorFeatures4_PROBE 0x08000000
283#define chipMinorFeatures4_UNK28 0x10000000 282#define chipMinorFeatures4_MEDIUM_PRECISION 0x10000000
284#define chipMinorFeatures4_2D_SUPER_TILE_VERSION 0x20000000 283#define chipMinorFeatures4_2D_SUPER_TILE_VERSION 0x20000000
285#define chipMinorFeatures4_UNK30 0x40000000 284#define chipMinorFeatures4_BUG_FIXES19 0x40000000
286#define chipMinorFeatures4_UNK31 0x80000000 285#define chipMinorFeatures4_SH_ENHANCEMENTS6 0x80000000
287#define chipMinorFeatures5_UNK0 0x00000001 286#define chipMinorFeatures5_SH_ENHANCEMENTS7 0x00000001
288#define chipMinorFeatures5_UNK1 0x00000002 287#define chipMinorFeatures5_BUG_FIXES20 0x00000002
289#define chipMinorFeatures5_UNK2 0x00000004 288#define chipMinorFeatures5_DE_ADDRESS_40 0x00000004
290#define chipMinorFeatures5_UNK3 0x00000008 289#define chipMinorFeatures5_MINI_MMU_FIX 0x00000008
291#define chipMinorFeatures5_EEZ 0x00000010 290#define chipMinorFeatures5_EEZ 0x00000010
292#define chipMinorFeatures5_UNK5 0x00000020 291#define chipMinorFeatures5_BUG_FIXES21 0x00000020
293#define chipMinorFeatures5_UNK6 0x00000040 292#define chipMinorFeatures5_EXTRA_VG_CAPS 0x00000040
294#define chipMinorFeatures5_UNK7 0x00000080 293#define chipMinorFeatures5_MULTI_SRC_V15 0x00000080
295#define chipMinorFeatures5_UNK8 0x00000100 294#define chipMinorFeatures5_BUG_FIXES22 0x00000100
296#define chipMinorFeatures5_HALTI3 0x00000200 295#define chipMinorFeatures5_HALTI3 0x00000200
297#define chipMinorFeatures5_UNK10 0x00000400 296#define chipMinorFeatures5_TESSELATION_SHADERS 0x00000400
298#define chipMinorFeatures5_2D_ONE_PASS_FILTER_TAP 0x00000800 297#define chipMinorFeatures5_2D_ONE_PASS_FILTER_TAP 0x00000800
299#define chipMinorFeatures5_UNK12 0x00001000 298#define chipMinorFeatures5_MULTI_SRC_V2_STR_QUAD 0x00001000
300#define chipMinorFeatures5_SEPARATE_SRC_DST 0x00002000 299#define chipMinorFeatures5_SEPARATE_SRC_DST 0x00002000
301#define chipMinorFeatures5_HALTI4 0x00004000 300#define chipMinorFeatures5_HALTI4 0x00004000
302#define chipMinorFeatures5_UNK15 0x00008000 301#define chipMinorFeatures5_RA_WRITE_DEPTH 0x00008000
303#define chipMinorFeatures5_ANDROID_ONLY 0x00010000 302#define chipMinorFeatures5_ANDROID_ONLY 0x00010000
304#define chipMinorFeatures5_HAS_PRODUCTID 0x00020000 303#define chipMinorFeatures5_HAS_PRODUCTID 0x00020000
305#define chipMinorFeatures5_UNK18 0x00040000 304#define chipMinorFeatures5_TX_SUPPORT_DEC 0x00040000
306#define chipMinorFeatures5_UNK19 0x00080000 305#define chipMinorFeatures5_S8_MSAA_COMPRESSION 0x00080000
307#define chipMinorFeatures5_PE_DITHER_FIX2 0x00100000 306#define chipMinorFeatures5_PE_DITHER_FIX2 0x00100000
308#define chipMinorFeatures5_UNK21 0x00200000 307#define chipMinorFeatures5_L2_CACHE_REMOVE 0x00200000
309#define chipMinorFeatures5_UNK22 0x00400000 308#define chipMinorFeatures5_FE_ALLOW_RND_VTX_CNT 0x00400000
310#define chipMinorFeatures5_UNK23 0x00800000 309#define chipMinorFeatures5_CUBE_MAP_FL28 0x00800000
311#define chipMinorFeatures5_UNK24 0x01000000 310#define chipMinorFeatures5_TX_6BIT_FRAC 0x01000000
312#define chipMinorFeatures5_UNK25 0x02000000 311#define chipMinorFeatures5_FE_ALLOW_STALL_PREFETCH_ENG 0x02000000
313#define chipMinorFeatures5_UNK26 0x04000000 312#define chipMinorFeatures5_THIRD_PARTY_COMPRESSION 0x04000000
314#define chipMinorFeatures5_RS_DEPTHSTENCIL_NATIVE_SUPPORT 0x08000000 313#define chipMinorFeatures5_RS_DEPTHSTENCIL_NATIVE_SUPPORT 0x08000000
315#define chipMinorFeatures5_V2_MSAA_COMP_FIX 0x10000000 314#define chipMinorFeatures5_V2_MSAA_COMP_FIX 0x10000000
316#define chipMinorFeatures5_UNK29 0x20000000 315#define chipMinorFeatures5_HALTI5 0x20000000
317#define chipMinorFeatures5_UNK30 0x40000000 316#define chipMinorFeatures5_EVIS 0x40000000
318#define chipMinorFeatures5_UNK31 0x80000000 317#define chipMinorFeatures5_BLT_ENGINE 0x80000000
318#define chipMinorFeatures6_BUG_FIXES_23 0x00000001
319#define chipMinorFeatures6_BUG_FIXES_24 0x00000002
320#define chipMinorFeatures6_DEC 0x00000004
321#define chipMinorFeatures6_VS_TILE_NV12 0x00000008
322#define chipMinorFeatures6_VS_TILE_NV12_10BIT 0x00000010
323#define chipMinorFeatures6_RENDER_TARGET_8 0x00000020
324#define chipMinorFeatures6_TEX_LOD_FLOW_CORR 0x00000040
325#define chipMinorFeatures6_FACE_LOD 0x00000080
326#define chipMinorFeatures6_MULTI_CORE_SEMAPHORE_STALL_V2 0x00000100
327#define chipMinorFeatures6_VMSAA 0x00000200
328#define chipMinorFeatures6_CHIP_ENABLE_LINK 0x00000400
329#define chipMinorFeatures6_MULTI_SRC_BLT_1_5_ENHANCEMENT 0x00000800
330#define chipMinorFeatures6_MULTI_SRC_BLT_BILINEAR_FILTER 0x00001000
331#define chipMinorFeatures6_RA_HZEZ_CLOCK_CONTROL 0x00002000
332#define chipMinorFeatures6_CACHE128B256BPERLINE 0x00004000
333#define chipMinorFeatures6_V4_COMPRESSION 0x00008000
334#define chipMinorFeatures6_PE2D_MAJOR_SUPER_TILE 0x00010000
335#define chipMinorFeatures6_PE_32BPC_COLORMASK_FIX 0x00020000
336#define chipMinorFeatures6_ALPHA_BLENDING_OPT 0x00040000
337#define chipMinorFeatures6_NEW_GPIPE 0x00080000
338#define chipMinorFeatures6_PIPELINE_32_ATTRIBUTES 0x00100000
339#define chipMinorFeatures6_MSAA_SHADING 0x00200000
340#define chipMinorFeatures6_NO_ANISTRO_FILTER 0x00400000
341#define chipMinorFeatures6_NO_ASTC 0x00800000
342#define chipMinorFeatures6_NO_DXT 0x01000000
343#define chipMinorFeatures6_HWTFB 0x02000000
344#define chipMinorFeatures6_RA_DEPTH_WRITE_MSAA1X_FIX 0x04000000
345#define chipMinorFeatures6_EZHZ_CLOCKGATE_FIX 0x08000000
346#define chipMinorFeatures6_SH_SNAP2PAGE_FIX 0x10000000
347#define chipMinorFeatures6_SH_HALFDEPENDENCY_FIX 0x20000000
348#define chipMinorFeatures6_USC_MCFILL_FIX 0x40000000
349#define chipMinorFeatures6_TPG_TCPERF_FIX 0x80000000
350#define chipMinorFeatures7_USC_MDFIFO_OVERFLOW_FIX 0x00000001
351#define chipMinorFeatures7_SH_TEXLD_BARRIER_IN_CS_FIX 0x00000002
352#define chipMinorFeatures7_RS_NEW_BASEADDR 0x00000004
353#define chipMinorFeatures7_PE_8BPP_DUALPIPE_FIX 0x00000008
354#define chipMinorFeatures7_SH_ADVANCED_INSTR 0x00000010
355#define chipMinorFeatures7_SH_FLAT_INTERPOLATION_DUAL16_FIX 0x00000020
356#define chipMinorFeatures7_USC_CONTINUOUS_FLUS_FIX 0x00000040
357#define chipMinorFeatures7_SH_SUPPORT_V4 0x00000080
358#define chipMinorFeatures7_SH_SUPPORT_ALPHA_KILL 0x00000100
359#define chipMinorFeatures7_PE_NO_ALPHA_TEST 0x00000200
360#define chipMinorFeatures7_TX_LOD_NEAREST_SELECT 0x00000400
361#define chipMinorFeatures7_SH_FIX_LDEXP 0x00000800
362#define chipMinorFeatures7_SUPPORT_MOVAI 0x00001000
363#define chipMinorFeatures7_SH_SNAP2PAGE_MAXPAGES_FIX 0x00002000
364#define chipMinorFeatures7_PE_RGBA16I_FIX 0x00004000
365#define chipMinorFeatures7_BLT_8bpp_256TILE_FC_FIX 0x00008000
366#define chipMinorFeatures7_PE_64BIT_FENCE_FIX 0x00010000
367#define chipMinorFeatures7_USC_FULL_CACHE_FIX 0x00020000
368#define chipMinorFeatures7_TX_YUV_ASSEMBLER_10BIT 0x00040000
369#define chipMinorFeatures7_FE_32BIT_INDEX_FIX 0x00080000
370#define chipMinorFeatures7_BLT_64BPP_MASKED_CLEAR_FIX 0x00100000
371#define chipMinorFeatures7_BIT_SECURITY 0x00200000
372#define chipMinorFeatures7_BIT_ROBUSTNESS 0x00400000
373#define chipMinorFeatures7_USC_ATOMIC_FIX 0x00800000
374#define chipMinorFeatures7_SH_PSO_MSAA1x_FIX 0x01000000
375#define chipMinorFeatures7_BIT_USC_VX_PERF_FIX 0x02000000
376#define chipMinorFeatures7_EVIS_NO_ABSDIFF 0x04000000
377#define chipMinorFeatures7_EVIS_NO_BITREPLACE 0x08000000
378#define chipMinorFeatures7_EVIS_NO_BOXFILTER 0x10000000
379#define chipMinorFeatures7_EVIS_NO_CORDIAC 0x20000000
380#define chipMinorFeatures7_EVIS_NO_DP32 0x40000000
381#define chipMinorFeatures7_EVIS_NO_FILTER 0x80000000
382#define chipMinorFeatures8_EVIS_NO_IADD 0x00000001
383#define chipMinorFeatures8_EVIS_NO_SELECTADD 0x00000002
384#define chipMinorFeatures8_EVIS_LERP_7OUTPUT 0x00000004
385#define chipMinorFeatures8_EVIS_ACCSQ_8OUTPUT 0x00000008
386#define chipMinorFeatures8_USC_GOS_ADDR_FIX 0x00000010
387#define chipMinorFeatures8_TX_8BIT_UVFRAC 0x00000020
388#define chipMinorFeatures8_TX_DESC_CACHE_CLOCKGATE_FIX 0x00000040
389#define chipMinorFeatures8_RSBLT_MSAA_DECOMPRESSION 0x00000080
390#define chipMinorFeatures8_TX_INTEGER_COORDINATE 0x00000100
391#define chipMinorFeatures8_DRAWID 0x00000200
392#define chipMinorFeatures8_PSIO_SAMPLEMASK_IN_R0ZW_FIX 0x00000400
393#define chipMinorFeatures8_TX_INTEGER_COORDINATE_V2 0x00000800
394#define chipMinorFeatures8_MULTI_CORE_BLOCK_SET_CONFIG 0x00001000
395#define chipMinorFeatures8_VG_RESOLVE_ENGINE 0x00002000
396#define chipMinorFeatures8_VG_PE_COLOR_KEY 0x00004000
397#define chipMinorFeatures8_VG_IM_INDEX_FORMAT 0x00008000
398#define chipMinorFeatures8_SNAPPAGE_CMD 0x00010000
399#define chipMinorFeatures8_SH_NO_INDEX_CONST_ON_A0 0x00020000
400#define chipMinorFeatures8_SH_NO_ONECONST_LIMIT 0x00040000
401#define chipMinorFeatures8_SH_IMG_LDST_ON_TEMP 0x00080000
402#define chipMinorFeatures8_COMPUTE_ONLY 0x00100000
403#define chipMinorFeatures8_SH_IMG_LDST_CLAMP 0x00200000
404#define chipMinorFeatures8_SH_ICACHE_ALLOC_COUNT_FIX 0x00400000
405#define chipMinorFeatures8_SH_ICACHE_PREFETCH 0x00800000
406#define chipMinorFeatures8_PE2D_SEPARATE_CACHE 0x01000000
407#define chipMinorFeatures8_VG_AYUV_INPUT_OUTPUT 0x02000000
408#define chipMinorFeatures8_VG_DOUBLE_IMAGE 0x04000000
409#define chipMinorFeatures8_VG_RECTANGLE_STRIPE_MODE 0x08000000
410#define chipMinorFeatures8_VG_MMU 0x10000000
411#define chipMinorFeatures8_VG_IM_FILTER 0x20000000
412#define chipMinorFeatures8_VG_IM_YUV_PACKET 0x40000000
413#define chipMinorFeatures8_VG_IM_YUV_PLANAR 0x80000000
414#define chipMinorFeatures9_VG_PE_YUV_PACKET 0x00000001
415#define chipMinorFeatures9_VG_COLOR_PRECISION_8_BIT 0x00000002
416#define chipMinorFeatures9_PE_MSAA_OQ_FIX 0x00000004
417#define chipMinorFeatures9_PSIO_MSAA_CL_FIX 0x00000008
418#define chipMinorFeatures9_USC_DEFER_FILL_FIX 0x00000010
419#define chipMinorFeatures9_SH_CLOCK_GATE_FIX 0x00000020
420#define chipMinorFeatures9_FE_NEED_DUMMYDRAW 0x00000040
421#define chipMinorFeatures9_PE2D_LINEAR_YUV420_OUTPUT 0x00000080
422#define chipMinorFeatures9_PE2D_LINEAR_YUV420_10BIT 0x00000100
423#define chipMinorFeatures9_MULTI_CLUSTER 0x00000200
424#define chipMinorFeatures9_VG_TS_CULLING 0x00000400
425#define chipMinorFeatures9_VG_FP25 0x00000800
426#define chipMinorFeatures9_SH_MULTI_WG_PACK 0x00001000
427#define chipMinorFeatures9_SH_DUAL16_SAMPLEMASK_ZW 0x00002000
428#define chipMinorFeatures9_TPG_TRIVIAL_MODE_FIX 0x00004000
429#define chipMinorFeatures9_TX_ASTC_MULTISLICE_FIX 0x00008000
430#define chipMinorFeatures9_FE_ROBUST_FIX 0x00010000
431#define chipMinorFeatures9_SH_GPIPE_ACCESS_FULLTEMPS 0x00020000
432#define chipMinorFeatures9_PSIO_INTERLOCK 0x00040000
433#define chipMinorFeatures9_PA_WIDELINE_FIX 0x00080000
434#define chipMinorFeatures9_WIDELINE_HELPER_FIX 0x00100000
435#define chipMinorFeatures9_G2D_3RD_PARTY_COMPRESSION_1_1 0x00200000
436#define chipMinorFeatures9_TX_FLUSH_L1CACHE 0x00400000
437#define chipMinorFeatures9_PE_DITHER_FIX2 0x00800000
438#define chipMinorFeatures9_G2D_DEC400 0x01000000
439#define chipMinorFeatures9_SH_TEXLD_U_FIX 0x02000000
440#define chipMinorFeatures9_MC_FCCACHE_BYTEMASK 0x04000000
441#define chipMinorFeatures9_SH_MULTI_WG_PACK_FIX 0x08000000
442#define chipMinorFeatures9_DC_OVERLAY_SCALING 0x10000000
443#define chipMinorFeatures9_DC_SOURCE_ROTATION 0x20000000
444#define chipMinorFeatures9_DC_TILED 0x40000000
445#define chipMinorFeatures9_DC_YUV_L1 0x80000000
446#define chipMinorFeatures10_DC_D30_OUTPUT 0x00000001
447#define chipMinorFeatures10_DC_MMU 0x00000002
448#define chipMinorFeatures10_DC_COMPRESSION 0x00000004
449#define chipMinorFeatures10_DC_QOS 0x00000008
450#define chipMinorFeatures10_PE_ADVANCE_BLEND_PART0 0x00000010
451#define chipMinorFeatures10_FE_PATCHLIST_FETCH_FIX 0x00000020
452#define chipMinorFeatures10_RA_CG_FIX 0x00000040
453#define chipMinorFeatures10_EVIS_VX2 0x00000080
454#define chipMinorFeatures10_NN_FLOAT 0x00000100
455#define chipMinorFeatures10_DEC400 0x00000200
456#define chipMinorFeatures10_LS_SUPPORT_PERCOMP_DEPENDENCY 0x00000400
457#define chipMinorFeatures10_TP_ENGINE 0x00000800
458#define chipMinorFeatures10_MULTI_CORE_BLOCK_SET_CONFIG2 0x00001000
459#define chipMinorFeatures10_PE_VMSAA_COVERAGE_CACHE_FIX 0x00002000
460#define chipMinorFeatures10_SECURITY_AHB 0x00004000
461#define chipMinorFeatures10_MULTICORE_SEMAPHORESTALL_V3 0x00008000
462#define chipMinorFeatures10_SMALLBATCH 0x00010000
463#define chipMinorFeatures10_SH_CMPLX 0x00020000
464#define chipMinorFeatures10_SH_IDIV0_SWZL_EHS 0x00040000
465#define chipMinorFeatures10_TX_LERP_LESS_BIT 0x00080000
466#define chipMinorFeatures10_SH_GM_ENDIAN 0x00100000
467#define chipMinorFeatures10_SH_GM_USC_UNALLOC 0x00200000
468#define chipMinorFeatures10_SH_END_OF_BB 0x00400000
469#define chipMinorFeatures10_VIP_V7 0x00800000
470#define chipMinorFeatures10_TX_BORDER_CLAMP_FIX 0x01000000
471#define chipMinorFeatures10_SH_IMG_LD_LASTPIXEL_FIX 0x02000000
472#define chipMinorFeatures10_ASYNC_BLT 0x04000000
473#define chipMinorFeatures10_ASYNC_FE_FENCE_FIX 0x08000000
474#define chipMinorFeatures10_PSCS_THROTTLE 0x10000000
475#define chipMinorFeatures10_SEPARATE_LS 0x20000000
476#define chipMinorFeatures10_MCFE 0x40000000
477#define chipMinorFeatures10_WIDELINE_TRIANGLE_EMU 0x80000000
478#define chipMinorFeatures11_VG_RESOLUTION_8K 0x00000001
479#define chipMinorFeatures11_FENCE_32BIT 0x00000002
480#define chipMinorFeatures11_FENCE_64BIT 0x00000004
481#define chipMinorFeatures11_NN_INTERLEVE8 0x00000008
482#define chipMinorFeatures11_TP_REORDER 0x00000010
483#define chipMinorFeatures11_PE_DEPTH_ONLY_OQFIX 0x00000020
319 484
320#endif /* COMMON_XML */ 485#endif /* COMMON_XML */
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
index 99ad2f073c6e..bfc6d4aa3b7c 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
@@ -215,6 +215,24 @@ u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe
215 return buffer->user_size / 8; 215 return buffer->user_size / 8;
216} 216}
217 217
218u16 etnaviv_buffer_config_pta(struct etnaviv_gpu *gpu)
219{
220 struct etnaviv_cmdbuf *buffer = &gpu->buffer;
221
222 lockdep_assert_held(&gpu->lock);
223
224 buffer->user_size = 0;
225
226 CMD_LOAD_STATE(buffer, VIVS_MMUv2_PTA_CONFIG,
227 VIVS_MMUv2_PTA_CONFIG_INDEX(0));
228
229 CMD_END(buffer);
230
231 buffer->user_size = ALIGN(buffer->user_size, 8);
232
233 return buffer->user_size / 8;
234}
235
218void etnaviv_buffer_end(struct etnaviv_gpu *gpu) 236void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
219{ 237{
220 struct etnaviv_cmdbuf *buffer = &gpu->buffer; 238 struct etnaviv_cmdbuf *buffer = &gpu->buffer;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 6faf4042db23..ab50090d066c 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -101,12 +101,25 @@ static void load_gpu(struct drm_device *dev)
101 101
102static int etnaviv_open(struct drm_device *dev, struct drm_file *file) 102static int etnaviv_open(struct drm_device *dev, struct drm_file *file)
103{ 103{
104 struct etnaviv_drm_private *priv = dev->dev_private;
104 struct etnaviv_file_private *ctx; 105 struct etnaviv_file_private *ctx;
106 int i;
105 107
106 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 108 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
107 if (!ctx) 109 if (!ctx)
108 return -ENOMEM; 110 return -ENOMEM;
109 111
112 for (i = 0; i < ETNA_MAX_PIPES; i++) {
113 struct etnaviv_gpu *gpu = priv->gpu[i];
114
115 if (gpu) {
116 drm_sched_entity_init(&gpu->sched,
117 &ctx->sched_entity[i],
118 &gpu->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL],
119 32, NULL);
120 }
121 }
122
110 file->driver_priv = ctx; 123 file->driver_priv = ctx;
111 124
112 return 0; 125 return 0;
@@ -126,6 +139,9 @@ static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file)
126 if (gpu->lastctx == ctx) 139 if (gpu->lastctx == ctx)
127 gpu->lastctx = NULL; 140 gpu->lastctx = NULL;
128 mutex_unlock(&gpu->lock); 141 mutex_unlock(&gpu->lock);
142
143 drm_sched_entity_fini(&gpu->sched,
144 &ctx->sched_entity[i]);
129 } 145 }
130 } 146 }
131 147
@@ -637,25 +653,21 @@ static int compare_str(struct device *dev, void *data)
637static int etnaviv_pdev_probe(struct platform_device *pdev) 653static int etnaviv_pdev_probe(struct platform_device *pdev)
638{ 654{
639 struct device *dev = &pdev->dev; 655 struct device *dev = &pdev->dev;
640 struct device_node *node = dev->of_node;
641 struct component_match *match = NULL; 656 struct component_match *match = NULL;
642 657
643 dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); 658 dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
644 659
645 if (node) { 660 if (!dev->platform_data) {
646 struct device_node *core_node; 661 struct device_node *core_node;
647 int i;
648 662
649 for (i = 0; ; i++) { 663 for_each_compatible_node(core_node, NULL, "vivante,gc") {
650 core_node = of_parse_phandle(node, "cores", i); 664 if (!of_device_is_available(core_node))
651 if (!core_node) 665 continue;
652 break;
653 666
654 drm_of_component_match_add(&pdev->dev, &match, 667 drm_of_component_match_add(&pdev->dev, &match,
655 compare_of, core_node); 668 compare_of, core_node);
656 of_node_put(core_node);
657 } 669 }
658 } else if (dev->platform_data) { 670 } else {
659 char **names = dev->platform_data; 671 char **names = dev->platform_data;
660 unsigned i; 672 unsigned i;
661 673
@@ -673,25 +685,18 @@ static int etnaviv_pdev_remove(struct platform_device *pdev)
673 return 0; 685 return 0;
674} 686}
675 687
676static const struct of_device_id dt_match[] = {
677 { .compatible = "fsl,imx-gpu-subsystem" },
678 { .compatible = "marvell,dove-gpu-subsystem" },
679 {}
680};
681MODULE_DEVICE_TABLE(of, dt_match);
682
683static struct platform_driver etnaviv_platform_driver = { 688static struct platform_driver etnaviv_platform_driver = {
684 .probe = etnaviv_pdev_probe, 689 .probe = etnaviv_pdev_probe,
685 .remove = etnaviv_pdev_remove, 690 .remove = etnaviv_pdev_remove,
686 .driver = { 691 .driver = {
687 .name = "etnaviv", 692 .name = "etnaviv",
688 .of_match_table = dt_match,
689 }, 693 },
690}; 694};
691 695
692static int __init etnaviv_init(void) 696static int __init etnaviv_init(void)
693{ 697{
694 int ret; 698 int ret;
699 struct device_node *np;
695 700
696 etnaviv_validate_init(); 701 etnaviv_validate_init();
697 702
@@ -703,6 +708,19 @@ static int __init etnaviv_init(void)
703 if (ret != 0) 708 if (ret != 0)
704 platform_driver_unregister(&etnaviv_gpu_driver); 709 platform_driver_unregister(&etnaviv_gpu_driver);
705 710
711 /*
712 * If the DT contains at least one available GPU device, instantiate
713 * the DRM platform device.
714 */
715 for_each_compatible_node(np, NULL, "vivante,gc") {
716 if (!of_device_is_available(np))
717 continue;
718
719 platform_device_register_simple("etnaviv", -1, NULL, 0);
720 of_node_put(np);
721 break;
722 }
723
706 return ret; 724 return ret;
707} 725}
708module_init(etnaviv_init); 726module_init(etnaviv_init);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index a54f0b758a5c..ddb17ee565e9 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -34,6 +34,7 @@
34#include <drm/drm_fb_helper.h> 34#include <drm/drm_fb_helper.h>
35#include <drm/drm_gem.h> 35#include <drm/drm_gem.h>
36#include <drm/etnaviv_drm.h> 36#include <drm/etnaviv_drm.h>
37#include <drm/gpu_scheduler.h>
37 38
38struct etnaviv_cmdbuf; 39struct etnaviv_cmdbuf;
39struct etnaviv_gpu; 40struct etnaviv_gpu;
@@ -42,11 +43,11 @@ struct etnaviv_gem_object;
42struct etnaviv_gem_submit; 43struct etnaviv_gem_submit;
43 44
44struct etnaviv_file_private { 45struct etnaviv_file_private {
45 /* currently we don't do anything useful with this.. but when 46 /*
46 * per-context address spaces are supported we'd keep track of 47 * When per-context address spaces are supported we'd keep track of
47 * the context's page-tables here. 48 * the context's page-tables here.
48 */ 49 */
49 int dummy; 50 struct drm_sched_entity sched_entity[ETNA_MAX_PIPES];
50}; 51};
51 52
52struct etnaviv_drm_private { 53struct etnaviv_drm_private {
@@ -85,6 +86,7 @@ int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file,
85 uintptr_t ptr, u32 size, u32 flags, u32 *handle); 86 uintptr_t ptr, u32 size, u32 flags, u32 *handle);
86u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu); 87u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu);
87u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr); 88u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr);
89u16 etnaviv_buffer_config_pta(struct etnaviv_gpu *gpu);
88void etnaviv_buffer_end(struct etnaviv_gpu *gpu); 90void etnaviv_buffer_end(struct etnaviv_gpu *gpu);
89void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event); 91void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event);
90void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, 92void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
index 6d0909c589d1..48aef6cf6a42 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
@@ -20,9 +20,13 @@
20#include "etnaviv_gem.h" 20#include "etnaviv_gem.h"
21#include "etnaviv_gpu.h" 21#include "etnaviv_gpu.h"
22#include "etnaviv_mmu.h" 22#include "etnaviv_mmu.h"
23#include "etnaviv_sched.h"
23#include "state.xml.h" 24#include "state.xml.h"
24#include "state_hi.xml.h" 25#include "state_hi.xml.h"
25 26
27static bool etnaviv_dump_core = true;
28module_param_named(dump_core, etnaviv_dump_core, bool, 0600);
29
26struct core_dump_iterator { 30struct core_dump_iterator {
27 void *start; 31 void *start;
28 struct etnaviv_dump_object_header *hdr; 32 struct etnaviv_dump_object_header *hdr;
@@ -121,10 +125,16 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
121 struct etnaviv_vram_mapping *vram; 125 struct etnaviv_vram_mapping *vram;
122 struct etnaviv_gem_object *obj; 126 struct etnaviv_gem_object *obj;
123 struct etnaviv_gem_submit *submit; 127 struct etnaviv_gem_submit *submit;
128 struct drm_sched_job *s_job;
124 unsigned int n_obj, n_bomap_pages; 129 unsigned int n_obj, n_bomap_pages;
125 size_t file_size, mmu_size; 130 size_t file_size, mmu_size;
126 __le64 *bomap, *bomap_start; 131 __le64 *bomap, *bomap_start;
127 132
133 /* Only catch the first event, or when manually re-armed */
134 if (!etnaviv_dump_core)
135 return;
136 etnaviv_dump_core = false;
137
128 mmu_size = etnaviv_iommu_dump_size(gpu->mmu); 138 mmu_size = etnaviv_iommu_dump_size(gpu->mmu);
129 139
130 /* We always dump registers, mmu, ring and end marker */ 140 /* We always dump registers, mmu, ring and end marker */
@@ -135,10 +145,13 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
135 mmu_size + gpu->buffer.size; 145 mmu_size + gpu->buffer.size;
136 146
137 /* Add in the active command buffers */ 147 /* Add in the active command buffers */
138 list_for_each_entry(submit, &gpu->active_submit_list, node) { 148 spin_lock(&gpu->sched.job_list_lock);
149 list_for_each_entry(s_job, &gpu->sched.ring_mirror_list, node) {
150 submit = to_etnaviv_submit(s_job);
139 file_size += submit->cmdbuf.size; 151 file_size += submit->cmdbuf.size;
140 n_obj++; 152 n_obj++;
141 } 153 }
154 spin_unlock(&gpu->sched.job_list_lock);
142 155
143 /* Add in the active buffer objects */ 156 /* Add in the active buffer objects */
144 list_for_each_entry(vram, &gpu->mmu->mappings, mmu_node) { 157 list_for_each_entry(vram, &gpu->mmu->mappings, mmu_node) {
@@ -180,10 +193,14 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
180 gpu->buffer.size, 193 gpu->buffer.size,
181 etnaviv_cmdbuf_get_va(&gpu->buffer)); 194 etnaviv_cmdbuf_get_va(&gpu->buffer));
182 195
183 list_for_each_entry(submit, &gpu->active_submit_list, node) 196 spin_lock(&gpu->sched.job_list_lock);
197 list_for_each_entry(s_job, &gpu->sched.ring_mirror_list, node) {
198 submit = to_etnaviv_submit(s_job);
184 etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD, 199 etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD,
185 submit->cmdbuf.vaddr, submit->cmdbuf.size, 200 submit->cmdbuf.vaddr, submit->cmdbuf.size,
186 etnaviv_cmdbuf_get_va(&submit->cmdbuf)); 201 etnaviv_cmdbuf_get_va(&submit->cmdbuf));
202 }
203 spin_unlock(&gpu->sched.job_list_lock);
187 204
188 /* Reserve space for the bomap */ 205 /* Reserve space for the bomap */
189 if (n_bomap_pages) { 206 if (n_bomap_pages) {
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h
index be72a9833f2b..93e696fcc14f 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h
@@ -94,6 +94,9 @@ struct etnaviv_gem_submit_bo {
94 u32 flags; 94 u32 flags;
95 struct etnaviv_gem_object *obj; 95 struct etnaviv_gem_object *obj;
96 struct etnaviv_vram_mapping *mapping; 96 struct etnaviv_vram_mapping *mapping;
97 struct dma_fence *excl;
98 unsigned int nr_shared;
99 struct dma_fence **shared;
97}; 100};
98 101
99/* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, 102/* Created per submit-ioctl, to track bo's and cmdstream bufs, etc,
@@ -101,9 +104,11 @@ struct etnaviv_gem_submit_bo {
101 * make it easier to unwind when things go wrong, etc). 104 * make it easier to unwind when things go wrong, etc).
102 */ 105 */
103struct etnaviv_gem_submit { 106struct etnaviv_gem_submit {
107 struct drm_sched_job sched_job;
104 struct kref refcount; 108 struct kref refcount;
105 struct etnaviv_gpu *gpu; 109 struct etnaviv_gpu *gpu;
106 struct dma_fence *out_fence, *in_fence; 110 struct dma_fence *out_fence, *in_fence;
111 int out_fence_id;
107 struct list_head node; /* GPU active submit list */ 112 struct list_head node; /* GPU active submit list */
108 struct etnaviv_cmdbuf cmdbuf; 113 struct etnaviv_cmdbuf cmdbuf;
109 bool runtime_resumed; 114 bool runtime_resumed;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 1f8202bca061..46ecd3e66ac9 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -22,6 +22,7 @@
22#include "etnaviv_gpu.h" 22#include "etnaviv_gpu.h"
23#include "etnaviv_gem.h" 23#include "etnaviv_gem.h"
24#include "etnaviv_perfmon.h" 24#include "etnaviv_perfmon.h"
25#include "etnaviv_sched.h"
25 26
26/* 27/*
27 * Cmdstream submission: 28 * Cmdstream submission:
@@ -169,29 +170,33 @@ fail:
169 return ret; 170 return ret;
170} 171}
171 172
172static int submit_fence_sync(const struct etnaviv_gem_submit *submit) 173static int submit_fence_sync(struct etnaviv_gem_submit *submit)
173{ 174{
174 unsigned int context = submit->gpu->fence_context;
175 int i, ret = 0; 175 int i, ret = 0;
176 176
177 for (i = 0; i < submit->nr_bos; i++) { 177 for (i = 0; i < submit->nr_bos; i++) {
178 struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj; 178 struct etnaviv_gem_submit_bo *bo = &submit->bos[i];
179 bool write = submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE; 179 struct reservation_object *robj = bo->obj->resv;
180 bool explicit = !!(submit->flags & ETNA_SUBMIT_NO_IMPLICIT);
181 180
182 ret = etnaviv_gpu_fence_sync_obj(etnaviv_obj, context, write, 181 if (!(bo->flags & ETNA_SUBMIT_BO_WRITE)) {
183 explicit); 182 ret = reservation_object_reserve_shared(robj);
184 if (ret) 183 if (ret)
185 break; 184 return ret;
186 } 185 }
186
187 if (submit->flags & ETNA_SUBMIT_NO_IMPLICIT)
188 continue;
189
190 if (bo->flags & ETNA_SUBMIT_BO_WRITE) {
191 ret = reservation_object_get_fences_rcu(robj, &bo->excl,
192 &bo->nr_shared,
193 &bo->shared);
194 if (ret)
195 return ret;
196 } else {
197 bo->excl = reservation_object_get_excl_rcu(robj);
198 }
187 199
188 if (submit->flags & ETNA_SUBMIT_FENCE_FD_IN) {
189 /*
190 * Wait if the fence is from a foreign context, or if the fence
191 * array contains any fence from a foreign context.
192 */
193 if (!dma_fence_match_context(submit->in_fence, context))
194 ret = dma_fence_wait(submit->in_fence, true);
195 } 200 }
196 201
197 return ret; 202 return ret;
@@ -381,8 +386,13 @@ static void submit_cleanup(struct kref *kref)
381 386
382 if (submit->in_fence) 387 if (submit->in_fence)
383 dma_fence_put(submit->in_fence); 388 dma_fence_put(submit->in_fence);
384 if (submit->out_fence) 389 if (submit->out_fence) {
390 /* first remove from IDR, so fence can not be found anymore */
391 mutex_lock(&submit->gpu->fence_idr_lock);
392 idr_remove(&submit->gpu->fence_idr, submit->out_fence_id);
393 mutex_unlock(&submit->gpu->fence_idr_lock);
385 dma_fence_put(submit->out_fence); 394 dma_fence_put(submit->out_fence);
395 }
386 kfree(submit->pmrs); 396 kfree(submit->pmrs);
387 kfree(submit); 397 kfree(submit);
388} 398}
@@ -395,6 +405,7 @@ void etnaviv_submit_put(struct etnaviv_gem_submit *submit)
395int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, 405int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
396 struct drm_file *file) 406 struct drm_file *file)
397{ 407{
408 struct etnaviv_file_private *ctx = file->driver_priv;
398 struct etnaviv_drm_private *priv = dev->dev_private; 409 struct etnaviv_drm_private *priv = dev->dev_private;
399 struct drm_etnaviv_gem_submit *args = data; 410 struct drm_etnaviv_gem_submit *args = data;
400 struct drm_etnaviv_gem_submit_reloc *relocs; 411 struct drm_etnaviv_gem_submit_reloc *relocs;
@@ -503,10 +514,6 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
503 if (ret) 514 if (ret)
504 goto err_submit_objects; 515 goto err_submit_objects;
505 516
506 ret = submit_lock_objects(submit, &ticket);
507 if (ret)
508 goto err_submit_objects;
509
510 if (!etnaviv_cmd_validate_one(gpu, stream, args->stream_size / 4, 517 if (!etnaviv_cmd_validate_one(gpu, stream, args->stream_size / 4,
511 relocs, args->nr_relocs)) { 518 relocs, args->nr_relocs)) {
512 ret = -EINVAL; 519 ret = -EINVAL;
@@ -521,10 +528,6 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
521 } 528 }
522 } 529 }
523 530
524 ret = submit_fence_sync(submit);
525 if (ret)
526 goto err_submit_objects;
527
528 ret = submit_pin_objects(submit); 531 ret = submit_pin_objects(submit);
529 if (ret) 532 if (ret)
530 goto err_submit_objects; 533 goto err_submit_objects;
@@ -539,9 +542,16 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
539 goto err_submit_objects; 542 goto err_submit_objects;
540 543
541 memcpy(submit->cmdbuf.vaddr, stream, args->stream_size); 544 memcpy(submit->cmdbuf.vaddr, stream, args->stream_size);
542 submit->cmdbuf.user_size = ALIGN(args->stream_size, 8);
543 545
544 ret = etnaviv_gpu_submit(gpu, submit); 546 ret = submit_lock_objects(submit, &ticket);
547 if (ret)
548 goto err_submit_objects;
549
550 ret = submit_fence_sync(submit);
551 if (ret)
552 goto err_submit_objects;
553
554 ret = etnaviv_sched_push_job(&ctx->sched_entity[args->pipe], submit);
545 if (ret) 555 if (ret)
546 goto err_submit_objects; 556 goto err_submit_objects;
547 557
@@ -563,7 +573,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
563 } 573 }
564 574
565 args->fence_fd = out_fence_fd; 575 args->fence_fd = out_fence_fd;
566 args->fence = submit->out_fence->seqno; 576 args->fence = submit->out_fence_id;
567 577
568err_submit_objects: 578err_submit_objects:
569 etnaviv_submit_put(submit); 579 etnaviv_submit_put(submit);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 21d0d22f1168..8a88799bf79b 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -26,19 +26,21 @@
26#include "etnaviv_gem.h" 26#include "etnaviv_gem.h"
27#include "etnaviv_mmu.h" 27#include "etnaviv_mmu.h"
28#include "etnaviv_perfmon.h" 28#include "etnaviv_perfmon.h"
29#include "etnaviv_sched.h"
29#include "common.xml.h" 30#include "common.xml.h"
30#include "state.xml.h" 31#include "state.xml.h"
31#include "state_hi.xml.h" 32#include "state_hi.xml.h"
32#include "cmdstream.xml.h" 33#include "cmdstream.xml.h"
33 34
35#ifndef PHYS_OFFSET
36#define PHYS_OFFSET 0
37#endif
38
34static const struct platform_device_id gpu_ids[] = { 39static const struct platform_device_id gpu_ids[] = {
35 { .name = "etnaviv-gpu,2d" }, 40 { .name = "etnaviv-gpu,2d" },
36 { }, 41 { },
37}; 42};
38 43
39static bool etnaviv_dump_core = true;
40module_param_named(dump_core, etnaviv_dump_core, bool, 0600);
41
42/* 44/*
43 * Driver functions: 45 * Driver functions:
44 */ 46 */
@@ -82,6 +84,30 @@ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value)
82 *value = gpu->identity.minor_features5; 84 *value = gpu->identity.minor_features5;
83 break; 85 break;
84 86
87 case ETNAVIV_PARAM_GPU_FEATURES_7:
88 *value = gpu->identity.minor_features6;
89 break;
90
91 case ETNAVIV_PARAM_GPU_FEATURES_8:
92 *value = gpu->identity.minor_features7;
93 break;
94
95 case ETNAVIV_PARAM_GPU_FEATURES_9:
96 *value = gpu->identity.minor_features8;
97 break;
98
99 case ETNAVIV_PARAM_GPU_FEATURES_10:
100 *value = gpu->identity.minor_features9;
101 break;
102
103 case ETNAVIV_PARAM_GPU_FEATURES_11:
104 *value = gpu->identity.minor_features10;
105 break;
106
107 case ETNAVIV_PARAM_GPU_FEATURES_12:
108 *value = gpu->identity.minor_features11;
109 break;
110
85 case ETNAVIV_PARAM_GPU_STREAM_COUNT: 111 case ETNAVIV_PARAM_GPU_STREAM_COUNT:
86 *value = gpu->identity.stream_count; 112 *value = gpu->identity.stream_count;
87 break; 113 break;
@@ -348,6 +374,13 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
348 dev_info(gpu->dev, "model: GC%x, revision: %x\n", 374 dev_info(gpu->dev, "model: GC%x, revision: %x\n",
349 gpu->identity.model, gpu->identity.revision); 375 gpu->identity.model, gpu->identity.revision);
350 376
377 /*
378 * If there is a match in the HWDB, we aren't interested in the
379 * remaining register values, as they might be wrong.
380 */
381 if (etnaviv_fill_identity_from_hwdb(gpu))
382 return;
383
351 gpu->identity.features = gpu_read(gpu, VIVS_HI_CHIP_FEATURE); 384 gpu->identity.features = gpu_read(gpu, VIVS_HI_CHIP_FEATURE);
352 385
353 /* Disable fast clear on GC700. */ 386 /* Disable fast clear on GC700. */
@@ -448,9 +481,14 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
448 control |= VIVS_HI_CLOCK_CONTROL_ISOLATE_GPU; 481 control |= VIVS_HI_CLOCK_CONTROL_ISOLATE_GPU;
449 gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control); 482 gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
450 483
451 /* set soft reset. */ 484 if (gpu->sec_mode == ETNA_SEC_KERNEL) {
452 control |= VIVS_HI_CLOCK_CONTROL_SOFT_RESET; 485 gpu_write(gpu, VIVS_MMUv2_AHB_CONTROL,
453 gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control); 486 VIVS_MMUv2_AHB_CONTROL_RESET);
487 } else {
488 /* set soft reset. */
489 control |= VIVS_HI_CLOCK_CONTROL_SOFT_RESET;
490 gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
491 }
454 492
455 /* wait for reset. */ 493 /* wait for reset. */
456 usleep_range(10, 20); 494 usleep_range(10, 20);
@@ -561,6 +599,12 @@ void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
561 gpu_write(gpu, VIVS_FE_COMMAND_CONTROL, 599 gpu_write(gpu, VIVS_FE_COMMAND_CONTROL,
562 VIVS_FE_COMMAND_CONTROL_ENABLE | 600 VIVS_FE_COMMAND_CONTROL_ENABLE |
563 VIVS_FE_COMMAND_CONTROL_PREFETCH(prefetch)); 601 VIVS_FE_COMMAND_CONTROL_PREFETCH(prefetch));
602
603 if (gpu->sec_mode == ETNA_SEC_KERNEL) {
604 gpu_write(gpu, VIVS_MMUv2_SEC_COMMAND_CONTROL,
605 VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE |
606 VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(prefetch));
607 }
564} 608}
565 609
566static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu) 610static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu)
@@ -634,6 +678,12 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
634 gpu_write(gpu, VIVS_MC_BUS_CONFIG, bus_config); 678 gpu_write(gpu, VIVS_MC_BUS_CONFIG, bus_config);
635 } 679 }
636 680
681 if (gpu->sec_mode == ETNA_SEC_KERNEL) {
682 u32 val = gpu_read(gpu, VIVS_MMUv2_AHB_CONTROL);
683 val |= VIVS_MMUv2_AHB_CONTROL_NONSEC_ACCESS;
684 gpu_write(gpu, VIVS_MMUv2_AHB_CONTROL, val);
685 }
686
637 /* setup the pulse eater */ 687 /* setup the pulse eater */
638 etnaviv_gpu_setup_pulse_eater(gpu); 688 etnaviv_gpu_setup_pulse_eater(gpu);
639 689
@@ -696,6 +746,14 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
696 gpu->identity.features &= ~chipFeatures_FAST_CLEAR; 746 gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
697 } 747 }
698 748
749 /*
750 * On cores with security features supported, we claim control over the
751 * security states.
752 */
753 if ((gpu->identity.minor_features7 & chipMinorFeatures7_BIT_SECURITY) &&
754 (gpu->identity.minor_features10 & chipMinorFeatures10_SECURITY_AHB))
755 gpu->sec_mode = ETNA_SEC_KERNEL;
756
699 ret = etnaviv_hw_reset(gpu); 757 ret = etnaviv_hw_reset(gpu);
700 if (ret) { 758 if (ret) {
701 dev_err(gpu->dev, "GPU reset failed\n"); 759 dev_err(gpu->dev, "GPU reset failed\n");
@@ -807,6 +865,8 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
807 verify_dma(gpu, &debug); 865 verify_dma(gpu, &debug);
808 866
809 seq_puts(m, "\tfeatures\n"); 867 seq_puts(m, "\tfeatures\n");
868 seq_printf(m, "\t major_features: 0x%08x\n",
869 gpu->identity.features);
810 seq_printf(m, "\t minor_features0: 0x%08x\n", 870 seq_printf(m, "\t minor_features0: 0x%08x\n",
811 gpu->identity.minor_features0); 871 gpu->identity.minor_features0);
812 seq_printf(m, "\t minor_features1: 0x%08x\n", 872 seq_printf(m, "\t minor_features1: 0x%08x\n",
@@ -819,6 +879,18 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
819 gpu->identity.minor_features4); 879 gpu->identity.minor_features4);
820 seq_printf(m, "\t minor_features5: 0x%08x\n", 880 seq_printf(m, "\t minor_features5: 0x%08x\n",
821 gpu->identity.minor_features5); 881 gpu->identity.minor_features5);
882 seq_printf(m, "\t minor_features6: 0x%08x\n",
883 gpu->identity.minor_features6);
884 seq_printf(m, "\t minor_features7: 0x%08x\n",
885 gpu->identity.minor_features7);
886 seq_printf(m, "\t minor_features8: 0x%08x\n",
887 gpu->identity.minor_features8);
888 seq_printf(m, "\t minor_features9: 0x%08x\n",
889 gpu->identity.minor_features9);
890 seq_printf(m, "\t minor_features10: 0x%08x\n",
891 gpu->identity.minor_features10);
892 seq_printf(m, "\t minor_features11: 0x%08x\n",
893 gpu->identity.minor_features11);
822 894
823 seq_puts(m, "\tspecs\n"); 895 seq_puts(m, "\tspecs\n");
824 seq_printf(m, "\t stream_count: %d\n", 896 seq_printf(m, "\t stream_count: %d\n",
@@ -912,38 +984,24 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
912} 984}
913#endif 985#endif
914 986
915/* 987void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
916 * Hangcheck detection for locked gpu:
917 */
918static void recover_worker(struct work_struct *work)
919{ 988{
920 struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu,
921 recover_work);
922 unsigned long flags; 989 unsigned long flags;
923 unsigned int i = 0; 990 unsigned int i = 0;
924 991
925 dev_err(gpu->dev, "hangcheck recover!\n"); 992 dev_err(gpu->dev, "recover hung GPU!\n");
926 993
927 if (pm_runtime_get_sync(gpu->dev) < 0) 994 if (pm_runtime_get_sync(gpu->dev) < 0)
928 return; 995 return;
929 996
930 mutex_lock(&gpu->lock); 997 mutex_lock(&gpu->lock);
931 998
932 /* Only catch the first event, or when manually re-armed */
933 if (etnaviv_dump_core) {
934 etnaviv_core_dump(gpu);
935 etnaviv_dump_core = false;
936 }
937
938 etnaviv_hw_reset(gpu); 999 etnaviv_hw_reset(gpu);
939 1000
940 /* complete all events, the GPU won't do it after the reset */ 1001 /* complete all events, the GPU won't do it after the reset */
941 spin_lock_irqsave(&gpu->event_spinlock, flags); 1002 spin_lock_irqsave(&gpu->event_spinlock, flags);
942 for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS) { 1003 for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS)
943 dma_fence_signal(gpu->event[i].fence);
944 gpu->event[i].fence = NULL;
945 complete(&gpu->event_free); 1004 complete(&gpu->event_free);
946 }
947 bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS); 1005 bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS);
948 spin_unlock_irqrestore(&gpu->event_spinlock, flags); 1006 spin_unlock_irqrestore(&gpu->event_spinlock, flags);
949 gpu->completed_fence = gpu->active_fence; 1007 gpu->completed_fence = gpu->active_fence;
@@ -955,56 +1013,6 @@ static void recover_worker(struct work_struct *work)
955 mutex_unlock(&gpu->lock); 1013 mutex_unlock(&gpu->lock);
956 pm_runtime_mark_last_busy(gpu->dev); 1014 pm_runtime_mark_last_busy(gpu->dev);
957 pm_runtime_put_autosuspend(gpu->dev); 1015 pm_runtime_put_autosuspend(gpu->dev);
958
959 /* Retire the buffer objects in a work */
960 queue_work(gpu->wq, &gpu->retire_work);
961}
962
963static void hangcheck_timer_reset(struct etnaviv_gpu *gpu)
964{
965 DBG("%s", dev_name(gpu->dev));
966 mod_timer(&gpu->hangcheck_timer,
967 round_jiffies_up(jiffies + DRM_ETNAVIV_HANGCHECK_JIFFIES));
968}
969
970static void hangcheck_handler(struct timer_list *t)
971{
972 struct etnaviv_gpu *gpu = from_timer(gpu, t, hangcheck_timer);
973 u32 fence = gpu->completed_fence;
974 bool progress = false;
975
976 if (fence != gpu->hangcheck_fence) {
977 gpu->hangcheck_fence = fence;
978 progress = true;
979 }
980
981 if (!progress) {
982 u32 dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS);
983 int change = dma_addr - gpu->hangcheck_dma_addr;
984
985 if (change < 0 || change > 16) {
986 gpu->hangcheck_dma_addr = dma_addr;
987 progress = true;
988 }
989 }
990
991 if (!progress && fence_after(gpu->active_fence, fence)) {
992 dev_err(gpu->dev, "hangcheck detected gpu lockup!\n");
993 dev_err(gpu->dev, " completed fence: %u\n", fence);
994 dev_err(gpu->dev, " active fence: %u\n",
995 gpu->active_fence);
996 queue_work(gpu->wq, &gpu->recover_work);
997 }
998
999 /* if still more pending work, reset the hangcheck timer: */
1000 if (fence_after(gpu->active_fence, gpu->hangcheck_fence))
1001 hangcheck_timer_reset(gpu);
1002}
1003
1004static void hangcheck_disable(struct etnaviv_gpu *gpu)
1005{
1006 del_timer_sync(&gpu->hangcheck_timer);
1007 cancel_work_sync(&gpu->recover_work);
1008} 1016}
1009 1017
1010/* fence object management */ 1018/* fence object management */
@@ -1080,54 +1088,6 @@ static struct dma_fence *etnaviv_gpu_fence_alloc(struct etnaviv_gpu *gpu)
1080 return &f->base; 1088 return &f->base;
1081} 1089}
1082 1090
1083int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj,
1084 unsigned int context, bool exclusive, bool explicit)
1085{
1086 struct reservation_object *robj = etnaviv_obj->resv;
1087 struct reservation_object_list *fobj;
1088 struct dma_fence *fence;
1089 int i, ret;
1090
1091 if (!exclusive) {
1092 ret = reservation_object_reserve_shared(robj);
1093 if (ret)
1094 return ret;
1095 }
1096
1097 if (explicit)
1098 return 0;
1099
1100 /*
1101 * If we have any shared fences, then the exclusive fence
1102 * should be ignored as it will already have been signalled.
1103 */
1104 fobj = reservation_object_get_list(robj);
1105 if (!fobj || fobj->shared_count == 0) {
1106 /* Wait on any existing exclusive fence which isn't our own */
1107 fence = reservation_object_get_excl(robj);
1108 if (fence && fence->context != context) {
1109 ret = dma_fence_wait(fence, true);
1110 if (ret)
1111 return ret;
1112 }
1113 }
1114
1115 if (!exclusive || !fobj)
1116 return 0;
1117
1118 for (i = 0; i < fobj->shared_count; i++) {
1119 fence = rcu_dereference_protected(fobj->shared[i],
1120 reservation_object_held(robj));
1121 if (fence->context != context) {
1122 ret = dma_fence_wait(fence, true);
1123 if (ret)
1124 return ret;
1125 }
1126 }
1127
1128 return 0;
1129}
1130
1131/* 1091/*
1132 * event management: 1092 * event management:
1133 */ 1093 */
@@ -1194,67 +1154,47 @@ static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
1194/* 1154/*
1195 * Cmdstream submission/retirement: 1155 * Cmdstream submission/retirement:
1196 */ 1156 */
1197
1198static void retire_worker(struct work_struct *work)
1199{
1200 struct etnaviv_gpu *gpu = container_of(work, struct etnaviv_gpu,
1201 retire_work);
1202 u32 fence = gpu->completed_fence;
1203 struct etnaviv_gem_submit *submit, *tmp;
1204 LIST_HEAD(retire_list);
1205
1206 mutex_lock(&gpu->lock);
1207 list_for_each_entry_safe(submit, tmp, &gpu->active_submit_list, node) {
1208 if (!dma_fence_is_signaled(submit->out_fence))
1209 break;
1210
1211 list_move(&submit->node, &retire_list);
1212 }
1213
1214 gpu->retired_fence = fence;
1215
1216 mutex_unlock(&gpu->lock);
1217
1218 list_for_each_entry_safe(submit, tmp, &retire_list, node)
1219 etnaviv_submit_put(submit);
1220}
1221
1222int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu, 1157int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu,
1223 u32 fence, struct timespec *timeout) 1158 u32 id, struct timespec *timeout)
1224{ 1159{
1160 struct dma_fence *fence;
1225 int ret; 1161 int ret;
1226 1162
1227 if (fence_after(fence, gpu->next_fence)) { 1163 /*
1228 DRM_ERROR("waiting on invalid fence: %u (of %u)\n", 1164 * Look up the fence and take a reference. We might still find a fence
1229 fence, gpu->next_fence); 1165 * whose refcount has already dropped to zero. dma_fence_get_rcu
1230 return -EINVAL; 1166 * pretends we didn't find a fence in that case.
1231 } 1167 */
1168 rcu_read_lock();
1169 fence = idr_find(&gpu->fence_idr, id);
1170 if (fence)
1171 fence = dma_fence_get_rcu(fence);
1172 rcu_read_unlock();
1173
1174 if (!fence)
1175 return 0;
1232 1176
1233 if (!timeout) { 1177 if (!timeout) {
1234 /* No timeout was requested: just test for completion */ 1178 /* No timeout was requested: just test for completion */
1235 ret = fence_completed(gpu, fence) ? 0 : -EBUSY; 1179 ret = dma_fence_is_signaled(fence) ? 0 : -EBUSY;
1236 } else { 1180 } else {
1237 unsigned long remaining = etnaviv_timeout_to_jiffies(timeout); 1181 unsigned long remaining = etnaviv_timeout_to_jiffies(timeout);
1238 1182
1239 ret = wait_event_interruptible_timeout(gpu->fence_event, 1183 ret = dma_fence_wait_timeout(fence, true, remaining);
1240 fence_completed(gpu, fence), 1184 if (ret == 0)
1241 remaining);
1242 if (ret == 0) {
1243 DBG("timeout waiting for fence: %u (retired: %u completed: %u)",
1244 fence, gpu->retired_fence,
1245 gpu->completed_fence);
1246 ret = -ETIMEDOUT; 1185 ret = -ETIMEDOUT;
1247 } else if (ret != -ERESTARTSYS) { 1186 else if (ret != -ERESTARTSYS)
1248 ret = 0; 1187 ret = 0;
1249 } 1188
1250 } 1189 }
1251 1190
1191 dma_fence_put(fence);
1252 return ret; 1192 return ret;
1253} 1193}
1254 1194
1255/* 1195/*
1256 * Wait for an object to become inactive. This, on it's own, is not race 1196 * Wait for an object to become inactive. This, on it's own, is not race
1257 * free: the object is moved by the retire worker off the active list, and 1197 * free: the object is moved by the scheduler off the active list, and
1258 * then the iova is put. Moreover, the object could be re-submitted just 1198 * then the iova is put. Moreover, the object could be re-submitted just
1259 * after we notice that it's become inactive. 1199 * after we notice that it's become inactive.
1260 * 1200 *
@@ -1343,16 +1283,19 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
1343 1283
1344 1284
1345/* add bo's to gpu's ring, and kick gpu: */ 1285/* add bo's to gpu's ring, and kick gpu: */
1346int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, 1286struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit)
1347 struct etnaviv_gem_submit *submit)
1348{ 1287{
1288 struct etnaviv_gpu *gpu = submit->gpu;
1289 struct dma_fence *gpu_fence;
1349 unsigned int i, nr_events = 1, event[3]; 1290 unsigned int i, nr_events = 1, event[3];
1350 int ret; 1291 int ret;
1351 1292
1352 ret = pm_runtime_get_sync(gpu->dev); 1293 if (!submit->runtime_resumed) {
1353 if (ret < 0) 1294 ret = pm_runtime_get_sync(gpu->dev);
1354 return ret; 1295 if (ret < 0)
1355 submit->runtime_resumed = true; 1296 return NULL;
1297 submit->runtime_resumed = true;
1298 }
1356 1299
1357 /* 1300 /*
1358 * if there are performance monitor requests we need to have 1301 * if there are performance monitor requests we need to have
@@ -1367,21 +1310,20 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
1367 ret = event_alloc(gpu, nr_events, event); 1310 ret = event_alloc(gpu, nr_events, event);
1368 if (ret) { 1311 if (ret) {
1369 DRM_ERROR("no free events\n"); 1312 DRM_ERROR("no free events\n");
1370 return ret; 1313 return NULL;
1371 } 1314 }
1372 1315
1373 mutex_lock(&gpu->lock); 1316 mutex_lock(&gpu->lock);
1374 1317
1375 submit->out_fence = etnaviv_gpu_fence_alloc(gpu); 1318 gpu_fence = etnaviv_gpu_fence_alloc(gpu);
1376 if (!submit->out_fence) { 1319 if (!gpu_fence) {
1377 for (i = 0; i < nr_events; i++) 1320 for (i = 0; i < nr_events; i++)
1378 event_free(gpu, event[i]); 1321 event_free(gpu, event[i]);
1379 1322
1380 ret = -ENOMEM;
1381 goto out_unlock; 1323 goto out_unlock;
1382 } 1324 }
1383 1325
1384 gpu->active_fence = submit->out_fence->seqno; 1326 gpu->active_fence = gpu_fence->seqno;
1385 1327
1386 if (submit->nr_pmrs) { 1328 if (submit->nr_pmrs) {
1387 gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre; 1329 gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre;
@@ -1390,8 +1332,8 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
1390 etnaviv_sync_point_queue(gpu, event[1]); 1332 etnaviv_sync_point_queue(gpu, event[1]);
1391 } 1333 }
1392 1334
1393 kref_get(&submit->refcount); 1335 gpu->event[event[0]].fence = gpu_fence;
1394 gpu->event[event[0]].fence = submit->out_fence; 1336 submit->cmdbuf.user_size = submit->cmdbuf.size - 8;
1395 etnaviv_buffer_queue(gpu, submit->exec_state, event[0], 1337 etnaviv_buffer_queue(gpu, submit->exec_state, event[0],
1396 &submit->cmdbuf); 1338 &submit->cmdbuf);
1397 1339
@@ -1402,15 +1344,10 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
1402 etnaviv_sync_point_queue(gpu, event[2]); 1344 etnaviv_sync_point_queue(gpu, event[2]);
1403 } 1345 }
1404 1346
1405 list_add_tail(&submit->node, &gpu->active_submit_list);
1406
1407 hangcheck_timer_reset(gpu);
1408 ret = 0;
1409
1410out_unlock: 1347out_unlock:
1411 mutex_unlock(&gpu->lock); 1348 mutex_unlock(&gpu->lock);
1412 1349
1413 return ret; 1350 return gpu_fence;
1414} 1351}
1415 1352
1416static void sync_point_worker(struct work_struct *work) 1353static void sync_point_worker(struct work_struct *work)
@@ -1428,9 +1365,35 @@ static void sync_point_worker(struct work_struct *work)
1428 etnaviv_gpu_start_fe(gpu, addr + 2, 2); 1365 etnaviv_gpu_start_fe(gpu, addr + 2, 2);
1429} 1366}
1430 1367
1431/* 1368static void dump_mmu_fault(struct etnaviv_gpu *gpu)
1432 * Init/Cleanup: 1369{
1433 */ 1370 u32 status_reg, status;
1371 int i;
1372
1373 if (gpu->sec_mode == ETNA_SEC_NONE)
1374 status_reg = VIVS_MMUv2_STATUS;
1375 else
1376 status_reg = VIVS_MMUv2_SEC_STATUS;
1377
1378 status = gpu_read(gpu, status_reg);
1379 dev_err_ratelimited(gpu->dev, "MMU fault status 0x%08x\n", status);
1380
1381 for (i = 0; i < 4; i++) {
1382 u32 address_reg;
1383
1384 if (!(status & (VIVS_MMUv2_STATUS_EXCEPTION0__MASK << (i * 4))))
1385 continue;
1386
1387 if (gpu->sec_mode == ETNA_SEC_NONE)
1388 address_reg = VIVS_MMUv2_EXCEPTION_ADDR(i);
1389 else
1390 address_reg = VIVS_MMUv2_SEC_EXCEPTION_ADDR;
1391
1392 dev_err_ratelimited(gpu->dev, "MMU %d fault addr 0x%08x\n", i,
1393 gpu_read(gpu, address_reg));
1394 }
1395}
1396
1434static irqreturn_t irq_handler(int irq, void *data) 1397static irqreturn_t irq_handler(int irq, void *data)
1435{ 1398{
1436 struct etnaviv_gpu *gpu = data; 1399 struct etnaviv_gpu *gpu = data;
@@ -1451,17 +1414,7 @@ static irqreturn_t irq_handler(int irq, void *data)
1451 } 1414 }
1452 1415
1453 if (intr & VIVS_HI_INTR_ACKNOWLEDGE_MMU_EXCEPTION) { 1416 if (intr & VIVS_HI_INTR_ACKNOWLEDGE_MMU_EXCEPTION) {
1454 int i; 1417 dump_mmu_fault(gpu);
1455
1456 dev_err_ratelimited(gpu->dev,
1457 "MMU fault status 0x%08x\n",
1458 gpu_read(gpu, VIVS_MMUv2_STATUS));
1459 for (i = 0; i < 4; i++) {
1460 dev_err_ratelimited(gpu->dev,
1461 "MMU %d fault addr 0x%08x\n",
1462 i, gpu_read(gpu,
1463 VIVS_MMUv2_EXCEPTION_ADDR(i)));
1464 }
1465 intr &= ~VIVS_HI_INTR_ACKNOWLEDGE_MMU_EXCEPTION; 1418 intr &= ~VIVS_HI_INTR_ACKNOWLEDGE_MMU_EXCEPTION;
1466 } 1419 }
1467 1420
@@ -1484,7 +1437,6 @@ static irqreturn_t irq_handler(int irq, void *data)
1484 continue; 1437 continue;
1485 1438
1486 gpu->event[event].fence = NULL; 1439 gpu->event[event].fence = NULL;
1487 dma_fence_signal(fence);
1488 1440
1489 /* 1441 /*
1490 * Events can be processed out of order. Eg, 1442 * Events can be processed out of order. Eg,
@@ -1497,13 +1449,11 @@ static irqreturn_t irq_handler(int irq, void *data)
1497 */ 1449 */
1498 if (fence_after(fence->seqno, gpu->completed_fence)) 1450 if (fence_after(fence->seqno, gpu->completed_fence))
1499 gpu->completed_fence = fence->seqno; 1451 gpu->completed_fence = fence->seqno;
1452 dma_fence_signal(fence);
1500 1453
1501 event_free(gpu, event); 1454 event_free(gpu, event);
1502 } 1455 }
1503 1456
1504 /* Retire the buffer objects in a work */
1505 queue_work(gpu->wq, &gpu->retire_work);
1506
1507 ret = IRQ_HANDLED; 1457 ret = IRQ_HANDLED;
1508 } 1458 }
1509 1459
@@ -1514,6 +1464,12 @@ static int etnaviv_gpu_clk_enable(struct etnaviv_gpu *gpu)
1514{ 1464{
1515 int ret; 1465 int ret;
1516 1466
1467 if (gpu->clk_reg) {
1468 ret = clk_prepare_enable(gpu->clk_reg);
1469 if (ret)
1470 return ret;
1471 }
1472
1517 if (gpu->clk_bus) { 1473 if (gpu->clk_bus) {
1518 ret = clk_prepare_enable(gpu->clk_bus); 1474 ret = clk_prepare_enable(gpu->clk_bus);
1519 if (ret) 1475 if (ret)
@@ -1552,6 +1508,8 @@ static int etnaviv_gpu_clk_disable(struct etnaviv_gpu *gpu)
1552 clk_disable_unprepare(gpu->clk_core); 1508 clk_disable_unprepare(gpu->clk_core);
1553 if (gpu->clk_bus) 1509 if (gpu->clk_bus)
1554 clk_disable_unprepare(gpu->clk_bus); 1510 clk_disable_unprepare(gpu->clk_bus);
1511 if (gpu->clk_reg)
1512 clk_disable_unprepare(gpu->clk_reg);
1555 1513
1556 return 0; 1514 return 0;
1557} 1515}
@@ -1675,41 +1633,49 @@ static int etnaviv_gpu_bind(struct device *dev, struct device *master,
1675 1633
1676 gpu->wq = alloc_ordered_workqueue(dev_name(dev), 0); 1634 gpu->wq = alloc_ordered_workqueue(dev_name(dev), 0);
1677 if (!gpu->wq) { 1635 if (!gpu->wq) {
1678 if (IS_ENABLED(CONFIG_DRM_ETNAVIV_THERMAL)) 1636 ret = -ENOMEM;
1679 thermal_cooling_device_unregister(gpu->cooling); 1637 goto out_thermal;
1680 return -ENOMEM;
1681 } 1638 }
1682 1639
1640 ret = etnaviv_sched_init(gpu);
1641 if (ret)
1642 goto out_workqueue;
1643
1683#ifdef CONFIG_PM 1644#ifdef CONFIG_PM
1684 ret = pm_runtime_get_sync(gpu->dev); 1645 ret = pm_runtime_get_sync(gpu->dev);
1685#else 1646#else
1686 ret = etnaviv_gpu_clk_enable(gpu); 1647 ret = etnaviv_gpu_clk_enable(gpu);
1687#endif 1648#endif
1688 if (ret < 0) { 1649 if (ret < 0)
1689 destroy_workqueue(gpu->wq); 1650 goto out_sched;
1690 if (IS_ENABLED(CONFIG_DRM_ETNAVIV_THERMAL)) 1651
1691 thermal_cooling_device_unregister(gpu->cooling);
1692 return ret;
1693 }
1694 1652
1695 gpu->drm = drm; 1653 gpu->drm = drm;
1696 gpu->fence_context = dma_fence_context_alloc(1); 1654 gpu->fence_context = dma_fence_context_alloc(1);
1655 idr_init(&gpu->fence_idr);
1697 spin_lock_init(&gpu->fence_spinlock); 1656 spin_lock_init(&gpu->fence_spinlock);
1698 1657
1699 INIT_LIST_HEAD(&gpu->active_submit_list);
1700 INIT_WORK(&gpu->retire_work, retire_worker);
1701 INIT_WORK(&gpu->sync_point_work, sync_point_worker); 1658 INIT_WORK(&gpu->sync_point_work, sync_point_worker);
1702 INIT_WORK(&gpu->recover_work, recover_worker);
1703 init_waitqueue_head(&gpu->fence_event); 1659 init_waitqueue_head(&gpu->fence_event);
1704 1660
1705 timer_setup(&gpu->hangcheck_timer, hangcheck_handler, TIMER_DEFERRABLE);
1706
1707 priv->gpu[priv->num_gpus++] = gpu; 1661 priv->gpu[priv->num_gpus++] = gpu;
1708 1662
1709 pm_runtime_mark_last_busy(gpu->dev); 1663 pm_runtime_mark_last_busy(gpu->dev);
1710 pm_runtime_put_autosuspend(gpu->dev); 1664 pm_runtime_put_autosuspend(gpu->dev);
1711 1665
1712 return 0; 1666 return 0;
1667
1668out_sched:
1669 etnaviv_sched_fini(gpu);
1670
1671out_workqueue:
1672 destroy_workqueue(gpu->wq);
1673
1674out_thermal:
1675 if (IS_ENABLED(CONFIG_DRM_ETNAVIV_THERMAL))
1676 thermal_cooling_device_unregister(gpu->cooling);
1677
1678 return ret;
1713} 1679}
1714 1680
1715static void etnaviv_gpu_unbind(struct device *dev, struct device *master, 1681static void etnaviv_gpu_unbind(struct device *dev, struct device *master,
@@ -1719,11 +1685,11 @@ static void etnaviv_gpu_unbind(struct device *dev, struct device *master,
1719 1685
1720 DBG("%s", dev_name(gpu->dev)); 1686 DBG("%s", dev_name(gpu->dev));
1721 1687
1722 hangcheck_disable(gpu);
1723
1724 flush_workqueue(gpu->wq); 1688 flush_workqueue(gpu->wq);
1725 destroy_workqueue(gpu->wq); 1689 destroy_workqueue(gpu->wq);
1726 1690
1691 etnaviv_sched_fini(gpu);
1692
1727#ifdef CONFIG_PM 1693#ifdef CONFIG_PM
1728 pm_runtime_get_sync(gpu->dev); 1694 pm_runtime_get_sync(gpu->dev);
1729 pm_runtime_put_sync_suspend(gpu->dev); 1695 pm_runtime_put_sync_suspend(gpu->dev);
@@ -1745,6 +1711,7 @@ static void etnaviv_gpu_unbind(struct device *dev, struct device *master,
1745 } 1711 }
1746 1712
1747 gpu->drm = NULL; 1713 gpu->drm = NULL;
1714 idr_destroy(&gpu->fence_idr);
1748 1715
1749 if (IS_ENABLED(CONFIG_DRM_ETNAVIV_THERMAL)) 1716 if (IS_ENABLED(CONFIG_DRM_ETNAVIV_THERMAL))
1750 thermal_cooling_device_unregister(gpu->cooling); 1717 thermal_cooling_device_unregister(gpu->cooling);
@@ -1762,6 +1729,7 @@ static const struct of_device_id etnaviv_gpu_match[] = {
1762 }, 1729 },
1763 { /* sentinel */ } 1730 { /* sentinel */ }
1764}; 1731};
1732MODULE_DEVICE_TABLE(of, etnaviv_gpu_match);
1765 1733
1766static int etnaviv_gpu_platform_probe(struct platform_device *pdev) 1734static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
1767{ 1735{
@@ -1775,6 +1743,7 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
1775 1743
1776 gpu->dev = &pdev->dev; 1744 gpu->dev = &pdev->dev;
1777 mutex_init(&gpu->lock); 1745 mutex_init(&gpu->lock);
1746 mutex_init(&gpu->fence_idr_lock);
1778 1747
1779 /* Map registers: */ 1748 /* Map registers: */
1780 gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev)); 1749 gpu->mmio = etnaviv_ioremap(pdev, NULL, dev_name(gpu->dev));
@@ -1796,6 +1765,11 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
1796 } 1765 }
1797 1766
1798 /* Get Clocks: */ 1767 /* Get Clocks: */
1768 gpu->clk_reg = devm_clk_get(&pdev->dev, "reg");
1769 DBG("clk_reg: %p", gpu->clk_reg);
1770 if (IS_ERR(gpu->clk_reg))
1771 gpu->clk_reg = NULL;
1772
1799 gpu->clk_bus = devm_clk_get(&pdev->dev, "bus"); 1773 gpu->clk_bus = devm_clk_get(&pdev->dev, "bus");
1800 DBG("clk_bus: %p", gpu->clk_bus); 1774 DBG("clk_bus: %p", gpu->clk_bus);
1801 if (IS_ERR(gpu->clk_bus)) 1775 if (IS_ERR(gpu->clk_bus))
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index 7623905210dc..3c3005501846 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -38,21 +38,17 @@ struct etnaviv_chip_identity {
38 38
39 /* Supported minor feature fields. */ 39 /* Supported minor feature fields. */
40 u32 minor_features0; 40 u32 minor_features0;
41
42 /* Supported minor feature 1 fields. */
43 u32 minor_features1; 41 u32 minor_features1;
44
45 /* Supported minor feature 2 fields. */
46 u32 minor_features2; 42 u32 minor_features2;
47
48 /* Supported minor feature 3 fields. */
49 u32 minor_features3; 43 u32 minor_features3;
50
51 /* Supported minor feature 4 fields. */
52 u32 minor_features4; 44 u32 minor_features4;
53
54 /* Supported minor feature 5 fields. */
55 u32 minor_features5; 45 u32 minor_features5;
46 u32 minor_features6;
47 u32 minor_features7;
48 u32 minor_features8;
49 u32 minor_features9;
50 u32 minor_features10;
51 u32 minor_features11;
56 52
57 /* Number of streams supported. */ 53 /* Number of streams supported. */
58 u32 stream_count; 54 u32 stream_count;
@@ -88,6 +84,12 @@ struct etnaviv_chip_identity {
88 u8 varyings_count; 84 u8 varyings_count;
89}; 85};
90 86
87enum etnaviv_sec_mode {
88 ETNA_SEC_NONE = 0,
89 ETNA_SEC_KERNEL,
90 ETNA_SEC_TZ
91};
92
91struct etnaviv_event { 93struct etnaviv_event {
92 struct dma_fence *fence; 94 struct dma_fence *fence;
93 struct etnaviv_gem_submit *submit; 95 struct etnaviv_gem_submit *submit;
@@ -106,8 +108,10 @@ struct etnaviv_gpu {
106 struct device *dev; 108 struct device *dev;
107 struct mutex lock; 109 struct mutex lock;
108 struct etnaviv_chip_identity identity; 110 struct etnaviv_chip_identity identity;
111 enum etnaviv_sec_mode sec_mode;
109 struct etnaviv_file_private *lastctx; 112 struct etnaviv_file_private *lastctx;
110 struct workqueue_struct *wq; 113 struct workqueue_struct *wq;
114 struct drm_gpu_scheduler sched;
111 115
112 /* 'ring'-buffer: */ 116 /* 'ring'-buffer: */
113 struct etnaviv_cmdbuf buffer; 117 struct etnaviv_cmdbuf buffer;
@@ -122,23 +126,18 @@ struct etnaviv_gpu {
122 struct completion event_free; 126 struct completion event_free;
123 spinlock_t event_spinlock; 127 spinlock_t event_spinlock;
124 128
125 /* list of currently in-flight command buffers */
126 struct list_head active_submit_list;
127
128 u32 idle_mask; 129 u32 idle_mask;
129 130
130 /* Fencing support */ 131 /* Fencing support */
132 struct mutex fence_idr_lock;
133 struct idr fence_idr;
131 u32 next_fence; 134 u32 next_fence;
132 u32 active_fence; 135 u32 active_fence;
133 u32 completed_fence; 136 u32 completed_fence;
134 u32 retired_fence;
135 wait_queue_head_t fence_event; 137 wait_queue_head_t fence_event;
136 u64 fence_context; 138 u64 fence_context;
137 spinlock_t fence_spinlock; 139 spinlock_t fence_spinlock;
138 140
139 /* worker for handling active-list retiring: */
140 struct work_struct retire_work;
141
142 /* worker for handling 'sync' points: */ 141 /* worker for handling 'sync' points: */
143 struct work_struct sync_point_work; 142 struct work_struct sync_point_work;
144 int sync_point_event; 143 int sync_point_event;
@@ -151,16 +150,10 @@ struct etnaviv_gpu {
151 150
152 /* Power Control: */ 151 /* Power Control: */
153 struct clk *clk_bus; 152 struct clk *clk_bus;
153 struct clk *clk_reg;
154 struct clk *clk_core; 154 struct clk *clk_core;
155 struct clk *clk_shader; 155 struct clk *clk_shader;
156 156
157 /* Hang Detction: */
158#define DRM_ETNAVIV_HANGCHECK_PERIOD 500 /* in ms */
159#define DRM_ETNAVIV_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_ETNAVIV_HANGCHECK_PERIOD)
160 struct timer_list hangcheck_timer;
161 u32 hangcheck_fence;
162 u32 hangcheck_dma_addr;
163 struct work_struct recover_work;
164 unsigned int freq_scale; 157 unsigned int freq_scale;
165 unsigned long base_rate_core; 158 unsigned long base_rate_core;
166 unsigned long base_rate_shader; 159 unsigned long base_rate_shader;
@@ -181,29 +174,22 @@ static inline bool fence_completed(struct etnaviv_gpu *gpu, u32 fence)
181 return fence_after_eq(gpu->completed_fence, fence); 174 return fence_after_eq(gpu->completed_fence, fence);
182} 175}
183 176
184static inline bool fence_retired(struct etnaviv_gpu *gpu, u32 fence)
185{
186 return fence_after_eq(gpu->retired_fence, fence);
187}
188
189int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); 177int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value);
190 178
191int etnaviv_gpu_init(struct etnaviv_gpu *gpu); 179int etnaviv_gpu_init(struct etnaviv_gpu *gpu);
180bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu);
192 181
193#ifdef CONFIG_DEBUG_FS 182#ifdef CONFIG_DEBUG_FS
194int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m); 183int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m);
195#endif 184#endif
196 185
197int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj, 186void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu);
198 unsigned int context, bool exclusive, bool implicit);
199
200void etnaviv_gpu_retire(struct etnaviv_gpu *gpu); 187void etnaviv_gpu_retire(struct etnaviv_gpu *gpu);
201int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu, 188int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu,
202 u32 fence, struct timespec *timeout); 189 u32 fence, struct timespec *timeout);
203int etnaviv_gpu_wait_obj_inactive(struct etnaviv_gpu *gpu, 190int etnaviv_gpu_wait_obj_inactive(struct etnaviv_gpu *gpu,
204 struct etnaviv_gem_object *etnaviv_obj, struct timespec *timeout); 191 struct etnaviv_gem_object *etnaviv_obj, struct timespec *timeout);
205int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, 192struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit);
206 struct etnaviv_gem_submit *submit);
207int etnaviv_gpu_pm_get_sync(struct etnaviv_gpu *gpu); 193int etnaviv_gpu_pm_get_sync(struct etnaviv_gpu *gpu);
208void etnaviv_gpu_pm_put(struct etnaviv_gpu *gpu); 194void etnaviv_gpu_pm_put(struct etnaviv_gpu *gpu);
209int etnaviv_gpu_wait_idle(struct etnaviv_gpu *gpu, unsigned int timeout_ms); 195int etnaviv_gpu_wait_idle(struct etnaviv_gpu *gpu, unsigned int timeout_ms);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
new file mode 100644
index 000000000000..ea08bb38caaf
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
@@ -0,0 +1,65 @@
1/*
2 * Copyright (C) 2018 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "etnaviv_gpu.h"
18
19static const struct etnaviv_chip_identity etnaviv_chip_identities[] = {
20 {
21 .model = 0x7000,
22 .revision = 0x6214,
23 .stream_count = 16,
24 .register_max = 64,
25 .thread_count = 1024,
26 .shader_core_count = 4,
27 .vertex_cache_size = 16,
28 .vertex_output_buffer_size = 1024,
29 .pixel_pipes = 2,
30 .instruction_count = 512,
31 .num_constants = 320,
32 .buffer_size = 0,
33 .varyings_count = 16,
34 .features = 0xe0287cad,
35 .minor_features0 = 0xc1799eff,
36 .minor_features1 = 0xfefbfad9,
37 .minor_features2 = 0xeb9d4fbf,
38 .minor_features3 = 0xedfffced,
39 .minor_features4 = 0xdb0dafc7,
40 .minor_features5 = 0xbb5ac333,
41 .minor_features6 = 0xfc8ee200,
42 .minor_features7 = 0x03fbfa6f,
43 .minor_features8 = 0x00ef0ef0,
44 .minor_features9 = 0x0edbf03c,
45 .minor_features10 = 0x90044250,
46 .minor_features11 = 0x00000024,
47 },
48};
49
50bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu)
51{
52 struct etnaviv_chip_identity *ident = &gpu->identity;
53 int i;
54
55 for (i = 0; i < ARRAY_SIZE(etnaviv_chip_identities); i++) {
56 if (etnaviv_chip_identities[i].model == ident->model &&
57 etnaviv_chip_identities[i].revision == ident->revision) {
58 memcpy(ident, &etnaviv_chip_identities[i],
59 sizeof(*ident));
60 return true;
61 }
62 }
63
64 return false;
65}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
index 7a8c94731748..4b9b11ca6f03 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
@@ -158,7 +158,7 @@ void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu)
158 gpu_write(gpu, VIVS_MC_MMU_RA_PAGE_TABLE, pgtable); 158 gpu_write(gpu, VIVS_MC_MMU_RA_PAGE_TABLE, pgtable);
159} 159}
160 160
161const struct etnaviv_iommu_domain_ops etnaviv_iommuv1_ops = { 161static const struct etnaviv_iommu_domain_ops etnaviv_iommuv1_ops = {
162 .free = etnaviv_iommuv1_domain_free, 162 .free = etnaviv_iommuv1_domain_free,
163 .map = etnaviv_iommuv1_map, 163 .map = etnaviv_iommuv1_map,
164 .unmap = etnaviv_iommuv1_unmap, 164 .unmap = etnaviv_iommuv1_unmap,
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
index 1e956e266aa3..9752dbd5d28b 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
@@ -40,6 +40,9 @@
40 40
41struct etnaviv_iommuv2_domain { 41struct etnaviv_iommuv2_domain {
42 struct etnaviv_iommu_domain base; 42 struct etnaviv_iommu_domain base;
43 /* P(age) T(able) A(rray) */
44 u64 *pta_cpu;
45 dma_addr_t pta_dma;
43 /* M(aster) TLB aka first level pagetable */ 46 /* M(aster) TLB aka first level pagetable */
44 u32 *mtlb_cpu; 47 u32 *mtlb_cpu;
45 dma_addr_t mtlb_dma; 48 dma_addr_t mtlb_dma;
@@ -114,6 +117,15 @@ static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain)
114 for (i = 0; i < SZ_4K / 4; i++) 117 for (i = 0; i < SZ_4K / 4; i++)
115 *p++ = 0xdead55aa; 118 *p++ = 0xdead55aa;
116 119
120 etnaviv_domain->pta_cpu = dma_alloc_coherent(etnaviv_domain->base.dev,
121 SZ_4K,
122 &etnaviv_domain->pta_dma,
123 GFP_KERNEL);
124 if (!etnaviv_domain->pta_cpu) {
125 ret = -ENOMEM;
126 goto fail_mem;
127 }
128
117 etnaviv_domain->mtlb_cpu = dma_alloc_coherent(etnaviv_domain->base.dev, 129 etnaviv_domain->mtlb_cpu = dma_alloc_coherent(etnaviv_domain->base.dev,
118 SZ_4K, 130 SZ_4K,
119 &etnaviv_domain->mtlb_dma, 131 &etnaviv_domain->mtlb_dma,
@@ -150,6 +162,11 @@ fail_mem:
150 etnaviv_domain->base.bad_page_cpu, 162 etnaviv_domain->base.bad_page_cpu,
151 etnaviv_domain->base.bad_page_dma); 163 etnaviv_domain->base.bad_page_dma);
152 164
165 if (etnaviv_domain->pta_cpu)
166 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K,
167 etnaviv_domain->pta_cpu,
168 etnaviv_domain->pta_dma);
169
153 if (etnaviv_domain->mtlb_cpu) 170 if (etnaviv_domain->mtlb_cpu)
154 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 171 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K,
155 etnaviv_domain->mtlb_cpu, 172 etnaviv_domain->mtlb_cpu,
@@ -176,6 +193,10 @@ static void etnaviv_iommuv2_domain_free(struct etnaviv_iommu_domain *domain)
176 etnaviv_domain->base.bad_page_dma); 193 etnaviv_domain->base.bad_page_dma);
177 194
178 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K, 195 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K,
196 etnaviv_domain->pta_cpu,
197 etnaviv_domain->pta_dma);
198
199 dma_free_coherent(etnaviv_domain->base.dev, SZ_4K,
179 etnaviv_domain->mtlb_cpu, 200 etnaviv_domain->mtlb_cpu,
180 etnaviv_domain->mtlb_dma); 201 etnaviv_domain->mtlb_dma);
181 202
@@ -216,7 +237,7 @@ static void etnaviv_iommuv2_dump(struct etnaviv_iommu_domain *domain, void *buf)
216 memcpy(buf, etnaviv_domain->stlb_cpu[i], SZ_4K); 237 memcpy(buf, etnaviv_domain->stlb_cpu[i], SZ_4K);
217} 238}
218 239
219void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu) 240static void etnaviv_iommuv2_restore_nonsec(struct etnaviv_gpu *gpu)
220{ 241{
221 struct etnaviv_iommuv2_domain *etnaviv_domain = 242 struct etnaviv_iommuv2_domain *etnaviv_domain =
222 to_etnaviv_domain(gpu->mmu->domain); 243 to_etnaviv_domain(gpu->mmu->domain);
@@ -236,7 +257,60 @@ void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu)
236 gpu_write(gpu, VIVS_MMUv2_CONTROL, VIVS_MMUv2_CONTROL_ENABLE); 257 gpu_write(gpu, VIVS_MMUv2_CONTROL, VIVS_MMUv2_CONTROL_ENABLE);
237} 258}
238 259
239const struct etnaviv_iommu_domain_ops etnaviv_iommuv2_ops = { 260static void etnaviv_iommuv2_restore_sec(struct etnaviv_gpu *gpu)
261{
262 struct etnaviv_iommuv2_domain *etnaviv_domain =
263 to_etnaviv_domain(gpu->mmu->domain);
264 u16 prefetch;
265
266 /* If the MMU is already enabled the state is still there. */
267 if (gpu_read(gpu, VIVS_MMUv2_SEC_CONTROL) & VIVS_MMUv2_SEC_CONTROL_ENABLE)
268 return;
269
270 gpu_write(gpu, VIVS_MMUv2_PTA_ADDRESS_LOW,
271 lower_32_bits(etnaviv_domain->pta_dma));
272 gpu_write(gpu, VIVS_MMUv2_PTA_ADDRESS_HIGH,
273 upper_32_bits(etnaviv_domain->pta_dma));
274 gpu_write(gpu, VIVS_MMUv2_PTA_CONTROL, VIVS_MMUv2_PTA_CONTROL_ENABLE);
275
276 gpu_write(gpu, VIVS_MMUv2_NONSEC_SAFE_ADDR_LOW,
277 lower_32_bits(etnaviv_domain->base.bad_page_dma));
278 gpu_write(gpu, VIVS_MMUv2_SEC_SAFE_ADDR_LOW,
279 lower_32_bits(etnaviv_domain->base.bad_page_dma));
280 gpu_write(gpu, VIVS_MMUv2_SAFE_ADDRESS_CONFIG,
281 VIVS_MMUv2_SAFE_ADDRESS_CONFIG_NON_SEC_SAFE_ADDR_HIGH(
282 upper_32_bits(etnaviv_domain->base.bad_page_dma)) |
283 VIVS_MMUv2_SAFE_ADDRESS_CONFIG_SEC_SAFE_ADDR_HIGH(
284 upper_32_bits(etnaviv_domain->base.bad_page_dma)));
285
286 etnaviv_domain->pta_cpu[0] = etnaviv_domain->mtlb_dma |
287 VIVS_MMUv2_CONFIGURATION_MODE_MODE4_K;
288
289 /* trigger a PTA load through the FE */
290 prefetch = etnaviv_buffer_config_pta(gpu);
291 etnaviv_gpu_start_fe(gpu, (u32)etnaviv_cmdbuf_get_pa(&gpu->buffer),
292 prefetch);
293 etnaviv_gpu_wait_idle(gpu, 100);
294
295 gpu_write(gpu, VIVS_MMUv2_SEC_CONTROL, VIVS_MMUv2_SEC_CONTROL_ENABLE);
296}
297
298void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu)
299{
300 switch (gpu->sec_mode) {
301 case ETNA_SEC_NONE:
302 etnaviv_iommuv2_restore_nonsec(gpu);
303 break;
304 case ETNA_SEC_KERNEL:
305 etnaviv_iommuv2_restore_sec(gpu);
306 break;
307 default:
308 WARN(1, "unhandled GPU security mode\n");
309 break;
310 }
311}
312
313static const struct etnaviv_iommu_domain_ops etnaviv_iommuv2_ops = {
240 .free = etnaviv_iommuv2_domain_free, 314 .free = etnaviv_iommuv2_domain_free,
241 .map = etnaviv_iommuv2_map, 315 .map = etnaviv_iommuv2_map,
242 .unmap = etnaviv_iommuv2_unmap, 316 .unmap = etnaviv_iommuv2_unmap,
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
index d113fe06e6b5..49e049713a52 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
@@ -29,7 +29,7 @@ static void etnaviv_domain_unmap(struct etnaviv_iommu_domain *domain,
29 size_t pgsize = SZ_4K; 29 size_t pgsize = SZ_4K;
30 30
31 if (!IS_ALIGNED(iova | size, pgsize)) { 31 if (!IS_ALIGNED(iova | size, pgsize)) {
32 pr_err("unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%x\n", 32 pr_err("unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%zx\n",
33 iova, size, pgsize); 33 iova, size, pgsize);
34 return; 34 return;
35 } 35 }
@@ -54,7 +54,7 @@ static int etnaviv_domain_map(struct etnaviv_iommu_domain *domain,
54 int ret = 0; 54 int ret = 0;
55 55
56 if (!IS_ALIGNED(iova | paddr | size, pgsize)) { 56 if (!IS_ALIGNED(iova | paddr | size, pgsize)) {
57 pr_err("unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%x\n", 57 pr_err("unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%zx\n",
58 iova, &paddr, size, pgsize); 58 iova, &paddr, size, pgsize);
59 return -EINVAL; 59 return -EINVAL;
60 } 60 }
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
new file mode 100644
index 000000000000..6cf0775dbcd7
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
@@ -0,0 +1,170 @@
1/*
2 * Copyright (C) 2017 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/kthread.h>
18
19#include "etnaviv_drv.h"
20#include "etnaviv_dump.h"
21#include "etnaviv_gem.h"
22#include "etnaviv_gpu.h"
23#include "etnaviv_sched.h"
24
25static int etnaviv_job_hang_limit = 0;
26module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444);
27static int etnaviv_hw_jobs_limit = 4;
28module_param_named(hw_job_limit, etnaviv_hw_jobs_limit, int , 0444);
29
30static struct dma_fence *
31etnaviv_sched_dependency(struct drm_sched_job *sched_job,
32 struct drm_sched_entity *entity)
33{
34 struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job);
35 struct dma_fence *fence;
36 int i;
37
38 if (unlikely(submit->in_fence)) {
39 fence = submit->in_fence;
40 submit->in_fence = NULL;
41
42 if (!dma_fence_is_signaled(fence))
43 return fence;
44
45 dma_fence_put(fence);
46 }
47
48 for (i = 0; i < submit->nr_bos; i++) {
49 struct etnaviv_gem_submit_bo *bo = &submit->bos[i];
50 int j;
51
52 if (bo->excl) {
53 fence = bo->excl;
54 bo->excl = NULL;
55
56 if (!dma_fence_is_signaled(fence))
57 return fence;
58
59 dma_fence_put(fence);
60 }
61
62 for (j = 0; j < bo->nr_shared; j++) {
63 if (!bo->shared[j])
64 continue;
65
66 fence = bo->shared[j];
67 bo->shared[j] = NULL;
68
69 if (!dma_fence_is_signaled(fence))
70 return fence;
71
72 dma_fence_put(fence);
73 }
74 kfree(bo->shared);
75 bo->nr_shared = 0;
76 bo->shared = NULL;
77 }
78
79 return NULL;
80}
81
82static struct dma_fence *etnaviv_sched_run_job(struct drm_sched_job *sched_job)
83{
84 struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job);
85 struct dma_fence *fence = NULL;
86
87 if (likely(!sched_job->s_fence->finished.error))
88 fence = etnaviv_gpu_submit(submit);
89 else
90 dev_dbg(submit->gpu->dev, "skipping bad job\n");
91
92 return fence;
93}
94
95static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
96{
97 struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job);
98 struct etnaviv_gpu *gpu = submit->gpu;
99
100 /* block scheduler */
101 kthread_park(gpu->sched.thread);
102 drm_sched_hw_job_reset(&gpu->sched, sched_job);
103
104 /* get the GPU back into the init state */
105 etnaviv_core_dump(gpu);
106 etnaviv_gpu_recover_hang(gpu);
107
108 /* restart scheduler after GPU is usable again */
109 drm_sched_job_recovery(&gpu->sched);
110 kthread_unpark(gpu->sched.thread);
111}
112
113static void etnaviv_sched_free_job(struct drm_sched_job *sched_job)
114{
115 struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job);
116
117 etnaviv_submit_put(submit);
118}
119
120static const struct drm_sched_backend_ops etnaviv_sched_ops = {
121 .dependency = etnaviv_sched_dependency,
122 .run_job = etnaviv_sched_run_job,
123 .timedout_job = etnaviv_sched_timedout_job,
124 .free_job = etnaviv_sched_free_job,
125};
126
127int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity,
128 struct etnaviv_gem_submit *submit)
129{
130 int ret;
131
132 ret = drm_sched_job_init(&submit->sched_job, &submit->gpu->sched,
133 sched_entity, submit->cmdbuf.ctx);
134 if (ret)
135 return ret;
136
137 submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
138 mutex_lock(&submit->gpu->fence_idr_lock);
139 submit->out_fence_id = idr_alloc_cyclic(&submit->gpu->fence_idr,
140 submit->out_fence, 0,
141 INT_MAX, GFP_KERNEL);
142 mutex_unlock(&submit->gpu->fence_idr_lock);
143 if (submit->out_fence_id < 0)
144 return -ENOMEM;
145
146 /* the scheduler holds on to the job now */
147 kref_get(&submit->refcount);
148
149 drm_sched_entity_push_job(&submit->sched_job, sched_entity);
150
151 return 0;
152}
153
154int etnaviv_sched_init(struct etnaviv_gpu *gpu)
155{
156 int ret;
157
158 ret = drm_sched_init(&gpu->sched, &etnaviv_sched_ops,
159 etnaviv_hw_jobs_limit, etnaviv_job_hang_limit,
160 msecs_to_jiffies(500), dev_name(gpu->dev));
161 if (ret)
162 return ret;
163
164 return 0;
165}
166
167void etnaviv_sched_fini(struct etnaviv_gpu *gpu)
168{
169 drm_sched_fini(&gpu->sched);
170}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.h b/drivers/gpu/drm/etnaviv/etnaviv_sched.h
new file mode 100644
index 000000000000..097635fa78ae
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) 2017 Etnaviv Project
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __ETNAVIV_SCHED_H__
18#define __ETNAVIV_SCHED_H__
19
20#include <drm/gpu_scheduler.h>
21
22struct etnaviv_gpu;
23
24static inline
25struct etnaviv_gem_submit *to_etnaviv_submit(struct drm_sched_job *sched_job)
26{
27 return container_of(sched_job, struct etnaviv_gem_submit, sched_job);
28}
29
30int etnaviv_sched_init(struct etnaviv_gpu *gpu);
31void etnaviv_sched_fini(struct etnaviv_gpu *gpu);
32int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity,
33 struct etnaviv_gem_submit *submit);
34
35#endif /* __ETNAVIV_SCHED_H__ */
diff --git a/drivers/gpu/drm/etnaviv/state.xml.h b/drivers/gpu/drm/etnaviv/state.xml.h
index c27c1484cfa9..421cb7cc0053 100644
--- a/drivers/gpu/drm/etnaviv/state.xml.h
+++ b/drivers/gpu/drm/etnaviv/state.xml.h
@@ -1,4 +1,3 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef STATE_XML 1#ifndef STATE_XML
3#define STATE_XML 2#define STATE_XML
4 3
@@ -9,14 +8,40 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
9git clone git://0x04.net/rules-ng-ng 8git clone git://0x04.net/rules-ng-ng
10 9
11The rules-ng-ng source files this header was generated from are: 10The rules-ng-ng source files this header was generated from are:
12- state.xml ( 18882 bytes, from 2015-03-25 11:42:32) 11- state.xml ( 26087 bytes, from 2017-12-18 16:51:59)
13- common.xml ( 18437 bytes, from 2015-03-25 11:27:41) 12- common.xml ( 35468 bytes, from 2018-01-22 13:48:54)
14- state_hi.xml ( 23420 bytes, from 2015-03-25 11:47:21) 13- common_3d.xml ( 14615 bytes, from 2017-12-18 16:51:59)
15- state_2d.xml ( 51549 bytes, from 2015-03-25 11:25:06) 14- state_hi.xml ( 30232 bytes, from 2018-02-15 15:48:01)
16- state_3d.xml ( 54600 bytes, from 2015-03-25 11:25:19) 15- copyright.xml ( 1597 bytes, from 2016-12-08 16:37:56)
17- state_vg.xml ( 5973 bytes, from 2015-03-25 11:26:01) 16- state_2d.xml ( 51552 bytes, from 2016-12-08 16:37:56)
18 17- state_3d.xml ( 79992 bytes, from 2017-12-18 16:51:59)
19Copyright (C) 2015 18- state_blt.xml ( 13405 bytes, from 2017-12-18 16:51:59)
19- state_vg.xml ( 5975 bytes, from 2016-12-08 16:37:56)
20
21Copyright (C) 2012-2017 by the following authors:
22- Wladimir J. van der Laan <laanwj@gmail.com>
23- Christian Gmeiner <christian.gmeiner@gmail.com>
24- Lucas Stach <l.stach@pengutronix.de>
25- Russell King <rmk@arm.linux.org.uk>
26
27Permission is hereby granted, free of charge, to any person obtaining a
28copy of this software and associated documentation files (the "Software"),
29to deal in the Software without restriction, including without limitation
30the rights to use, copy, modify, merge, publish, distribute, sub license,
31and/or sell copies of the Software, and to permit persons to whom the
32Software is furnished to do so, subject to the following conditions:
33
34The above copyright notice and this permission notice (including the
35next paragraph) shall be included in all copies or substantial portions
36of the Software.
37
38THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
41THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
43FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
44DEALINGS IN THE SOFTWARE.
20*/ 45*/
21 46
22 47
@@ -24,9 +49,25 @@ Copyright (C) 2015
24#define VARYING_COMPONENT_USE_USED 0x00000001 49#define VARYING_COMPONENT_USE_USED 0x00000001
25#define VARYING_COMPONENT_USE_POINTCOORD_X 0x00000002 50#define VARYING_COMPONENT_USE_POINTCOORD_X 0x00000002
26#define VARYING_COMPONENT_USE_POINTCOORD_Y 0x00000003 51#define VARYING_COMPONENT_USE_POINTCOORD_Y 0x00000003
52#define FE_DATA_TYPE_BYTE 0x00000000
53#define FE_DATA_TYPE_UNSIGNED_BYTE 0x00000001
54#define FE_DATA_TYPE_SHORT 0x00000002
55#define FE_DATA_TYPE_UNSIGNED_SHORT 0x00000003
56#define FE_DATA_TYPE_INT 0x00000004
57#define FE_DATA_TYPE_UNSIGNED_INT 0x00000005
58#define FE_DATA_TYPE_FLOAT 0x00000008
59#define FE_DATA_TYPE_HALF_FLOAT 0x00000009
60#define FE_DATA_TYPE_FIXED 0x0000000b
61#define FE_DATA_TYPE_INT_10_10_10_2 0x0000000c
62#define FE_DATA_TYPE_UNSIGNED_INT_10_10_10_2 0x0000000d
63#define FE_DATA_TYPE_BYTE_I 0x0000000e
64#define FE_DATA_TYPE_SHORT_I 0x0000000f
27#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__MASK 0x000000ff 65#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__MASK 0x000000ff
28#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT 0 66#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT 0
29#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE(x) (((x) << FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT) & FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__MASK) 67#define FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE(x) (((x) << FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__SHIFT) & FE_VERTEX_STREAM_CONTROL_VERTEX_STRIDE__MASK)
68#define FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR__MASK 0x00ff0000
69#define FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR__SHIFT 16
70#define FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR(x) (((x) << FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR__SHIFT) & FE_VERTEX_STREAM_CONTROL_VERTEX_DIVISOR__MASK)
30#define VIVS_FE 0x00000000 71#define VIVS_FE 0x00000000
31 72
32#define VIVS_FE_VERTEX_ELEMENT_CONFIG(i0) (0x00000600 + 0x4*(i0)) 73#define VIVS_FE_VERTEX_ELEMENT_CONFIG(i0) (0x00000600 + 0x4*(i0))
@@ -34,17 +75,7 @@ Copyright (C) 2015
34#define VIVS_FE_VERTEX_ELEMENT_CONFIG__LEN 0x00000010 75#define VIVS_FE_VERTEX_ELEMENT_CONFIG__LEN 0x00000010
35#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__MASK 0x0000000f 76#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__MASK 0x0000000f
36#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__SHIFT 0 77#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__SHIFT 0
37#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_BYTE 0x00000000 78#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE__MASK)
38#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_BYTE 0x00000001
39#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_SHORT 0x00000002
40#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_SHORT 0x00000003
41#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_INT 0x00000004
42#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_INT 0x00000005
43#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FLOAT 0x00000008
44#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_HALF_FLOAT 0x00000009
45#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_FIXED 0x0000000b
46#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_INT_10_10_10_2 0x0000000c
47#define VIVS_FE_VERTEX_ELEMENT_CONFIG_TYPE_UNSIGNED_INT_10_10_10_2 0x0000000d
48#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__MASK 0x00000030 79#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__MASK 0x00000030
49#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT 4 80#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT 4
50#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__MASK) 81#define VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(x) (((x) << VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__SHIFT) & VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN__MASK)
@@ -76,6 +107,7 @@ Copyright (C) 2015
76#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR 0x00000000 107#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_CHAR 0x00000000
77#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT 0x00000001 108#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_SHORT 0x00000001
78#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT 0x00000002 109#define VIVS_FE_INDEX_STREAM_CONTROL_TYPE_UNSIGNED_INT 0x00000002
110#define VIVS_FE_INDEX_STREAM_CONTROL_PRIMITIVE_RESTART 0x00000100
79 111
80#define VIVS_FE_VERTEX_STREAM_BASE_ADDR 0x0000064c 112#define VIVS_FE_VERTEX_STREAM_BASE_ADDR 0x0000064c
81 113
@@ -151,6 +183,8 @@ Copyright (C) 2015
151 183
152#define VIVS_FE_AUTO_FLUSH 0x00000670 184#define VIVS_FE_AUTO_FLUSH 0x00000670
153 185
186#define VIVS_FE_PRIMITIVE_RESTART_INDEX 0x00000674
187
154#define VIVS_FE_UNK00678 0x00000678 188#define VIVS_FE_UNK00678 0x00000678
155 189
156#define VIVS_FE_UNK0067C 0x0000067c 190#define VIVS_FE_UNK0067C 0x0000067c
@@ -163,17 +197,40 @@ Copyright (C) 2015
163 197
164#define VIVS_FE_VERTEX_STREAMS_CONTROL(i0) (0x000006a0 + 0x4*(i0)) 198#define VIVS_FE_VERTEX_STREAMS_CONTROL(i0) (0x000006a0 + 0x4*(i0))
165 199
166#define VIVS_FE_UNK00700(i0) (0x00000700 + 0x4*(i0)) 200#define VIVS_FE_GENERIC_ATTRIB(i0) (0x00000000 + 0x4*(i0))
167#define VIVS_FE_UNK00700__ESIZE 0x00000004 201#define VIVS_FE_GENERIC_ATTRIB__ESIZE 0x00000004
168#define VIVS_FE_UNK00700__LEN 0x00000010 202#define VIVS_FE_GENERIC_ATTRIB__LEN 0x00000010
203
204#define VIVS_FE_GENERIC_ATTRIB_UNK006C0(i0) (0x000006c0 + 0x4*(i0))
205
206#define VIVS_FE_GENERIC_ATTRIB_UNK00700(i0) (0x00000700 + 0x4*(i0))
207
208#define VIVS_FE_GENERIC_ATTRIB_UNK00740(i0) (0x00000740 + 0x4*(i0))
209
210#define VIVS_FE_GENERIC_ATTRIB_SCALE(i0) (0x00000780 + 0x4*(i0))
211
212#define VIVS_FE_HALTI5_UNK007C4 0x000007c4
213
214#define VIVS_FE_HALTI5_UNK007D0(i0) (0x000007d0 + 0x4*(i0))
215#define VIVS_FE_HALTI5_UNK007D0__ESIZE 0x00000004
216#define VIVS_FE_HALTI5_UNK007D0__LEN 0x00000002
217
218#define VIVS_FE_HALTI5_UNK007D8 0x000007d8
219
220#define VIVS_FE_DESC_START 0x000007dc
221
222#define VIVS_FE_DESC_END 0x000007e0
223
224#define VIVS_FE_DESC_AVAIL 0x000007e4
225#define VIVS_FE_DESC_AVAIL_COUNT__MASK 0x0000007f
226#define VIVS_FE_DESC_AVAIL_COUNT__SHIFT 0
227#define VIVS_FE_DESC_AVAIL_COUNT(x) (((x) << VIVS_FE_DESC_AVAIL_COUNT__SHIFT) & VIVS_FE_DESC_AVAIL_COUNT__MASK)
228
229#define VIVS_FE_FENCE_WAIT_DATA_LOW 0x000007e8
169 230
170#define VIVS_FE_UNK00740(i0) (0x00000740 + 0x4*(i0)) 231#define VIVS_FE_FENCE_WAIT_DATA_HIGH 0x000007f4
171#define VIVS_FE_UNK00740__ESIZE 0x00000004
172#define VIVS_FE_UNK00740__LEN 0x00000010
173 232
174#define VIVS_FE_UNK00780(i0) (0x00000780 + 0x4*(i0)) 233#define VIVS_FE_ROBUSTNESS_UNK007F8 0x000007f8
175#define VIVS_FE_UNK00780__ESIZE 0x00000004
176#define VIVS_FE_UNK00780__LEN 0x00000010
177 234
178#define VIVS_GL 0x00000000 235#define VIVS_GL 0x00000000
179 236
@@ -188,6 +245,7 @@ Copyright (C) 2015
188#define VIVS_GL_EVENT_EVENT_ID(x) (((x) << VIVS_GL_EVENT_EVENT_ID__SHIFT) & VIVS_GL_EVENT_EVENT_ID__MASK) 245#define VIVS_GL_EVENT_EVENT_ID(x) (((x) << VIVS_GL_EVENT_EVENT_ID__SHIFT) & VIVS_GL_EVENT_EVENT_ID__MASK)
189#define VIVS_GL_EVENT_FROM_FE 0x00000020 246#define VIVS_GL_EVENT_FROM_FE 0x00000020
190#define VIVS_GL_EVENT_FROM_PE 0x00000040 247#define VIVS_GL_EVENT_FROM_PE 0x00000040
248#define VIVS_GL_EVENT_FROM_BLT 0x00000080
191#define VIVS_GL_EVENT_SOURCE__MASK 0x00001f00 249#define VIVS_GL_EVENT_SOURCE__MASK 0x00001f00
192#define VIVS_GL_EVENT_SOURCE__SHIFT 8 250#define VIVS_GL_EVENT_SOURCE__SHIFT 8
193#define VIVS_GL_EVENT_SOURCE(x) (((x) << VIVS_GL_EVENT_SOURCE__SHIFT) & VIVS_GL_EVENT_SOURCE__MASK) 251#define VIVS_GL_EVENT_SOURCE(x) (((x) << VIVS_GL_EVENT_SOURCE__SHIFT) & VIVS_GL_EVENT_SOURCE__MASK)
@@ -199,6 +257,9 @@ Copyright (C) 2015
199#define VIVS_GL_SEMAPHORE_TOKEN_TO__MASK 0x00001f00 257#define VIVS_GL_SEMAPHORE_TOKEN_TO__MASK 0x00001f00
200#define VIVS_GL_SEMAPHORE_TOKEN_TO__SHIFT 8 258#define VIVS_GL_SEMAPHORE_TOKEN_TO__SHIFT 8
201#define VIVS_GL_SEMAPHORE_TOKEN_TO(x) (((x) << VIVS_GL_SEMAPHORE_TOKEN_TO__SHIFT) & VIVS_GL_SEMAPHORE_TOKEN_TO__MASK) 259#define VIVS_GL_SEMAPHORE_TOKEN_TO(x) (((x) << VIVS_GL_SEMAPHORE_TOKEN_TO__SHIFT) & VIVS_GL_SEMAPHORE_TOKEN_TO__MASK)
260#define VIVS_GL_SEMAPHORE_TOKEN_UNK28__MASK 0x30000000
261#define VIVS_GL_SEMAPHORE_TOKEN_UNK28__SHIFT 28
262#define VIVS_GL_SEMAPHORE_TOKEN_UNK28(x) (((x) << VIVS_GL_SEMAPHORE_TOKEN_UNK28__SHIFT) & VIVS_GL_SEMAPHORE_TOKEN_UNK28__MASK)
202 263
203#define VIVS_GL_FLUSH_CACHE 0x0000380c 264#define VIVS_GL_FLUSH_CACHE 0x0000380c
204#define VIVS_GL_FLUSH_CACHE_DEPTH 0x00000001 265#define VIVS_GL_FLUSH_CACHE_DEPTH 0x00000001
@@ -208,6 +269,10 @@ Copyright (C) 2015
208#define VIVS_GL_FLUSH_CACHE_TEXTUREVS 0x00000010 269#define VIVS_GL_FLUSH_CACHE_TEXTUREVS 0x00000010
209#define VIVS_GL_FLUSH_CACHE_SHADER_L1 0x00000020 270#define VIVS_GL_FLUSH_CACHE_SHADER_L1 0x00000020
210#define VIVS_GL_FLUSH_CACHE_SHADER_L2 0x00000040 271#define VIVS_GL_FLUSH_CACHE_SHADER_L2 0x00000040
272#define VIVS_GL_FLUSH_CACHE_UNK10 0x00000400
273#define VIVS_GL_FLUSH_CACHE_UNK11 0x00000800
274#define VIVS_GL_FLUSH_CACHE_DESCRIPTOR_UNK12 0x00001000
275#define VIVS_GL_FLUSH_CACHE_DESCRIPTOR_UNK13 0x00002000
211 276
212#define VIVS_GL_FLUSH_MMU 0x00003810 277#define VIVS_GL_FLUSH_MMU 0x00003810
213#define VIVS_GL_FLUSH_MMU_FLUSH_FEMMU 0x00000001 278#define VIVS_GL_FLUSH_MMU_FLUSH_FEMMU 0x00000001
@@ -244,30 +309,8 @@ Copyright (C) 2015
244#define VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(x) (((x) << VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__SHIFT) & VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__MASK) 309#define VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(x) (((x) << VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__SHIFT) & VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM__MASK)
245 310
246#define VIVS_GL_VARYING_NUM_COMPONENTS 0x00003820 311#define VIVS_GL_VARYING_NUM_COMPONENTS 0x00003820
247#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__MASK 0x00000007 312
248#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__SHIFT 0 313#define VIVS_GL_OCCLUSION_QUERY_ADDR 0x00003824
249#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR0(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR0__MASK)
250#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__MASK 0x00000070
251#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__SHIFT 4
252#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR1(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR1__MASK)
253#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__MASK 0x00000700
254#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__SHIFT 8
255#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR2(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR2__MASK)
256#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__MASK 0x00007000
257#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__SHIFT 12
258#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR3(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR3__MASK)
259#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__MASK 0x00070000
260#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__SHIFT 16
261#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR4(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR4__MASK)
262#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__MASK 0x00700000
263#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__SHIFT 20
264#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR5(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR5__MASK)
265#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__MASK 0x07000000
266#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__SHIFT 24
267#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR6(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR6__MASK)
268#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__MASK 0x70000000
269#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__SHIFT 28
270#define VIVS_GL_VARYING_NUM_COMPONENTS_VAR7(x) (((x) << VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__SHIFT) & VIVS_GL_VARYING_NUM_COMPONENTS_VAR7__MASK)
271 314
272#define VIVS_GL_VARYING_COMPONENT_USE(i0) (0x00003828 + 0x4*(i0)) 315#define VIVS_GL_VARYING_COMPONENT_USE(i0) (0x00003828 + 0x4*(i0))
273#define VIVS_GL_VARYING_COMPONENT_USE__ESIZE 0x00000004 316#define VIVS_GL_VARYING_COMPONENT_USE__ESIZE 0x00000004
@@ -321,6 +364,10 @@ Copyright (C) 2015
321#define VIVS_GL_VARYING_COMPONENT_USE_COMP15__SHIFT 30 364#define VIVS_GL_VARYING_COMPONENT_USE_COMP15__SHIFT 30
322#define VIVS_GL_VARYING_COMPONENT_USE_COMP15(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP15__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP15__MASK) 365#define VIVS_GL_VARYING_COMPONENT_USE_COMP15(x) (((x) << VIVS_GL_VARYING_COMPONENT_USE_COMP15__SHIFT) & VIVS_GL_VARYING_COMPONENT_USE_COMP15__MASK)
323 366
367#define VIVS_GL_UNK0382C 0x0000382c
368
369#define VIVS_GL_OCCLUSION_QUERY_CONTROL 0x00003830
370
324#define VIVS_GL_UNK03834 0x00003834 371#define VIVS_GL_UNK03834 0x00003834
325 372
326#define VIVS_GL_UNK03838 0x00003838 373#define VIVS_GL_UNK03838 0x00003838
@@ -332,8 +379,58 @@ Copyright (C) 2015
332 379
333#define VIVS_GL_CONTEXT_POINTER 0x00003850 380#define VIVS_GL_CONTEXT_POINTER 0x00003850
334 381
382#define VIVS_GL_UNK03854 0x00003854
383
384#define VIVS_GL_BUG_FIXES 0x00003860
385
386#define VIVS_GL_FENCE_OUT_ADDRESS 0x00003868
387
388#define VIVS_GL_FENCE_OUT_DATA_LOW 0x0000386c
389
390#define VIVS_GL_HALTI5_UNK03884 0x00003884
391
392#define VIVS_GL_HALTI5_SH_SPECIALS 0x00003888
393#define VIVS_GL_HALTI5_SH_SPECIALS_VS_PSIZE_OUT__MASK 0x0000007f
394#define VIVS_GL_HALTI5_SH_SPECIALS_VS_PSIZE_OUT__SHIFT 0
395#define VIVS_GL_HALTI5_SH_SPECIALS_VS_PSIZE_OUT(x) (((x) << VIVS_GL_HALTI5_SH_SPECIALS_VS_PSIZE_OUT__SHIFT) & VIVS_GL_HALTI5_SH_SPECIALS_VS_PSIZE_OUT__MASK)
396#define VIVS_GL_HALTI5_SH_SPECIALS_PS_PCOORD_IN__MASK 0x00007f00
397#define VIVS_GL_HALTI5_SH_SPECIALS_PS_PCOORD_IN__SHIFT 8
398#define VIVS_GL_HALTI5_SH_SPECIALS_PS_PCOORD_IN(x) (((x) << VIVS_GL_HALTI5_SH_SPECIALS_PS_PCOORD_IN__SHIFT) & VIVS_GL_HALTI5_SH_SPECIALS_PS_PCOORD_IN__MASK)
399#define VIVS_GL_HALTI5_SH_SPECIALS_UNK16__MASK 0x007f0000
400#define VIVS_GL_HALTI5_SH_SPECIALS_UNK16__SHIFT 16
401#define VIVS_GL_HALTI5_SH_SPECIALS_UNK16(x) (((x) << VIVS_GL_HALTI5_SH_SPECIALS_UNK16__SHIFT) & VIVS_GL_HALTI5_SH_SPECIALS_UNK16__MASK)
402#define VIVS_GL_HALTI5_SH_SPECIALS_UNK24__MASK 0xff000000
403#define VIVS_GL_HALTI5_SH_SPECIALS_UNK24__SHIFT 24
404#define VIVS_GL_HALTI5_SH_SPECIALS_UNK24(x) (((x) << VIVS_GL_HALTI5_SH_SPECIALS_UNK24__SHIFT) & VIVS_GL_HALTI5_SH_SPECIALS_UNK24__MASK)
405
406#define VIVS_GL_GS_UNK0388C 0x0000388c
407
408#define VIVS_GL_FENCE_OUT_DATA_HIGH 0x00003898
409
410#define VIVS_GL_SHADER_INDEX 0x0000389c
411
412#define VIVS_GL_GS_UNK038A0(i0) (0x000038a0 + 0x4*(i0))
413#define VIVS_GL_GS_UNK038A0__ESIZE 0x00000004
414#define VIVS_GL_GS_UNK038A0__LEN 0x00000008
415
416#define VIVS_GL_HALTI5_UNK038C0(i0) (0x000038c0 + 0x4*(i0))
417#define VIVS_GL_HALTI5_UNK038C0__ESIZE 0x00000004
418#define VIVS_GL_HALTI5_UNK038C0__LEN 0x00000010
419
420#define VIVS_GL_SECURITY_UNK3900 0x00003900
421
422#define VIVS_GL_SECURITY_UNK3904 0x00003904
423
335#define VIVS_GL_UNK03A00 0x00003a00 424#define VIVS_GL_UNK03A00 0x00003a00
336 425
426#define VIVS_GL_UNK03A04 0x00003a04
427
428#define VIVS_GL_UNK03A08 0x00003a08
429
430#define VIVS_GL_UNK03A0C 0x00003a0c
431
432#define VIVS_GL_UNK03A10 0x00003a10
433
337#define VIVS_GL_STALL_TOKEN 0x00003c00 434#define VIVS_GL_STALL_TOKEN 0x00003c00
338#define VIVS_GL_STALL_TOKEN_FROM__MASK 0x0000001f 435#define VIVS_GL_STALL_TOKEN_FROM__MASK 0x0000001f
339#define VIVS_GL_STALL_TOKEN_FROM__SHIFT 0 436#define VIVS_GL_STALL_TOKEN_FROM__SHIFT 0
@@ -344,6 +441,59 @@ Copyright (C) 2015
344#define VIVS_GL_STALL_TOKEN_FLIP0 0x40000000 441#define VIVS_GL_STALL_TOKEN_FLIP0 0x40000000
345#define VIVS_GL_STALL_TOKEN_FLIP1 0x80000000 442#define VIVS_GL_STALL_TOKEN_FLIP1 0x80000000
346 443
444#define VIVS_NFE 0x00000000
445
446#define VIVS_NFE_VERTEX_STREAMS(i0) (0x00000000 + 0x4*(i0))
447#define VIVS_NFE_VERTEX_STREAMS__ESIZE 0x00000004
448#define VIVS_NFE_VERTEX_STREAMS__LEN 0x00000010
449
450#define VIVS_NFE_VERTEX_STREAMS_BASE_ADDR(i0) (0x00014600 + 0x4*(i0))
451
452#define VIVS_NFE_VERTEX_STREAMS_CONTROL(i0) (0x00014640 + 0x4*(i0))
453
454#define VIVS_NFE_VERTEX_STREAMS_UNK14680(i0) (0x00014680 + 0x4*(i0))
455
456#define VIVS_NFE_VERTEX_STREAMS_ROBUSTNESS_UNK146C0(i0) (0x000146c0 + 0x4*(i0))
457
458#define VIVS_NFE_GENERIC_ATTRIB(i0) (0x00000000 + 0x4*(i0))
459#define VIVS_NFE_GENERIC_ATTRIB__ESIZE 0x00000004
460#define VIVS_NFE_GENERIC_ATTRIB__LEN 0x00000020
461
462#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0(i0) (0x00017800 + 0x4*(i0))
463#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_TYPE__MASK 0x0000000f
464#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_TYPE__SHIFT 0
465#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_TYPE(x) (((x) << VIVS_NFE_GENERIC_ATTRIB_CONFIG0_TYPE__SHIFT) & VIVS_NFE_GENERIC_ATTRIB_CONFIG0_TYPE__MASK)
466#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN__MASK 0x00000030
467#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN__SHIFT 4
468#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN(x) (((x) << VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN__SHIFT) & VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN__MASK)
469#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM__MASK 0x00000700
470#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM__SHIFT 8
471#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM(x) (((x) << VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM__SHIFT) & VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM__MASK)
472#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM__MASK 0x00003000
473#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM__SHIFT 12
474#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM(x) (((x) << VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM__SHIFT) & VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM__MASK)
475#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NORMALIZE__MASK 0x0000c000
476#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NORMALIZE__SHIFT 14
477#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NORMALIZE_OFF 0x00000000
478#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NORMALIZE_ON 0x00008000
479#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START__MASK 0x00ff0000
480#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START__SHIFT 16
481#define VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START(x) (((x) << VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START__SHIFT) & VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START__MASK)
482
483#define VIVS_NFE_GENERIC_ATTRIB_UNK17880(i0) (0x00017880 + 0x4*(i0))
484
485#define VIVS_NFE_GENERIC_ATTRIB_UNK17900(i0) (0x00017900 + 0x4*(i0))
486
487#define VIVS_NFE_GENERIC_ATTRIB_UNK17980(i0) (0x00017980 + 0x4*(i0))
488
489#define VIVS_NFE_GENERIC_ATTRIB_SCALE(i0) (0x00017a00 + 0x4*(i0))
490
491#define VIVS_NFE_GENERIC_ATTRIB_CONFIG1(i0) (0x00017a80 + 0x4*(i0))
492#define VIVS_NFE_GENERIC_ATTRIB_CONFIG1_END__MASK 0x000000ff
493#define VIVS_NFE_GENERIC_ATTRIB_CONFIG1_END__SHIFT 0
494#define VIVS_NFE_GENERIC_ATTRIB_CONFIG1_END(x) (((x) << VIVS_NFE_GENERIC_ATTRIB_CONFIG1_END__SHIFT) & VIVS_NFE_GENERIC_ATTRIB_CONFIG1_END__MASK)
495#define VIVS_NFE_GENERIC_ATTRIB_CONFIG1_NONCONSECUTIVE 0x00000800
496
347#define VIVS_DUMMY 0x00000000 497#define VIVS_DUMMY 0x00000000
348 498
349#define VIVS_DUMMY_DUMMY 0x0003fffc 499#define VIVS_DUMMY_DUMMY 0x0003fffc
diff --git a/drivers/gpu/drm/etnaviv/state_3d.xml.h b/drivers/gpu/drm/etnaviv/state_3d.xml.h
index 73a97d35c51b..ebbd4fcf3096 100644
--- a/drivers/gpu/drm/etnaviv/state_3d.xml.h
+++ b/drivers/gpu/drm/etnaviv/state_3d.xml.h
@@ -7,4 +7,9 @@
7#define VIVS_TS_FLUSH_CACHE 0x00001650 7#define VIVS_TS_FLUSH_CACHE 0x00001650
8#define VIVS_TS_FLUSH_CACHE_FLUSH 0x00000001 8#define VIVS_TS_FLUSH_CACHE_FLUSH 0x00000001
9 9
10#define VIVS_NTE_DESCRIPTOR_FLUSH 0x00014c44
11#define VIVS_NTE_DESCRIPTOR_FLUSH_UNK28__MASK 0xf0000000
12#define VIVS_NTE_DESCRIPTOR_FLUSH_UNK28__SHIFT 28
13#define VIVS_NTE_DESCRIPTOR_FLUSH_UNK28(x) (((x) << VIVS_NTE_DESCRIPTOR_FLUSH_UNK28__SHIFT) & VIVS_NTE_DESCRIPTOR_FLUSH_UNK28__MASK)
14
10#endif /* STATE_3D_XML */ 15#endif /* STATE_3D_XML */
diff --git a/drivers/gpu/drm/etnaviv/state_blt.xml.h b/drivers/gpu/drm/etnaviv/state_blt.xml.h
new file mode 100644
index 000000000000..daae55995def
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/state_blt.xml.h
@@ -0,0 +1,52 @@
1#ifndef STATE_BLT_XML
2#define STATE_BLT_XML
3
4/* Autogenerated file, DO NOT EDIT manually!
5
6This file was generated by the rules-ng-ng headergen tool in this git repository:
7http://0x04.net/cgit/index.cgi/rules-ng-ng
8git clone git://0x04.net/rules-ng-ng
9
10The rules-ng-ng source files this header was generated from are:
11- state.xml ( 26087 bytes, from 2017-12-18 16:51:59)
12- common.xml ( 35468 bytes, from 2018-01-22 13:48:54)
13- common_3d.xml ( 14615 bytes, from 2017-12-18 16:51:59)
14- state_hi.xml ( 30232 bytes, from 2018-02-15 15:48:01)
15- copyright.xml ( 1597 bytes, from 2016-12-08 16:37:56)
16- state_2d.xml ( 51552 bytes, from 2016-12-08 16:37:56)
17- state_3d.xml ( 79992 bytes, from 2017-12-18 16:51:59)
18- state_blt.xml ( 13405 bytes, from 2017-12-18 16:51:59)
19- state_vg.xml ( 5975 bytes, from 2016-12-08 16:37:56)
20
21Copyright (C) 2012-2017 by the following authors:
22- Wladimir J. van der Laan <laanwj@gmail.com>
23- Christian Gmeiner <christian.gmeiner@gmail.com>
24- Lucas Stach <l.stach@pengutronix.de>
25- Russell King <rmk@arm.linux.org.uk>
26
27Permission is hereby granted, free of charge, to any person obtaining a
28copy of this software and associated documentation files (the "Software"),
29to deal in the Software without restriction, including without limitation
30the rights to use, copy, modify, merge, publish, distribute, sub license,
31and/or sell copies of the Software, and to permit persons to whom the
32Software is furnished to do so, subject to the following conditions:
33
34The above copyright notice and this permission notice (including the
35next paragraph) shall be included in all copies or substantial portions
36of the Software.
37
38THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
41THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
43FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
44DEALINGS IN THE SOFTWARE.
45*/
46
47/* This is a cut-down version of the state_blt.xml.h file */
48
49#define VIVS_BLT_ENABLE 0x000140b8
50#define VIVS_BLT_ENABLE_ENABLE 0x00000001
51
52#endif /* STATE_BLT_XML */
diff --git a/drivers/gpu/drm/etnaviv/state_hi.xml.h b/drivers/gpu/drm/etnaviv/state_hi.xml.h
index 60808daf7e8d..41d8da2b6f4f 100644
--- a/drivers/gpu/drm/etnaviv/state_hi.xml.h
+++ b/drivers/gpu/drm/etnaviv/state_hi.xml.h
@@ -1,4 +1,3 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef STATE_HI_XML 1#ifndef STATE_HI_XML
3#define STATE_HI_XML 2#define STATE_HI_XML
4 3
@@ -9,10 +8,40 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
9git clone git://0x04.net/rules-ng-ng 8git clone git://0x04.net/rules-ng-ng
10 9
11The rules-ng-ng source files this header was generated from are: 10The rules-ng-ng source files this header was generated from are:
12- state_hi.xml ( 25620 bytes, from 2016-08-19 22:07:37) 11- state.xml ( 26087 bytes, from 2017-12-18 16:51:59)
13- common.xml ( 20583 bytes, from 2016-06-07 05:22:38) 12- common.xml ( 35468 bytes, from 2018-01-22 13:48:54)
14 13- common_3d.xml ( 14615 bytes, from 2017-12-18 16:51:59)
15Copyright (C) 2016 14- state_hi.xml ( 30232 bytes, from 2018-02-15 15:48:01)
15- copyright.xml ( 1597 bytes, from 2016-12-08 16:37:56)
16- state_2d.xml ( 51552 bytes, from 2016-12-08 16:37:56)
17- state_3d.xml ( 79992 bytes, from 2017-12-18 16:51:59)
18- state_blt.xml ( 13405 bytes, from 2017-12-18 16:51:59)
19- state_vg.xml ( 5975 bytes, from 2016-12-08 16:37:56)
20
21Copyright (C) 2012-2018 by the following authors:
22- Wladimir J. van der Laan <laanwj@gmail.com>
23- Christian Gmeiner <christian.gmeiner@gmail.com>
24- Lucas Stach <l.stach@pengutronix.de>
25- Russell King <rmk@arm.linux.org.uk>
26
27Permission is hereby granted, free of charge, to any person obtaining a
28copy of this software and associated documentation files (the "Software"),
29to deal in the Software without restriction, including without limitation
30the rights to use, copy, modify, merge, publish, distribute, sub license,
31and/or sell copies of the Software, and to permit persons to whom the
32Software is furnished to do so, subject to the following conditions:
33
34The above copyright notice and this permission notice (including the
35next paragraph) shall be included in all copies or substantial portions
36of the Software.
37
38THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
41THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
43FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
44DEALINGS IN THE SOFTWARE.
16*/ 45*/
17 46
18 47
@@ -192,6 +221,9 @@ Copyright (C) 2016
192#define VIVS_HI_CHIP_SPECS_3_GPU_CORE_COUNT__SHIFT 0 221#define VIVS_HI_CHIP_SPECS_3_GPU_CORE_COUNT__SHIFT 0
193#define VIVS_HI_CHIP_SPECS_3_GPU_CORE_COUNT(x) (((x) << VIVS_HI_CHIP_SPECS_3_GPU_CORE_COUNT__SHIFT) & VIVS_HI_CHIP_SPECS_3_GPU_CORE_COUNT__MASK) 222#define VIVS_HI_CHIP_SPECS_3_GPU_CORE_COUNT(x) (((x) << VIVS_HI_CHIP_SPECS_3_GPU_CORE_COUNT__SHIFT) & VIVS_HI_CHIP_SPECS_3_GPU_CORE_COUNT__MASK)
194 223
224#define VIVS_HI_COMPRESSION_FLAGS 0x00000090
225#define VIVS_HI_COMPRESSION_FLAGS_DEC300 0x00000040
226
195#define VIVS_HI_CHIP_MINOR_FEATURE_4 0x00000094 227#define VIVS_HI_CHIP_MINOR_FEATURE_4 0x00000094
196 228
197#define VIVS_HI_CHIP_SPECS_4 0x0000009c 229#define VIVS_HI_CHIP_SPECS_4 0x0000009c
@@ -203,6 +235,10 @@ Copyright (C) 2016
203 235
204#define VIVS_HI_CHIP_PRODUCT_ID 0x000000a8 236#define VIVS_HI_CHIP_PRODUCT_ID 0x000000a8
205 237
238#define VIVS_HI_BLT_INTR 0x000000d4
239
240#define VIVS_HI_AUXBIT 0x000000ec
241
206#define VIVS_PM 0x00000000 242#define VIVS_PM 0x00000000
207 243
208#define VIVS_PM_POWER_CONTROLS 0x00000100 244#define VIVS_PM_POWER_CONTROLS 0x00000100
@@ -239,6 +275,17 @@ Copyright (C) 2016
239#define VIVS_PM_MODULE_STATUS_MODULE_CLOCK_GATED_TX 0x00000080 275#define VIVS_PM_MODULE_STATUS_MODULE_CLOCK_GATED_TX 0x00000080
240 276
241#define VIVS_PM_PULSE_EATER 0x0000010c 277#define VIVS_PM_PULSE_EATER 0x0000010c
278#define VIVS_PM_PULSE_EATER_DISABLE 0x00000001
279#define VIVS_PM_PULSE_EATER_DVFS_PERIOD__MASK 0x0000ff00
280#define VIVS_PM_PULSE_EATER_DVFS_PERIOD__SHIFT 8
281#define VIVS_PM_PULSE_EATER_DVFS_PERIOD(x) (((x) << VIVS_PM_PULSE_EATER_DVFS_PERIOD__SHIFT) & VIVS_PM_PULSE_EATER_DVFS_PERIOD__MASK)
282#define VIVS_PM_PULSE_EATER_UNK16 0x00010000
283#define VIVS_PM_PULSE_EATER_UNK17 0x00020000
284#define VIVS_PM_PULSE_EATER_INTERNAL_DFS 0x00040000
285#define VIVS_PM_PULSE_EATER_UNK19 0x00080000
286#define VIVS_PM_PULSE_EATER_UNK20 0x00100000
287#define VIVS_PM_PULSE_EATER_UNK22 0x00400000
288#define VIVS_PM_PULSE_EATER_UNK23 0x00800000
242 289
243#define VIVS_MMUv2 0x00000000 290#define VIVS_MMUv2 0x00000000
244 291
@@ -280,6 +327,68 @@ Copyright (C) 2016
280#define VIVS_MMUv2_EXCEPTION_ADDR__ESIZE 0x00000004 327#define VIVS_MMUv2_EXCEPTION_ADDR__ESIZE 0x00000004
281#define VIVS_MMUv2_EXCEPTION_ADDR__LEN 0x00000004 328#define VIVS_MMUv2_EXCEPTION_ADDR__LEN 0x00000004
282 329
330#define VIVS_MMUv2_PROFILE_BLT_READ 0x000001a4
331
332#define VIVS_MMUv2_PTA_CONFIG 0x000001ac
333#define VIVS_MMUv2_PTA_CONFIG_INDEX__MASK 0x0000ffff
334#define VIVS_MMUv2_PTA_CONFIG_INDEX__SHIFT 0
335#define VIVS_MMUv2_PTA_CONFIG_INDEX(x) (((x) << VIVS_MMUv2_PTA_CONFIG_INDEX__SHIFT) & VIVS_MMUv2_PTA_CONFIG_INDEX__MASK)
336#define VIVS_MMUv2_PTA_CONFIG_UNK16 0x00010000
337
338#define VIVS_MMUv2_AXI_POLICY(i0) (0x000001c0 + 0x4*(i0))
339#define VIVS_MMUv2_AXI_POLICY__ESIZE 0x00000004
340#define VIVS_MMUv2_AXI_POLICY__LEN 0x00000008
341
342#define VIVS_MMUv2_SEC_EXCEPTION_ADDR 0x00000380
343
344#define VIVS_MMUv2_SEC_STATUS 0x00000384
345#define VIVS_MMUv2_SEC_STATUS_EXCEPTION0__MASK 0x00000003
346#define VIVS_MMUv2_SEC_STATUS_EXCEPTION0__SHIFT 0
347#define VIVS_MMUv2_SEC_STATUS_EXCEPTION0(x) (((x) << VIVS_MMUv2_SEC_STATUS_EXCEPTION0__SHIFT) & VIVS_MMUv2_SEC_STATUS_EXCEPTION0__MASK)
348#define VIVS_MMUv2_SEC_STATUS_EXCEPTION1__MASK 0x00000030
349#define VIVS_MMUv2_SEC_STATUS_EXCEPTION1__SHIFT 4
350#define VIVS_MMUv2_SEC_STATUS_EXCEPTION1(x) (((x) << VIVS_MMUv2_SEC_STATUS_EXCEPTION1__SHIFT) & VIVS_MMUv2_SEC_STATUS_EXCEPTION1__MASK)
351#define VIVS_MMUv2_SEC_STATUS_EXCEPTION2__MASK 0x00000300
352#define VIVS_MMUv2_SEC_STATUS_EXCEPTION2__SHIFT 8
353#define VIVS_MMUv2_SEC_STATUS_EXCEPTION2(x) (((x) << VIVS_MMUv2_SEC_STATUS_EXCEPTION2__SHIFT) & VIVS_MMUv2_SEC_STATUS_EXCEPTION2__MASK)
354#define VIVS_MMUv2_SEC_STATUS_EXCEPTION3__MASK 0x00003000
355#define VIVS_MMUv2_SEC_STATUS_EXCEPTION3__SHIFT 12
356#define VIVS_MMUv2_SEC_STATUS_EXCEPTION3(x) (((x) << VIVS_MMUv2_SEC_STATUS_EXCEPTION3__SHIFT) & VIVS_MMUv2_SEC_STATUS_EXCEPTION3__MASK)
357
358#define VIVS_MMUv2_SEC_CONTROL 0x00000388
359#define VIVS_MMUv2_SEC_CONTROL_ENABLE 0x00000001
360
361#define VIVS_MMUv2_PTA_ADDRESS_LOW 0x0000038c
362
363#define VIVS_MMUv2_PTA_ADDRESS_HIGH 0x00000390
364
365#define VIVS_MMUv2_PTA_CONTROL 0x00000394
366#define VIVS_MMUv2_PTA_CONTROL_ENABLE 0x00000001
367
368#define VIVS_MMUv2_NONSEC_SAFE_ADDR_LOW 0x00000398
369
370#define VIVS_MMUv2_SEC_SAFE_ADDR_LOW 0x0000039c
371
372#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG 0x000003a0
373#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG_NON_SEC_SAFE_ADDR_HIGH__MASK 0x000000ff
374#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG_NON_SEC_SAFE_ADDR_HIGH__SHIFT 0
375#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG_NON_SEC_SAFE_ADDR_HIGH(x) (((x) << VIVS_MMUv2_SAFE_ADDRESS_CONFIG_NON_SEC_SAFE_ADDR_HIGH__SHIFT) & VIVS_MMUv2_SAFE_ADDRESS_CONFIG_NON_SEC_SAFE_ADDR_HIGH__MASK)
376#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG_UNK15 0x00008000
377#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG_SEC_SAFE_ADDR_HIGH__MASK 0x00ff0000
378#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG_SEC_SAFE_ADDR_HIGH__SHIFT 16
379#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG_SEC_SAFE_ADDR_HIGH(x) (((x) << VIVS_MMUv2_SAFE_ADDRESS_CONFIG_SEC_SAFE_ADDR_HIGH__SHIFT) & VIVS_MMUv2_SAFE_ADDRESS_CONFIG_SEC_SAFE_ADDR_HIGH__MASK)
380#define VIVS_MMUv2_SAFE_ADDRESS_CONFIG_UNK31 0x80000000
381
382#define VIVS_MMUv2_SEC_COMMAND_CONTROL 0x000003a4
383#define VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH__MASK 0x0000ffff
384#define VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH__SHIFT 0
385#define VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(x) (((x) << VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH__SHIFT) & VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH__MASK)
386#define VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE 0x00010000
387
388#define VIVS_MMUv2_AHB_CONTROL 0x000003a8
389#define VIVS_MMUv2_AHB_CONTROL_RESET 0x00000001
390#define VIVS_MMUv2_AHB_CONTROL_NONSEC_ACCESS 0x00000002
391
283#define VIVS_MC 0x00000000 392#define VIVS_MC 0x00000000
284 393
285#define VIVS_MC_MMU_FE_PAGE_TABLE 0x00000400 394#define VIVS_MC_MMU_FE_PAGE_TABLE 0x00000400
@@ -340,13 +449,13 @@ Copyright (C) 2016
340#define VIVS_MC_PROFILE_HI_READ 0x0000046c 449#define VIVS_MC_PROFILE_HI_READ 0x0000046c
341 450
342#define VIVS_MC_PROFILE_CONFIG0 0x00000470 451#define VIVS_MC_PROFILE_CONFIG0 0x00000470
343#define VIVS_MC_PROFILE_CONFIG0_FE__MASK 0x0000000f 452#define VIVS_MC_PROFILE_CONFIG0_FE__MASK 0x000000ff
344#define VIVS_MC_PROFILE_CONFIG0_FE__SHIFT 0 453#define VIVS_MC_PROFILE_CONFIG0_FE__SHIFT 0
345#define VIVS_MC_PROFILE_CONFIG0_FE_RESET 0x0000000f 454#define VIVS_MC_PROFILE_CONFIG0_FE_RESET 0x0000000f
346#define VIVS_MC_PROFILE_CONFIG0_DE__MASK 0x00000f00 455#define VIVS_MC_PROFILE_CONFIG0_DE__MASK 0x0000ff00
347#define VIVS_MC_PROFILE_CONFIG0_DE__SHIFT 8 456#define VIVS_MC_PROFILE_CONFIG0_DE__SHIFT 8
348#define VIVS_MC_PROFILE_CONFIG0_DE_RESET 0x00000f00 457#define VIVS_MC_PROFILE_CONFIG0_DE_RESET 0x00000f00
349#define VIVS_MC_PROFILE_CONFIG0_PE__MASK 0x000f0000 458#define VIVS_MC_PROFILE_CONFIG0_PE__MASK 0x00ff0000
350#define VIVS_MC_PROFILE_CONFIG0_PE__SHIFT 16 459#define VIVS_MC_PROFILE_CONFIG0_PE__SHIFT 16
351#define VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE 0x00000000 460#define VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE 0x00000000
352#define VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE 0x00010000 461#define VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE 0x00010000
@@ -354,7 +463,7 @@ Copyright (C) 2016
354#define VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE 0x00030000 463#define VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE 0x00030000
355#define VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D 0x000b0000 464#define VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D 0x000b0000
356#define VIVS_MC_PROFILE_CONFIG0_PE_RESET 0x000f0000 465#define VIVS_MC_PROFILE_CONFIG0_PE_RESET 0x000f0000
357#define VIVS_MC_PROFILE_CONFIG0_SH__MASK 0x0f000000 466#define VIVS_MC_PROFILE_CONFIG0_SH__MASK 0xff000000
358#define VIVS_MC_PROFILE_CONFIG0_SH__SHIFT 24 467#define VIVS_MC_PROFILE_CONFIG0_SH__SHIFT 24
359#define VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES 0x04000000 468#define VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES 0x04000000
360#define VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER 0x07000000 469#define VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER 0x07000000
@@ -368,7 +477,7 @@ Copyright (C) 2016
368#define VIVS_MC_PROFILE_CONFIG0_SH_RESET 0x0f000000 477#define VIVS_MC_PROFILE_CONFIG0_SH_RESET 0x0f000000
369 478
370#define VIVS_MC_PROFILE_CONFIG1 0x00000474 479#define VIVS_MC_PROFILE_CONFIG1 0x00000474
371#define VIVS_MC_PROFILE_CONFIG1_PA__MASK 0x0000000f 480#define VIVS_MC_PROFILE_CONFIG1_PA__MASK 0x000000ff
372#define VIVS_MC_PROFILE_CONFIG1_PA__SHIFT 0 481#define VIVS_MC_PROFILE_CONFIG1_PA__SHIFT 0
373#define VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER 0x00000003 482#define VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER 0x00000003
374#define VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER 0x00000004 483#define VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER 0x00000004
@@ -377,12 +486,12 @@ Copyright (C) 2016
377#define VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER 0x00000007 486#define VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER 0x00000007
378#define VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER 0x00000008 487#define VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER 0x00000008
379#define VIVS_MC_PROFILE_CONFIG1_PA_RESET 0x0000000f 488#define VIVS_MC_PROFILE_CONFIG1_PA_RESET 0x0000000f
380#define VIVS_MC_PROFILE_CONFIG1_SE__MASK 0x00000f00 489#define VIVS_MC_PROFILE_CONFIG1_SE__MASK 0x0000ff00
381#define VIVS_MC_PROFILE_CONFIG1_SE__SHIFT 8 490#define VIVS_MC_PROFILE_CONFIG1_SE__SHIFT 8
382#define VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT 0x00000000 491#define VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT 0x00000000
383#define VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT 0x00000100 492#define VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT 0x00000100
384#define VIVS_MC_PROFILE_CONFIG1_SE_RESET 0x00000f00 493#define VIVS_MC_PROFILE_CONFIG1_SE_RESET 0x00000f00
385#define VIVS_MC_PROFILE_CONFIG1_RA__MASK 0x000f0000 494#define VIVS_MC_PROFILE_CONFIG1_RA__MASK 0x00ff0000
386#define VIVS_MC_PROFILE_CONFIG1_RA__SHIFT 16 495#define VIVS_MC_PROFILE_CONFIG1_RA__SHIFT 16
387#define VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT 0x00000000 496#define VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT 0x00000000
388#define VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT 0x00010000 497#define VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT 0x00010000
@@ -392,7 +501,7 @@ Copyright (C) 2016
392#define VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER 0x000a0000 501#define VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER 0x000a0000
393#define VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT 0x000b0000 502#define VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT 0x000b0000
394#define VIVS_MC_PROFILE_CONFIG1_RA_RESET 0x000f0000 503#define VIVS_MC_PROFILE_CONFIG1_RA_RESET 0x000f0000
395#define VIVS_MC_PROFILE_CONFIG1_TX__MASK 0x0f000000 504#define VIVS_MC_PROFILE_CONFIG1_TX__MASK 0xff000000
396#define VIVS_MC_PROFILE_CONFIG1_TX__SHIFT 24 505#define VIVS_MC_PROFILE_CONFIG1_TX__SHIFT 24
397#define VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS 0x00000000 506#define VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS 0x00000000
398#define VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS 0x01000000 507#define VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS 0x01000000
@@ -407,18 +516,21 @@ Copyright (C) 2016
407#define VIVS_MC_PROFILE_CONFIG1_TX_RESET 0x0f000000 516#define VIVS_MC_PROFILE_CONFIG1_TX_RESET 0x0f000000
408 517
409#define VIVS_MC_PROFILE_CONFIG2 0x00000478 518#define VIVS_MC_PROFILE_CONFIG2 0x00000478
410#define VIVS_MC_PROFILE_CONFIG2_MC__MASK 0x0000000f 519#define VIVS_MC_PROFILE_CONFIG2_MC__MASK 0x000000ff
411#define VIVS_MC_PROFILE_CONFIG2_MC__SHIFT 0 520#define VIVS_MC_PROFILE_CONFIG2_MC__SHIFT 0
412#define VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE 0x00000001 521#define VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE 0x00000001
413#define VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP 0x00000002 522#define VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP 0x00000002
414#define VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE 0x00000003 523#define VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE 0x00000003
415#define VIVS_MC_PROFILE_CONFIG2_MC_RESET 0x0000000f 524#define VIVS_MC_PROFILE_CONFIG2_MC_RESET 0x0000000f
416#define VIVS_MC_PROFILE_CONFIG2_HI__MASK 0x00000f00 525#define VIVS_MC_PROFILE_CONFIG2_HI__MASK 0x0000ff00
417#define VIVS_MC_PROFILE_CONFIG2_HI__SHIFT 8 526#define VIVS_MC_PROFILE_CONFIG2_HI__SHIFT 8
418#define VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED 0x00000000 527#define VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED 0x00000000
419#define VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED 0x00000100 528#define VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED 0x00000100
420#define VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED 0x00000200 529#define VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED 0x00000200
421#define VIVS_MC_PROFILE_CONFIG2_HI_RESET 0x00000f00 530#define VIVS_MC_PROFILE_CONFIG2_HI_RESET 0x00000f00
531#define VIVS_MC_PROFILE_CONFIG2_BLT__MASK 0xff000000
532#define VIVS_MC_PROFILE_CONFIG2_BLT__SHIFT 24
533#define VIVS_MC_PROFILE_CONFIG2_BLT_UNK0 0x00000000
422 534
423#define VIVS_MC_PROFILE_CONFIG3 0x0000047c 535#define VIVS_MC_PROFILE_CONFIG3 0x0000047c
424 536
@@ -432,7 +544,13 @@ Copyright (C) 2016
432 544
433#define VIVS_MC_START_COMPOSITION 0x00000554 545#define VIVS_MC_START_COMPOSITION 0x00000554
434 546
435#define VIVS_MC_128B_MERGE 0x00000558 547#define VIVS_MC_FLAGS 0x00000558
548#define VIVS_MC_FLAGS_128B_MERGE 0x00000001
549#define VIVS_MC_FLAGS_TPCV11_COMPRESSION 0x08000000
550
551#define VIVS_MC_L2_CACHE_CONFIG 0x0000055c
552
553#define VIVS_MC_PROFILE_L2_READ 0x00000564
436 554
437 555
438#endif /* STATE_HI_XML */ 556#endif /* STATE_HI_XML */
diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c
index 89ab0f70aa22..c6a7beabd58d 100644
--- a/drivers/gpu/drm/i915/intel_color.c
+++ b/drivers/gpu/drm/i915/intel_color.c
@@ -39,7 +39,7 @@
39#define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0) 39#define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0)
40#define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1)) 40#define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1))
41 41
42#define LEGACY_LUT_LENGTH (sizeof(struct drm_color_lut) * 256) 42#define LEGACY_LUT_LENGTH 256
43 43
44/* Post offset values for RGB->YCBCR conversion */ 44/* Post offset values for RGB->YCBCR conversion */
45#define POSTOFF_RGB_TO_YUV_HI 0x800 45#define POSTOFF_RGB_TO_YUV_HI 0x800
@@ -79,7 +79,7 @@ static bool crtc_state_is_legacy_gamma(struct drm_crtc_state *state)
79 return !state->degamma_lut && 79 return !state->degamma_lut &&
80 !state->ctm && 80 !state->ctm &&
81 state->gamma_lut && 81 state->gamma_lut &&
82 state->gamma_lut->length == LEGACY_LUT_LENGTH; 82 drm_color_lut_size(state->gamma_lut) == LEGACY_LUT_LENGTH;
83} 83}
84 84
85/* 85/*
@@ -153,8 +153,7 @@ static void ilk_load_csc_matrix(struct drm_crtc_state *crtc_state)
153 ilk_load_ycbcr_conversion_matrix(intel_crtc); 153 ilk_load_ycbcr_conversion_matrix(intel_crtc);
154 return; 154 return;
155 } else if (crtc_state->ctm) { 155 } else if (crtc_state->ctm) {
156 struct drm_color_ctm *ctm = 156 struct drm_color_ctm *ctm = crtc_state->ctm->data;
157 (struct drm_color_ctm *)crtc_state->ctm->data;
158 const u64 *input; 157 const u64 *input;
159 u64 temp[9]; 158 u64 temp[9];
160 159
@@ -262,8 +261,7 @@ static void cherryview_load_csc_matrix(struct drm_crtc_state *state)
262 uint32_t mode; 261 uint32_t mode;
263 262
264 if (state->ctm) { 263 if (state->ctm) {
265 struct drm_color_ctm *ctm = 264 struct drm_color_ctm *ctm = state->ctm->data;
266 (struct drm_color_ctm *) state->ctm->data;
267 uint16_t coeffs[9] = { 0, }; 265 uint16_t coeffs[9] = { 0, };
268 int i; 266 int i;
269 267
@@ -330,7 +328,7 @@ static void i9xx_load_luts_internal(struct drm_crtc *crtc,
330 } 328 }
331 329
332 if (blob) { 330 if (blob) {
333 struct drm_color_lut *lut = (struct drm_color_lut *) blob->data; 331 struct drm_color_lut *lut = blob->data;
334 for (i = 0; i < 256; i++) { 332 for (i = 0; i < 256; i++) {
335 uint32_t word = 333 uint32_t word =
336 (drm_color_lut_extract(lut[i].red, 8) << 16) | 334 (drm_color_lut_extract(lut[i].red, 8) << 16) |
@@ -400,8 +398,7 @@ static void bdw_load_degamma_lut(struct drm_crtc_state *state)
400 PAL_PREC_SPLIT_MODE | PAL_PREC_AUTO_INCREMENT); 398 PAL_PREC_SPLIT_MODE | PAL_PREC_AUTO_INCREMENT);
401 399
402 if (state->degamma_lut) { 400 if (state->degamma_lut) {
403 struct drm_color_lut *lut = 401 struct drm_color_lut *lut = state->degamma_lut->data;
404 (struct drm_color_lut *) state->degamma_lut->data;
405 402
406 for (i = 0; i < lut_size; i++) { 403 for (i = 0; i < lut_size; i++) {
407 uint32_t word = 404 uint32_t word =
@@ -435,8 +432,7 @@ static void bdw_load_gamma_lut(struct drm_crtc_state *state, u32 offset)
435 offset); 432 offset);
436 433
437 if (state->gamma_lut) { 434 if (state->gamma_lut) {
438 struct drm_color_lut *lut = 435 struct drm_color_lut *lut = state->gamma_lut->data;
439 (struct drm_color_lut *) state->gamma_lut->data;
440 436
441 for (i = 0; i < lut_size; i++) { 437 for (i = 0; i < lut_size; i++) {
442 uint32_t word = 438 uint32_t word =
@@ -568,7 +564,7 @@ static void cherryview_load_luts(struct drm_crtc_state *state)
568 } 564 }
569 565
570 if (state->degamma_lut) { 566 if (state->degamma_lut) {
571 lut = (struct drm_color_lut *) state->degamma_lut->data; 567 lut = state->degamma_lut->data;
572 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size; 568 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
573 for (i = 0; i < lut_size; i++) { 569 for (i = 0; i < lut_size; i++) {
574 /* Write LUT in U0.14 format. */ 570 /* Write LUT in U0.14 format. */
@@ -583,7 +579,7 @@ static void cherryview_load_luts(struct drm_crtc_state *state)
583 } 579 }
584 580
585 if (state->gamma_lut) { 581 if (state->gamma_lut) {
586 lut = (struct drm_color_lut *) state->gamma_lut->data; 582 lut = state->gamma_lut->data;
587 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size; 583 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
588 for (i = 0; i < lut_size; i++) { 584 for (i = 0; i < lut_size; i++) {
589 /* Write LUT in U0.10 format. */ 585 /* Write LUT in U0.10 format. */
@@ -623,19 +619,17 @@ int intel_color_check(struct drm_crtc *crtc,
623 struct drm_i915_private *dev_priv = to_i915(crtc->dev); 619 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
624 size_t gamma_length, degamma_length; 620 size_t gamma_length, degamma_length;
625 621
626 degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size * 622 degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
627 sizeof(struct drm_color_lut); 623 gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
628 gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size *
629 sizeof(struct drm_color_lut);
630 624
631 /* 625 /*
632 * We allow both degamma & gamma luts at the right size or 626 * We allow both degamma & gamma luts at the right size or
633 * NULL. 627 * NULL.
634 */ 628 */
635 if ((!crtc_state->degamma_lut || 629 if ((!crtc_state->degamma_lut ||
636 crtc_state->degamma_lut->length == degamma_length) && 630 drm_color_lut_size(crtc_state->degamma_lut) == degamma_length) &&
637 (!crtc_state->gamma_lut || 631 (!crtc_state->gamma_lut ||
638 crtc_state->gamma_lut->length == gamma_length)) 632 drm_color_lut_size(crtc_state->gamma_lut) == gamma_length))
639 return 0; 633 return 0;
640 634
641 /* 635 /*
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 331084082545..3b48fd2561fe 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11059,24 +11059,17 @@ intel_compare_link_m_n(const struct intel_link_m_n *m_n,
11059static void __printf(3, 4) 11059static void __printf(3, 4)
11060pipe_config_err(bool adjust, const char *name, const char *format, ...) 11060pipe_config_err(bool adjust, const char *name, const char *format, ...)
11061{ 11061{
11062 char *level;
11063 unsigned int category;
11064 struct va_format vaf; 11062 struct va_format vaf;
11065 va_list args; 11063 va_list args;
11066 11064
11067 if (adjust) {
11068 level = KERN_DEBUG;
11069 category = DRM_UT_KMS;
11070 } else {
11071 level = KERN_ERR;
11072 category = DRM_UT_NONE;
11073 }
11074
11075 va_start(args, format); 11065 va_start(args, format);
11076 vaf.fmt = format; 11066 vaf.fmt = format;
11077 vaf.va = &args; 11067 vaf.va = &args;
11078 11068
11079 drm_printk(level, category, "mismatch in %s %pV", name, &vaf); 11069 if (adjust)
11070 drm_dbg(DRM_UT_KMS, "mismatch in %s %pV", name, &vaf);
11071 else
11072 drm_err("mismatch in %s %pV", name, &vaf);
11080 11073
11081 va_end(args); 11074 va_end(args);
11082} 11075}
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index f9ad0e960263..32b1a6cdecfc 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -189,40 +189,55 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
189 189
190 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu"); 190 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu");
191 regs = devm_ioremap_resource(dev, res); 191 regs = devm_ioremap_resource(dev, res);
192 if (IS_ERR(regs)) 192 if (IS_ERR(regs)) {
193 return PTR_ERR(regs); 193 ret = PTR_ERR(regs);
194 goto free_drm;
195 }
194 196
195 priv->io_base = regs; 197 priv->io_base = regs;
196 198
197 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi"); 199 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi");
200 if (!res)
201 return -EINVAL;
198 /* Simply ioremap since it may be a shared register zone */ 202 /* Simply ioremap since it may be a shared register zone */
199 regs = devm_ioremap(dev, res->start, resource_size(res)); 203 regs = devm_ioremap(dev, res->start, resource_size(res));
200 if (!regs) 204 if (!regs) {
201 return -EADDRNOTAVAIL; 205 ret = -EADDRNOTAVAIL;
206 goto free_drm;
207 }
202 208
203 priv->hhi = devm_regmap_init_mmio(dev, regs, 209 priv->hhi = devm_regmap_init_mmio(dev, regs,
204 &meson_regmap_config); 210 &meson_regmap_config);
205 if (IS_ERR(priv->hhi)) { 211 if (IS_ERR(priv->hhi)) {
206 dev_err(&pdev->dev, "Couldn't create the HHI regmap\n"); 212 dev_err(&pdev->dev, "Couldn't create the HHI regmap\n");
207 return PTR_ERR(priv->hhi); 213 ret = PTR_ERR(priv->hhi);
214 goto free_drm;
208 } 215 }
209 216
210 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc"); 217 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
218 if (!res)
219 return -EINVAL;
211 /* Simply ioremap since it may be a shared register zone */ 220 /* Simply ioremap since it may be a shared register zone */
212 regs = devm_ioremap(dev, res->start, resource_size(res)); 221 regs = devm_ioremap(dev, res->start, resource_size(res));
213 if (!regs) 222 if (!regs) {
214 return -EADDRNOTAVAIL; 223 ret = -EADDRNOTAVAIL;
224 goto free_drm;
225 }
215 226
216 priv->dmc = devm_regmap_init_mmio(dev, regs, 227 priv->dmc = devm_regmap_init_mmio(dev, regs,
217 &meson_regmap_config); 228 &meson_regmap_config);
218 if (IS_ERR(priv->dmc)) { 229 if (IS_ERR(priv->dmc)) {
219 dev_err(&pdev->dev, "Couldn't create the DMC regmap\n"); 230 dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
220 return PTR_ERR(priv->dmc); 231 ret = PTR_ERR(priv->dmc);
232 goto free_drm;
221 } 233 }
222 234
223 priv->vsync_irq = platform_get_irq(pdev, 0); 235 priv->vsync_irq = platform_get_irq(pdev, 0);
224 236
225 drm_vblank_init(drm, 1); 237 ret = drm_vblank_init(drm, 1);
238 if (ret)
239 goto free_drm;
240
226 drm_mode_config_init(drm); 241 drm_mode_config_init(drm);
227 drm->mode_config.max_width = 3840; 242 drm->mode_config.max_width = 3840;
228 drm->mode_config.max_height = 2160; 243 drm->mode_config.max_height = 2160;
@@ -281,7 +296,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
281 return 0; 296 return 0;
282 297
283free_drm: 298free_drm:
284 drm_dev_unref(drm); 299 drm_dev_put(drm);
285 300
286 return ret; 301 return ret;
287} 302}
@@ -300,7 +315,7 @@ static void meson_drv_unbind(struct device *dev)
300 drm_kms_helper_poll_fini(drm); 315 drm_kms_helper_poll_fini(drm);
301 drm_fbdev_cma_fini(priv->fbdev); 316 drm_fbdev_cma_fini(priv->fbdev);
302 drm_mode_config_cleanup(drm); 317 drm_mode_config_cleanup(drm);
303 drm_dev_unref(drm); 318 drm_dev_put(drm);
304 319
305} 320}
306 321
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index d49af17310c9..a393095aac1a 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -538,7 +538,6 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
538 return IRQ_HANDLED; 538 return IRQ_HANDLED;
539} 539}
540 540
541/* TOFIX Enable support for non-vic modes */
542static enum drm_mode_status 541static enum drm_mode_status
543dw_hdmi_mode_valid(struct drm_connector *connector, 542dw_hdmi_mode_valid(struct drm_connector *connector,
544 const struct drm_display_mode *mode) 543 const struct drm_display_mode *mode)
@@ -555,12 +554,12 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
555 mode->vdisplay, mode->vsync_start, 554 mode->vdisplay, mode->vsync_start,
556 mode->vsync_end, mode->vtotal, mode->type, mode->flags); 555 mode->vsync_end, mode->vtotal, mode->type, mode->flags);
557 556
558 /* For now, only accept VIC modes */ 557 /* Check against non-VIC supported modes */
559 if (!vic) 558 if (!vic) {
560 return MODE_BAD; 559 if (!meson_venc_hdmi_supported_mode(mode))
561 560 return MODE_BAD;
562 /* For now, filter by supported VIC modes */ 561 /* Check against supported VIC modes */
563 if (!meson_venc_hdmi_supported_vic(vic)) 562 } else if (!meson_venc_hdmi_supported_vic(vic))
564 return MODE_BAD; 563 return MODE_BAD;
565 564
566 vclk_freq = mode->clock; 565 vclk_freq = mode->clock;
@@ -586,9 +585,14 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
586 585
587 /* Finally filter by configurable vclk frequencies */ 586 /* Finally filter by configurable vclk frequencies */
588 switch (vclk_freq) { 587 switch (vclk_freq) {
588 case 25175:
589 case 40000:
589 case 54000: 590 case 54000:
591 case 65000:
590 case 74250: 592 case 74250:
593 case 108000:
591 case 148500: 594 case 148500:
595 case 162000:
592 case 297000: 596 case 297000:
593 case 594000: 597 case 594000:
594 return MODE_OK; 598 return MODE_OK;
@@ -653,10 +657,6 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder,
653 DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n", 657 DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n",
654 mode->base.id, mode->name, vic); 658 mode->base.id, mode->name, vic);
655 659
656 /* Should have been filtered */
657 if (!vic)
658 return;
659
660 /* VENC + VENC-DVI Mode setup */ 660 /* VENC + VENC-DVI Mode setup */
661 meson_venc_hdmi_mode_set(priv, vic, mode); 661 meson_venc_hdmi_mode_set(priv, vic, mode);
662 662
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index 47677047e42d..f0511220317f 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -328,14 +328,24 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
328#define MESON_VCLK_HDMI_DDR_54000 2 328#define MESON_VCLK_HDMI_DDR_54000 2
329/* 2970 /4 /1 /1 /5 /1 => /1 /2 */ 329/* 2970 /4 /1 /1 /5 /1 => /1 /2 */
330#define MESON_VCLK_HDMI_DDR_148500 3 330#define MESON_VCLK_HDMI_DDR_148500 3
331/* 4028 /4 /4 /1 /5 /2 => /1 /1 */
332#define MESON_VCLK_HDMI_25175 4
333/* 3200 /4 /2 /1 /5 /2 => /1 /1 */
334#define MESON_VCLK_HDMI_40000 5
335/* 5200 /4 /2 /1 /5 /2 => /1 /1 */
336#define MESON_VCLK_HDMI_65000 6
331/* 2970 /2 /2 /2 /5 /1 => /1 /1 */ 337/* 2970 /2 /2 /2 /5 /1 => /1 /1 */
332#define MESON_VCLK_HDMI_74250 4 338#define MESON_VCLK_HDMI_74250 7
339/* 4320 /4 /1 /1 /5 /2 => /1 /1 */
340#define MESON_VCLK_HDMI_108000 8
333/* 2970 /1 /2 /2 /5 /1 => /1 /1 */ 341/* 2970 /1 /2 /2 /5 /1 => /1 /1 */
334#define MESON_VCLK_HDMI_148500 5 342#define MESON_VCLK_HDMI_148500 9
343/* 3240 /2 /1 /1 /5 /2 => /1 /1 */
344#define MESON_VCLK_HDMI_162000 10
335/* 2970 /1 /1 /1 /5 /2 => /1 /1 */ 345/* 2970 /1 /1 /1 /5 /2 => /1 /1 */
336#define MESON_VCLK_HDMI_297000 6 346#define MESON_VCLK_HDMI_297000 11
337/* 5940 /1 /1 /2 /5 /1 => /1 /1 */ 347/* 5940 /1 /1 /2 /5 /1 => /1 /1 */
338#define MESON_VCLK_HDMI_594000 7 348#define MESON_VCLK_HDMI_594000 12
339 349
340struct meson_vclk_params { 350struct meson_vclk_params {
341 unsigned int pll_base_freq; 351 unsigned int pll_base_freq;
@@ -401,6 +411,46 @@ struct meson_vclk_params {
401 .vid_pll_div = VID_PLL_DIV_5, 411 .vid_pll_div = VID_PLL_DIV_5,
402 .vclk_div = 1, 412 .vclk_div = 1,
403 }, 413 },
414 [MESON_VCLK_HDMI_25175] = {
415 .pll_base_freq = 4028000,
416 .pll_od1 = 4,
417 .pll_od2 = 4,
418 .pll_od3 = 1,
419 .vid_pll_div = VID_PLL_DIV_5,
420 .vclk_div = 2,
421 },
422 [MESON_VCLK_HDMI_40000] = {
423 .pll_base_freq = 3200000,
424 .pll_od1 = 4,
425 .pll_od2 = 2,
426 .pll_od3 = 1,
427 .vid_pll_div = VID_PLL_DIV_5,
428 .vclk_div = 2,
429 },
430 [MESON_VCLK_HDMI_65000] = {
431 .pll_base_freq = 5200000,
432 .pll_od1 = 4,
433 .pll_od2 = 2,
434 .pll_od3 = 1,
435 .vid_pll_div = VID_PLL_DIV_5,
436 .vclk_div = 2,
437 },
438 [MESON_VCLK_HDMI_108000] = {
439 .pll_base_freq = 4320000,
440 .pll_od1 = 4,
441 .pll_od2 = 1,
442 .pll_od3 = 1,
443 .vid_pll_div = VID_PLL_DIV_5,
444 .vclk_div = 2,
445 },
446 [MESON_VCLK_HDMI_162000] = {
447 .pll_base_freq = 3240000,
448 .pll_od1 = 2,
449 .pll_od2 = 1,
450 .pll_od3 = 1,
451 .vid_pll_div = VID_PLL_DIV_5,
452 .vclk_div = 2,
453 },
404}; 454};
405 455
406static inline unsigned int pll_od_to_reg(unsigned int od) 456static inline unsigned int pll_od_to_reg(unsigned int od)
@@ -451,6 +501,90 @@ void meson_hdmi_pll_set(struct meson_drm *priv,
451 0xFFFF, 0x4e00); 501 0xFFFF, 0x4e00);
452 break; 502 break;
453 503
504 case 3200000:
505 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000242);
506 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
507 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
508 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
509 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
510 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
511
512 /* unreset */
513 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
514 BIT(28), 0);
515
516 /* Poll for lock bit */
517 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
518 val, (val & HDMI_PLL_LOCK), 10, 0);
519
520 /* div_frac */
521 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
522 0xFFFF, 0x4aab);
523 break;
524
525 case 3240000:
526 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000243);
527 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
528 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
529 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
530 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
531 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
532
533 /* unreset */
534 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
535 BIT(28), 0);
536
537 /* Poll for lock bit */
538 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
539 val, (val & HDMI_PLL_LOCK), 10, 0);
540
541 /* div_frac */
542 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
543 0xFFFF, 0x4800);
544 break;
545
546 case 3865000:
547 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000250);
548 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
549 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
550 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
551 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
552 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
553
554 /* unreset */
555 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
556 BIT(28), 0);
557
558 /* Poll for lock bit */
559 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
560 val, (val & HDMI_PLL_LOCK), 10, 0);
561
562 /* div_frac */
563 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
564 0xFFFF, 0x4855);
565 break;
566
567 case 4028000:
568 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000253);
569 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
570 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
571 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
572 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
573 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
574
575 /* unreset */
576 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
577 BIT(28), 0);
578
579 /* Poll for lock bit */
580 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
581 val, (val & HDMI_PLL_LOCK), 10, 0);
582
583 /* div_frac */
584 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
585 0xFFFF, 0x4eab);
586 break;
587
454 case 4320000: 588 case 4320000:
455 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a); 589 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a);
456 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); 590 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
@@ -485,6 +619,23 @@ void meson_hdmi_pll_set(struct meson_drm *priv,
485 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, 619 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
486 val, (val & HDMI_PLL_LOCK), 10, 0); 620 val, (val & HDMI_PLL_LOCK), 10, 0);
487 break; 621 break;
622
623 case 5200000:
624 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800026c);
625 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
626 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091);
627 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
628 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
629 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
630
631 /* unreset */
632 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
633 BIT(28), 0);
634
635 /* Poll for lock bit */
636 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
637 val, (val & HDMI_PLL_LOCK), 10, 0);
638 break;
488 }; 639 };
489 } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || 640 } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
490 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { 641 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
@@ -498,6 +649,42 @@ void meson_hdmi_pll_set(struct meson_drm *priv,
498 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); 649 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
499 break; 650 break;
500 651
652 case 3200000:
653 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000285);
654 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb155);
655 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
656 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
657 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
658 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
659 break;
660
661 case 3240000:
662 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000287);
663 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
664 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
665 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
666 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
667 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
668 break;
669
670 case 3865000:
671 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a1);
672 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb02b);
673 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
674 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
675 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
676 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
677 break;
678
679 case 4028000:
680 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a7);
681 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb355);
682 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
683 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
684 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
685 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
686 break;
687
501 case 4320000: 688 case 4320000:
502 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4); 689 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4);
503 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); 690 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
@@ -516,6 +703,15 @@ void meson_hdmi_pll_set(struct meson_drm *priv,
516 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); 703 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
517 break; 704 break;
518 705
706 case 5200000:
707 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002d8);
708 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab);
709 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
710 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
711 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
712 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
713 break;
714
519 }; 715 };
520 716
521 /* Reset PLL */ 717 /* Reset PLL */
@@ -590,15 +786,30 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
590 else 786 else
591 freq = MESON_VCLK_HDMI_DDR_54000; 787 freq = MESON_VCLK_HDMI_DDR_54000;
592 break; 788 break;
789 case 25175:
790 freq = MESON_VCLK_HDMI_25175;
791 break;
792 case 40000:
793 freq = MESON_VCLK_HDMI_40000;
794 break;
795 case 65000:
796 freq = MESON_VCLK_HDMI_65000;
797 break;
593 case 74250: 798 case 74250:
594 freq = MESON_VCLK_HDMI_74250; 799 freq = MESON_VCLK_HDMI_74250;
595 break; 800 break;
801 case 108000:
802 freq = MESON_VCLK_HDMI_108000;
803 break;
596 case 148500: 804 case 148500:
597 if (dac_freq != 148500) 805 if (dac_freq != 148500)
598 freq = MESON_VCLK_HDMI_DDR_148500; 806 freq = MESON_VCLK_HDMI_DDR_148500;
599 else 807 else
600 freq = MESON_VCLK_HDMI_148500; 808 freq = MESON_VCLK_HDMI_148500;
601 break; 809 break;
810 case 162000:
811 freq = MESON_VCLK_HDMI_162000;
812 break;
602 case 297000: 813 case 297000:
603 freq = MESON_VCLK_HDMI_297000; 814 freq = MESON_VCLK_HDMI_297000;
604 break; 815 break;
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 9509017dbded..6e2701389801 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -697,6 +697,314 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
697 }, 697 },
698}; 698};
699 699
700union meson_hdmi_venc_mode meson_hdmi_encp_mode_640x480_60 = {
701 .encp = {
702 .dvi_settings = 0x21,
703 .video_mode = 0x4040,
704 .video_mode_adv = 0x18,
705 /* video_prog_mode */
706 /* video_sync_mode */
707 /* video_yc_dly */
708 /* video_rgb_ctrl */
709 /* video_filt_ctrl */
710 /* video_ofld_voav_ofst */
711 /* yfp1_htime */
712 /* yfp2_htime */
713 .max_pxcnt = 0x31f,
714 /* hspuls_begin */
715 /* hspuls_end */
716 /* hspuls_switch */
717 /* vspuls_begin */
718 /* vspuls_end */
719 /* vspuls_bline */
720 /* vspuls_eline */
721 .havon_begin = 0x90,
722 .havon_end = 0x30f,
723 .vavon_bline = 0x23,
724 .vavon_eline = 0x202,
725 /* eqpuls_begin */
726 /* eqpuls_end */
727 /* eqpuls_bline */
728 /* eqpuls_eline */
729 .hso_begin = 0,
730 .hso_end = 0x60,
731 .vso_begin = 0x1e,
732 .vso_end = 0x32,
733 .vso_bline = 0,
734 .vso_eline = 2,
735 .vso_eline_present = true,
736 /* sy_val */
737 /* sy2_val */
738 .max_lncnt = 0x20c,
739 },
740};
741
742union meson_hdmi_venc_mode meson_hdmi_encp_mode_800x600_60 = {
743 .encp = {
744 .dvi_settings = 0x21,
745 .video_mode = 0x4040,
746 .video_mode_adv = 0x18,
747 /* video_prog_mode */
748 /* video_sync_mode */
749 /* video_yc_dly */
750 /* video_rgb_ctrl */
751 /* video_filt_ctrl */
752 /* video_ofld_voav_ofst */
753 /* yfp1_htime */
754 /* yfp2_htime */
755 .max_pxcnt = 0x41f,
756 /* hspuls_begin */
757 /* hspuls_end */
758 /* hspuls_switch */
759 /* vspuls_begin */
760 /* vspuls_end */
761 /* vspuls_bline */
762 /* vspuls_eline */
763 .havon_begin = 0xD8,
764 .havon_end = 0x3f7,
765 .vavon_bline = 0x1b,
766 .vavon_eline = 0x272,
767 /* eqpuls_begin */
768 /* eqpuls_end */
769 /* eqpuls_bline */
770 /* eqpuls_eline */
771 .hso_begin = 0,
772 .hso_end = 0x80,
773 .vso_begin = 0x1e,
774 .vso_end = 0x32,
775 .vso_bline = 0,
776 .vso_eline = 4,
777 .vso_eline_present = true,
778 /* sy_val */
779 /* sy2_val */
780 .max_lncnt = 0x273,
781 },
782};
783
784union meson_hdmi_venc_mode meson_hdmi_encp_mode_1024x768_60 = {
785 .encp = {
786 .dvi_settings = 0x21,
787 .video_mode = 0x4040,
788 .video_mode_adv = 0x18,
789 /* video_prog_mode */
790 /* video_sync_mode */
791 /* video_yc_dly */
792 /* video_rgb_ctrl */
793 /* video_filt_ctrl */
794 /* video_ofld_voav_ofst */
795 /* yfp1_htime */
796 /* yfp2_htime */
797 .max_pxcnt = 1343,
798 /* hspuls_begin */
799 /* hspuls_end */
800 /* hspuls_switch */
801 /* vspuls_begin */
802 /* vspuls_end */
803 /* vspuls_bline */
804 /* vspuls_eline */
805 .havon_begin = 296,
806 .havon_end = 1319,
807 .vavon_bline = 35,
808 .vavon_eline = 802,
809 /* eqpuls_begin */
810 /* eqpuls_end */
811 /* eqpuls_bline */
812 /* eqpuls_eline */
813 .hso_begin = 0,
814 .hso_end = 136,
815 .vso_begin = 30,
816 .vso_end = 50,
817 .vso_bline = 0,
818 .vso_eline = 6,
819 .vso_eline_present = true,
820 /* sy_val */
821 /* sy2_val */
822 .max_lncnt = 805,
823 },
824};
825
826union meson_hdmi_venc_mode meson_hdmi_encp_mode_1152x864_75 = {
827 .encp = {
828 .dvi_settings = 0x21,
829 .video_mode = 0x4040,
830 .video_mode_adv = 0x18,
831 /* video_prog_mode */
832 /* video_sync_mode */
833 /* video_yc_dly */
834 /* video_rgb_ctrl */
835 /* video_filt_ctrl */
836 /* video_ofld_voav_ofst */
837 /* yfp1_htime */
838 /* yfp2_htime */
839 .max_pxcnt = 0x63f,
840 /* hspuls_begin */
841 /* hspuls_end */
842 /* hspuls_switch */
843 /* vspuls_begin */
844 /* vspuls_end */
845 /* vspuls_bline */
846 /* vspuls_eline */
847 .havon_begin = 0x180,
848 .havon_end = 0x5ff,
849 .vavon_bline = 0x23,
850 .vavon_eline = 0x382,
851 /* eqpuls_begin */
852 /* eqpuls_end */
853 /* eqpuls_bline */
854 /* eqpuls_eline */
855 .hso_begin = 0,
856 .hso_end = 0x80,
857 .vso_begin = 0x1e,
858 .vso_end = 0x32,
859 .vso_bline = 0,
860 .vso_eline = 3,
861 .vso_eline_present = true,
862 /* sy_val */
863 /* sy2_val */
864 .max_lncnt = 0x383,
865 },
866};
867
868union meson_hdmi_venc_mode meson_hdmi_encp_mode_1280x1024_60 = {
869 .encp = {
870 .dvi_settings = 0x21,
871 .video_mode = 0x4040,
872 .video_mode_adv = 0x18,
873 /* video_prog_mode */
874 /* video_sync_mode */
875 /* video_yc_dly */
876 /* video_rgb_ctrl */
877 /* video_filt_ctrl */
878 /* video_ofld_voav_ofst */
879 /* yfp1_htime */
880 /* yfp2_htime */
881 .max_pxcnt = 0x697,
882 /* hspuls_begin */
883 /* hspuls_end */
884 /* hspuls_switch */
885 /* vspuls_begin */
886 /* vspuls_end */
887 /* vspuls_bline */
888 /* vspuls_eline */
889 .havon_begin = 0x168,
890 .havon_end = 0x667,
891 .vavon_bline = 0x29,
892 .vavon_eline = 0x428,
893 /* eqpuls_begin */
894 /* eqpuls_end */
895 /* eqpuls_bline */
896 /* eqpuls_eline */
897 .hso_begin = 0,
898 .hso_end = 0x70,
899 .vso_begin = 0x1e,
900 .vso_end = 0x32,
901 .vso_bline = 0,
902 .vso_eline = 3,
903 .vso_eline_present = true,
904 /* sy_val */
905 /* sy2_val */
906 .max_lncnt = 0x429,
907 },
908};
909
910union meson_hdmi_venc_mode meson_hdmi_encp_mode_1600x1200_60 = {
911 .encp = {
912 .dvi_settings = 0x21,
913 .video_mode = 0x4040,
914 .video_mode_adv = 0x18,
915 /* video_prog_mode */
916 /* video_sync_mode */
917 /* video_yc_dly */
918 /* video_rgb_ctrl */
919 /* video_filt_ctrl */
920 /* video_ofld_voav_ofst */
921 /* yfp1_htime */
922 /* yfp2_htime */
923 .max_pxcnt = 0x86f,
924 /* hspuls_begin */
925 /* hspuls_end */
926 /* hspuls_switch */
927 /* vspuls_begin */
928 /* vspuls_end */
929 /* vspuls_bline */
930 /* vspuls_eline */
931 .havon_begin = 0x1f0,
932 .havon_end = 0x82f,
933 .vavon_bline = 0x31,
934 .vavon_eline = 0x4e0,
935 /* eqpuls_begin */
936 /* eqpuls_end */
937 /* eqpuls_bline */
938 /* eqpuls_eline */
939 .hso_begin = 0,
940 .hso_end = 0xc0,
941 .vso_begin = 0x1e,
942 .vso_end = 0x32,
943 .vso_bline = 0,
944 .vso_eline = 3,
945 .vso_eline_present = true,
946 /* sy_val */
947 /* sy2_val */
948 .max_lncnt = 0x4e1,
949 },
950};
951
952struct meson_hdmi_venc_dmt_mode {
953 struct drm_display_mode drm_mode;
954 union meson_hdmi_venc_mode *mode;
955} meson_hdmi_venc_dmt_modes[] = {
956 /* 640x480@60Hz */
957 {
958 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
959 752, 800, 0, 480, 490, 492, 525, 0,
960 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
961 &meson_hdmi_encp_mode_640x480_60,
962 },
963 /* 800x600@60Hz */
964 {
965 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
966 968, 1056, 0, 600, 601, 605, 628, 0,
967 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
968 &meson_hdmi_encp_mode_800x600_60,
969 },
970 /* 1024x768@60Hz */
971 {
972 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024,
973 1048, 1184, 1344, 0, 768, 771, 777, 806, 0,
974 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
975 &meson_hdmi_encp_mode_1024x768_60,
976 },
977 /* 1152x864@75Hz */
978 {
979 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152,
980 1216, 1344, 1600, 0, 864, 865, 868, 900, 0,
981 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
982 &meson_hdmi_encp_mode_1152x864_75,
983 },
984 /* 1280x1024@60Hz */
985 {
986 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280,
987 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
988 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
989 &meson_hdmi_encp_mode_1280x1024_60,
990 },
991 /* 1600x1200@60Hz */
992 {
993 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600,
994 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
995 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
996 &meson_hdmi_encp_mode_1600x1200_60,
997 },
998 /* 1920x1080@60Hz */
999 {
1000 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920,
1001 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
1002 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
1003 &meson_hdmi_encp_mode_1080p60
1004 },
1005 { }, /* sentinel */
1006};
1007
700struct meson_hdmi_venc_vic_mode { 1008struct meson_hdmi_venc_vic_mode {
701 unsigned int vic; 1009 unsigned int vic;
702 union meson_hdmi_venc_mode *mode; 1010 union meson_hdmi_venc_mode *mode;
@@ -736,6 +1044,20 @@ static unsigned long modulo(unsigned long a, unsigned long b)
736 return a; 1044 return a;
737} 1045}
738 1046
1047bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
1048{
1049 struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes;
1050
1051 while (vmode->mode) {
1052 if (drm_mode_equal(&vmode->drm_mode, mode))
1053 return true;
1054 vmode++;
1055 }
1056
1057 return false;
1058}
1059EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
1060
739bool meson_venc_hdmi_supported_vic(int vic) 1061bool meson_venc_hdmi_supported_vic(int vic)
740{ 1062{
741 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; 1063 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
@@ -750,6 +1072,20 @@ bool meson_venc_hdmi_supported_vic(int vic)
750} 1072}
751EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); 1073EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
752 1074
1075static union meson_hdmi_venc_mode
1076*meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode)
1077{
1078 struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes;
1079
1080 while (vmode->mode) {
1081 if (drm_mode_equal(&vmode->drm_mode, mode))
1082 return vmode->mode;
1083 vmode++;
1084 }
1085
1086 return NULL;
1087}
1088
753static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) 1089static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
754{ 1090{
755 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; 1091 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
@@ -811,10 +1147,13 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
811 unsigned int sof_lines; 1147 unsigned int sof_lines;
812 unsigned int vsync_lines; 1148 unsigned int vsync_lines;
813 1149
814 vmode = meson_venc_hdmi_get_vic_vmode(vic); 1150 if (meson_venc_hdmi_supported_vic(vic))
1151 vmode = meson_venc_hdmi_get_vic_vmode(vic);
1152 else
1153 vmode = meson_venc_hdmi_get_dmt_vmode(mode);
815 if (!vmode) { 1154 if (!vmode) {
816 dev_err(priv->dev, "%s: Fatal Error, unsupported vic %d\n", 1155 dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
817 __func__, vic); 1156 DRM_MODE_FMT "\n", __func__, DRM_MODE_ARG(mode));
818 return; 1157 return;
819 } 1158 }
820 1159
@@ -864,7 +1203,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
864 hsync_pixels_venc *= 2; 1203 hsync_pixels_venc *= 2;
865 1204
866 /* Disable VDACs */ 1205 /* Disable VDACs */
867 writel_bits_relaxed(0x1f, 0x1f, 1206 writel_bits_relaxed(0xff, 0xff,
868 priv->io_base + _REG(VENC_VDAC_SETTING)); 1207 priv->io_base + _REG(VENC_VDAC_SETTING));
869 1208
870 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 1209 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
index a1b96e898c14..7c18a36a0dd0 100644
--- a/drivers/gpu/drm/meson/meson_venc.h
+++ b/drivers/gpu/drm/meson/meson_venc.h
@@ -58,6 +58,7 @@ struct meson_cvbs_enci_mode {
58}; 58};
59 59
60/* HDMI Clock parameters */ 60/* HDMI Clock parameters */
61bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
61bool meson_venc_hdmi_supported_vic(int vic); 62bool meson_venc_hdmi_supported_vic(int vic);
62bool meson_venc_hdmi_venc_repeat(int vic); 63bool meson_venc_hdmi_venc_repeat(int vic);
63 64
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 3e293029e3a6..bbbf353682e1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -510,37 +510,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
510 return 0; 510 return 0;
511} 511}
512 512
513#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
514
515static void
516nouveau_get_hdmi_dev(struct nouveau_drm *drm)
517{
518 struct pci_dev *pdev = drm->dev->pdev;
519
520 if (!pdev) {
521 NV_DEBUG(drm, "not a PCI device; no HDMI\n");
522 drm->hdmi_device = NULL;
523 return;
524 }
525
526 /* subfunction one is a hdmi audio device? */
527 drm->hdmi_device = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
528 (unsigned int)pdev->bus->number,
529 PCI_DEVFN(PCI_SLOT(pdev->devfn), 1));
530
531 if (!drm->hdmi_device) {
532 NV_DEBUG(drm, "hdmi device not found %d %d %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), 1);
533 return;
534 }
535
536 if ((drm->hdmi_device->class >> 8) != PCI_CLASS_MULTIMEDIA_HD_AUDIO) {
537 NV_DEBUG(drm, "possible hdmi device not audio %d\n", drm->hdmi_device->class);
538 pci_dev_put(drm->hdmi_device);
539 drm->hdmi_device = NULL;
540 return;
541 }
542}
543
544static int 513static int
545nouveau_drm_load(struct drm_device *dev, unsigned long flags) 514nouveau_drm_load(struct drm_device *dev, unsigned long flags)
546{ 515{
@@ -568,8 +537,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
568 INIT_LIST_HEAD(&drm->clients); 537 INIT_LIST_HEAD(&drm->clients);
569 spin_lock_init(&drm->tile.lock); 538 spin_lock_init(&drm->tile.lock);
570 539
571 nouveau_get_hdmi_dev(drm);
572
573 /* workaround an odd issue on nvc1 by disabling the device's 540 /* workaround an odd issue on nvc1 by disabling the device's
574 * nosnoop capability. hopefully won't cause issues until a 541 * nosnoop capability. hopefully won't cause issues until a
575 * better fix is found - assuming there is one... 542 * better fix is found - assuming there is one...
@@ -655,8 +622,6 @@ nouveau_drm_unload(struct drm_device *dev)
655 nouveau_ttm_fini(drm); 622 nouveau_ttm_fini(drm);
656 nouveau_vga_fini(drm); 623 nouveau_vga_fini(drm);
657 624
658 if (drm->hdmi_device)
659 pci_dev_put(drm->hdmi_device);
660 nouveau_cli_fini(&drm->client); 625 nouveau_cli_fini(&drm->client);
661 nouveau_cli_fini(&drm->master); 626 nouveau_cli_fini(&drm->master);
662 kfree(drm); 627 kfree(drm);
@@ -856,7 +821,6 @@ nouveau_pmops_runtime_suspend(struct device *dev)
856 } 821 }
857 822
858 drm_kms_helper_poll_disable(drm_dev); 823 drm_kms_helper_poll_disable(drm_dev);
859 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
860 nouveau_switcheroo_optimus_dsm(); 824 nouveau_switcheroo_optimus_dsm();
861 ret = nouveau_do_suspend(drm_dev, true); 825 ret = nouveau_do_suspend(drm_dev, true);
862 pci_save_state(pdev); 826 pci_save_state(pdev);
@@ -891,7 +855,6 @@ nouveau_pmops_runtime_resume(struct device *dev)
891 855
892 /* do magic */ 856 /* do magic */
893 nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25)); 857 nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25));
894 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
895 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; 858 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
896 859
897 /* Monitors may have been connected / disconnected during suspend */ 860 /* Monitors may have been connected / disconnected during suspend */
@@ -913,15 +876,6 @@ nouveau_pmops_runtime_idle(struct device *dev)
913 return -EBUSY; 876 return -EBUSY;
914 } 877 }
915 878
916 /* if we have a hdmi audio device - make sure it has a driver loaded */
917 if (drm->hdmi_device) {
918 if (!drm->hdmi_device->driver) {
919 DRM_DEBUG_DRIVER("failing to power off - no HDMI audio driver loaded\n");
920 pm_runtime_mark_last_busy(dev);
921 return -EBUSY;
922 }
923 }
924
925 list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) { 879 list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) {
926 if (crtc->enabled) { 880 if (crtc->enabled) {
927 DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); 881 DRM_DEBUG_DRIVER("failing to power off - crtc active\n");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 96f6bd8aee5d..881b44b89a01 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -208,7 +208,6 @@ struct nouveau_drm {
208 bool have_disp_power_ref; 208 bool have_disp_power_ref;
209 209
210 struct dev_pm_domain vga_pm_domain; 210 struct dev_pm_domain vga_pm_domain;
211 struct pci_dev *hdmi_device;
212}; 211};
213 212
214static inline struct nouveau_drm * 213static inline struct nouveau_drm *
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 988048ebcc22..25682ff3449a 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -108,6 +108,15 @@ config DRM_PANEL_RASPBERRYPI_TOUCHSCREEN
108 Pi 7" Touchscreen. To compile this driver as a module, 108 Pi 7" Touchscreen. To compile this driver as a module,
109 choose M here. 109 choose M here.
110 110
111config DRM_PANEL_RAYDIUM_RM68200
112 tristate "Raydium RM68200 720x1280 DSI video mode panel"
113 depends on OF
114 depends on DRM_MIPI_DSI
115 depends on BACKLIGHT_CLASS_DEVICE
116 help
117 Say Y here if you want to enable support for Raydium RM68200
118 720x1280 DSI video mode panel.
119
111config DRM_PANEL_SAMSUNG_S6E3HA2 120config DRM_PANEL_SAMSUNG_S6E3HA2
112 tristate "Samsung S6E3HA2 DSI video mode panel" 121 tristate "Samsung S6E3HA2 DSI video mode panel"
113 depends on OF 122 depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 3d2a88d0e965..f26efc11d746 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
9obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o 9obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o
10obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o 10obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
11obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o 11obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o
12obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o
12obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o 13obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
13obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o 14obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
14obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o 15obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
index b4ec0ecff807..bd38bf4f1ba6 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
@@ -179,7 +179,7 @@ enum ili9322_input {
179 ILI9322_INPUT_UNKNOWN = 0xc, 179 ILI9322_INPUT_UNKNOWN = 0xc,
180}; 180};
181 181
182const char *ili9322_inputs[] = { 182static const char * const ili9322_inputs[] = {
183 "8 bit serial RGB through", 183 "8 bit serial RGB through",
184 "8 bit serial RGB aligned", 184 "8 bit serial RGB aligned",
185 "8 bit serial RGB dummy 320x240", 185 "8 bit serial RGB dummy 320x240",
@@ -340,7 +340,7 @@ static bool ili9322_writeable_reg(struct device *dev, unsigned int reg)
340 return true; 340 return true;
341} 341}
342 342
343const struct regmap_config ili9322_regmap_config = { 343static const struct regmap_config ili9322_regmap_config = {
344 .reg_bits = 8, 344 .reg_bits = 8,
345 .val_bits = 8, 345 .val_bits = 8,
346 .max_register = 0x44, 346 .max_register = 0x44,
diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index b5e3994f0aa8..5185819c5b79 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * rcar_du_crtc.c -- R-Car Display Unit CRTCs 2 * Generic LVDS panel driver
3 * 3 *
4 * Copyright (C) 2016 Laurent Pinchart 4 * Copyright (C) 2016 Laurent Pinchart
5 * Copyright (C) 2016 Renesas Electronics Corporation 5 * Copyright (C) 2016 Renesas Electronics Corporation
diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
index c189cd6329c8..90f1ae4af93c 100644
--- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
+++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
@@ -1,16 +1,17 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) STMicroelectronics SA 2017 3 * Copyright (C) STMicroelectronics SA 2017
3 * 4 *
4 * Authors: Philippe Cornu <philippe.cornu@st.com> 5 * Authors: Philippe Cornu <philippe.cornu@st.com>
5 * Yannick Fertre <yannick.fertre@st.com> 6 * Yannick Fertre <yannick.fertre@st.com>
6 *
7 * License terms: GNU General Public License (GPL), version 2
8 */ 7 */
8
9#include <drm/drmP.h> 9#include <drm/drmP.h>
10#include <drm/drm_mipi_dsi.h> 10#include <drm/drm_mipi_dsi.h>
11#include <drm/drm_panel.h> 11#include <drm/drm_panel.h>
12#include <linux/backlight.h> 12#include <linux/backlight.h>
13#include <linux/gpio/consumer.h> 13#include <linux/gpio/consumer.h>
14#include <linux/regulator/consumer.h>
14#include <video/mipi_display.h> 15#include <video/mipi_display.h>
15 16
16#define DRV_NAME "orisetech_otm8009a" 17#define DRV_NAME "orisetech_otm8009a"
@@ -62,6 +63,7 @@ struct otm8009a {
62 struct drm_panel panel; 63 struct drm_panel panel;
63 struct backlight_device *bl_dev; 64 struct backlight_device *bl_dev;
64 struct gpio_desc *reset_gpio; 65 struct gpio_desc *reset_gpio;
66 struct regulator *supply;
65 bool prepared; 67 bool prepared;
66 bool enabled; 68 bool enabled;
67}; 69};
@@ -279,6 +281,8 @@ static int otm8009a_unprepare(struct drm_panel *panel)
279 msleep(20); 281 msleep(20);
280 } 282 }
281 283
284 regulator_disable(ctx->supply);
285
282 ctx->prepared = false; 286 ctx->prepared = false;
283 287
284 return 0; 288 return 0;
@@ -292,6 +296,12 @@ static int otm8009a_prepare(struct drm_panel *panel)
292 if (ctx->prepared) 296 if (ctx->prepared)
293 return 0; 297 return 0;
294 298
299 ret = regulator_enable(ctx->supply);
300 if (ret < 0) {
301 DRM_ERROR("failed to enable supply: %d\n", ret);
302 return ret;
303 }
304
295 if (ctx->reset_gpio) { 305 if (ctx->reset_gpio) {
296 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 306 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
297 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 307 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
@@ -414,6 +424,13 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi)
414 return PTR_ERR(ctx->reset_gpio); 424 return PTR_ERR(ctx->reset_gpio);
415 } 425 }
416 426
427 ctx->supply = devm_regulator_get(dev, "power");
428 if (IS_ERR(ctx->supply)) {
429 ret = PTR_ERR(ctx->supply);
430 dev_err(dev, "failed to request regulator: %d\n", ret);
431 return ret;
432 }
433
417 mipi_dsi_set_drvdata(dsi, ctx); 434 mipi_dsi_set_drvdata(dsi, ctx);
418 435
419 ctx->dev = dev; 436 ctx->dev = dev;
diff --git a/drivers/gpu/drm/panel/panel-raydium-rm68200.c b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
new file mode 100644
index 000000000000..77593533abcd
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
@@ -0,0 +1,448 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) STMicroelectronics SA 2017
4 *
5 * Authors: Philippe Cornu <philippe.cornu@st.com>
6 * Yannick Fertre <yannick.fertre@st.com>
7 */
8
9#include <linux/backlight.h>
10#include <linux/gpio/consumer.h>
11#include <linux/regulator/consumer.h>
12
13#include <video/mipi_display.h>
14
15#include <drm/drmP.h>
16#include <drm/drm_mipi_dsi.h>
17#include <drm/drm_panel.h>
18
19/*** Manufacturer Command Set ***/
20#define MCS_CMD_MODE_SW 0xFE /* CMD Mode Switch */
21#define MCS_CMD1_UCS 0x00 /* User Command Set (UCS = CMD1) */
22#define MCS_CMD2_P0 0x01 /* Manufacture Command Set Page0 (CMD2 P0) */
23#define MCS_CMD2_P1 0x02 /* Manufacture Command Set Page1 (CMD2 P1) */
24#define MCS_CMD2_P2 0x03 /* Manufacture Command Set Page2 (CMD2 P2) */
25#define MCS_CMD2_P3 0x04 /* Manufacture Command Set Page3 (CMD2 P3) */
26
27/* CMD2 P0 commands (Display Options and Power) */
28#define MCS_STBCTR 0x12 /* TE1 Output Setting Zig-Zag Connection */
29#define MCS_SGOPCTR 0x16 /* Source Bias Current */
30#define MCS_SDCTR 0x1A /* Source Output Delay Time */
31#define MCS_INVCTR 0x1B /* Inversion Type */
32#define MCS_EXT_PWR_IC 0x24 /* External PWR IC Control */
33#define MCS_SETAVDD 0x27 /* PFM Control for AVDD Output */
34#define MCS_SETAVEE 0x29 /* PFM Control for AVEE Output */
35#define MCS_BT2CTR 0x2B /* DDVDL Charge Pump Control */
36#define MCS_BT3CTR 0x2F /* VGH Charge Pump Control */
37#define MCS_BT4CTR 0x34 /* VGL Charge Pump Control */
38#define MCS_VCMCTR 0x46 /* VCOM Output Level Control */
39#define MCS_SETVGN 0x52 /* VG M/S N Control */
40#define MCS_SETVGP 0x54 /* VG M/S P Control */
41#define MCS_SW_CTRL 0x5F /* Interface Control for PFM and MIPI */
42
43/* CMD2 P2 commands (GOA Timing Control) - no description in datasheet */
44#define GOA_VSTV1 0x00
45#define GOA_VSTV2 0x07
46#define GOA_VCLK1 0x0E
47#define GOA_VCLK2 0x17
48#define GOA_VCLK_OPT1 0x20
49#define GOA_BICLK1 0x2A
50#define GOA_BICLK2 0x37
51#define GOA_BICLK3 0x44
52#define GOA_BICLK4 0x4F
53#define GOA_BICLK_OPT1 0x5B
54#define GOA_BICLK_OPT2 0x60
55#define MCS_GOA_GPO1 0x6D
56#define MCS_GOA_GPO2 0x71
57#define MCS_GOA_EQ 0x74
58#define MCS_GOA_CLK_GALLON 0x7C
59#define MCS_GOA_FS_SEL0 0x7E
60#define MCS_GOA_FS_SEL1 0x87
61#define MCS_GOA_FS_SEL2 0x91
62#define MCS_GOA_FS_SEL3 0x9B
63#define MCS_GOA_BS_SEL0 0xAC
64#define MCS_GOA_BS_SEL1 0xB5
65#define MCS_GOA_BS_SEL2 0xBF
66#define MCS_GOA_BS_SEL3 0xC9
67#define MCS_GOA_BS_SEL4 0xD3
68
69/* CMD2 P3 commands (Gamma) */
70#define MCS_GAMMA_VP 0x60 /* Gamma VP1~VP16 */
71#define MCS_GAMMA_VN 0x70 /* Gamma VN1~VN16 */
72
73struct rm68200 {
74 struct device *dev;
75 struct drm_panel panel;
76 struct gpio_desc *reset_gpio;
77 struct regulator *supply;
78 struct backlight_device *backlight;
79 bool prepared;
80 bool enabled;
81};
82
83static const struct drm_display_mode default_mode = {
84 .clock = 52582,
85 .hdisplay = 720,
86 .hsync_start = 720 + 38,
87 .hsync_end = 720 + 38 + 8,
88 .htotal = 720 + 38 + 8 + 38,
89 .vdisplay = 1280,
90 .vsync_start = 1280 + 12,
91 .vsync_end = 1280 + 12 + 4,
92 .vtotal = 1280 + 12 + 4 + 12,
93 .vrefresh = 50,
94 .flags = 0,
95 .width_mm = 68,
96 .height_mm = 122,
97};
98
99static inline struct rm68200 *panel_to_rm68200(struct drm_panel *panel)
100{
101 return container_of(panel, struct rm68200, panel);
102}
103
104static void rm68200_dcs_write_buf(struct rm68200 *ctx, const void *data,
105 size_t len)
106{
107 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
108 int err;
109
110 err = mipi_dsi_dcs_write_buffer(dsi, data, len);
111 if (err < 0)
112 DRM_ERROR_RATELIMITED("MIPI DSI DCS write buffer failed: %d\n",
113 err);
114}
115
116static void rm68200_dcs_write_cmd(struct rm68200 *ctx, u8 cmd, u8 value)
117{
118 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
119 int err;
120
121 err = mipi_dsi_dcs_write(dsi, cmd, &value, 1);
122 if (err < 0)
123 DRM_ERROR_RATELIMITED("MIPI DSI DCS write failed: %d\n", err);
124}
125
126#define dcs_write_seq(ctx, seq...) \
127({ \
128 static const u8 d[] = { seq }; \
129 \
130 rm68200_dcs_write_buf(ctx, d, ARRAY_SIZE(d)); \
131})
132
133/*
134 * This panel is not able to auto-increment all cmd addresses so for some of
135 * them, we need to send them one by one...
136 */
137#define dcs_write_cmd_seq(ctx, cmd, seq...) \
138({ \
139 static const u8 d[] = { seq }; \
140 unsigned int i; \
141 \
142 for (i = 0; i < ARRAY_SIZE(d) ; i++) \
143 rm68200_dcs_write_cmd(ctx, cmd + i, d[i]); \
144})
145
146static void rm68200_init_sequence(struct rm68200 *ctx)
147{
148 /* Enter CMD2 with page 0 */
149 dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P0);
150 dcs_write_cmd_seq(ctx, MCS_EXT_PWR_IC, 0xC0, 0x53, 0x00);
151 dcs_write_seq(ctx, MCS_BT2CTR, 0xE5);
152 dcs_write_seq(ctx, MCS_SETAVDD, 0x0A);
153 dcs_write_seq(ctx, MCS_SETAVEE, 0x0A);
154 dcs_write_seq(ctx, MCS_SGOPCTR, 0x52);
155 dcs_write_seq(ctx, MCS_BT3CTR, 0x53);
156 dcs_write_seq(ctx, MCS_BT4CTR, 0x5A);
157 dcs_write_seq(ctx, MCS_INVCTR, 0x00);
158 dcs_write_seq(ctx, MCS_STBCTR, 0x0A);
159 dcs_write_seq(ctx, MCS_SDCTR, 0x06);
160 dcs_write_seq(ctx, MCS_VCMCTR, 0x56);
161 dcs_write_seq(ctx, MCS_SETVGN, 0xA0, 0x00);
162 dcs_write_seq(ctx, MCS_SETVGP, 0xA0, 0x00);
163 dcs_write_seq(ctx, MCS_SW_CTRL, 0x11); /* 2 data lanes, see doc */
164
165 dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P2);
166 dcs_write_seq(ctx, GOA_VSTV1, 0x05);
167 dcs_write_seq(ctx, 0x02, 0x0B);
168 dcs_write_seq(ctx, 0x03, 0x0F);
169 dcs_write_seq(ctx, 0x04, 0x7D, 0x00, 0x50);
170 dcs_write_cmd_seq(ctx, GOA_VSTV2, 0x05, 0x16, 0x0D, 0x11, 0x7D, 0x00,
171 0x50);
172 dcs_write_cmd_seq(ctx, GOA_VCLK1, 0x07, 0x08, 0x01, 0x02, 0x00, 0x7D,
173 0x00, 0x85, 0x08);
174 dcs_write_cmd_seq(ctx, GOA_VCLK2, 0x03, 0x04, 0x05, 0x06, 0x00, 0x7D,
175 0x00, 0x85, 0x08);
176 dcs_write_seq(ctx, GOA_VCLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00);
178 dcs_write_cmd_seq(ctx, GOA_BICLK1, 0x07, 0x08);
179 dcs_write_seq(ctx, 0x2D, 0x01);
180 dcs_write_seq(ctx, 0x2F, 0x02, 0x00, 0x40, 0x05, 0x08, 0x54, 0x7D,
181 0x00);
182 dcs_write_cmd_seq(ctx, GOA_BICLK2, 0x03, 0x04, 0x05, 0x06, 0x00);
183 dcs_write_seq(ctx, 0x3D, 0x40);
184 dcs_write_seq(ctx, 0x3F, 0x05, 0x08, 0x54, 0x7D, 0x00);
185 dcs_write_seq(ctx, GOA_BICLK3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00);
187 dcs_write_seq(ctx, GOA_BICLK4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188 0x00, 0x00);
189 dcs_write_seq(ctx, 0x58, 0x00, 0x00, 0x00);
190 dcs_write_seq(ctx, GOA_BICLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00);
191 dcs_write_seq(ctx, GOA_BICLK_OPT2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
193 dcs_write_seq(ctx, MCS_GOA_GPO1, 0x00, 0x00, 0x00, 0x00);
194 dcs_write_seq(ctx, MCS_GOA_GPO2, 0x00, 0x20, 0x00);
195 dcs_write_seq(ctx, MCS_GOA_EQ, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
196 0x00, 0x00);
197 dcs_write_seq(ctx, MCS_GOA_CLK_GALLON, 0x00, 0x00);
198 dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL0, 0xBF, 0x02, 0x06, 0x14, 0x10,
199 0x16, 0x12, 0x08, 0x3F);
200 dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0C,
201 0x0A, 0x0E, 0x3F, 0x3F, 0x00);
202 dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL2, 0x04, 0x3F, 0x3F, 0x3F, 0x3F,
203 0x05, 0x01, 0x3F, 0x3F, 0x0F);
204 dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL3, 0x0B, 0x0D, 0x3F, 0x3F, 0x3F,
205 0x3F);
206 dcs_write_cmd_seq(ctx, 0xA2, 0x3F, 0x09, 0x13, 0x17, 0x11, 0x15);
207 dcs_write_cmd_seq(ctx, 0xA9, 0x07, 0x03, 0x3F);
208 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL0, 0x3F, 0x05, 0x01, 0x17, 0x13,
209 0x15, 0x11, 0x0F, 0x3F);
210 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0B,
211 0x0D, 0x09, 0x3F, 0x3F, 0x07);
212 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL2, 0x03, 0x3F, 0x3F, 0x3F, 0x3F,
213 0x02, 0x06, 0x3F, 0x3F, 0x08);
214 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL3, 0x0C, 0x0A, 0x3F, 0x3F, 0x3F,
215 0x3F, 0x3F, 0x0E, 0x10, 0x14);
216 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL4, 0x12, 0x16, 0x00, 0x04, 0x3F);
217 dcs_write_seq(ctx, 0xDC, 0x02);
218 dcs_write_seq(ctx, 0xDE, 0x12);
219
220 dcs_write_seq(ctx, MCS_CMD_MODE_SW, 0x0E); /* No documentation */
221 dcs_write_seq(ctx, 0x01, 0x75);
222
223 dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P3);
224 dcs_write_cmd_seq(ctx, MCS_GAMMA_VP, 0x00, 0x0C, 0x12, 0x0E, 0x06,
225 0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F,
226 0x12, 0x0C, 0x00);
227 dcs_write_cmd_seq(ctx, MCS_GAMMA_VN, 0x00, 0x0C, 0x12, 0x0E, 0x06,
228 0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F,
229 0x12, 0x0C, 0x00);
230
231 /* Exit CMD2 */
232 dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD1_UCS);
233}
234
235static int rm68200_disable(struct drm_panel *panel)
236{
237 struct rm68200 *ctx = panel_to_rm68200(panel);
238
239 if (!ctx->enabled)
240 return 0;
241
242 backlight_disable(ctx->backlight);
243
244 ctx->enabled = false;
245
246 return 0;
247}
248
249static int rm68200_unprepare(struct drm_panel *panel)
250{
251 struct rm68200 *ctx = panel_to_rm68200(panel);
252 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
253 int ret;
254
255 if (!ctx->prepared)
256 return 0;
257
258 ret = mipi_dsi_dcs_set_display_off(dsi);
259 if (ret)
260 DRM_WARN("failed to set display off: %d\n", ret);
261
262 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
263 if (ret)
264 DRM_WARN("failed to enter sleep mode: %d\n", ret);
265
266 msleep(120);
267
268 if (ctx->reset_gpio) {
269 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
270 msleep(20);
271 }
272
273 regulator_disable(ctx->supply);
274
275 ctx->prepared = false;
276
277 return 0;
278}
279
280static int rm68200_prepare(struct drm_panel *panel)
281{
282 struct rm68200 *ctx = panel_to_rm68200(panel);
283 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
284 int ret;
285
286 if (ctx->prepared)
287 return 0;
288
289 ret = regulator_enable(ctx->supply);
290 if (ret < 0) {
291 DRM_ERROR("failed to enable supply: %d\n", ret);
292 return ret;
293 }
294
295 if (ctx->reset_gpio) {
296 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
297 msleep(20);
298 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
299 msleep(100);
300 }
301
302 rm68200_init_sequence(ctx);
303
304 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
305 if (ret)
306 return ret;
307
308 msleep(125);
309
310 ret = mipi_dsi_dcs_set_display_on(dsi);
311 if (ret)
312 return ret;
313
314 msleep(20);
315
316 ctx->prepared = true;
317
318 return 0;
319}
320
321static int rm68200_enable(struct drm_panel *panel)
322{
323 struct rm68200 *ctx = panel_to_rm68200(panel);
324
325 if (ctx->enabled)
326 return 0;
327
328 backlight_enable(ctx->backlight);
329
330 ctx->enabled = true;
331
332 return 0;
333}
334
335static int rm68200_get_modes(struct drm_panel *panel)
336{
337 struct drm_display_mode *mode;
338
339 mode = drm_mode_duplicate(panel->drm, &default_mode);
340 if (!mode) {
341 DRM_ERROR("failed to add mode %ux%ux@%u\n",
342 default_mode.hdisplay, default_mode.vdisplay,
343 default_mode.vrefresh);
344 return -ENOMEM;
345 }
346
347 drm_mode_set_name(mode);
348
349 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
350 drm_mode_probed_add(panel->connector, mode);
351
352 panel->connector->display_info.width_mm = mode->width_mm;
353 panel->connector->display_info.height_mm = mode->height_mm;
354
355 return 1;
356}
357
358static const struct drm_panel_funcs rm68200_drm_funcs = {
359 .disable = rm68200_disable,
360 .unprepare = rm68200_unprepare,
361 .prepare = rm68200_prepare,
362 .enable = rm68200_enable,
363 .get_modes = rm68200_get_modes,
364};
365
366static int rm68200_probe(struct mipi_dsi_device *dsi)
367{
368 struct device *dev = &dsi->dev;
369 struct rm68200 *ctx;
370 int ret;
371
372 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
373 if (!ctx)
374 return -ENOMEM;
375
376 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
377 if (IS_ERR(ctx->reset_gpio)) {
378 ret = PTR_ERR(ctx->reset_gpio);
379 dev_err(dev, "cannot get reset GPIO: %d\n", ret);
380 return ret;
381 }
382
383 ctx->supply = devm_regulator_get(dev, "power");
384 if (IS_ERR(ctx->supply)) {
385 ret = PTR_ERR(ctx->supply);
386 dev_err(dev, "cannot get regulator: %d\n", ret);
387 return ret;
388 }
389
390 ctx->backlight = devm_of_find_backlight(dev);
391 if (IS_ERR(ctx->backlight))
392 return PTR_ERR(ctx->backlight);
393
394 mipi_dsi_set_drvdata(dsi, ctx);
395
396 ctx->dev = dev;
397
398 dsi->lanes = 2;
399 dsi->format = MIPI_DSI_FMT_RGB888;
400 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
401 MIPI_DSI_MODE_LPM;
402
403 drm_panel_init(&ctx->panel);
404 ctx->panel.dev = dev;
405 ctx->panel.funcs = &rm68200_drm_funcs;
406
407 drm_panel_add(&ctx->panel);
408
409 ret = mipi_dsi_attach(dsi);
410 if (ret < 0) {
411 dev_err(dev, "mipi_dsi_attach() failed: %d\n", ret);
412 drm_panel_remove(&ctx->panel);
413 return ret;
414 }
415
416 return 0;
417}
418
419static int rm68200_remove(struct mipi_dsi_device *dsi)
420{
421 struct rm68200 *ctx = mipi_dsi_get_drvdata(dsi);
422
423 mipi_dsi_detach(dsi);
424 drm_panel_remove(&ctx->panel);
425
426 return 0;
427}
428
429static const struct of_device_id raydium_rm68200_of_match[] = {
430 { .compatible = "raydium,rm68200" },
431 { }
432};
433MODULE_DEVICE_TABLE(of, raydium_rm68200_of_match);
434
435static struct mipi_dsi_driver raydium_rm68200_driver = {
436 .probe = rm68200_probe,
437 .remove = rm68200_remove,
438 .driver = {
439 .name = "panel-raydium-rm68200",
440 .of_match_table = raydium_rm68200_of_match,
441 },
442};
443module_mipi_dsi_driver(raydium_rm68200_driver);
444
445MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
446MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
447MODULE_DESCRIPTION("DRM Driver for Raydium RM68200 MIPI DSI panel");
448MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 5591984a392b..cbf1ab404ee7 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -581,6 +581,29 @@ static const struct panel_desc auo_b133htn01 = {
581 }, 581 },
582}; 582};
583 583
584static const struct drm_display_mode auo_g104sn02_mode = {
585 .clock = 40000,
586 .hdisplay = 800,
587 .hsync_start = 800 + 40,
588 .hsync_end = 800 + 40 + 216,
589 .htotal = 800 + 40 + 216 + 128,
590 .vdisplay = 600,
591 .vsync_start = 600 + 10,
592 .vsync_end = 600 + 10 + 35,
593 .vtotal = 600 + 10 + 35 + 2,
594 .vrefresh = 60,
595};
596
597static const struct panel_desc auo_g104sn02 = {
598 .modes = &auo_g104sn02_mode,
599 .num_modes = 1,
600 .bpc = 8,
601 .size = {
602 .width = 211,
603 .height = 158,
604 },
605};
606
584static const struct display_timing auo_g133han01_timings = { 607static const struct display_timing auo_g133han01_timings = {
585 .pixelclock = { 134000000, 141200000, 149000000 }, 608 .pixelclock = { 134000000, 141200000, 149000000 },
586 .hactive = { 1920, 1920, 1920 }, 609 .hactive = { 1920, 1920, 1920 },
@@ -1217,6 +1240,30 @@ static const struct panel_desc innolux_zj070na_01p = {
1217 }, 1240 },
1218}; 1241};
1219 1242
1243static const struct display_timing koe_tx31d200vm0baa_timing = {
1244 .pixelclock = { 39600000, 43200000, 48000000 },
1245 .hactive = { 1280, 1280, 1280 },
1246 .hfront_porch = { 16, 36, 56 },
1247 .hback_porch = { 16, 36, 56 },
1248 .hsync_len = { 8, 8, 8 },
1249 .vactive = { 480, 480, 480 },
1250 .vfront_porch = { 6, 21, 33.5 },
1251 .vback_porch = { 6, 21, 33.5 },
1252 .vsync_len = { 8, 8, 8 },
1253 .flags = DISPLAY_FLAGS_DE_HIGH,
1254};
1255
1256static const struct panel_desc koe_tx31d200vm0baa = {
1257 .timings = &koe_tx31d200vm0baa_timing,
1258 .num_timings = 1,
1259 .bpc = 6,
1260 .size = {
1261 .width = 292,
1262 .height = 109,
1263 },
1264 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
1265};
1266
1220static const struct display_timing kyo_tcg121xglp_timing = { 1267static const struct display_timing kyo_tcg121xglp_timing = {
1221 .pixelclock = { 52000000, 65000000, 71000000 }, 1268 .pixelclock = { 52000000, 65000000, 71000000 },
1222 .hactive = { 1024, 1024, 1024 }, 1269 .hactive = { 1024, 1024, 1024 },
@@ -1597,7 +1644,7 @@ static const struct panel_desc ontat_yx700wv03 = {
1597 .width = 154, 1644 .width = 154,
1598 .height = 83, 1645 .height = 83,
1599 }, 1646 },
1600 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1647 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1601}; 1648};
1602 1649
1603static const struct drm_display_mode ortustech_com43h4m85ulc_mode = { 1650static const struct drm_display_mode ortustech_com43h4m85ulc_mode = {
@@ -1741,23 +1788,22 @@ static const struct panel_desc sharp_lq101k1ly04 = {
1741 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 1788 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
1742}; 1789};
1743 1790
1744static const struct drm_display_mode sharp_lq123p1jx31_mode = { 1791static const struct display_timing sharp_lq123p1jx31_timing = {
1745 .clock = 252750, 1792 .pixelclock = { 252750000, 252750000, 266604720 },
1746 .hdisplay = 2400, 1793 .hactive = { 2400, 2400, 2400 },
1747 .hsync_start = 2400 + 48, 1794 .hfront_porch = { 48, 48, 48 },
1748 .hsync_end = 2400 + 48 + 32, 1795 .hback_porch = { 80, 80, 84 },
1749 .htotal = 2400 + 48 + 32 + 80, 1796 .hsync_len = { 32, 32, 32 },
1750 .vdisplay = 1600, 1797 .vactive = { 1600, 1600, 1600 },
1751 .vsync_start = 1600 + 3, 1798 .vfront_porch = { 3, 3, 3 },
1752 .vsync_end = 1600 + 3 + 10, 1799 .vback_porch = { 33, 33, 120 },
1753 .vtotal = 1600 + 3 + 10 + 33, 1800 .vsync_len = { 10, 10, 10 },
1754 .vrefresh = 60, 1801 .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW,
1755 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1756}; 1802};
1757 1803
1758static const struct panel_desc sharp_lq123p1jx31 = { 1804static const struct panel_desc sharp_lq123p1jx31 = {
1759 .modes = &sharp_lq123p1jx31_mode, 1805 .timings = &sharp_lq123p1jx31_timing,
1760 .num_modes = 1, 1806 .num_timings = 1,
1761 .bpc = 8, 1807 .bpc = 8,
1762 .size = { 1808 .size = {
1763 .width = 259, 1809 .width = 259,
@@ -2049,6 +2095,9 @@ static const struct of_device_id platform_of_match[] = {
2049 .compatible = "auo,b133xtn01", 2095 .compatible = "auo,b133xtn01",
2050 .data = &auo_b133xtn01, 2096 .data = &auo_b133xtn01,
2051 }, { 2097 }, {
2098 .compatible = "auo,g104sn02",
2099 .data = &auo_g104sn02,
2100 }, {
2052 .compatible = "auo,g133han01", 2101 .compatible = "auo,g133han01",
2053 .data = &auo_g133han01, 2102 .data = &auo_g133han01,
2054 }, { 2103 }, {
@@ -2124,6 +2173,9 @@ static const struct of_device_id platform_of_match[] = {
2124 .compatible = "innolux,zj070na-01p", 2173 .compatible = "innolux,zj070na-01p",
2125 .data = &innolux_zj070na_01p, 2174 .data = &innolux_zj070na_01p,
2126 }, { 2175 }, {
2176 .compatible = "koe,tx31d200vm0baa",
2177 .data = &koe_tx31d200vm0baa,
2178 }, {
2127 .compatible = "kyo,tcg121xglp", 2179 .compatible = "kyo,tcg121xglp",
2128 .data = &kyo_tcg121xglp, 2180 .data = &kyo_tcg121xglp,
2129 }, { 2181 }, {
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 9a9214ae0fb5..ecb35ed0eac8 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -309,7 +309,7 @@ void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb)
309 struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj); 309 struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj);
310 310
311 WARN_ON(bo->shadow); 311 WARN_ON(bo->shadow);
312 drm_gem_object_unreference_unlocked(qxl_fb->obj); 312 drm_gem_object_put_unlocked(qxl_fb->obj);
313 drm_framebuffer_cleanup(fb); 313 drm_framebuffer_cleanup(fb);
314 kfree(qxl_fb); 314 kfree(qxl_fb);
315} 315}
@@ -1215,7 +1215,7 @@ qxl_user_framebuffer_create(struct drm_device *dev,
1215 ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs); 1215 ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs);
1216 if (ret) { 1216 if (ret) {
1217 kfree(qxl_fb); 1217 kfree(qxl_fb);
1218 drm_gem_object_unreference_unlocked(obj); 1218 drm_gem_object_put_unlocked(obj);
1219 return NULL; 1219 return NULL;
1220 } 1220 }
1221 1221
diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c
index 11085ab01374..c666b89eed5d 100644
--- a/drivers/gpu/drm/qxl/qxl_dumb.c
+++ b/drivers/gpu/drm/qxl/qxl_dumb.c
@@ -82,6 +82,6 @@ int qxl_mode_dumb_mmap(struct drm_file *file_priv,
82 return -ENOENT; 82 return -ENOENT;
83 qobj = gem_to_qxl_bo(gobj); 83 qobj = gem_to_qxl_bo(gobj);
84 *offset_p = qxl_bo_mmap_offset(qobj); 84 *offset_p = qxl_bo_mmap_offset(qobj);
85 drm_gem_object_unreference_unlocked(gobj); 85 drm_gem_object_put_unlocked(gobj);
86 return 0; 86 return 0;
87} 87}
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
index 23af3e352673..338891401f35 100644
--- a/drivers/gpu/drm/qxl/qxl_fb.c
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
@@ -95,7 +95,7 @@ static void qxlfb_destroy_pinned_object(struct drm_gem_object *gobj)
95 qxl_bo_kunmap(qbo); 95 qxl_bo_kunmap(qbo);
96 qxl_bo_unpin(qbo); 96 qxl_bo_unpin(qbo);
97 97
98 drm_gem_object_unreference_unlocked(gobj); 98 drm_gem_object_put_unlocked(gobj);
99} 99}
100 100
101int qxl_get_handle_for_primary_fb(struct qxl_device *qdev, 101int qxl_get_handle_for_primary_fb(struct qxl_device *qdev,
@@ -316,11 +316,11 @@ out_unref:
316 qxl_bo_unpin(qbo); 316 qxl_bo_unpin(qbo);
317 } 317 }
318 if (fb && ret) { 318 if (fb && ret) {
319 drm_gem_object_unreference_unlocked(gobj); 319 drm_gem_object_put_unlocked(gobj);
320 drm_framebuffer_cleanup(fb); 320 drm_framebuffer_cleanup(fb);
321 kfree(fb); 321 kfree(fb);
322 } 322 }
323 drm_gem_object_unreference_unlocked(gobj); 323 drm_gem_object_put_unlocked(gobj);
324 return ret; 324 return ret;
325} 325}
326 326
diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c
index 85f546719adb..f5c1e7872e92 100644
--- a/drivers/gpu/drm/qxl/qxl_gem.c
+++ b/drivers/gpu/drm/qxl/qxl_gem.c
@@ -98,7 +98,7 @@ int qxl_gem_object_create_with_handle(struct qxl_device *qdev,
98 return r; 98 return r;
99 /* drop reference from allocate - handle holds it now */ 99 /* drop reference from allocate - handle holds it now */
100 *qobj = gem_to_qxl_bo(gobj); 100 *qobj = gem_to_qxl_bo(gobj);
101 drm_gem_object_unreference_unlocked(gobj); 101 drm_gem_object_put_unlocked(gobj);
102 return 0; 102 return 0;
103} 103}
104 104
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index e8c0b1037230..e238a1a2eca1 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -121,7 +121,7 @@ static int qxlhw_handle_to_bo(struct drm_file *file_priv, uint64_t handle,
121 qobj = gem_to_qxl_bo(gobj); 121 qobj = gem_to_qxl_bo(gobj);
122 122
123 ret = qxl_release_list_add(release, qobj); 123 ret = qxl_release_list_add(release, qobj);
124 drm_gem_object_unreference_unlocked(gobj); 124 drm_gem_object_put_unlocked(gobj);
125 if (ret) 125 if (ret)
126 return ret; 126 return ret;
127 127
@@ -343,7 +343,7 @@ out2:
343 qxl_bo_unreserve(qobj); 343 qxl_bo_unreserve(qobj);
344 344
345out: 345out:
346 drm_gem_object_unreference_unlocked(gobj); 346 drm_gem_object_put_unlocked(gobj);
347 return ret; 347 return ret;
348} 348}
349 349
diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index af62824ed4cc..6a30196e9d6c 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -211,13 +211,13 @@ void qxl_bo_unref(struct qxl_bo **bo)
211 if ((*bo) == NULL) 211 if ((*bo) == NULL)
212 return; 212 return;
213 213
214 drm_gem_object_unreference_unlocked(&(*bo)->gem_base); 214 drm_gem_object_put_unlocked(&(*bo)->gem_base);
215 *bo = NULL; 215 *bo = NULL;
216} 216}
217 217
218struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo) 218struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
219{ 219{
220 drm_gem_object_reference(&bo->gem_base); 220 drm_gem_object_get(&bo->gem_base);
221 return bo; 221 return bo;
222} 222}
223 223
@@ -318,7 +318,7 @@ void qxl_bo_force_delete(struct qxl_device *qdev)
318 list_del_init(&bo->list); 318 list_del_init(&bo->list);
319 mutex_unlock(&qdev->gem.mutex); 319 mutex_unlock(&qdev->gem.mutex);
320 /* this should unref the ttm bo */ 320 /* this should unref the ttm bo */
321 drm_gem_object_unreference_unlocked(&bo->gem_base); 321 drm_gem_object_put_unlocked(&bo->gem_base);
322 } 322 }
323} 323}
324 324
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 31dd04f6baa1..b28288a781ef 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -415,7 +415,6 @@ static int radeon_pmops_runtime_suspend(struct device *dev)
415 415
416 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 416 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
417 drm_kms_helper_poll_disable(drm_dev); 417 drm_kms_helper_poll_disable(drm_dev);
418 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
419 418
420 ret = radeon_suspend_kms(drm_dev, false, false, false); 419 ret = radeon_suspend_kms(drm_dev, false, false, false);
421 pci_save_state(pdev); 420 pci_save_state(pdev);
@@ -452,7 +451,6 @@ static int radeon_pmops_runtime_resume(struct device *dev)
452 451
453 ret = radeon_resume_kms(drm_dev, false, false); 452 ret = radeon_resume_kms(drm_dev, false, false);
454 drm_kms_helper_poll_enable(drm_dev); 453 drm_kms_helper_poll_enable(drm_dev);
455 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
456 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; 454 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
457 return 0; 455 return 0;
458} 456}
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 7d76ff47028d..3e8bf79bea58 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -71,10 +71,6 @@ struct rockchip_dp_device {
71 struct regmap *grf; 71 struct regmap *grf;
72 struct reset_control *rst; 72 struct reset_control *rst;
73 73
74 struct work_struct psr_work;
75 struct mutex psr_lock;
76 unsigned int psr_state;
77
78 const struct rockchip_dp_chip_data *data; 74 const struct rockchip_dp_chip_data *data;
79 75
80 struct analogix_dp_device *adp; 76 struct analogix_dp_device *adp;
@@ -84,28 +80,13 @@ struct rockchip_dp_device {
84static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled) 80static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
85{ 81{
86 struct rockchip_dp_device *dp = to_dp(encoder); 82 struct rockchip_dp_device *dp = to_dp(encoder);
83 int ret;
87 84
88 if (!analogix_dp_psr_supported(dp->adp)) 85 if (!analogix_dp_psr_enabled(dp->adp))
89 return; 86 return;
90 87
91 DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); 88 DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
92 89
93 mutex_lock(&dp->psr_lock);
94 if (enabled)
95 dp->psr_state = EDP_VSC_PSR_STATE_ACTIVE;
96 else
97 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
98
99 schedule_work(&dp->psr_work);
100 mutex_unlock(&dp->psr_lock);
101}
102
103static void analogix_dp_psr_work(struct work_struct *work)
104{
105 struct rockchip_dp_device *dp =
106 container_of(work, typeof(*dp), psr_work);
107 int ret;
108
109 ret = rockchip_drm_wait_vact_end(dp->encoder.crtc, 90 ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
110 PSR_WAIT_LINE_FLAG_TIMEOUT_MS); 91 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
111 if (ret) { 92 if (ret) {
@@ -113,12 +94,10 @@ static void analogix_dp_psr_work(struct work_struct *work)
113 return; 94 return;
114 } 95 }
115 96
116 mutex_lock(&dp->psr_lock); 97 if (enabled)
117 if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
118 analogix_dp_enable_psr(dp->adp); 98 analogix_dp_enable_psr(dp->adp);
119 else 99 else
120 analogix_dp_disable_psr(dp->adp); 100 analogix_dp_disable_psr(dp->adp);
121 mutex_unlock(&dp->psr_lock);
122} 101}
123 102
124static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) 103static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
@@ -135,8 +114,6 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
135 struct rockchip_dp_device *dp = to_dp(plat_data); 114 struct rockchip_dp_device *dp = to_dp(plat_data);
136 int ret; 115 int ret;
137 116
138 cancel_work_sync(&dp->psr_work);
139
140 ret = clk_prepare_enable(dp->pclk); 117 ret = clk_prepare_enable(dp->pclk);
141 if (ret < 0) { 118 if (ret < 0) {
142 DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret); 119 DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
@@ -355,10 +332,6 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
355 dp->plat_data.power_off = rockchip_dp_powerdown; 332 dp->plat_data.power_off = rockchip_dp_powerdown;
356 dp->plat_data.get_modes = rockchip_dp_get_modes; 333 dp->plat_data.get_modes = rockchip_dp_get_modes;
357 334
358 mutex_init(&dp->psr_lock);
359 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
360 INIT_WORK(&dp->psr_work, analogix_dp_psr_work);
361
362 ret = rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set); 335 ret = rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set);
363 if (ret < 0) 336 if (ret < 0)
364 goto err_cleanup_encoder; 337 goto err_cleanup_encoder;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index ec999d9f15f6..c6fbdcd87c16 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -43,8 +43,6 @@
43#define GRF_SOC_CON9 0x6224 43#define GRF_SOC_CON9 0x6224
44#define DP_SEL_VOP_LIT BIT(12) 44#define DP_SEL_VOP_LIT BIT(12)
45#define GRF_SOC_CON26 0x6268 45#define GRF_SOC_CON26 0x6268
46#define UPHY_SEL_BIT 3
47#define UPHY_SEL_MASK BIT(19)
48#define DPTX_HPD_SEL (3 << 12) 46#define DPTX_HPD_SEL (3 << 12)
49#define DPTX_HPD_DEL (2 << 12) 47#define DPTX_HPD_DEL (2 << 12)
50#define DPTX_HPD_SEL_MASK (3 << 28) 48#define DPTX_HPD_SEL_MASK (3 << 28)
@@ -394,11 +392,6 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
394 union extcon_property_value property; 392 union extcon_property_value property;
395 int ret; 393 int ret;
396 394
397 ret = cdn_dp_grf_write(dp, GRF_SOC_CON26,
398 (port->id << UPHY_SEL_BIT) | UPHY_SEL_MASK);
399 if (ret)
400 return ret;
401
402 if (!port->phy_enabled) { 395 if (!port->phy_enabled) {
403 ret = phy_power_on(port->phy); 396 ret = phy_power_on(port->phy);
404 if (ret) { 397 if (ret) {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 158e79e5062e..53d4afe15278 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -117,6 +117,8 @@ struct vop {
117 spinlock_t reg_lock; 117 spinlock_t reg_lock;
118 /* lock vop irq reg */ 118 /* lock vop irq reg */
119 spinlock_t irq_lock; 119 spinlock_t irq_lock;
120 /* protects crtc enable/disable */
121 struct mutex vop_lock;
120 122
121 unsigned int irq; 123 unsigned int irq;
122 124
@@ -517,7 +519,10 @@ static int vop_enable(struct drm_crtc *crtc)
517 goto err_disable_aclk; 519 goto err_disable_aclk;
518 } 520 }
519 521
520 memcpy(vop->regs, vop->regsbak, vop->len); 522 spin_lock(&vop->reg_lock);
523 for (i = 0; i < vop->len; i += 4)
524 writel_relaxed(vop->regsbak[i / 4], vop->regs + i);
525
521 /* 526 /*
522 * We need to make sure that all windows are disabled before we 527 * We need to make sure that all windows are disabled before we
523 * enable the crtc. Otherwise we might try to scan from a destroyed 528 * enable the crtc. Otherwise we might try to scan from a destroyed
@@ -527,10 +532,9 @@ static int vop_enable(struct drm_crtc *crtc)
527 struct vop_win *vop_win = &vop->win[i]; 532 struct vop_win *vop_win = &vop->win[i];
528 const struct vop_win_data *win = vop_win->data; 533 const struct vop_win_data *win = vop_win->data;
529 534
530 spin_lock(&vop->reg_lock);
531 VOP_WIN_SET(vop, win, enable, 0); 535 VOP_WIN_SET(vop, win, enable, 0);
532 spin_unlock(&vop->reg_lock);
533 } 536 }
537 spin_unlock(&vop->reg_lock);
534 538
535 vop_cfg_done(vop); 539 vop_cfg_done(vop);
536 540
@@ -569,6 +573,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
569 573
570 WARN_ON(vop->event); 574 WARN_ON(vop->event);
571 575
576 mutex_lock(&vop->vop_lock);
572 drm_crtc_vblank_off(crtc); 577 drm_crtc_vblank_off(crtc);
573 578
574 /* 579 /*
@@ -604,6 +609,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
604 clk_disable(vop->aclk); 609 clk_disable(vop->aclk);
605 clk_disable(vop->hclk); 610 clk_disable(vop->hclk);
606 pm_runtime_put(vop->dev); 611 pm_runtime_put(vop->dev);
612 mutex_unlock(&vop->vop_lock);
607 613
608 if (crtc->state->event && !crtc->state->active) { 614 if (crtc->state->event && !crtc->state->active) {
609 spin_lock_irq(&crtc->dev->event_lock); 615 spin_lock_irq(&crtc->dev->event_lock);
@@ -868,10 +874,13 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
868 uint32_t pin_pol, val; 874 uint32_t pin_pol, val;
869 int ret; 875 int ret;
870 876
877 mutex_lock(&vop->vop_lock);
878
871 WARN_ON(vop->event); 879 WARN_ON(vop->event);
872 880
873 ret = vop_enable(crtc); 881 ret = vop_enable(crtc);
874 if (ret) { 882 if (ret) {
883 mutex_unlock(&vop->vop_lock);
875 DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret); 884 DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
876 return; 885 return;
877 } 886 }
@@ -935,6 +944,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
935 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); 944 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
936 945
937 VOP_REG_SET(vop, common, standby, 0); 946 VOP_REG_SET(vop, common, standby, 0);
947 mutex_unlock(&vop->vop_lock);
938} 948}
939 949
940static bool vop_fs_irq_is_pending(struct vop *vop) 950static bool vop_fs_irq_is_pending(struct vop *vop)
@@ -1137,15 +1147,14 @@ static void vop_handle_vblank(struct vop *vop)
1137{ 1147{
1138 struct drm_device *drm = vop->drm_dev; 1148 struct drm_device *drm = vop->drm_dev;
1139 struct drm_crtc *crtc = &vop->crtc; 1149 struct drm_crtc *crtc = &vop->crtc;
1140 unsigned long flags;
1141 1150
1142 spin_lock_irqsave(&drm->event_lock, flags); 1151 spin_lock(&drm->event_lock);
1143 if (vop->event) { 1152 if (vop->event) {
1144 drm_crtc_send_vblank_event(crtc, vop->event); 1153 drm_crtc_send_vblank_event(crtc, vop->event);
1145 drm_crtc_vblank_put(crtc); 1154 drm_crtc_vblank_put(crtc);
1146 vop->event = NULL; 1155 vop->event = NULL;
1147 } 1156 }
1148 spin_unlock_irqrestore(&drm->event_lock, flags); 1157 spin_unlock(&drm->event_lock);
1149 1158
1150 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending)) 1159 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending))
1151 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq); 1160 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq);
@@ -1156,21 +1165,20 @@ static irqreturn_t vop_isr(int irq, void *data)
1156 struct vop *vop = data; 1165 struct vop *vop = data;
1157 struct drm_crtc *crtc = &vop->crtc; 1166 struct drm_crtc *crtc = &vop->crtc;
1158 uint32_t active_irqs; 1167 uint32_t active_irqs;
1159 unsigned long flags;
1160 int ret = IRQ_NONE; 1168 int ret = IRQ_NONE;
1161 1169
1162 /* 1170 /*
1163 * interrupt register has interrupt status, enable and clear bits, we 1171 * interrupt register has interrupt status, enable and clear bits, we
1164 * must hold irq_lock to avoid a race with enable/disable_vblank(). 1172 * must hold irq_lock to avoid a race with enable/disable_vblank().
1165 */ 1173 */
1166 spin_lock_irqsave(&vop->irq_lock, flags); 1174 spin_lock(&vop->irq_lock);
1167 1175
1168 active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK); 1176 active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK);
1169 /* Clear all active interrupt sources */ 1177 /* Clear all active interrupt sources */
1170 if (active_irqs) 1178 if (active_irqs)
1171 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1); 1179 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1);
1172 1180
1173 spin_unlock_irqrestore(&vop->irq_lock, flags); 1181 spin_unlock(&vop->irq_lock);
1174 1182
1175 /* This is expected for vop iommu irqs, since the irq is shared */ 1183 /* This is expected for vop iommu irqs, since the irq is shared */
1176 if (!active_irqs) 1184 if (!active_irqs)
@@ -1393,7 +1401,11 @@ static int vop_initial(struct vop *vop)
1393 usleep_range(10, 20); 1401 usleep_range(10, 20);
1394 reset_control_deassert(ahb_rst); 1402 reset_control_deassert(ahb_rst);
1395 1403
1396 memcpy(vop->regsbak, vop->regs, vop->len); 1404 VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1);
1405 VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0);
1406
1407 for (i = 0; i < vop->len; i += sizeof(u32))
1408 vop->regsbak[i / 4] = readl_relaxed(vop->regs + i);
1397 1409
1398 VOP_REG_SET(vop, misc, global_regdone_en, 1); 1410 VOP_REG_SET(vop, misc, global_regdone_en, 1);
1399 VOP_REG_SET(vop, common, dsp_blank, 0); 1411 VOP_REG_SET(vop, common, dsp_blank, 0);
@@ -1473,15 +1485,21 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
1473{ 1485{
1474 struct vop *vop = to_vop(crtc); 1486 struct vop *vop = to_vop(crtc);
1475 unsigned long jiffies_left; 1487 unsigned long jiffies_left;
1488 int ret = 0;
1476 1489
1477 if (!crtc || !vop->is_enabled) 1490 if (!crtc || !vop->is_enabled)
1478 return -ENODEV; 1491 return -ENODEV;
1479 1492
1480 if (mstimeout <= 0) 1493 mutex_lock(&vop->vop_lock);
1481 return -EINVAL; 1494 if (mstimeout <= 0) {
1495 ret = -EINVAL;
1496 goto out;
1497 }
1482 1498
1483 if (vop_line_flag_irq_is_enabled(vop)) 1499 if (vop_line_flag_irq_is_enabled(vop)) {
1484 return -EBUSY; 1500 ret = -EBUSY;
1501 goto out;
1502 }
1485 1503
1486 reinit_completion(&vop->line_flag_completion); 1504 reinit_completion(&vop->line_flag_completion);
1487 vop_line_flag_irq_enable(vop); 1505 vop_line_flag_irq_enable(vop);
@@ -1492,10 +1510,13 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
1492 1510
1493 if (jiffies_left == 0) { 1511 if (jiffies_left == 0) {
1494 DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n"); 1512 DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
1495 return -ETIMEDOUT; 1513 ret = -ETIMEDOUT;
1514 goto out;
1496 } 1515 }
1497 1516
1498 return 0; 1517out:
1518 mutex_unlock(&vop->vop_lock);
1519 return ret;
1499} 1520}
1500EXPORT_SYMBOL(rockchip_drm_wait_vact_end); 1521EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
1501 1522
@@ -1545,18 +1566,11 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
1545 1566
1546 spin_lock_init(&vop->reg_lock); 1567 spin_lock_init(&vop->reg_lock);
1547 spin_lock_init(&vop->irq_lock); 1568 spin_lock_init(&vop->irq_lock);
1548 1569 mutex_init(&vop->vop_lock);
1549 ret = devm_request_irq(dev, vop->irq, vop_isr,
1550 IRQF_SHARED, dev_name(dev), vop);
1551 if (ret)
1552 return ret;
1553
1554 /* IRQ is initially disabled; it gets enabled in power_on */
1555 disable_irq(vop->irq);
1556 1570
1557 ret = vop_create_crtc(vop); 1571 ret = vop_create_crtc(vop);
1558 if (ret) 1572 if (ret)
1559 goto err_enable_irq; 1573 return ret;
1560 1574
1561 pm_runtime_enable(&pdev->dev); 1575 pm_runtime_enable(&pdev->dev);
1562 1576
@@ -1567,13 +1581,19 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
1567 goto err_disable_pm_runtime; 1581 goto err_disable_pm_runtime;
1568 } 1582 }
1569 1583
1584 ret = devm_request_irq(dev, vop->irq, vop_isr,
1585 IRQF_SHARED, dev_name(dev), vop);
1586 if (ret)
1587 goto err_disable_pm_runtime;
1588
1589 /* IRQ is initially disabled; it gets enabled in power_on */
1590 disable_irq(vop->irq);
1591
1570 return 0; 1592 return 0;
1571 1593
1572err_disable_pm_runtime: 1594err_disable_pm_runtime:
1573 pm_runtime_disable(&pdev->dev); 1595 pm_runtime_disable(&pdev->dev);
1574 vop_destroy_crtc(vop); 1596 vop_destroy_crtc(vop);
1575err_enable_irq:
1576 enable_irq(vop->irq); /* To balance out the disable_irq above */
1577 return ret; 1597 return ret;
1578} 1598}
1579 1599
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 092ade4ff6a5..9bad54f3de38 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -42,6 +42,56 @@ static const u32 sunxi_rgb2yuv_coef[12] = {
42 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808 42 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
43}; 43};
44 44
45/*
46 * These coefficients are taken from the A33 BSP from Allwinner.
47 *
48 * The formula is for each component, each coefficient being multiplied by
49 * 1024 and each constant being multiplied by 16:
50 * G = 1.164 * Y - 0.391 * U - 0.813 * V + 135
51 * R = 1.164 * Y + 1.596 * V - 222
52 * B = 1.164 * Y + 2.018 * U + 276
53 *
54 * This seems to be a conversion from Y[16:235] UV[16:240] to RGB[0:255],
55 * following the BT601 spec.
56 */
57static const u32 sunxi_bt601_yuv2rgb_coef[12] = {
58 0x000004a7, 0x00001e6f, 0x00001cbf, 0x00000877,
59 0x000004a7, 0x00000000, 0x00000662, 0x00003211,
60 0x000004a7, 0x00000812, 0x00000000, 0x00002eb1,
61};
62
63static inline bool sun4i_backend_format_is_planar_yuv(uint32_t format)
64{
65 switch (format) {
66 case DRM_FORMAT_YUV411:
67 case DRM_FORMAT_YUV422:
68 case DRM_FORMAT_YUV444:
69 return true;
70 default:
71 return false;
72 }
73}
74
75static inline bool sun4i_backend_format_is_packed_yuv422(uint32_t format)
76{
77 switch (format) {
78 case DRM_FORMAT_YUYV:
79 case DRM_FORMAT_YVYU:
80 case DRM_FORMAT_UYVY:
81 case DRM_FORMAT_VYUY:
82 return true;
83
84 default:
85 return false;
86 }
87}
88
89static inline bool sun4i_backend_format_is_yuv(uint32_t format)
90{
91 return sun4i_backend_format_is_planar_yuv(format) ||
92 sun4i_backend_format_is_packed_yuv422(format);
93}
94
45static void sun4i_backend_apply_color_correction(struct sunxi_engine *engine) 95static void sun4i_backend_apply_color_correction(struct sunxi_engine *engine)
46{ 96{
47 int i; 97 int i;
@@ -166,6 +216,61 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
166 return 0; 216 return 0;
167} 217}
168 218
219static int sun4i_backend_update_yuv_format(struct sun4i_backend *backend,
220 int layer, struct drm_plane *plane)
221{
222 struct drm_plane_state *state = plane->state;
223 struct drm_framebuffer *fb = state->fb;
224 uint32_t format = fb->format->format;
225 u32 val = SUN4I_BACKEND_IYUVCTL_EN;
226 int i;
227
228 for (i = 0; i < ARRAY_SIZE(sunxi_bt601_yuv2rgb_coef); i++)
229 regmap_write(backend->engine.regs,
230 SUN4I_BACKEND_YGCOEF_REG(i),
231 sunxi_bt601_yuv2rgb_coef[i]);
232
233 /*
234 * We should do that only for a single plane, but the
235 * framebuffer's atomic_check has our back on this.
236 */
237 regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
238 SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN,
239 SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN);
240
241 /* TODO: Add support for the multi-planar YUV formats */
242 if (sun4i_backend_format_is_packed_yuv422(format))
243 val |= SUN4I_BACKEND_IYUVCTL_FBFMT_PACKED_YUV422;
244 else
245 DRM_DEBUG_DRIVER("Unsupported YUV format (0x%x)\n", format);
246
247 /*
248 * Allwinner seems to list the pixel sequence from right to left, while
249 * DRM lists it from left to right.
250 */
251 switch (format) {
252 case DRM_FORMAT_YUYV:
253 val |= SUN4I_BACKEND_IYUVCTL_FBPS_VYUY;
254 break;
255 case DRM_FORMAT_YVYU:
256 val |= SUN4I_BACKEND_IYUVCTL_FBPS_UYVY;
257 break;
258 case DRM_FORMAT_UYVY:
259 val |= SUN4I_BACKEND_IYUVCTL_FBPS_YVYU;
260 break;
261 case DRM_FORMAT_VYUY:
262 val |= SUN4I_BACKEND_IYUVCTL_FBPS_YUYV;
263 break;
264 default:
265 DRM_DEBUG_DRIVER("Unsupported YUV pixel sequence (0x%x)\n",
266 format);
267 }
268
269 regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVCTL_REG, val);
270
271 return 0;
272}
273
169int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, 274int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
170 int layer, struct drm_plane *plane) 275 int layer, struct drm_plane *plane)
171{ 276{
@@ -175,6 +280,10 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
175 u32 val; 280 u32 val;
176 int ret; 281 int ret;
177 282
283 /* Clear the YUV mode */
284 regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
285 SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN, 0);
286
178 if (plane->state->crtc) 287 if (plane->state->crtc)
179 interlaced = plane->state->crtc->state->adjusted_mode.flags 288 interlaced = plane->state->crtc->state->adjusted_mode.flags
180 & DRM_MODE_FLAG_INTERLACE; 289 & DRM_MODE_FLAG_INTERLACE;
@@ -186,6 +295,9 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
186 DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n", 295 DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n",
187 interlaced ? "on" : "off"); 296 interlaced ? "on" : "off");
188 297
298 if (sun4i_backend_format_is_yuv(fb->format->format))
299 return sun4i_backend_update_yuv_format(backend, layer, plane);
300
189 ret = sun4i_backend_drm_format_to_layer(fb->format->format, &val); 301 ret = sun4i_backend_drm_format_to_layer(fb->format->format, &val);
190 if (ret) { 302 if (ret) {
191 DRM_DEBUG_DRIVER("Invalid format\n"); 303 DRM_DEBUG_DRIVER("Invalid format\n");
@@ -223,6 +335,21 @@ int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend,
223 return 0; 335 return 0;
224} 336}
225 337
338static int sun4i_backend_update_yuv_buffer(struct sun4i_backend *backend,
339 struct drm_framebuffer *fb,
340 dma_addr_t paddr)
341{
342 /* TODO: Add support for the multi-planar YUV formats */
343 DRM_DEBUG_DRIVER("Setting packed YUV buffer address to %pad\n", &paddr);
344 regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVADD_REG(0), paddr);
345
346 DRM_DEBUG_DRIVER("Layer line width: %d bits\n", fb->pitches[0] * 8);
347 regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVLINEWIDTH_REG(0),
348 fb->pitches[0] * 8);
349
350 return 0;
351}
352
226int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, 353int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
227 int layer, struct drm_plane *plane) 354 int layer, struct drm_plane *plane)
228{ 355{
@@ -248,6 +375,9 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
248 */ 375 */
249 paddr -= PHYS_OFFSET; 376 paddr -= PHYS_OFFSET;
250 377
378 if (sun4i_backend_format_is_yuv(fb->format->format))
379 return sun4i_backend_update_yuv_buffer(backend, fb, paddr);
380
251 /* Write the 32 lower bits of the address (in bits) */ 381 /* Write the 32 lower bits of the address (in bits) */
252 lo_paddr = paddr << 3; 382 lo_paddr = paddr << 3;
253 DRM_DEBUG_DRIVER("Setting address lower bits to 0x%x\n", lo_paddr); 383 DRM_DEBUG_DRIVER("Setting address lower bits to 0x%x\n", lo_paddr);
@@ -330,6 +460,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
330 unsigned int num_planes = 0; 460 unsigned int num_planes = 0;
331 unsigned int num_alpha_planes = 0; 461 unsigned int num_alpha_planes = 0;
332 unsigned int num_frontend_planes = 0; 462 unsigned int num_frontend_planes = 0;
463 unsigned int num_yuv_planes = 0;
333 unsigned int current_pipe = 0; 464 unsigned int current_pipe = 0;
334 unsigned int i; 465 unsigned int i;
335 466
@@ -362,6 +493,11 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
362 if (fb->format->has_alpha) 493 if (fb->format->has_alpha)
363 num_alpha_planes++; 494 num_alpha_planes++;
364 495
496 if (sun4i_backend_format_is_yuv(fb->format->format)) {
497 DRM_DEBUG_DRIVER("Plane FB format is YUV\n");
498 num_yuv_planes++;
499 }
500
365 DRM_DEBUG_DRIVER("Plane zpos is %d\n", 501 DRM_DEBUG_DRIVER("Plane zpos is %d\n",
366 plane_state->normalized_zpos); 502 plane_state->normalized_zpos);
367 503
@@ -430,13 +566,20 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
430 s_state->pipe = current_pipe; 566 s_state->pipe = current_pipe;
431 } 567 }
432 568
569 /* We can only have a single YUV plane at a time */
570 if (num_yuv_planes > SUN4I_BACKEND_NUM_YUV_PLANES) {
571 DRM_DEBUG_DRIVER("Too many planes with YUV, rejecting...\n");
572 return -EINVAL;
573 }
574
433 if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) { 575 if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) {
434 DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n"); 576 DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n");
435 return -EINVAL; 577 return -EINVAL;
436 } 578 }
437 579
438 DRM_DEBUG_DRIVER("State valid with %u planes, %u alpha, %u video\n", 580 DRM_DEBUG_DRIVER("State valid with %u planes, %u alpha, %u video, %u YUV\n",
439 num_planes, num_alpha_planes, num_frontend_planes); 581 num_planes, num_alpha_planes, num_frontend_planes,
582 num_yuv_planes);
440 583
441 return 0; 584 return 0;
442} 585}
@@ -793,6 +936,9 @@ static const struct sun4i_backend_quirks sun7i_backend_quirks = {
793static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = { 936static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = {
794}; 937};
795 938
939static const struct sun4i_backend_quirks sun9i_backend_quirks = {
940};
941
796static const struct of_device_id sun4i_backend_of_table[] = { 942static const struct of_device_id sun4i_backend_of_table[] = {
797 { 943 {
798 .compatible = "allwinner,sun4i-a10-display-backend", 944 .compatible = "allwinner,sun4i-a10-display-backend",
@@ -814,6 +960,10 @@ static const struct of_device_id sun4i_backend_of_table[] = {
814 .compatible = "allwinner,sun8i-a33-display-backend", 960 .compatible = "allwinner,sun8i-a33-display-backend",
815 .data = &sun8i_a33_backend_quirks, 961 .data = &sun8i_a33_backend_quirks,
816 }, 962 },
963 {
964 .compatible = "allwinner,sun9i-a80-display-backend",
965 .data = &sun9i_backend_quirks,
966 },
817 { } 967 { }
818}; 968};
819MODULE_DEVICE_TABLE(of, sun4i_backend_of_table); 969MODULE_DEVICE_TABLE(of, sun4i_backend_of_table);
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index 52e77591186a..316f2179e9e1 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -72,6 +72,7 @@
72#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(x) ((x) << 15) 72#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(x) ((x) << 15)
73#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK GENMASK(11, 10) 73#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK GENMASK(11, 10)
74#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(x) ((x) << 10) 74#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(x) ((x) << 10)
75#define SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN BIT(2)
75#define SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN BIT(1) 76#define SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN BIT(1)
76 77
77#define SUN4I_BACKEND_ATTCTL_REG1(l) (0x8a0 + (0x4 * (l))) 78#define SUN4I_BACKEND_ATTCTL_REG1(l) (0x8a0 + (0x4 * (l)))
@@ -110,7 +111,23 @@
110#define SUN4I_BACKEND_SPREN_REG 0x900 111#define SUN4I_BACKEND_SPREN_REG 0x900
111#define SUN4I_BACKEND_SPRFMTCTL_REG 0x908 112#define SUN4I_BACKEND_SPRFMTCTL_REG 0x908
112#define SUN4I_BACKEND_SPRALPHACTL_REG 0x90c 113#define SUN4I_BACKEND_SPRALPHACTL_REG 0x90c
114
113#define SUN4I_BACKEND_IYUVCTL_REG 0x920 115#define SUN4I_BACKEND_IYUVCTL_REG 0x920
116#define SUN4I_BACKEND_IYUVCTL_FBFMT_MASK GENMASK(14, 12)
117#define SUN4I_BACKEND_IYUVCTL_FBFMT_PACKED_YUV444 (4 << 12)
118#define SUN4I_BACKEND_IYUVCTL_FBFMT_PACKED_YUV422 (3 << 12)
119#define SUN4I_BACKEND_IYUVCTL_FBFMT_PLANAR_YUV444 (2 << 12)
120#define SUN4I_BACKEND_IYUVCTL_FBFMT_PLANAR_YUV222 (1 << 12)
121#define SUN4I_BACKEND_IYUVCTL_FBFMT_PLANAR_YUV111 (0 << 12)
122#define SUN4I_BACKEND_IYUVCTL_FBPS_MASK GENMASK(9, 8)
123#define SUN4I_BACKEND_IYUVCTL_FBPS_YVYU (3 << 8)
124#define SUN4I_BACKEND_IYUVCTL_FBPS_VYUY (2 << 8)
125#define SUN4I_BACKEND_IYUVCTL_FBPS_YUYV (1 << 8)
126#define SUN4I_BACKEND_IYUVCTL_FBPS_UYVY (0 << 8)
127#define SUN4I_BACKEND_IYUVCTL_FBPS_VUYA (1 << 8)
128#define SUN4I_BACKEND_IYUVCTL_FBPS_AYUV (0 << 8)
129#define SUN4I_BACKEND_IYUVCTL_EN BIT(0)
130
114#define SUN4I_BACKEND_IYUVADD_REG(c) (0x930 + (0x4 * (c))) 131#define SUN4I_BACKEND_IYUVADD_REG(c) (0x930 + (0x4 * (c)))
115 132
116#define SUN4I_BACKEND_IYUVLINEWIDTH_REG(c) (0x940 + (0x4 * (c))) 133#define SUN4I_BACKEND_IYUVLINEWIDTH_REG(c) (0x940 + (0x4 * (c)))
@@ -149,6 +166,7 @@
149#define SUN4I_BACKEND_NUM_LAYERS 4 166#define SUN4I_BACKEND_NUM_LAYERS 4
150#define SUN4I_BACKEND_NUM_ALPHA_LAYERS 1 167#define SUN4I_BACKEND_NUM_ALPHA_LAYERS 1
151#define SUN4I_BACKEND_NUM_FRONTEND_LAYERS 1 168#define SUN4I_BACKEND_NUM_FRONTEND_LAYERS 1
169#define SUN4I_BACKEND_NUM_YUV_PLANES 1
152 170
153struct sun4i_backend { 171struct sun4i_backend {
154 struct sunxi_engine engine; 172 struct sunxi_engine engine;
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index a0f43b81c64c..7f0705ef9f4e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -176,7 +176,13 @@ static bool sun4i_drv_node_is_frontend(struct device_node *node)
176 of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") || 176 of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") ||
177 of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") || 177 of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") ||
178 of_device_is_compatible(node, "allwinner,sun7i-a20-display-frontend") || 178 of_device_is_compatible(node, "allwinner,sun7i-a20-display-frontend") ||
179 of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend"); 179 of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend") ||
180 of_device_is_compatible(node, "allwinner,sun9i-a80-display-frontend");
181}
182
183static bool sun4i_drv_node_is_deu(struct device_node *node)
184{
185 return of_device_is_compatible(node, "allwinner,sun9i-a80-deu");
180} 186}
181 187
182static bool sun4i_drv_node_is_supported_frontend(struct device_node *node) 188static bool sun4i_drv_node_is_supported_frontend(struct device_node *node)
@@ -257,7 +263,8 @@ static int sun4i_drv_add_endpoints(struct device *dev,
257 * enabled frontend supported by the driver, we add it to our 263 * enabled frontend supported by the driver, we add it to our
258 * component list. 264 * component list.
259 */ 265 */
260 if (!sun4i_drv_node_is_frontend(node) || 266 if (!(sun4i_drv_node_is_frontend(node) ||
267 sun4i_drv_node_is_deu(node)) ||
261 (sun4i_drv_node_is_supported_frontend(node) && 268 (sun4i_drv_node_is_supported_frontend(node) &&
262 of_device_is_available(node))) { 269 of_device_is_available(node))) {
263 /* Add current component */ 270 /* Add current component */
@@ -361,6 +368,7 @@ static const struct of_device_id sun4i_drv_of_table[] = {
361 { .compatible = "allwinner,sun8i-a83t-display-engine" }, 368 { .compatible = "allwinner,sun8i-a83t-display-engine" },
362 { .compatible = "allwinner,sun8i-h3-display-engine" }, 369 { .compatible = "allwinner,sun8i-h3-display-engine" },
363 { .compatible = "allwinner,sun8i-v3s-display-engine" }, 370 { .compatible = "allwinner,sun8i-v3s-display-engine" },
371 { .compatible = "allwinner,sun9i-a80-display-engine" },
364 { } 372 { }
365}; 373};
366MODULE_DEVICE_TABLE(of, sun4i_drv_of_table); 374MODULE_DEVICE_TABLE(of, sun4i_drv_of_table);
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 33ad377569ec..2949a3c912c1 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -134,7 +134,11 @@ static const uint32_t sun4i_backend_layer_formats[] = {
134 DRM_FORMAT_RGBA4444, 134 DRM_FORMAT_RGBA4444,
135 DRM_FORMAT_RGB888, 135 DRM_FORMAT_RGB888,
136 DRM_FORMAT_RGB565, 136 DRM_FORMAT_RGB565,
137 DRM_FORMAT_UYVY,
138 DRM_FORMAT_VYUY,
137 DRM_FORMAT_XRGB8888, 139 DRM_FORMAT_XRGB8888,
140 DRM_FORMAT_YUYV,
141 DRM_FORMAT_YVYU,
138}; 142};
139 143
140static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, 144static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c
index be3f14d7746d..bffff4c9fbf5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_lvds.c
+++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c
@@ -94,9 +94,64 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder)
94 } 94 }
95} 95}
96 96
97static enum drm_mode_status sun4i_lvds_encoder_mode_valid(struct drm_encoder *crtc,
98 const struct drm_display_mode *mode)
99{
100 struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(crtc);
101 struct sun4i_tcon *tcon = lvds->tcon;
102 u32 hsync = mode->hsync_end - mode->hsync_start;
103 u32 vsync = mode->vsync_end - mode->vsync_start;
104 unsigned long rate = mode->clock * 1000;
105 long rounded_rate;
106
107 DRM_DEBUG_DRIVER("Validating modes...\n");
108
109 if (hsync < 1)
110 return MODE_HSYNC_NARROW;
111
112 if (hsync > 0x3ff)
113 return MODE_HSYNC_WIDE;
114
115 if ((mode->hdisplay < 1) || (mode->htotal < 1))
116 return MODE_H_ILLEGAL;
117
118 if ((mode->hdisplay > 0x7ff) || (mode->htotal > 0xfff))
119 return MODE_BAD_HVALUE;
120
121 DRM_DEBUG_DRIVER("Horizontal parameters OK\n");
122
123 if (vsync < 1)
124 return MODE_VSYNC_NARROW;
125
126 if (vsync > 0x3ff)
127 return MODE_VSYNC_WIDE;
128
129 if ((mode->vdisplay < 1) || (mode->vtotal < 1))
130 return MODE_V_ILLEGAL;
131
132 if ((mode->vdisplay > 0x7ff) || (mode->vtotal > 0xfff))
133 return MODE_BAD_VVALUE;
134
135 DRM_DEBUG_DRIVER("Vertical parameters OK\n");
136
137 tcon->dclk_min_div = 7;
138 tcon->dclk_max_div = 7;
139 rounded_rate = clk_round_rate(tcon->dclk, rate);
140 if (rounded_rate < rate)
141 return MODE_CLOCK_LOW;
142
143 if (rounded_rate > rate)
144 return MODE_CLOCK_HIGH;
145
146 DRM_DEBUG_DRIVER("Clock rate OK\n");
147
148 return MODE_OK;
149}
150
97static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = { 151static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = {
98 .disable = sun4i_lvds_encoder_disable, 152 .disable = sun4i_lvds_encoder_disable,
99 .enable = sun4i_lvds_encoder_enable, 153 .enable = sun4i_lvds_encoder_enable,
154 .mode_valid = sun4i_lvds_encoder_mode_valid,
100}; 155};
101 156
102static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = { 157static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
index 832f8f9bc47f..a2a697a099e6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
@@ -52,10 +52,10 @@ static int sun4i_rgb_get_modes(struct drm_connector *connector)
52 return drm_panel_get_modes(tcon->panel); 52 return drm_panel_get_modes(tcon->panel);
53} 53}
54 54
55static int sun4i_rgb_mode_valid(struct drm_connector *connector, 55static enum drm_mode_status sun4i_rgb_mode_valid(struct drm_encoder *crtc,
56 struct drm_display_mode *mode) 56 const struct drm_display_mode *mode)
57{ 57{
58 struct sun4i_rgb *rgb = drm_connector_to_sun4i_rgb(connector); 58 struct sun4i_rgb *rgb = drm_encoder_to_sun4i_rgb(crtc);
59 struct sun4i_tcon *tcon = rgb->tcon; 59 struct sun4i_tcon *tcon = rgb->tcon;
60 u32 hsync = mode->hsync_end - mode->hsync_start; 60 u32 hsync = mode->hsync_end - mode->hsync_start;
61 u32 vsync = mode->vsync_end - mode->vsync_start; 61 u32 vsync = mode->vsync_end - mode->vsync_start;
@@ -106,7 +106,6 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector,
106 106
107static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = { 107static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = {
108 .get_modes = sun4i_rgb_get_modes, 108 .get_modes = sun4i_rgb_get_modes,
109 .mode_valid = sun4i_rgb_mode_valid,
110}; 109};
111 110
112static void 111static void
@@ -156,6 +155,7 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder)
156static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = { 155static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = {
157 .disable = sun4i_rgb_encoder_disable, 156 .disable = sun4i_rgb_encoder_disable,
158 .enable = sun4i_rgb_encoder_enable, 157 .enable = sun4i_rgb_encoder_enable,
158 .mode_valid = sun4i_rgb_mode_valid,
159}; 159};
160 160
161static void sun4i_rgb_enc_destroy(struct drm_encoder *encoder) 161static void sun4i_rgb_enc_destroy(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 0d6c5ed44795..1a114e380f13 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -17,6 +17,7 @@
17#include <drm/drm_encoder.h> 17#include <drm/drm_encoder.h>
18#include <drm/drm_modes.h> 18#include <drm/drm_modes.h>
19#include <drm/drm_of.h> 19#include <drm/drm_of.h>
20#include <drm/drm_panel.h>
20 21
21#include <uapi/drm/drm_mode.h> 22#include <uapi/drm/drm_mode.h>
22 23
@@ -343,6 +344,9 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
343static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, 344static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
344 const struct drm_display_mode *mode) 345 const struct drm_display_mode *mode)
345{ 346{
347 struct drm_panel *panel = tcon->panel;
348 struct drm_connector *connector = panel->connector;
349 struct drm_display_info display_info = connector->display_info;
346 unsigned int bp, hsync, vsync; 350 unsigned int bp, hsync, vsync;
347 u8 clk_delay; 351 u8 clk_delay;
348 u32 val = 0; 352 u32 val = 0;
@@ -400,6 +404,27 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
400 if (mode->flags & DRM_MODE_FLAG_PVSYNC) 404 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
401 val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; 405 val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
402 406
407 /*
408 * On A20 and similar SoCs, the only way to achieve Positive Edge
409 * (Rising Edge), is setting dclk clock phase to 2/3(240°).
410 * By default TCON works in Negative Edge(Falling Edge),
411 * this is why phase is set to 0 in that case.
412 * Unfortunately there's no way to logically invert dclk through
413 * IO_POL register.
414 * The only acceptable way to work, triple checked with scope,
415 * is using clock phase set to 0° for Negative Edge and set to 240°
416 * for Positive Edge.
417 * On A33 and similar SoCs there would be a 90° phase option,
418 * but it divides also dclk by 2.
419 * Following code is a way to avoid quirks all around TCON
420 * and DOTCLOCK drivers.
421 */
422 if (display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
423 clk_set_phase(tcon->dclk, 240);
424
425 if (display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
426 clk_set_phase(tcon->dclk, 0);
427
403 regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG, 428 regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG,
404 SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE, 429 SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE,
405 val); 430 val);
@@ -850,6 +875,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
850 struct sunxi_engine *engine; 875 struct sunxi_engine *engine;
851 struct device_node *remote; 876 struct device_node *remote;
852 struct sun4i_tcon *tcon; 877 struct sun4i_tcon *tcon;
878 struct reset_control *edp_rstc;
853 bool has_lvds_rst, has_lvds_alt, can_lvds; 879 bool has_lvds_rst, has_lvds_alt, can_lvds;
854 int ret; 880 int ret;
855 881
@@ -874,6 +900,20 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
874 return PTR_ERR(tcon->lcd_rst); 900 return PTR_ERR(tcon->lcd_rst);
875 } 901 }
876 902
903 if (tcon->quirks->needs_edp_reset) {
904 edp_rstc = devm_reset_control_get_shared(dev, "edp");
905 if (IS_ERR(edp_rstc)) {
906 dev_err(dev, "Couldn't get edp reset line\n");
907 return PTR_ERR(edp_rstc);
908 }
909
910 ret = reset_control_deassert(edp_rstc);
911 if (ret) {
912 dev_err(dev, "Couldn't deassert edp reset line\n");
913 return ret;
914 }
915 }
916
877 /* Make sure our TCON is reset */ 917 /* Make sure our TCON is reset */
878 ret = reset_control_reset(tcon->lcd_rst); 918 ret = reset_control_reset(tcon->lcd_rst);
879 if (ret) { 919 if (ret) {
@@ -1166,6 +1206,16 @@ static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
1166 .has_channel_0 = true, 1206 .has_channel_0 = true,
1167}; 1207};
1168 1208
1209static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = {
1210 .has_channel_0 = true,
1211 .needs_edp_reset = true,
1212};
1213
1214static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = {
1215 .has_channel_1 = true,
1216 .needs_edp_reset = true,
1217};
1218
1169/* sun4i_drv uses this list to check if a device node is a TCON */ 1219/* sun4i_drv uses this list to check if a device node is a TCON */
1170const struct of_device_id sun4i_tcon_of_table[] = { 1220const struct of_device_id sun4i_tcon_of_table[] = {
1171 { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks }, 1221 { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
@@ -1177,6 +1227,8 @@ const struct of_device_id sun4i_tcon_of_table[] = {
1177 { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks }, 1227 { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks },
1178 { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks }, 1228 { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks },
1179 { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks }, 1229 { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
1230 { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks },
1231 { .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i_a80_tcon_tv_quirks },
1180 { } 1232 { }
1181}; 1233};
1182MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table); 1234MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 78d55e7cd2b3..d3a945b7bb60 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -176,6 +176,7 @@ struct sun4i_tcon_quirks {
176 bool has_channel_1; /* a33 does not have channel 1 */ 176 bool has_channel_1; /* a33 does not have channel 1 */
177 bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */ 177 bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */
178 bool needs_de_be_mux; /* sun6i needs mux to select backend */ 178 bool needs_de_be_mux; /* sun6i needs mux to select backend */
179 bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */
179 180
180 /* callback to handle tcon muxing options */ 181 /* callback to handle tcon muxing options */
181 int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *); 182 int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
diff --git a/drivers/gpu/drm/sun4i/sun6i_drc.c b/drivers/gpu/drm/sun4i/sun6i_drc.c
index 09bba853e2a4..b5e071a49045 100644
--- a/drivers/gpu/drm/sun4i/sun6i_drc.c
+++ b/drivers/gpu/drm/sun4i/sun6i_drc.c
@@ -101,6 +101,7 @@ static const struct of_device_id sun6i_drc_of_table[] = {
101 { .compatible = "allwinner,sun6i-a31-drc" }, 101 { .compatible = "allwinner,sun6i-a31-drc" },
102 { .compatible = "allwinner,sun6i-a31s-drc" }, 102 { .compatible = "allwinner,sun6i-a31s-drc" },
103 { .compatible = "allwinner,sun8i-a33-drc" }, 103 { .compatible = "allwinner,sun8i-a33-drc" },
104 { .compatible = "allwinner,sun9i-a80-drc" },
104 { } 105 { }
105}; 106};
106MODULE_DEVICE_TABLE(of, sun6i_drc_of_table); 107MODULE_DEVICE_TABLE(of, sun6i_drc_of_table);
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index ce1e3b9e14c9..bf4667481935 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -643,9 +643,12 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
643{ 643{
644 struct drm_device *dev = crtc->dev; 644 struct drm_device *dev = crtc->dev;
645 struct vc4_dev *vc4 = to_vc4_dev(dev); 645 struct vc4_dev *vc4 = to_vc4_dev(dev);
646 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
646 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 647 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
647 struct drm_plane *plane; 648 struct drm_plane *plane;
649 struct vc4_plane_state *vc4_plane_state;
648 bool debug_dump_regs = false; 650 bool debug_dump_regs = false;
651 bool enable_bg_fill = false;
649 u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start; 652 u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start;
650 u32 __iomem *dlist_next = dlist_start; 653 u32 __iomem *dlist_next = dlist_start;
651 654
@@ -656,6 +659,20 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
656 659
657 /* Copy all the active planes' dlist contents to the hardware dlist. */ 660 /* Copy all the active planes' dlist contents to the hardware dlist. */
658 drm_atomic_crtc_for_each_plane(plane, crtc) { 661 drm_atomic_crtc_for_each_plane(plane, crtc) {
662 /* Is this the first active plane? */
663 if (dlist_next == dlist_start) {
664 /* We need to enable background fill when a plane
665 * could be alpha blending from the background, i.e.
666 * where no other plane is underneath. It suffices to
667 * consider the first active plane here since we set
668 * needs_bg_fill such that either the first plane
669 * already needs it or all planes on top blend from
670 * the first or a lower plane.
671 */
672 vc4_plane_state = to_vc4_plane_state(plane->state);
673 enable_bg_fill = vc4_plane_state->needs_bg_fill;
674 }
675
659 dlist_next += vc4_plane_write_dlist(plane, dlist_next); 676 dlist_next += vc4_plane_write_dlist(plane, dlist_next);
660 } 677 }
661 678
@@ -664,6 +681,14 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
664 681
665 WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); 682 WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size);
666 683
684 if (enable_bg_fill)
685 /* This sets a black background color fill, as is the case
686 * with other DRM drivers.
687 */
688 HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel),
689 HVS_READ(SCALER_DISPBKGNDX(vc4_crtc->channel)) |
690 SCALER_DISPBKGND_FILL);
691
667 /* Only update DISPLIST if the CRTC was already running and is not 692 /* Only update DISPLIST if the CRTC was already running and is not
668 * being disabled. 693 * being disabled.
669 * vc4_crtc_enable() takes care of updating the dlist just after 694 * vc4_crtc_enable() takes care of updating the dlist just after
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index fefa1664a9f5..1b4cd1fabf56 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -310,6 +310,66 @@ to_vc4_plane(struct drm_plane *plane)
310 return (struct vc4_plane *)plane; 310 return (struct vc4_plane *)plane;
311} 311}
312 312
313enum vc4_scaling_mode {
314 VC4_SCALING_NONE,
315 VC4_SCALING_TPZ,
316 VC4_SCALING_PPF,
317};
318
319struct vc4_plane_state {
320 struct drm_plane_state base;
321 /* System memory copy of the display list for this element, computed
322 * at atomic_check time.
323 */
324 u32 *dlist;
325 u32 dlist_size; /* Number of dwords allocated for the display list */
326 u32 dlist_count; /* Number of used dwords in the display list. */
327
328 /* Offset in the dlist to various words, for pageflip or
329 * cursor updates.
330 */
331 u32 pos0_offset;
332 u32 pos2_offset;
333 u32 ptr0_offset;
334
335 /* Offset where the plane's dlist was last stored in the
336 * hardware at vc4_crtc_atomic_flush() time.
337 */
338 u32 __iomem *hw_dlist;
339
340 /* Clipped coordinates of the plane on the display. */
341 int crtc_x, crtc_y, crtc_w, crtc_h;
342 /* Clipped area being scanned from in the FB. */
343 u32 src_x, src_y;
344
345 u32 src_w[2], src_h[2];
346
347 /* Scaling selection for the RGB/Y plane and the Cb/Cr planes. */
348 enum vc4_scaling_mode x_scaling[2], y_scaling[2];
349 bool is_unity;
350 bool is_yuv;
351
352 /* Offset to start scanning out from the start of the plane's
353 * BO.
354 */
355 u32 offsets[3];
356
357 /* Our allocation in LBM for temporary storage during scaling. */
358 struct drm_mm_node lbm;
359
360 /* Set when the plane has per-pixel alpha content or does not cover
361 * the entire screen. This is a hint to the CRTC that it might need
362 * to enable background color fill.
363 */
364 bool needs_bg_fill;
365};
366
367static inline struct vc4_plane_state *
368to_vc4_plane_state(struct drm_plane_state *state)
369{
370 return (struct vc4_plane_state *)state;
371}
372
313enum vc4_encoder_type { 373enum vc4_encoder_type {
314 VC4_ENCODER_TYPE_NONE, 374 VC4_ENCODER_TYPE_NONE,
315 VC4_ENCODER_TYPE_HDMI, 375 VC4_ENCODER_TYPE_HDMI,
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index c4c7af11fec5..ce39390be389 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -27,60 +27,6 @@
27#include "vc4_drv.h" 27#include "vc4_drv.h"
28#include "vc4_regs.h" 28#include "vc4_regs.h"
29 29
30enum vc4_scaling_mode {
31 VC4_SCALING_NONE,
32 VC4_SCALING_TPZ,
33 VC4_SCALING_PPF,
34};
35
36struct vc4_plane_state {
37 struct drm_plane_state base;
38 /* System memory copy of the display list for this element, computed
39 * at atomic_check time.
40 */
41 u32 *dlist;
42 u32 dlist_size; /* Number of dwords allocated for the display list */
43 u32 dlist_count; /* Number of used dwords in the display list. */
44
45 /* Offset in the dlist to various words, for pageflip or
46 * cursor updates.
47 */
48 u32 pos0_offset;
49 u32 pos2_offset;
50 u32 ptr0_offset;
51
52 /* Offset where the plane's dlist was last stored in the
53 * hardware at vc4_crtc_atomic_flush() time.
54 */
55 u32 __iomem *hw_dlist;
56
57 /* Clipped coordinates of the plane on the display. */
58 int crtc_x, crtc_y, crtc_w, crtc_h;
59 /* Clipped area being scanned from in the FB. */
60 u32 src_x, src_y;
61
62 u32 src_w[2], src_h[2];
63
64 /* Scaling selection for the RGB/Y plane and the Cb/Cr planes. */
65 enum vc4_scaling_mode x_scaling[2], y_scaling[2];
66 bool is_unity;
67 bool is_yuv;
68
69 /* Offset to start scanning out from the start of the plane's
70 * BO.
71 */
72 u32 offsets[3];
73
74 /* Our allocation in LBM for temporary storage during scaling. */
75 struct drm_mm_node lbm;
76};
77
78static inline struct vc4_plane_state *
79to_vc4_plane_state(struct drm_plane_state *state)
80{
81 return (struct vc4_plane_state *)state;
82}
83
84static const struct hvs_format { 30static const struct hvs_format {
85 u32 drm; /* DRM_FORMAT_* */ 31 u32 drm; /* DRM_FORMAT_* */
86 u32 hvs; /* HVS_FORMAT_* */ 32 u32 hvs; /* HVS_FORMAT_* */
@@ -521,6 +467,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
521 u32 ctl0_offset = vc4_state->dlist_count; 467 u32 ctl0_offset = vc4_state->dlist_count;
522 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format); 468 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
523 int num_planes = drm_format_num_planes(format->drm); 469 int num_planes = drm_format_num_planes(format->drm);
470 bool covers_screen;
524 u32 scl0, scl1, pitch0; 471 u32 scl0, scl1, pitch0;
525 u32 lbm_size, tiling; 472 u32 lbm_size, tiling;
526 unsigned long irqflags; 473 unsigned long irqflags;
@@ -618,13 +565,14 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
618 SCALER_POS1_SCL_HEIGHT)); 565 SCALER_POS1_SCL_HEIGHT));
619 } 566 }
620 567
621 /* Position Word 2: Source Image Size, Alpha Mode */ 568 /* Position Word 2: Source Image Size, Alpha */
622 vc4_state->pos2_offset = vc4_state->dlist_count; 569 vc4_state->pos2_offset = vc4_state->dlist_count;
623 vc4_dlist_write(vc4_state, 570 vc4_dlist_write(vc4_state,
624 VC4_SET_FIELD(fb->format->has_alpha ? 571 VC4_SET_FIELD(fb->format->has_alpha ?
625 SCALER_POS2_ALPHA_MODE_PIPELINE : 572 SCALER_POS2_ALPHA_MODE_PIPELINE :
626 SCALER_POS2_ALPHA_MODE_FIXED, 573 SCALER_POS2_ALPHA_MODE_FIXED,
627 SCALER_POS2_ALPHA_MODE) | 574 SCALER_POS2_ALPHA_MODE) |
575 (fb->format->has_alpha ? SCALER_POS2_ALPHA_PREMULT : 0) |
628 VC4_SET_FIELD(vc4_state->src_w[0], SCALER_POS2_WIDTH) | 576 VC4_SET_FIELD(vc4_state->src_w[0], SCALER_POS2_WIDTH) |
629 VC4_SET_FIELD(vc4_state->src_h[0], SCALER_POS2_HEIGHT)); 577 VC4_SET_FIELD(vc4_state->src_h[0], SCALER_POS2_HEIGHT));
630 578
@@ -700,6 +648,16 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
700 vc4_state->dlist[ctl0_offset] |= 648 vc4_state->dlist[ctl0_offset] |=
701 VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE); 649 VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE);
702 650
651 /* crtc_* are already clipped coordinates. */
652 covers_screen = vc4_state->crtc_x == 0 && vc4_state->crtc_y == 0 &&
653 vc4_state->crtc_w == state->crtc->mode.hdisplay &&
654 vc4_state->crtc_h == state->crtc->mode.vdisplay;
655 /* Background fill might be necessary when the plane has per-pixel
656 * alpha content and blends from the background or does not cover
657 * the entire screen.
658 */
659 vc4_state->needs_bg_fill = fb->format->has_alpha || !covers_screen;
660
703 return 0; 661 return 0;
704} 662}
705 663
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index b9749cb24063..a141496104a6 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -848,6 +848,7 @@ enum hvs_pixel_format {
848#define SCALER_POS2_ALPHA_MODE_FIXED 1 848#define SCALER_POS2_ALPHA_MODE_FIXED 1
849#define SCALER_POS2_ALPHA_MODE_FIXED_NONZERO 2 849#define SCALER_POS2_ALPHA_MODE_FIXED_NONZERO 2
850#define SCALER_POS2_ALPHA_MODE_FIXED_OVER_0x07 3 850#define SCALER_POS2_ALPHA_MODE_FIXED_OVER_0x07 3
851#define SCALER_POS2_ALPHA_PREMULT BIT(29)
851 852
852#define SCALER_POS2_HEIGHT_MASK VC4_MASK(27, 16) 853#define SCALER_POS2_HEIGHT_MASK VC4_MASK(27, 16)
853#define SCALER_POS2_HEIGHT_SHIFT 16 854#define SCALER_POS2_HEIGHT_SHIFT 16
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 2db485abb186..eec76af49f04 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -753,7 +753,7 @@ validate_gl_shader_rec(struct drm_device *dev,
753 28, /* cs */ 753 28, /* cs */
754 }; 754 };
755 uint32_t shader_reloc_count = ARRAY_SIZE(shader_reloc_offsets); 755 uint32_t shader_reloc_count = ARRAY_SIZE(shader_reloc_offsets);
756 struct drm_gem_cma_object *bo[shader_reloc_count + 8]; 756 struct drm_gem_cma_object *bo[ARRAY_SIZE(shader_reloc_offsets) + 8];
757 uint32_t nr_attributes, nr_relocs, packet_size; 757 uint32_t nr_attributes, nr_relocs, packet_size;
758 int i; 758 int i;
759 759
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index be40cff3e1f6..2582ffd36bb5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -518,7 +518,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
518 } 518 }
519 519
520 if (cur_fb) { 520 if (cur_fb) {
521 drm_framebuffer_unreference(cur_fb); 521 drm_framebuffer_put(cur_fb);
522 par->set_fb = NULL; 522 par->set_fb = NULL;
523 } 523 }
524 524
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 67f844678ac8..c5e8eae0dbe2 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -316,7 +316,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
316out_no_surface: 316out_no_surface:
317 ttm_read_unlock(&dev_priv->reservation_sem); 317 ttm_read_unlock(&dev_priv->reservation_sem);
318out_no_ttm_lock: 318out_no_ttm_lock:
319 drm_framebuffer_unreference(fb); 319 drm_framebuffer_put(fb);
320out_no_fb: 320out_no_fb:
321 drm_modeset_unlock_all(dev); 321 drm_modeset_unlock_all(dev);
322out_no_copy: 322out_no_copy:
@@ -393,7 +393,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
393 393
394 ttm_read_unlock(&dev_priv->reservation_sem); 394 ttm_read_unlock(&dev_priv->reservation_sem);
395out_no_ttm_lock: 395out_no_ttm_lock:
396 drm_framebuffer_unreference(fb); 396 drm_framebuffer_put(fb);
397out_no_fb: 397out_no_fb:
398 drm_modeset_unlock_all(dev); 398 drm_modeset_unlock_all(dev);
399out_no_copy: 399out_no_copy:
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 3cd153c6d271..fc4adf3d34e8 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -92,7 +92,8 @@
92 * struct vga_switcheroo_client - registered client 92 * struct vga_switcheroo_client - registered client
93 * @pdev: client pci device 93 * @pdev: client pci device
94 * @fb_info: framebuffer to which console is remapped on switching 94 * @fb_info: framebuffer to which console is remapped on switching
95 * @pwr_state: current power state 95 * @pwr_state: current power state if manual power control is used.
96 * For driver power control, call vga_switcheroo_pwr_state().
96 * @ops: client callbacks 97 * @ops: client callbacks
97 * @id: client identifier. Determining the id requires the handler, 98 * @id: client identifier. Determining the id requires the handler,
98 * so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID 99 * so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID
@@ -104,8 +105,7 @@
104 * @list: client list 105 * @list: client list
105 * 106 *
106 * Registered client. A client can be either a GPU or an audio device on a GPU. 107 * Registered client. A client can be either a GPU or an audio device on a GPU.
107 * For audio clients, the @fb_info, @active and @driver_power_control members 108 * For audio clients, the @fb_info and @active members are bogus.
108 * are bogus.
109 */ 109 */
110struct vga_switcheroo_client { 110struct vga_switcheroo_client {
111 struct pci_dev *pdev; 111 struct pci_dev *pdev;
@@ -331,8 +331,8 @@ EXPORT_SYMBOL(vga_switcheroo_register_client);
331 * @ops: client callbacks 331 * @ops: client callbacks
332 * @id: client identifier 332 * @id: client identifier
333 * 333 *
334 * Register audio client (audio device on a GPU). The power state of the 334 * Register audio client (audio device on a GPU). The client is assumed
335 * client is assumed to be ON. Beforehand, vga_switcheroo_client_probe_defer() 335 * to use runtime PM. Beforehand, vga_switcheroo_client_probe_defer()
336 * shall be called to ensure that all prerequisites are met. 336 * shall be called to ensure that all prerequisites are met.
337 * 337 *
338 * Return: 0 on success, -ENOMEM on memory allocation error. 338 * Return: 0 on success, -ENOMEM on memory allocation error.
@@ -341,7 +341,7 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
341 const struct vga_switcheroo_client_ops *ops, 341 const struct vga_switcheroo_client_ops *ops,
342 enum vga_switcheroo_client_id id) 342 enum vga_switcheroo_client_id id)
343{ 343{
344 return register_client(pdev, ops, id | ID_BIT_AUDIO, false, false); 344 return register_client(pdev, ops, id | ID_BIT_AUDIO, false, true);
345} 345}
346EXPORT_SYMBOL(vga_switcheroo_register_audio_client); 346EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
347 347
@@ -406,6 +406,19 @@ bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)
406} 406}
407EXPORT_SYMBOL(vga_switcheroo_client_probe_defer); 407EXPORT_SYMBOL(vga_switcheroo_client_probe_defer);
408 408
409static enum vga_switcheroo_state
410vga_switcheroo_pwr_state(struct vga_switcheroo_client *client)
411{
412 if (client->driver_power_control)
413 if (pm_runtime_enabled(&client->pdev->dev) &&
414 pm_runtime_active(&client->pdev->dev))
415 return VGA_SWITCHEROO_ON;
416 else
417 return VGA_SWITCHEROO_OFF;
418 else
419 return client->pwr_state;
420}
421
409/** 422/**
410 * vga_switcheroo_get_client_state() - obtain power state of a given client 423 * vga_switcheroo_get_client_state() - obtain power state of a given client
411 * @pdev: client pci device 424 * @pdev: client pci device
@@ -425,7 +438,7 @@ enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *pdev)
425 if (!client) 438 if (!client)
426 ret = VGA_SWITCHEROO_NOT_FOUND; 439 ret = VGA_SWITCHEROO_NOT_FOUND;
427 else 440 else
428 ret = client->pwr_state; 441 ret = vga_switcheroo_pwr_state(client);
429 mutex_unlock(&vgasr_mutex); 442 mutex_unlock(&vgasr_mutex);
430 return ret; 443 return ret;
431} 444}
@@ -598,7 +611,7 @@ static int vga_switcheroo_show(struct seq_file *m, void *v)
598 client_is_vga(client) ? "" : "-Audio", 611 client_is_vga(client) ? "" : "-Audio",
599 client->active ? '+' : ' ', 612 client->active ? '+' : ' ',
600 client->driver_power_control ? "Dyn" : "", 613 client->driver_power_control ? "Dyn" : "",
601 client->pwr_state ? "Pwr" : "Off", 614 vga_switcheroo_pwr_state(client) ? "Pwr" : "Off",
602 pci_name(client->pdev)); 615 pci_name(client->pdev));
603 i++; 616 i++;
604 } 617 }
@@ -641,10 +654,8 @@ static void set_audio_state(enum vga_switcheroo_client_id id,
641 struct vga_switcheroo_client *client; 654 struct vga_switcheroo_client *client;
642 655
643 client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO); 656 client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
644 if (client && client->pwr_state != state) { 657 if (client)
645 client->ops->set_gpu_state(client->pdev, state); 658 client->ops->set_gpu_state(client->pdev, state);
646 client->pwr_state = state;
647 }
648} 659}
649 660
650/* stage one happens before delay */ 661/* stage one happens before delay */
@@ -656,7 +667,7 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
656 if (!active) 667 if (!active)
657 return 0; 668 return 0;
658 669
659 if (new_client->pwr_state == VGA_SWITCHEROO_OFF) 670 if (vga_switcheroo_pwr_state(new_client) == VGA_SWITCHEROO_OFF)
660 vga_switchon(new_client); 671 vga_switchon(new_client);
661 672
662 vga_set_default_device(new_client->pdev); 673 vga_set_default_device(new_client->pdev);
@@ -675,7 +686,9 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
675 686
676 active->active = false; 687 active->active = false;
677 688
678 set_audio_state(active->id, VGA_SWITCHEROO_OFF); 689 /* let HDA controller autosuspend if GPU uses driver power control */
690 if (!active->driver_power_control)
691 set_audio_state(active->id, VGA_SWITCHEROO_OFF);
679 692
680 if (new_client->fb_info) { 693 if (new_client->fb_info) {
681 struct fb_event event; 694 struct fb_event event;
@@ -695,10 +708,12 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
695 if (new_client->ops->reprobe) 708 if (new_client->ops->reprobe)
696 new_client->ops->reprobe(new_client->pdev); 709 new_client->ops->reprobe(new_client->pdev);
697 710
698 if (active->pwr_state == VGA_SWITCHEROO_ON) 711 if (vga_switcheroo_pwr_state(active) == VGA_SWITCHEROO_ON)
699 vga_switchoff(active); 712 vga_switchoff(active);
700 713
701 set_audio_state(new_client->id, VGA_SWITCHEROO_ON); 714 /* let HDA controller autoresume if GPU uses driver power control */
715 if (!new_client->driver_power_control)
716 set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
702 717
703 new_client->active = true; 718 new_client->active = true;
704 return 0; 719 return 0;
@@ -939,11 +954,6 @@ EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
939 * Specifying nouveau.runpm=0, radeon.runpm=0 or amdgpu.runpm=0 on the kernel 954 * Specifying nouveau.runpm=0, radeon.runpm=0 or amdgpu.runpm=0 on the kernel
940 * command line disables it. 955 * command line disables it.
941 * 956 *
942 * When the driver decides to power up or down, it notifies vga_switcheroo
943 * thereof so that it can (a) power the audio device on the GPU up or down,
944 * and (b) update its internal power state representation for the device.
945 * This is achieved by vga_switcheroo_set_dynamic_switch().
946 *
947 * After the GPU has been suspended, the handler needs to be called to cut 957 * After the GPU has been suspended, the handler needs to be called to cut
948 * power to the GPU. Likewise it needs to reinstate power before the GPU 958 * power to the GPU. Likewise it needs to reinstate power before the GPU
949 * can resume. This is achieved by vga_switcheroo_init_domain_pm_ops(), 959 * can resume. This is achieved by vga_switcheroo_init_domain_pm_ops(),
@@ -951,8 +961,9 @@ EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
951 * calls to the handler. 961 * calls to the handler.
952 * 962 *
953 * When the audio device resumes, the GPU needs to be woken. This is achieved 963 * When the audio device resumes, the GPU needs to be woken. This is achieved
954 * by vga_switcheroo_init_domain_pm_optimus_hdmi_audio(), which augments the 964 * by a PCI quirk which calls device_link_add() to declare a dependency on the
955 * audio device's resume function. 965 * GPU. That way, the GPU is kept awake whenever and as long as the audio
966 * device is in use.
956 * 967 *
957 * On muxed machines, if the mux is initially switched to the discrete GPU, 968 * On muxed machines, if the mux is initially switched to the discrete GPU,
958 * the user ends up with a black screen when the GPU powers down after boot. 969 * the user ends up with a black screen when the GPU powers down after boot.
@@ -978,35 +989,6 @@ static void vga_switcheroo_power_switch(struct pci_dev *pdev,
978 vgasr_priv.handler->power_state(client->id, state); 989 vgasr_priv.handler->power_state(client->id, state);
979} 990}
980 991
981/**
982 * vga_switcheroo_set_dynamic_switch() - helper for driver power control
983 * @pdev: client pci device
984 * @dynamic: new power state
985 *
986 * Helper for GPUs whose power state is controlled by the driver's runtime pm.
987 * When the driver decides to power up or down, it notifies vga_switcheroo
988 * thereof using this helper so that it can (a) power the audio device on
989 * the GPU up or down, and (b) update its internal power state representation
990 * for the device.
991 */
992void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev,
993 enum vga_switcheroo_state dynamic)
994{
995 struct vga_switcheroo_client *client;
996
997 mutex_lock(&vgasr_mutex);
998 client = find_client_from_pci(&vgasr_priv.clients, pdev);
999 if (!client || !client->driver_power_control) {
1000 mutex_unlock(&vgasr_mutex);
1001 return;
1002 }
1003
1004 client->pwr_state = dynamic;
1005 set_audio_state(client->id, dynamic);
1006 mutex_unlock(&vgasr_mutex);
1007}
1008EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
1009
1010/* switcheroo power domain */ 992/* switcheroo power domain */
1011static int vga_switcheroo_runtime_suspend(struct device *dev) 993static int vga_switcheroo_runtime_suspend(struct device *dev)
1012{ 994{
@@ -1022,6 +1004,7 @@ static int vga_switcheroo_runtime_suspend(struct device *dev)
1022 vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD); 1004 vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
1023 mutex_unlock(&vgasr_priv.mux_hw_lock); 1005 mutex_unlock(&vgasr_priv.mux_hw_lock);
1024 } 1006 }
1007 pci_bus_set_current_state(pdev->bus, PCI_D3cold);
1025 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF); 1008 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
1026 mutex_unlock(&vgasr_mutex); 1009 mutex_unlock(&vgasr_mutex);
1027 return 0; 1010 return 0;
@@ -1035,6 +1018,7 @@ static int vga_switcheroo_runtime_resume(struct device *dev)
1035 mutex_lock(&vgasr_mutex); 1018 mutex_lock(&vgasr_mutex);
1036 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON); 1019 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
1037 mutex_unlock(&vgasr_mutex); 1020 mutex_unlock(&vgasr_mutex);
1021 pci_wakeup_bus(pdev->bus);
1038 ret = dev->bus->pm->runtime_resume(dev); 1022 ret = dev->bus->pm->runtime_resume(dev);
1039 if (ret) 1023 if (ret)
1040 return ret; 1024 return ret;
@@ -1076,69 +1060,3 @@ void vga_switcheroo_fini_domain_pm_ops(struct device *dev)
1076 dev_pm_domain_set(dev, NULL); 1060 dev_pm_domain_set(dev, NULL);
1077} 1061}
1078EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops); 1062EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
1079
1080static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
1081{
1082 struct pci_dev *pdev = to_pci_dev(dev);
1083 struct vga_switcheroo_client *client;
1084 struct device *video_dev = NULL;
1085 int ret;
1086
1087 /* we need to check if we have to switch back on the video
1088 * device so the audio device can come back
1089 */
1090 mutex_lock(&vgasr_mutex);
1091 list_for_each_entry(client, &vgasr_priv.clients, list) {
1092 if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) &&
1093 client_is_vga(client)) {
1094 video_dev = &client->pdev->dev;
1095 break;
1096 }
1097 }
1098 mutex_unlock(&vgasr_mutex);
1099
1100 if (video_dev) {
1101 ret = pm_runtime_get_sync(video_dev);
1102 if (ret && ret != 1)
1103 return ret;
1104 }
1105 ret = dev->bus->pm->runtime_resume(dev);
1106
1107 /* put the reference for the gpu */
1108 if (video_dev) {
1109 pm_runtime_mark_last_busy(video_dev);
1110 pm_runtime_put_autosuspend(video_dev);
1111 }
1112 return ret;
1113}
1114
1115/**
1116 * vga_switcheroo_init_domain_pm_optimus_hdmi_audio() - helper for driver
1117 * power control
1118 * @dev: audio client device
1119 * @domain: power domain
1120 *
1121 * Helper for GPUs whose power state is controlled by the driver's runtime pm.
1122 * When the audio device resumes, the GPU needs to be woken. This helper
1123 * augments the audio device's resume function to do that.
1124 *
1125 * Return: 0 on success, -EINVAL if no power management operations are
1126 * defined for this device.
1127 */
1128int
1129vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev,
1130 struct dev_pm_domain *domain)
1131{
1132 /* copy over all the bus versions */
1133 if (dev->bus && dev->bus->pm) {
1134 domain->ops = *dev->bus->pm;
1135 domain->ops.runtime_resume =
1136 vga_switcheroo_runtime_resume_hdmi_audio;
1137
1138 dev_pm_domain_set(dev, domain);
1139 return 0;
1140 }
1141 dev_pm_domain_set(dev, NULL);
1142 return -EINVAL;
1143}
1144EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 3bed6beda051..6a67cdbd0e6a 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1224,11 +1224,14 @@ static int pci_pm_runtime_suspend(struct device *dev)
1224 int error; 1224 int error;
1225 1225
1226 /* 1226 /*
1227 * If pci_dev->driver is not set (unbound), the device should 1227 * If pci_dev->driver is not set (unbound), we leave the device in D0,
1228 * always remain in D0 regardless of the runtime PM status 1228 * but it may go to D3cold when the bridge above it runtime suspends.
1229 * Save its config space in case that happens.
1229 */ 1230 */
1230 if (!pci_dev->driver) 1231 if (!pci_dev->driver) {
1232 pci_save_state(pci_dev);
1231 return 0; 1233 return 0;
1234 }
1232 1235
1233 if (!pm || !pm->runtime_suspend) 1236 if (!pm || !pm->runtime_suspend)
1234 return -ENOSYS; 1237 return -ENOSYS;
@@ -1276,16 +1279,18 @@ static int pci_pm_runtime_resume(struct device *dev)
1276 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 1279 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
1277 1280
1278 /* 1281 /*
1279 * If pci_dev->driver is not set (unbound), the device should 1282 * Restoring config space is necessary even if the device is not bound
1280 * always remain in D0 regardless of the runtime PM status 1283 * to a driver because although we left it in D0, it may have gone to
1284 * D3cold when the bridge above it runtime suspended.
1281 */ 1285 */
1286 pci_restore_standard_config(pci_dev);
1287
1282 if (!pci_dev->driver) 1288 if (!pci_dev->driver)
1283 return 0; 1289 return 0;
1284 1290
1285 if (!pm || !pm->runtime_resume) 1291 if (!pm || !pm->runtime_resume)
1286 return -ENOSYS; 1292 return -ENOSYS;
1287 1293
1288 pci_restore_standard_config(pci_dev);
1289 pci_fixup_device(pci_fixup_resume_early, pci_dev); 1294 pci_fixup_device(pci_fixup_resume_early, pci_dev);
1290 pci_enable_wake(pci_dev, PCI_D0, false); 1295 pci_enable_wake(pci_dev, PCI_D0, false);
1291 pci_fixup_device(pci_fixup_resume, pci_dev); 1296 pci_fixup_device(pci_fixup_resume, pci_dev);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f6a4dd10d9b0..bd6f156dc3cf 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -800,7 +800,7 @@ static int pci_wakeup(struct pci_dev *pci_dev, void *ign)
800 * pci_wakeup_bus - Walk given bus and wake up devices on it 800 * pci_wakeup_bus - Walk given bus and wake up devices on it
801 * @bus: Top bus of the subtree to walk. 801 * @bus: Top bus of the subtree to walk.
802 */ 802 */
803static void pci_wakeup_bus(struct pci_bus *bus) 803void pci_wakeup_bus(struct pci_bus *bus)
804{ 804{
805 if (bus) 805 if (bus)
806 pci_walk_bus(bus, pci_wakeup, NULL); 806 pci_walk_bus(bus, pci_wakeup, NULL);
@@ -850,11 +850,11 @@ static int __pci_dev_set_current_state(struct pci_dev *dev, void *data)
850} 850}
851 851
852/** 852/**
853 * __pci_bus_set_current_state - Walk given bus and set current state of devices 853 * pci_bus_set_current_state - Walk given bus and set current state of devices
854 * @bus: Top bus of the subtree to walk. 854 * @bus: Top bus of the subtree to walk.
855 * @state: state to be set 855 * @state: state to be set
856 */ 856 */
857static void __pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state) 857void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state)
858{ 858{
859 if (bus) 859 if (bus)
860 pci_walk_bus(bus, __pci_dev_set_current_state, &state); 860 pci_walk_bus(bus, __pci_dev_set_current_state, &state);
@@ -876,7 +876,7 @@ int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
876 ret = pci_platform_power_transition(dev, state); 876 ret = pci_platform_power_transition(dev, state);
877 /* Power off the bridge may power off the whole hierarchy */ 877 /* Power off the bridge may power off the whole hierarchy */
878 if (!ret && state == PCI_D3cold) 878 if (!ret && state == PCI_D3cold)
879 __pci_bus_set_current_state(dev->subordinate, PCI_D3cold); 879 pci_bus_set_current_state(dev->subordinate, PCI_D3cold);
880 return ret; 880 return ret;
881} 881}
882EXPORT_SYMBOL_GPL(__pci_complete_power_transition); 882EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index fc734014206f..ec582d37c189 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -26,6 +26,7 @@
26#include <linux/ktime.h> 26#include <linux/ktime.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/platform_data/x86/apple.h> 28#include <linux/platform_data/x86/apple.h>
29#include <linux/pm_runtime.h>
29#include <asm/dma.h> /* isa_dma_bridge_buggy */ 30#include <asm/dma.h> /* isa_dma_bridge_buggy */
30#include "pci.h" 31#include "pci.h"
31 32
@@ -4832,3 +4833,41 @@ static void quirk_fsl_no_msi(struct pci_dev *pdev)
4832 pdev->no_msi = 1; 4833 pdev->no_msi = 1;
4833} 4834}
4834DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi); 4835DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi);
4836
4837/*
4838 * GPUs with integrated HDA controller for streaming audio to attached displays
4839 * need a device link from the HDA controller (consumer) to the GPU (supplier)
4840 * so that the GPU is powered up whenever the HDA controller is accessed.
4841 * The GPU and HDA controller are functions 0 and 1 of the same PCI device.
4842 * The device link stays in place until shutdown (or removal of the PCI device
4843 * if it's hotplugged). Runtime PM is allowed by default on the HDA controller
4844 * to prevent it from permanently keeping the GPU awake.
4845 */
4846static void quirk_gpu_hda(struct pci_dev *hda)
4847{
4848 struct pci_dev *gpu;
4849
4850 if (PCI_FUNC(hda->devfn) != 1)
4851 return;
4852
4853 gpu = pci_get_domain_bus_and_slot(pci_domain_nr(hda->bus),
4854 hda->bus->number,
4855 PCI_DEVFN(PCI_SLOT(hda->devfn), 0));
4856 if (!gpu || (gpu->class >> 16) != PCI_BASE_CLASS_DISPLAY) {
4857 pci_dev_put(gpu);
4858 return;
4859 }
4860
4861 if (!device_link_add(&hda->dev, &gpu->dev,
4862 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME))
4863 pci_err(hda, "cannot link HDA to GPU %s\n", pci_name(gpu));
4864
4865 pm_runtime_allow(&hda->dev);
4866 pci_dev_put(gpu);
4867}
4868DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
4869 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
4870DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_AMD, PCI_ANY_ID,
4871 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
4872DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
4873 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 711fff9b6803..e9a1116d2f8e 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -41,7 +41,7 @@ struct analogix_dp_plat_data {
41 struct drm_connector *); 41 struct drm_connector *);
42}; 42};
43 43
44int analogix_dp_psr_supported(struct analogix_dp_device *dp); 44int analogix_dp_psr_enabled(struct analogix_dp_device *dp);
45int analogix_dp_enable_psr(struct analogix_dp_device *dp); 45int analogix_dp_enable_psr(struct analogix_dp_device *dp);
46int analogix_dp_disable_psr(struct analogix_dp_device *dp); 46int analogix_dp_disable_psr(struct analogix_dp_device *dp);
47 47
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index b3b6d302ca8c..44f04233e3db 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -38,6 +38,18 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
38int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, 38int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
39 int gamma_size); 39 int gamma_size);
40 40
41/**
42 * drm_color_lut_size - calculate the number of entries in the LUT
43 * @blob: blob containing the LUT
44 *
45 * Returns:
46 * The number of entries in the color LUT stored in @blob.
47 */
48static inline int drm_color_lut_size(const struct drm_property_blob *blob)
49{
50 return blob->length / sizeof(struct drm_color_lut);
51}
52
41enum drm_color_encoding { 53enum drm_color_encoding {
42 DRM_COLOR_YCBCR_BT601, 54 DRM_COLOR_YCBCR_BT601,
43 DRM_COLOR_YCBCR_BT709, 55 DRM_COLOR_YCBCR_BT709,
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 4de97e94ef9d..62903bae0221 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -288,6 +288,7 @@
288#define DP_PSR_SUPPORT 0x070 /* XXX 1.2? */ 288#define DP_PSR_SUPPORT 0x070 /* XXX 1.2? */
289# define DP_PSR_IS_SUPPORTED 1 289# define DP_PSR_IS_SUPPORTED 1
290# define DP_PSR2_IS_SUPPORTED 2 /* eDP 1.4 */ 290# define DP_PSR2_IS_SUPPORTED 2 /* eDP 1.4 */
291# define DP_PSR2_WITH_Y_COORD_IS_SUPPORTED 3 /* eDP 1.4a */
291 292
292#define DP_PSR_CAPS 0x071 /* XXX 1.2? */ 293#define DP_PSR_CAPS 0x071 /* XXX 1.2? */
293# define DP_PSR_NO_TRAIN_ON_EXIT 1 294# define DP_PSR_NO_TRAIN_ON_EXIT 1
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index 7ba3913f30b5..c34a3e8030e1 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -120,30 +120,6 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
120void drm_mode_object_get(struct drm_mode_object *obj); 120void drm_mode_object_get(struct drm_mode_object *obj);
121void drm_mode_object_put(struct drm_mode_object *obj); 121void drm_mode_object_put(struct drm_mode_object *obj);
122 122
123/**
124 * drm_mode_object_reference - acquire a mode object reference
125 * @obj: DRM mode object
126 *
127 * This is a compatibility alias for drm_mode_object_get() and should not be
128 * used by new code.
129 */
130static inline void drm_mode_object_reference(struct drm_mode_object *obj)
131{
132 drm_mode_object_get(obj);
133}
134
135/**
136 * drm_mode_object_unreference - release a mode object reference
137 * @obj: DRM mode object
138 *
139 * This is a compatibility alias for drm_mode_object_put() and should not be
140 * used by new code.
141 */
142static inline void drm_mode_object_unreference(struct drm_mode_object *obj)
143{
144 drm_mode_object_put(obj);
145}
146
147int drm_object_property_set_value(struct drm_mode_object *obj, 123int drm_object_property_set_value(struct drm_mode_object *obj,
148 struct drm_property *property, 124 struct drm_property *property,
149 uint64_t val); 125 uint64_t val);
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 2a4a42e59a47..e1a46e9991cc 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -196,21 +196,22 @@ static inline struct drm_printer drm_debug_printer(const char *prefix)
196#define DRM_UT_STATE 0x40 196#define DRM_UT_STATE 0x40
197#define DRM_UT_LEASE 0x80 197#define DRM_UT_LEASE 0x80
198 198
199__printf(6, 7) 199__printf(3, 4)
200void drm_dev_printk(const struct device *dev, const char *level, 200void drm_dev_printk(const struct device *dev, const char *level,
201 unsigned int category, const char *function_name, 201 const char *format, ...);
202 const char *prefix, const char *format, ...);
203__printf(3, 4) 202__printf(3, 4)
204void drm_printk(const char *level, unsigned int category, 203void drm_dev_dbg(const struct device *dev, unsigned int category,
205 const char *format, ...); 204 const char *format, ...);
205
206__printf(2, 3)
207void drm_dbg(unsigned int category, const char *format, ...);
208__printf(1, 2)
209void drm_err(const char *format, ...);
206 210
207/* Macros to make printk easier */ 211/* Macros to make printk easier */
208 212
209#define _DRM_PRINTK(once, level, fmt, ...) \ 213#define _DRM_PRINTK(once, level, fmt, ...) \
210 do { \ 214 printk##once(KERN_##level "[" DRM_NAME "] " fmt, ##__VA_ARGS__)
211 printk##once(KERN_##level "[" DRM_NAME "] " fmt, \
212 ##__VA_ARGS__); \
213 } while (0)
214 215
215#define DRM_INFO(fmt, ...) \ 216#define DRM_INFO(fmt, ...) \
216 _DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__) 217 _DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__)
@@ -233,10 +234,9 @@ void drm_printk(const char *level, unsigned int category,
233 * @fmt: printf() like format string. 234 * @fmt: printf() like format string.
234 */ 235 */
235#define DRM_DEV_ERROR(dev, fmt, ...) \ 236#define DRM_DEV_ERROR(dev, fmt, ...) \
236 drm_dev_printk(dev, KERN_ERR, DRM_UT_NONE, __func__, " *ERROR*",\ 237 drm_dev_printk(dev, KERN_ERR, "*ERROR* " fmt, ##__VA_ARGS__)
237 fmt, ##__VA_ARGS__)
238#define DRM_ERROR(fmt, ...) \ 238#define DRM_ERROR(fmt, ...) \
239 drm_printk(KERN_ERR, DRM_UT_NONE, fmt, ##__VA_ARGS__) 239 drm_err(fmt, ##__VA_ARGS__)
240 240
241/** 241/**
242 * Rate limited error output. Like DRM_ERROR() but won't flood the log. 242 * Rate limited error output. Like DRM_ERROR() but won't flood the log.
@@ -257,8 +257,7 @@ void drm_printk(const char *level, unsigned int category,
257 DRM_DEV_ERROR_RATELIMITED(NULL, fmt, ##__VA_ARGS__) 257 DRM_DEV_ERROR_RATELIMITED(NULL, fmt, ##__VA_ARGS__)
258 258
259#define DRM_DEV_INFO(dev, fmt, ...) \ 259#define DRM_DEV_INFO(dev, fmt, ...) \
260 drm_dev_printk(dev, KERN_INFO, DRM_UT_NONE, __func__, "", fmt, \ 260 drm_dev_printk(dev, KERN_INFO, fmt, ##__VA_ARGS__)
261 ##__VA_ARGS__)
262 261
263#define DRM_DEV_INFO_ONCE(dev, fmt, ...) \ 262#define DRM_DEV_INFO_ONCE(dev, fmt, ...) \
264({ \ 263({ \
@@ -275,53 +274,46 @@ void drm_printk(const char *level, unsigned int category,
275 * @dev: device pointer 274 * @dev: device pointer
276 * @fmt: printf() like format string. 275 * @fmt: printf() like format string.
277 */ 276 */
278#define DRM_DEV_DEBUG(dev, fmt, args...) \ 277#define DRM_DEV_DEBUG(dev, fmt, ...) \
279 drm_dev_printk(dev, KERN_DEBUG, DRM_UT_CORE, __func__, "", fmt, \ 278 drm_dev_dbg(dev, DRM_UT_CORE, fmt, ##__VA_ARGS__)
280 ##args)
281#define DRM_DEBUG(fmt, ...) \ 279#define DRM_DEBUG(fmt, ...) \
282 drm_printk(KERN_DEBUG, DRM_UT_CORE, fmt, ##__VA_ARGS__) 280 drm_dbg(DRM_UT_CORE, fmt, ##__VA_ARGS__)
283 281
284#define DRM_DEV_DEBUG_DRIVER(dev, fmt, args...) \ 282#define DRM_DEV_DEBUG_DRIVER(dev, fmt, ...) \
285 drm_dev_printk(dev, KERN_DEBUG, DRM_UT_DRIVER, __func__, "", \ 283 drm_dev_dbg(dev, DRM_UT_DRIVER, fmt, ##__VA_ARGS__)
286 fmt, ##args)
287#define DRM_DEBUG_DRIVER(fmt, ...) \ 284#define DRM_DEBUG_DRIVER(fmt, ...) \
288 drm_printk(KERN_DEBUG, DRM_UT_DRIVER, fmt, ##__VA_ARGS__) 285 drm_dbg(DRM_UT_DRIVER, fmt, ##__VA_ARGS__)
289 286
290#define DRM_DEV_DEBUG_KMS(dev, fmt, args...) \ 287#define DRM_DEV_DEBUG_KMS(dev, fmt, ...) \
291 drm_dev_printk(dev, KERN_DEBUG, DRM_UT_KMS, __func__, "", fmt, \ 288 drm_dev_dbg(dev, DRM_UT_KMS, fmt, ##__VA_ARGS__)
292 ##args) 289#define DRM_DEBUG_KMS(fmt, ...) \
293#define DRM_DEBUG_KMS(fmt, ...) \ 290 drm_dbg(DRM_UT_KMS, fmt, ##__VA_ARGS__)
294 drm_printk(KERN_DEBUG, DRM_UT_KMS, fmt, ##__VA_ARGS__)
295 291
296#define DRM_DEV_DEBUG_PRIME(dev, fmt, args...) \ 292#define DRM_DEV_DEBUG_PRIME(dev, fmt, ...) \
297 drm_dev_printk(dev, KERN_DEBUG, DRM_UT_PRIME, __func__, "", \ 293 drm_dev_dbg(dev, DRM_UT_PRIME, fmt, ##__VA_ARGS__)
298 fmt, ##args)
299#define DRM_DEBUG_PRIME(fmt, ...) \ 294#define DRM_DEBUG_PRIME(fmt, ...) \
300 drm_printk(KERN_DEBUG, DRM_UT_PRIME, fmt, ##__VA_ARGS__) 295 drm_dbg(DRM_UT_PRIME, fmt, ##__VA_ARGS__)
301 296
302#define DRM_DEV_DEBUG_ATOMIC(dev, fmt, args...) \ 297#define DRM_DEV_DEBUG_ATOMIC(dev, fmt, ...) \
303 drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ATOMIC, __func__, "", \ 298 drm_dev_dbg(dev, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__)
304 fmt, ##args)
305#define DRM_DEBUG_ATOMIC(fmt, ...) \ 299#define DRM_DEBUG_ATOMIC(fmt, ...) \
306 drm_printk(KERN_DEBUG, DRM_UT_ATOMIC, fmt, ##__VA_ARGS__) 300 drm_dbg(DRM_UT_ATOMIC, fmt, ##__VA_ARGS__)
307 301
308#define DRM_DEV_DEBUG_VBL(dev, fmt, args...) \ 302#define DRM_DEV_DEBUG_VBL(dev, fmt, ...) \
309 drm_dev_printk(dev, KERN_DEBUG, DRM_UT_VBL, __func__, "", fmt, \ 303 drm_dev_dbg(dev, DRM_UT_VBL, fmt, ##__VA_ARGS__)
310 ##args) 304#define DRM_DEBUG_VBL(fmt, ...) \
311#define DRM_DEBUG_VBL(fmt, ...) \ 305 drm_dbg(DRM_UT_VBL, fmt, ##__VA_ARGS__)
312 drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__)
313 306
314#define DRM_DEBUG_LEASE(fmt, ...) \ 307#define DRM_DEBUG_LEASE(fmt, ...) \
315 drm_printk(KERN_DEBUG, DRM_UT_LEASE, fmt, ##__VA_ARGS__) 308 drm_dbg(DRM_UT_LEASE, fmt, ##__VA_ARGS__)
316 309
317#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \ 310#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, category, fmt, ...) \
318({ \ 311({ \
319 static DEFINE_RATELIMIT_STATE(_rs, \ 312 static DEFINE_RATELIMIT_STATE(_rs, \
320 DEFAULT_RATELIMIT_INTERVAL, \ 313 DEFAULT_RATELIMIT_INTERVAL, \
321 DEFAULT_RATELIMIT_BURST); \ 314 DEFAULT_RATELIMIT_BURST); \
322 if (__ratelimit(&_rs)) \ 315 if (__ratelimit(&_rs)) \
323 drm_dev_printk(dev, KERN_DEBUG, DRM_UT_ ## level, \ 316 drm_dev_dbg(dev, category, fmt, ##__VA_ARGS__); \
324 __func__, "", fmt, ##args); \
325}) 317})
326 318
327/** 319/**
@@ -330,21 +322,28 @@ void drm_printk(const char *level, unsigned int category,
330 * @dev: device pointer 322 * @dev: device pointer
331 * @fmt: printf() like format string. 323 * @fmt: printf() like format string.
332 */ 324 */
333#define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, args...) \ 325#define DRM_DEV_DEBUG_RATELIMITED(dev, fmt, ...) \
334 DEV__DRM_DEFINE_DEBUG_RATELIMITED(dev, CORE, fmt, ##args) 326 _DEV_DRM_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_CORE, \
335#define DRM_DEBUG_RATELIMITED(fmt, args...) \ 327 fmt, ##__VA_ARGS__)
336 DRM_DEV_DEBUG_RATELIMITED(NULL, fmt, ##args) 328#define DRM_DEBUG_RATELIMITED(fmt, ...) \
337#define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, args...) \ 329 DRM_DEV_DEBUG_RATELIMITED(NULL, fmt, ##__VA_ARGS__)
338 _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRIVER, fmt, ##args) 330
339#define DRM_DEBUG_DRIVER_RATELIMITED(fmt, args...) \ 331#define DRM_DEV_DEBUG_DRIVER_RATELIMITED(dev, fmt, ...) \
340 DRM_DEV_DEBUG_DRIVER_RATELIMITED(NULL, fmt, ##args) 332 _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_DRIVER, \
341#define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, args...) \ 333 fmt, ##__VA_ARGS__)
342 _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, KMS, fmt, ##args) 334#define DRM_DEBUG_DRIVER_RATELIMITED(fmt, ...) \
343#define DRM_DEBUG_KMS_RATELIMITED(fmt, args...) \ 335 DRM_DEV_DEBUG_DRIVER_RATELIMITED(NULL, fmt, ##__VA_ARGS__)
344 DRM_DEV_DEBUG_KMS_RATELIMITED(NULL, fmt, ##args) 336
345#define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, args...) \ 337#define DRM_DEV_DEBUG_KMS_RATELIMITED(dev, fmt, ...) \
346 _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, PRIME, fmt, ##args) 338 _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_KMS, \
347#define DRM_DEBUG_PRIME_RATELIMITED(fmt, args...) \ 339 fmt, ##__VA_ARGS__)
348 DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##args) 340#define DRM_DEBUG_KMS_RATELIMITED(fmt, ...) \
341 DRM_DEV_DEBUG_KMS_RATELIMITED(NULL, fmt, ##__VA_ARGS__)
342
343#define DRM_DEV_DEBUG_PRIME_RATELIMITED(dev, fmt, ...) \
344 _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, DRM_UT_PRIME, \
345 fmt, ##__VA_ARGS__)
346#define DRM_DEBUG_PRIME_RATELIMITED(fmt, ...) \
347 DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##__VA_ARGS__)
349 348
350#endif /* DRM_PRINT_H_ */ 349#endif /* DRM_PRINT_H_ */
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 937757a8a568..d1423c7f3c73 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -209,7 +209,7 @@ struct drm_property_blob {
209 struct list_head head_global; 209 struct list_head head_global;
210 struct list_head head_file; 210 struct list_head head_file;
211 size_t length; 211 size_t length;
212 unsigned char data[]; 212 void *data;
213}; 213};
214 214
215struct drm_prop_enum_list { 215struct drm_prop_enum_list {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 024a1beda008..ae42289662df 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1147,6 +1147,8 @@ void pci_pme_wakeup_bus(struct pci_bus *bus);
1147void pci_d3cold_enable(struct pci_dev *dev); 1147void pci_d3cold_enable(struct pci_dev *dev);
1148void pci_d3cold_disable(struct pci_dev *dev); 1148void pci_d3cold_disable(struct pci_dev *dev);
1149bool pcie_relaxed_ordering_enabled(struct pci_dev *dev); 1149bool pcie_relaxed_ordering_enabled(struct pci_dev *dev);
1150void pci_wakeup_bus(struct pci_bus *bus);
1151void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state);
1150 1152
1151/* PCI Virtual Channel */ 1153/* PCI Virtual Channel */
1152int pci_save_vc_state(struct pci_dev *dev); 1154int pci_save_vc_state(struct pci_dev *dev);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index a6b30667a331..a637a7d8ce5b 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -45,6 +45,7 @@
45#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400 45#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
46#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401 46#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
47#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402 47#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402
48#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
48#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480 49#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
49 50
50#define PCI_BASE_CLASS_MEMORY 0x05 51#define PCI_BASE_CLASS_MEMORY 0x05
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index 960bedbdec87..77f0f0af3a71 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -168,11 +168,8 @@ int vga_switcheroo_process_delayed_switch(void);
168bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev); 168bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev);
169enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev); 169enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev);
170 170
171void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic);
172
173int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain); 171int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain);
174void vga_switcheroo_fini_domain_pm_ops(struct device *dev); 172void vga_switcheroo_fini_domain_pm_ops(struct device *dev);
175int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain);
176#else 173#else
177 174
178static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} 175static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
@@ -192,11 +189,8 @@ static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
192static inline bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) { return false; } 189static inline bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) { return false; }
193static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } 190static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; }
194 191
195static inline void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic) {}
196
197static inline int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; } 192static inline int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; }
198static inline void vga_switcheroo_fini_domain_pm_ops(struct device *dev) {} 193static inline void vga_switcheroo_fini_domain_pm_ops(struct device *dev) {}
199static inline int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; }
200 194
201#endif 195#endif
202#endif /* _LINUX_VGA_SWITCHEROO_H_ */ 196#endif /* _LINUX_VGA_SWITCHEROO_H_ */
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 68169e3749de..5b2ed12f58ce 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -227,9 +227,6 @@ struct hdac_io_ops {
227#define HDA_UNSOL_QUEUE_SIZE 64 227#define HDA_UNSOL_QUEUE_SIZE 64
228#define HDA_MAX_CODECS 8 /* limit by controller side */ 228#define HDA_MAX_CODECS 8 /* limit by controller side */
229 229
230/* HD Audio class code */
231#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
232
233/* 230/*
234 * CORB/RIRB 231 * CORB/RIRB
235 * 232 *
diff --git a/include/uapi/drm/etnaviv_drm.h b/include/uapi/drm/etnaviv_drm.h
index e9b997a0ef27..0d5c49dc478c 100644
--- a/include/uapi/drm/etnaviv_drm.h
+++ b/include/uapi/drm/etnaviv_drm.h
@@ -55,6 +55,12 @@ struct drm_etnaviv_timespec {
55#define ETNAVIV_PARAM_GPU_FEATURES_4 0x07 55#define ETNAVIV_PARAM_GPU_FEATURES_4 0x07
56#define ETNAVIV_PARAM_GPU_FEATURES_5 0x08 56#define ETNAVIV_PARAM_GPU_FEATURES_5 0x08
57#define ETNAVIV_PARAM_GPU_FEATURES_6 0x09 57#define ETNAVIV_PARAM_GPU_FEATURES_6 0x09
58#define ETNAVIV_PARAM_GPU_FEATURES_7 0x0a
59#define ETNAVIV_PARAM_GPU_FEATURES_8 0x0b
60#define ETNAVIV_PARAM_GPU_FEATURES_9 0x0c
61#define ETNAVIV_PARAM_GPU_FEATURES_10 0x0d
62#define ETNAVIV_PARAM_GPU_FEATURES_11 0x0e
63#define ETNAVIV_PARAM_GPU_FEATURES_12 0x0f
58 64
59#define ETNAVIV_PARAM_GPU_STREAM_COUNT 0x10 65#define ETNAVIV_PARAM_GPU_STREAM_COUNT 0x10
60#define ETNAVIV_PARAM_GPU_REGISTER_MAX 0x11 66#define ETNAVIV_PARAM_GPU_REGISTER_MAX 0x11
diff --git a/scripts/coccinelle/api/drm-get-put.cocci b/scripts/coccinelle/api/drm-get-put.cocci
index 91fceb8f1fa2..ceb71ea7f61c 100644
--- a/scripts/coccinelle/api/drm-get-put.cocci
+++ b/scripts/coccinelle/api/drm-get-put.cocci
@@ -16,12 +16,6 @@ expression object;
16@@ 16@@
17 17
18( 18(
19- drm_mode_object_reference(object)
20+ drm_mode_object_get(object)
21|
22- drm_mode_object_unreference(object)
23+ drm_mode_object_put(object)
24|
25- drm_connector_reference(object) 19- drm_connector_reference(object)
26+ drm_connector_get(object) 20+ drm_connector_get(object)
27| 21|
@@ -62,10 +56,6 @@ position p;
62@@ 56@@
63 57
64( 58(
65drm_mode_object_unreference@p(object)
66|
67drm_mode_object_reference@p(object)
68|
69drm_connector_unreference@p(object) 59drm_connector_unreference@p(object)
70| 60|
71drm_connector_reference@p(object) 61drm_connector_reference@p(object)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c71dcacea807..ec4e6b829ee2 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1227,6 +1227,7 @@ static void azx_vs_set_state(struct pci_dev *pci,
1227 struct snd_card *card = pci_get_drvdata(pci); 1227 struct snd_card *card = pci_get_drvdata(pci);
1228 struct azx *chip = card->private_data; 1228 struct azx *chip = card->private_data;
1229 struct hda_intel *hda = container_of(chip, struct hda_intel, chip); 1229 struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
1230 struct hda_codec *codec;
1230 bool disabled; 1231 bool disabled;
1231 1232
1232 wait_for_completion(&hda->probe_wait); 1233 wait_for_completion(&hda->probe_wait);
@@ -1251,8 +1252,12 @@ static void azx_vs_set_state(struct pci_dev *pci,
1251 dev_info(chip->card->dev, "%s via vga_switcheroo\n", 1252 dev_info(chip->card->dev, "%s via vga_switcheroo\n",
1252 disabled ? "Disabling" : "Enabling"); 1253 disabled ? "Disabling" : "Enabling");
1253 if (disabled) { 1254 if (disabled) {
1254 pm_runtime_put_sync_suspend(card->dev); 1255 list_for_each_codec(codec, &chip->bus) {
1255 azx_suspend(card->dev); 1256 pm_runtime_suspend(hda_codec_dev(codec));
1257 pm_runtime_disable(hda_codec_dev(codec));
1258 }
1259 pm_runtime_suspend(card->dev);
1260 pm_runtime_disable(card->dev);
1256 /* when we get suspended by vga_switcheroo we end up in D3cold, 1261 /* when we get suspended by vga_switcheroo we end up in D3cold,
1257 * however we have no ACPI handle, so pci/acpi can't put us there, 1262 * however we have no ACPI handle, so pci/acpi can't put us there,
1258 * put ourselves there */ 1263 * put ourselves there */
@@ -1263,9 +1268,12 @@ static void azx_vs_set_state(struct pci_dev *pci,
1263 "Cannot lock devices!\n"); 1268 "Cannot lock devices!\n");
1264 } else { 1269 } else {
1265 snd_hda_unlock_devices(&chip->bus); 1270 snd_hda_unlock_devices(&chip->bus);
1266 pm_runtime_get_noresume(card->dev);
1267 chip->disabled = false; 1271 chip->disabled = false;
1268 azx_resume(card->dev); 1272 pm_runtime_enable(card->dev);
1273 list_for_each_codec(codec, &chip->bus) {
1274 pm_runtime_enable(hda_codec_dev(codec));
1275 pm_runtime_resume(hda_codec_dev(codec));
1276 }
1269 } 1277 }
1270 } 1278 }
1271} 1279}
@@ -1295,6 +1303,7 @@ static void init_vga_switcheroo(struct azx *chip)
1295 dev_info(chip->card->dev, 1303 dev_info(chip->card->dev,
1296 "Handle vga_switcheroo audio client\n"); 1304 "Handle vga_switcheroo audio client\n");
1297 hda->use_vga_switcheroo = 1; 1305 hda->use_vga_switcheroo = 1;
1306 chip->driver_caps |= AZX_DCAPS_PM_RUNTIME;
1298 pci_dev_put(p); 1307 pci_dev_put(p);
1299 } 1308 }
1300} 1309}
@@ -1320,9 +1329,6 @@ static int register_vga_switcheroo(struct azx *chip)
1320 return err; 1329 return err;
1321 hda->vga_switcheroo_registered = 1; 1330 hda->vga_switcheroo_registered = 1;
1322 1331
1323 /* register as an optimus hdmi audio power domain */
1324 vga_switcheroo_init_domain_pm_optimus_hdmi_audio(chip->card->dev,
1325 &hda->hdmi_pm_domain);
1326 return 0; 1332 return 0;
1327} 1333}
1328#else 1334#else
@@ -1351,10 +1357,8 @@ static int azx_free(struct azx *chip)
1351 if (use_vga_switcheroo(hda)) { 1357 if (use_vga_switcheroo(hda)) {
1352 if (chip->disabled && hda->probe_continued) 1358 if (chip->disabled && hda->probe_continued)
1353 snd_hda_unlock_devices(&chip->bus); 1359 snd_hda_unlock_devices(&chip->bus);
1354 if (hda->vga_switcheroo_registered) { 1360 if (hda->vga_switcheroo_registered)
1355 vga_switcheroo_unregister_client(chip->pci); 1361 vga_switcheroo_unregister_client(chip->pci);
1356 vga_switcheroo_fini_domain_pm_ops(chip->card->dev);
1357 }
1358 } 1362 }
1359 1363
1360 if (bus->chip_init) { 1364 if (bus->chip_init) {
@@ -2197,6 +2201,7 @@ static int azx_probe_continue(struct azx *chip)
2197 struct hda_intel *hda = container_of(chip, struct hda_intel, chip); 2201 struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
2198 struct hdac_bus *bus = azx_bus(chip); 2202 struct hdac_bus *bus = azx_bus(chip);
2199 struct pci_dev *pci = chip->pci; 2203 struct pci_dev *pci = chip->pci;
2204 struct hda_codec *codec;
2200 int dev = chip->dev_index; 2205 int dev = chip->dev_index;
2201 int err; 2206 int err;
2202 2207
@@ -2278,8 +2283,17 @@ static int azx_probe_continue(struct azx *chip)
2278 2283
2279 chip->running = 1; 2284 chip->running = 1;
2280 azx_add_card_list(chip); 2285 azx_add_card_list(chip);
2286
2287 /*
2288 * The discrete GPU cannot power down unless the HDA controller runtime
2289 * suspends, so activate runtime PM on codecs even if power_save == 0.
2290 */
2291 if (use_vga_switcheroo(hda))
2292 list_for_each_codec(codec, &chip->bus)
2293 codec->auto_runtime_pm = 1;
2294
2281 snd_hda_set_power_save(&chip->bus, power_save * 1000); 2295 snd_hda_set_power_save(&chip->bus, power_save * 1000);
2282 if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo) 2296 if (azx_has_pm_runtime(chip))
2283 pm_runtime_put_autosuspend(&pci->dev); 2297 pm_runtime_put_autosuspend(&pci->dev);
2284 2298
2285out_free: 2299out_free:
diff --git a/sound/pci/hda/hda_intel.h b/sound/pci/hda/hda_intel.h
index ff0c4d617bc1..e3a3d318d2e5 100644
--- a/sound/pci/hda/hda_intel.h
+++ b/sound/pci/hda/hda_intel.h
@@ -40,9 +40,6 @@ struct hda_intel {
40 unsigned int vga_switcheroo_registered:1; 40 unsigned int vga_switcheroo_registered:1;
41 unsigned int init_failed:1; /* delayed init failed */ 41 unsigned int init_failed:1; /* delayed init failed */
42 42
43 /* secondary power domain for hdmi audio under vga device */
44 struct dev_pm_domain hdmi_pm_domain;
45
46 bool need_i915_power:1; /* the hda controller needs i915 power */ 43 bool need_i915_power:1; /* the hda controller needs i915 power */
47}; 44};
48 45