diff options
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 @@ | |||
1 | Etnaviv DRM master device | ||
2 | ========================= | ||
3 | |||
4 | The Etnaviv DRM master device is a virtual device needed to list all | ||
5 | Vivante GPU cores that comprise the GPU subsystem. | ||
6 | |||
7 | Required 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 | |||
13 | example: | ||
14 | |||
15 | gpu-subsystem { | ||
16 | compatible = "fsl,imx-gpu-subsystem"; | ||
17 | cores = <&gpu_2d>, <&gpu_3d>; | ||
18 | }; | ||
19 | |||
20 | |||
21 | Vivante GPU core devices | 1 | Vivante 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 @@ | |||
1 | AU Optronics Corporation 10.4" (800x600) color TFT LCD panel | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be "auo,g104sn02" | ||
5 | - power-supply: as specified in the base binding | ||
6 | |||
7 | Optional properties: | ||
8 | - backlight: as specified in the base binding | ||
9 | - enable-gpios: as specified in the base binding | ||
10 | |||
11 | This binding is compatible with the simple-panel binding, which is specified | ||
12 | in 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 | ||
83 | Note: 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 | |||
83 | Example: | 88 | Example: |
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 @@ | |||
1 | Kaohsiung Opto-Electronics. TX31D200VM0BAA 12.3" HSXGA LVDS panel | ||
2 | |||
3 | This binding is compatible with the simple-panel binding, which is specified | ||
4 | in simple-panel.txt in this directory. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: should be "koe,tx31d200vm0baa" | ||
8 | |||
9 | Optional properties: | ||
10 | - backlight: phandle of the backlight device attached to the panel | ||
11 | |||
12 | Optional nodes: | ||
13 | - Video port for LVDS panel input. | ||
14 | |||
15 | Example: | ||
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 | ||
10 | Optional properties: | 10 | Optional 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 | ||
13 | Example: | 14 | Example: |
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 @@ | |||
1 | Raydium Semiconductor Corporation RM68200 5.5" 720p MIPI-DSI TFT LCD panel | ||
2 | |||
3 | The Raydium Semiconductor Corporation RM68200 is a 5.5" 720x1280 TFT LCD | ||
4 | panel connected using a MIPI-DSI video interface. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "raydium,rm68200" | ||
8 | - reg: the virtual channel number of a DSI peripheral | ||
9 | |||
10 | Optional 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 | |||
15 | Example: | ||
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 @@ | |||
1 | Simple display panel | 1 | Simple display panel |
2 | ==================== | ||
3 | |||
4 | panel node | ||
5 | ---------- | ||
2 | 6 | ||
3 | Required properties: | 7 | Required 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 | ||
174 | On SoCs other than the A33 and V3s, there is one more clock required: | 177 | For TCONs with channel 0, there is one more clock required: |
178 | - 'tcon-ch0': The clock driving the TCON channel 0 | ||
179 | For 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 | ||
177 | When TCON support LVDS (all TCONs except TV TCON on A83T and those found | 182 | When TCON support LVDS (all TCONs except TV TCON on A83T and those found |
@@ -186,7 +191,7 @@ DRC | |||
186 | --- | 191 | --- |
187 | 192 | ||
188 | The DRC (Dynamic Range Controller), found in the latest Allwinner SoCs | 193 | The 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 |
190 | brightness/contrast based on histogram measurements for LCD content | 195 | brightness/contrast based on histogram measurements for LCD content |
191 | adaptive backlight control. | 196 | adaptive 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 | ||
253 | DEU | ||
254 | --- | ||
255 | |||
256 | The DEU (Detail Enhancement Unit), found in the Allwinner A80 SoC, | ||
257 | can sharpen the display content in both luma and chroma channels. | ||
258 | |||
259 | Required 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 | |||
246 | Display Engine Frontend | 275 | Display 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 | |||
104 | elan Elan Microelectronic Corp. | 104 | elan Elan Microelectronic Corp. |
105 | embest Shenzhen Embest Technology Co., Ltd. | 105 | embest Shenzhen Embest Technology Co., Ltd. |
106 | emmicro EM Microelectronic | 106 | emmicro EM Microelectronic |
107 | emtrion emtrion GmbH | ||
107 | energymicro Silicon Laboratories (formerly Energy Micro AS) | 108 | energymicro Silicon Laboratories (formerly Energy Micro AS) |
108 | engicam Engicam S.r.l. | 109 | engicam Engicam S.r.l. |
109 | epcos EPCOS AG | 110 | epcos 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 | ======================== | ||
2 | GPU 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 | |||
289 | CRTC Abstraction | 292 | CRTC 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 | ||
39 | static const bool verify_fast_training; | ||
40 | |||
38 | struct bridge_init { | 41 | struct 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 | ||
101 | int analogix_dp_psr_supported(struct analogix_dp_device *dp) | 104 | int 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 | } |
106 | EXPORT_SYMBOL_GPL(analogix_dp_psr_supported); | 109 | EXPORT_SYMBOL_GPL(analogix_dp_psr_enabled); |
107 | 110 | ||
108 | int analogix_dp_enable_psr(struct analogix_dp_device *dp) | 111 | int 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 | } |
128 | EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); | 130 | EXPORT_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 | } |
155 | EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); | 156 | EXPORT_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 | ||
632 | static void analogix_dp_init_training(struct analogix_dp_device *dp, | 647 | static 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 | |||
670 | static 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 | ||
707 | static int analogix_dp_set_link_train(struct analogix_dp_device *dp, | 719 | static 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 | |||
794 | static 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 | ||
725 | static int analogix_dp_config_video(struct analogix_dp_device *dp) | 803 | static 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); | |||
247 | void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); | 252 | void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); |
248 | void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); | 253 | void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); |
249 | void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); | 254 | void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); |
250 | void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, | 255 | int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, |
251 | struct edp_vsc_psr *vsc); | 256 | struct edp_vsc_psr *vsc, bool blocking); |
252 | ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, | 257 | ssize_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 | ||
995 | void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, | 996 | static 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 | |||
1009 | int 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 | ||
1041 | ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, | 1071 | ssize_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 | ||
1682 | static 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 | |||
1688 | static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) | 1681 | static 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 | } |
410 | EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); | 409 | EXPORT_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 | */ | ||
412 | static int | 435 | static int |
413 | drm_atomic_replace_property_blob_from_id(struct drm_device *dev, | 436 | drm_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 | */ |
132 | static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | 132 | static 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 | ||
364 | int drm_legacy_addmap(struct drm_device * dev, resource_size_t offset, | 364 | int 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 | */ |
640 | static void drm_cleanup_buf_error(struct drm_device * dev, | 640 | static 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, | |||
1446 | int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p, | 1446 | int __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); | |||
773 | int drm_mode_vrefresh(const struct drm_display_mode *mode) | 773 | int 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 | |||
1631 | out: | ||
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 | } |
64 | EXPORT_SYMBOL(drm_printf); | 64 | EXPORT_SYMBOL(drm_printf); |
65 | 65 | ||
66 | #define DRM_PRINTK_FMT "[" DRM_NAME ":%s]%s %pV" | ||
67 | |||
68 | void drm_dev_printk(const struct device *dev, const char *level, | 66 | void 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 | } | ||
85 | EXPORT_SYMBOL(drm_dev_printk); | ||
86 | |||
87 | void 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 | } |
90 | EXPORT_SYMBOL(drm_dev_printk); | 109 | EXPORT_SYMBOL(drm_dev_dbg); |
91 | 110 | ||
92 | void drm_printk(const char *level, unsigned int category, | 111 | void 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 | } | ||
128 | EXPORT_SYMBOL(drm_dbg); | ||
129 | |||
130 | void 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 | } |
111 | EXPORT_SYMBOL(drm_printk); | 144 | EXPORT_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 | ||
17 | obj-$(CONFIG_DRM_ETNAVIV) += etnaviv.o | 19 | obj-$(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 | |||
8 | git clone git://0x04.net/rules-ng-ng | 8 | git clone git://0x04.net/rules-ng-ng |
9 | 9 | ||
10 | The rules-ng-ng source files this header was generated from are: | 10 | The 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 | ||
19 | Copyright (C) 2012-2017 by the following authors: | 16 | Copyright (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 | ||
218 | u16 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 | |||
218 | void etnaviv_buffer_end(struct etnaviv_gpu *gpu) | 236 | void 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 | ||
102 | static int etnaviv_open(struct drm_device *dev, struct drm_file *file) | 102 | static 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) | |||
637 | static int etnaviv_pdev_probe(struct platform_device *pdev) | 653 | static 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 | ||
676 | static const struct of_device_id dt_match[] = { | ||
677 | { .compatible = "fsl,imx-gpu-subsystem" }, | ||
678 | { .compatible = "marvell,dove-gpu-subsystem" }, | ||
679 | {} | ||
680 | }; | ||
681 | MODULE_DEVICE_TABLE(of, dt_match); | ||
682 | |||
683 | static struct platform_driver etnaviv_platform_driver = { | 688 | static 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 | ||
692 | static int __init etnaviv_init(void) | 696 | static 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 | } |
708 | module_init(etnaviv_init); | 726 | module_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 | ||
38 | struct etnaviv_cmdbuf; | 39 | struct etnaviv_cmdbuf; |
39 | struct etnaviv_gpu; | 40 | struct etnaviv_gpu; |
@@ -42,11 +43,11 @@ struct etnaviv_gem_object; | |||
42 | struct etnaviv_gem_submit; | 43 | struct etnaviv_gem_submit; |
43 | 44 | ||
44 | struct etnaviv_file_private { | 45 | struct 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 | ||
52 | struct etnaviv_drm_private { | 53 | struct 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); |
86 | u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu); | 87 | u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu); |
87 | u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr); | 88 | u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr); |
89 | u16 etnaviv_buffer_config_pta(struct etnaviv_gpu *gpu); | ||
88 | void etnaviv_buffer_end(struct etnaviv_gpu *gpu); | 90 | void etnaviv_buffer_end(struct etnaviv_gpu *gpu); |
89 | void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event); | 91 | void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event); |
90 | void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, | 92 | void 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 | ||
27 | static bool etnaviv_dump_core = true; | ||
28 | module_param_named(dump_core, etnaviv_dump_core, bool, 0600); | ||
29 | |||
26 | struct core_dump_iterator { | 30 | struct 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 | */ |
103 | struct etnaviv_gem_submit { | 106 | struct 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 | ||
172 | static int submit_fence_sync(const struct etnaviv_gem_submit *submit) | 173 | static 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) | |||
395 | int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, | 405 | int 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 | ||
568 | err_submit_objects: | 578 | err_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 | |||
34 | static const struct platform_device_id gpu_ids[] = { | 39 | static const struct platform_device_id gpu_ids[] = { |
35 | { .name = "etnaviv-gpu,2d" }, | 40 | { .name = "etnaviv-gpu,2d" }, |
36 | { }, | 41 | { }, |
37 | }; | 42 | }; |
38 | 43 | ||
39 | static bool etnaviv_dump_core = true; | ||
40 | module_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 | ||
566 | static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu) | 610 | static 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 | /* | 987 | void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu) |
916 | * Hangcheck detection for locked gpu: | ||
917 | */ | ||
918 | static 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 | |||
963 | static 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 | |||
970 | static 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 | |||
1004 | static 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 | ||
1083 | int 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 | |||
1198 | static 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 | |||
1222 | int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu, | 1157 | int 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: */ |
1346 | int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, | 1286 | struct 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 | |||
1410 | out_unlock: | 1347 | out_unlock: |
1411 | mutex_unlock(&gpu->lock); | 1348 | mutex_unlock(&gpu->lock); |
1412 | 1349 | ||
1413 | return ret; | 1350 | return gpu_fence; |
1414 | } | 1351 | } |
1415 | 1352 | ||
1416 | static void sync_point_worker(struct work_struct *work) | 1353 | static 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 | /* | 1368 | static 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 | |||
1434 | static irqreturn_t irq_handler(int irq, void *data) | 1397 | static 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 | |||
1668 | out_sched: | ||
1669 | etnaviv_sched_fini(gpu); | ||
1670 | |||
1671 | out_workqueue: | ||
1672 | destroy_workqueue(gpu->wq); | ||
1673 | |||
1674 | out_thermal: | ||
1675 | if (IS_ENABLED(CONFIG_DRM_ETNAVIV_THERMAL)) | ||
1676 | thermal_cooling_device_unregister(gpu->cooling); | ||
1677 | |||
1678 | return ret; | ||
1713 | } | 1679 | } |
1714 | 1680 | ||
1715 | static void etnaviv_gpu_unbind(struct device *dev, struct device *master, | 1681 | static 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 | }; |
1732 | MODULE_DEVICE_TABLE(of, etnaviv_gpu_match); | ||
1765 | 1733 | ||
1766 | static int etnaviv_gpu_platform_probe(struct platform_device *pdev) | 1734 | static 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 | ||
87 | enum etnaviv_sec_mode { | ||
88 | ETNA_SEC_NONE = 0, | ||
89 | ETNA_SEC_KERNEL, | ||
90 | ETNA_SEC_TZ | ||
91 | }; | ||
92 | |||
91 | struct etnaviv_event { | 93 | struct 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 | ||
184 | static inline bool fence_retired(struct etnaviv_gpu *gpu, u32 fence) | ||
185 | { | ||
186 | return fence_after_eq(gpu->retired_fence, fence); | ||
187 | } | ||
188 | |||
189 | int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); | 177 | int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); |
190 | 178 | ||
191 | int etnaviv_gpu_init(struct etnaviv_gpu *gpu); | 179 | int etnaviv_gpu_init(struct etnaviv_gpu *gpu); |
180 | bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu); | ||
192 | 181 | ||
193 | #ifdef CONFIG_DEBUG_FS | 182 | #ifdef CONFIG_DEBUG_FS |
194 | int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m); | 183 | int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m); |
195 | #endif | 184 | #endif |
196 | 185 | ||
197 | int etnaviv_gpu_fence_sync_obj(struct etnaviv_gem_object *etnaviv_obj, | 186 | void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu); |
198 | unsigned int context, bool exclusive, bool implicit); | ||
199 | |||
200 | void etnaviv_gpu_retire(struct etnaviv_gpu *gpu); | 187 | void etnaviv_gpu_retire(struct etnaviv_gpu *gpu); |
201 | int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu, | 188 | int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu, |
202 | u32 fence, struct timespec *timeout); | 189 | u32 fence, struct timespec *timeout); |
203 | int etnaviv_gpu_wait_obj_inactive(struct etnaviv_gpu *gpu, | 190 | int 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); |
205 | int etnaviv_gpu_submit(struct etnaviv_gpu *gpu, | 192 | struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit); |
206 | struct etnaviv_gem_submit *submit); | ||
207 | int etnaviv_gpu_pm_get_sync(struct etnaviv_gpu *gpu); | 193 | int etnaviv_gpu_pm_get_sync(struct etnaviv_gpu *gpu); |
208 | void etnaviv_gpu_pm_put(struct etnaviv_gpu *gpu); | 194 | void etnaviv_gpu_pm_put(struct etnaviv_gpu *gpu); |
209 | int etnaviv_gpu_wait_idle(struct etnaviv_gpu *gpu, unsigned int timeout_ms); | 195 | int 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 | |||
19 | static 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 | |||
50 | bool 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 | ||
161 | const struct etnaviv_iommu_domain_ops etnaviv_iommuv1_ops = { | 161 | static 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 | ||
41 | struct etnaviv_iommuv2_domain { | 41 | struct 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 | ||
219 | void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu) | 240 | static 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 | ||
239 | const struct etnaviv_iommu_domain_ops etnaviv_iommuv2_ops = { | 260 | static 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 | |||
298 | void 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 | |||
313 | static 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 | |||
25 | static int etnaviv_job_hang_limit = 0; | ||
26 | module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444); | ||
27 | static int etnaviv_hw_jobs_limit = 4; | ||
28 | module_param_named(hw_job_limit, etnaviv_hw_jobs_limit, int , 0444); | ||
29 | |||
30 | static struct dma_fence * | ||
31 | etnaviv_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 | |||
82 | static 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 | |||
95 | static 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 | |||
113 | static 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 | |||
120 | static 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 | |||
127 | int 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 | |||
154 | int 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 | |||
167 | void 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 | |||
22 | struct etnaviv_gpu; | ||
23 | |||
24 | static inline | ||
25 | struct 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 | |||
30 | int etnaviv_sched_init(struct etnaviv_gpu *gpu); | ||
31 | void etnaviv_sched_fini(struct etnaviv_gpu *gpu); | ||
32 | int 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 | |||
9 | git clone git://0x04.net/rules-ng-ng | 8 | git clone git://0x04.net/rules-ng-ng |
10 | 9 | ||
11 | The rules-ng-ng source files this header was generated from are: | 10 | The 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) | |
19 | Copyright (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 | |||
21 | Copyright (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 | |||
27 | Permission is hereby granted, free of charge, to any person obtaining a | ||
28 | copy of this software and associated documentation files (the "Software"), | ||
29 | to deal in the Software without restriction, including without limitation | ||
30 | the rights to use, copy, modify, merge, publish, distribute, sub license, | ||
31 | and/or sell copies of the Software, and to permit persons to whom the | ||
32 | Software is furnished to do so, subject to the following conditions: | ||
33 | |||
34 | The above copyright notice and this permission notice (including the | ||
35 | next paragraph) shall be included in all copies or substantial portions | ||
36 | of the Software. | ||
37 | |||
38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
40 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
41 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
43 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
44 | DEALINGS 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 | |||
6 | This file was generated by the rules-ng-ng headergen tool in this git repository: | ||
7 | http://0x04.net/cgit/index.cgi/rules-ng-ng | ||
8 | git clone git://0x04.net/rules-ng-ng | ||
9 | |||
10 | The 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 | |||
21 | Copyright (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 | |||
27 | Permission is hereby granted, free of charge, to any person obtaining a | ||
28 | copy of this software and associated documentation files (the "Software"), | ||
29 | to deal in the Software without restriction, including without limitation | ||
30 | the rights to use, copy, modify, merge, publish, distribute, sub license, | ||
31 | and/or sell copies of the Software, and to permit persons to whom the | ||
32 | Software is furnished to do so, subject to the following conditions: | ||
33 | |||
34 | The above copyright notice and this permission notice (including the | ||
35 | next paragraph) shall be included in all copies or substantial portions | ||
36 | of the Software. | ||
37 | |||
38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
40 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
41 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
43 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
44 | DEALINGS 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 | |||
9 | git clone git://0x04.net/rules-ng-ng | 8 | git clone git://0x04.net/rules-ng-ng |
10 | 9 | ||
11 | The rules-ng-ng source files this header was generated from are: | 10 | The 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) | |
15 | Copyright (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 | |||
21 | Copyright (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 | |||
27 | Permission is hereby granted, free of charge, to any person obtaining a | ||
28 | copy of this software and associated documentation files (the "Software"), | ||
29 | to deal in the Software without restriction, including without limitation | ||
30 | the rights to use, copy, modify, merge, publish, distribute, sub license, | ||
31 | and/or sell copies of the Software, and to permit persons to whom the | ||
32 | Software is furnished to do so, subject to the following conditions: | ||
33 | |||
34 | The above copyright notice and this permission notice (including the | ||
35 | next paragraph) shall be included in all copies or substantial portions | ||
36 | of the Software. | ||
37 | |||
38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
40 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
41 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
43 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
44 | DEALINGS 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, | |||
11059 | static void __printf(3, 4) | 11059 | static void __printf(3, 4) |
11060 | pipe_config_err(bool adjust, const char *name, const char *format, ...) | 11060 | pipe_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 | ||
283 | free_drm: | 298 | free_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 */ | ||
542 | static enum drm_mode_status | 541 | static enum drm_mode_status |
543 | dw_hdmi_mode_valid(struct drm_connector *connector, | 542 | dw_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 | ||
340 | struct meson_vclk_params { | 350 | struct 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 | ||
406 | static inline unsigned int pll_od_to_reg(unsigned int od) | 456 | static 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 | ||
700 | union 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 | |||
742 | union 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 | |||
784 | union 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 | |||
826 | union 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 | |||
868 | union 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 | |||
910 | union 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 | |||
952 | struct 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 | |||
700 | struct meson_hdmi_venc_vic_mode { | 1008 | struct 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 | ||
1047 | bool 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 | } | ||
1059 | EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode); | ||
1060 | |||
739 | bool meson_venc_hdmi_supported_vic(int vic) | 1061 | bool 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 | } |
751 | EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); | 1073 | EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); |
752 | 1074 | ||
1075 | static 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 | |||
753 | static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) | 1089 | static 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 */ |
61 | bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode); | ||
61 | bool meson_venc_hdmi_supported_vic(int vic); | 62 | bool meson_venc_hdmi_supported_vic(int vic); |
62 | bool meson_venc_hdmi_venc_repeat(int vic); | 63 | bool 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 | |||
515 | static void | ||
516 | nouveau_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 | |||
544 | static int | 513 | static int |
545 | nouveau_drm_load(struct drm_device *dev, unsigned long flags) | 514 | nouveau_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 | ||
214 | static inline struct nouveau_drm * | 213 | static 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 | ||
111 | config 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 | |||
111 | config DRM_PANEL_SAMSUNG_S6E3HA2 | 120 | config 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 | |||
9 | obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o | 9 | obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o |
10 | obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o | 10 | obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o |
11 | obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o | 11 | obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o |
12 | obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o | ||
12 | obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o | 13 | obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o |
13 | obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o | 14 | obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o |
14 | obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o | 15 | obj-$(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 | ||
182 | const char *ili9322_inputs[] = { | 182 | static 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 | ||
343 | const struct regmap_config ili9322_regmap_config = { | 343 | static 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 | |||
73 | struct 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 | |||
83 | static 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 | |||
99 | static inline struct rm68200 *panel_to_rm68200(struct drm_panel *panel) | ||
100 | { | ||
101 | return container_of(panel, struct rm68200, panel); | ||
102 | } | ||
103 | |||
104 | static 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 | |||
116 | static 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 | |||
146 | static 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 | |||
235 | static 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 | |||
249 | static 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 | |||
280 | static 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 | |||
321 | static 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 | |||
335 | static 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 | |||
358 | static 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 | |||
366 | static 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 | |||
419 | static 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 | |||
429 | static const struct of_device_id raydium_rm68200_of_match[] = { | ||
430 | { .compatible = "raydium,rm68200" }, | ||
431 | { } | ||
432 | }; | ||
433 | MODULE_DEVICE_TABLE(of, raydium_rm68200_of_match); | ||
434 | |||
435 | static 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 | }; | ||
443 | module_mipi_dsi_driver(raydium_rm68200_driver); | ||
444 | |||
445 | MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>"); | ||
446 | MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>"); | ||
447 | MODULE_DESCRIPTION("DRM Driver for Raydium RM68200 MIPI DSI panel"); | ||
448 | MODULE_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 | ||
584 | static 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 | |||
597 | static 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 | |||
584 | static const struct display_timing auo_g133han01_timings = { | 607 | static 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 | ||
1243 | static 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 | |||
1256 | static 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 | |||
1220 | static const struct display_timing kyo_tcg121xglp_timing = { | 1267 | static 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 | ||
1603 | static const struct drm_display_mode ortustech_com43h4m85ulc_mode = { | 1650 | static 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 | ||
1744 | static const struct drm_display_mode sharp_lq123p1jx31_mode = { | 1791 | static 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 | ||
1758 | static const struct panel_desc sharp_lq123p1jx31 = { | 1804 | static 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 | ||
101 | int qxl_get_handle_for_primary_fb(struct qxl_device *qdev, | 101 | int 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 | ||
345 | out: | 345 | out: |
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 | ||
218 | struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo) | 218 | struct 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 { | |||
84 | static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled) | 80 | static 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 | |||
103 | static 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 | ||
124 | static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) | 103 | static 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 | ||
940 | static bool vop_fs_irq_is_pending(struct vop *vop) | 950 | static 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; | 1517 | out: |
1518 | mutex_unlock(&vop->vop_lock); | ||
1519 | return ret; | ||
1499 | } | 1520 | } |
1500 | EXPORT_SYMBOL(rockchip_drm_wait_vact_end); | 1521 | EXPORT_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 | ||
1572 | err_disable_pm_runtime: | 1594 | err_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); |
1575 | err_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 | */ | ||
57 | static const u32 sunxi_bt601_yuv2rgb_coef[12] = { | ||
58 | 0x000004a7, 0x00001e6f, 0x00001cbf, 0x00000877, | ||
59 | 0x000004a7, 0x00000000, 0x00000662, 0x00003211, | ||
60 | 0x000004a7, 0x00000812, 0x00000000, 0x00002eb1, | ||
61 | }; | ||
62 | |||
63 | static 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 | |||
75 | static 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 | |||
89 | static 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 | |||
45 | static void sun4i_backend_apply_color_correction(struct sunxi_engine *engine) | 95 | static 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 | ||
219 | static 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 | |||
169 | int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, | 274 | int 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 | ||
338 | static 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 | |||
226 | int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, | 353 | int 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 = { | |||
793 | static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = { | 936 | static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = { |
794 | }; | 937 | }; |
795 | 938 | ||
939 | static const struct sun4i_backend_quirks sun9i_backend_quirks = { | ||
940 | }; | ||
941 | |||
796 | static const struct of_device_id sun4i_backend_of_table[] = { | 942 | static 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 | }; |
819 | MODULE_DEVICE_TABLE(of, sun4i_backend_of_table); | 969 | MODULE_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 | ||
153 | struct sun4i_backend { | 171 | struct 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 | |||
183 | static 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 | ||
182 | static bool sun4i_drv_node_is_supported_frontend(struct device_node *node) | 188 | static 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 | }; |
366 | MODULE_DEVICE_TABLE(of, sun4i_drv_of_table); | 374 | MODULE_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 | ||
140 | static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, | 144 | static 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 | ||
97 | static 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 | |||
97 | static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = { | 151 | static 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 | ||
102 | static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = { | 157 | static 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 | ||
55 | static int sun4i_rgb_mode_valid(struct drm_connector *connector, | 55 | static 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 | ||
107 | static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = { | 107 | static 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 | ||
112 | static void | 111 | static void |
@@ -156,6 +155,7 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder) | |||
156 | static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = { | 155 | static 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 | ||
161 | static void sun4i_rgb_enc_destroy(struct drm_encoder *encoder) | 161 | static 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, | |||
343 | static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, | 344 | static 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 | ||
1209 | static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = { | ||
1210 | .has_channel_0 = true, | ||
1211 | .needs_edp_reset = true, | ||
1212 | }; | ||
1213 | |||
1214 | static 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 */ |
1170 | const struct of_device_id sun4i_tcon_of_table[] = { | 1220 | const 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 | }; |
1182 | MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table); | 1234 | MODULE_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 | }; |
106 | MODULE_DEVICE_TABLE(of, sun6i_drc_of_table); | 107 | MODULE_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 | ||
313 | enum vc4_scaling_mode { | ||
314 | VC4_SCALING_NONE, | ||
315 | VC4_SCALING_TPZ, | ||
316 | VC4_SCALING_PPF, | ||
317 | }; | ||
318 | |||
319 | struct 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 | |||
367 | static inline struct vc4_plane_state * | ||
368 | to_vc4_plane_state(struct drm_plane_state *state) | ||
369 | { | ||
370 | return (struct vc4_plane_state *)state; | ||
371 | } | ||
372 | |||
313 | enum vc4_encoder_type { | 373 | enum 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 | ||
30 | enum vc4_scaling_mode { | ||
31 | VC4_SCALING_NONE, | ||
32 | VC4_SCALING_TPZ, | ||
33 | VC4_SCALING_PPF, | ||
34 | }; | ||
35 | |||
36 | struct 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 | |||
78 | static inline struct vc4_plane_state * | ||
79 | to_vc4_plane_state(struct drm_plane_state *state) | ||
80 | { | ||
81 | return (struct vc4_plane_state *)state; | ||
82 | } | ||
83 | |||
84 | static const struct hvs_format { | 30 | static 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, | |||
316 | out_no_surface: | 316 | out_no_surface: |
317 | ttm_read_unlock(&dev_priv->reservation_sem); | 317 | ttm_read_unlock(&dev_priv->reservation_sem); |
318 | out_no_ttm_lock: | 318 | out_no_ttm_lock: |
319 | drm_framebuffer_unreference(fb); | 319 | drm_framebuffer_put(fb); |
320 | out_no_fb: | 320 | out_no_fb: |
321 | drm_modeset_unlock_all(dev); | 321 | drm_modeset_unlock_all(dev); |
322 | out_no_copy: | 322 | out_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); |
395 | out_no_ttm_lock: | 395 | out_no_ttm_lock: |
396 | drm_framebuffer_unreference(fb); | 396 | drm_framebuffer_put(fb); |
397 | out_no_fb: | 397 | out_no_fb: |
398 | drm_modeset_unlock_all(dev); | 398 | drm_modeset_unlock_all(dev); |
399 | out_no_copy: | 399 | out_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 | */ |
110 | struct vga_switcheroo_client { | 110 | struct 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 | } |
346 | EXPORT_SYMBOL(vga_switcheroo_register_audio_client); | 346 | EXPORT_SYMBOL(vga_switcheroo_register_audio_client); |
347 | 347 | ||
@@ -406,6 +406,19 @@ bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) | |||
406 | } | 406 | } |
407 | EXPORT_SYMBOL(vga_switcheroo_client_probe_defer); | 407 | EXPORT_SYMBOL(vga_switcheroo_client_probe_defer); |
408 | 408 | ||
409 | static enum vga_switcheroo_state | ||
410 | vga_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 | */ | ||
992 | void 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 | } | ||
1008 | EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch); | ||
1009 | |||
1010 | /* switcheroo power domain */ | 992 | /* switcheroo power domain */ |
1011 | static int vga_switcheroo_runtime_suspend(struct device *dev) | 993 | static 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 | } |
1078 | EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops); | 1062 | EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops); |
1079 | |||
1080 | static 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 | */ | ||
1128 | int | ||
1129 | vga_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 | } | ||
1144 | EXPORT_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 | */ |
803 | static void pci_wakeup_bus(struct pci_bus *bus) | 803 | void 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 | */ |
857 | static void __pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state) | 857 | void 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 | } |
882 | EXPORT_SYMBOL_GPL(__pci_complete_power_transition); | 882 | EXPORT_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 | } |
4834 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi); | 4835 | DECLARE_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 | */ | ||
4846 | static 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 | } | ||
4868 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID, | ||
4869 | PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda); | ||
4870 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_AMD, PCI_ANY_ID, | ||
4871 | PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda); | ||
4872 | DECLARE_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 | ||
44 | int analogix_dp_psr_supported(struct analogix_dp_device *dp); | 44 | int analogix_dp_psr_enabled(struct analogix_dp_device *dp); |
45 | int analogix_dp_enable_psr(struct analogix_dp_device *dp); | 45 | int analogix_dp_enable_psr(struct analogix_dp_device *dp); |
46 | int analogix_dp_disable_psr(struct analogix_dp_device *dp); | 46 | int 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, | |||
38 | int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, | 38 | int 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 | */ | ||
48 | static inline int drm_color_lut_size(const struct drm_property_blob *blob) | ||
49 | { | ||
50 | return blob->length / sizeof(struct drm_color_lut); | ||
51 | } | ||
52 | |||
41 | enum drm_color_encoding { | 53 | enum 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, | |||
120 | void drm_mode_object_get(struct drm_mode_object *obj); | 120 | void drm_mode_object_get(struct drm_mode_object *obj); |
121 | void drm_mode_object_put(struct drm_mode_object *obj); | 121 | void 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 | */ | ||
130 | static 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 | */ | ||
142 | static inline void drm_mode_object_unreference(struct drm_mode_object *obj) | ||
143 | { | ||
144 | drm_mode_object_put(obj); | ||
145 | } | ||
146 | |||
147 | int drm_object_property_set_value(struct drm_mode_object *obj, | 123 | int 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) |
200 | void drm_dev_printk(const struct device *dev, const char *level, | 200 | void 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) |
204 | void drm_printk(const char *level, unsigned int category, | 203 | void drm_dev_dbg(const struct device *dev, unsigned int category, |
205 | const char *format, ...); | 204 | const char *format, ...); |
205 | |||
206 | __printf(2, 3) | ||
207 | void drm_dbg(unsigned int category, const char *format, ...); | ||
208 | __printf(1, 2) | ||
209 | void 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 | ||
215 | struct drm_prop_enum_list { | 215 | struct 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); | |||
1147 | void pci_d3cold_enable(struct pci_dev *dev); | 1147 | void pci_d3cold_enable(struct pci_dev *dev); |
1148 | void pci_d3cold_disable(struct pci_dev *dev); | 1148 | void pci_d3cold_disable(struct pci_dev *dev); |
1149 | bool pcie_relaxed_ordering_enabled(struct pci_dev *dev); | 1149 | bool pcie_relaxed_ordering_enabled(struct pci_dev *dev); |
1150 | void pci_wakeup_bus(struct pci_bus *bus); | ||
1151 | void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state); | ||
1150 | 1152 | ||
1151 | /* PCI Virtual Channel */ | 1153 | /* PCI Virtual Channel */ |
1152 | int pci_save_vc_state(struct pci_dev *dev); | 1154 | int 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); | |||
168 | bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev); | 168 | bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev); |
169 | enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev); | 169 | enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev); |
170 | 170 | ||
171 | void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic); | ||
172 | |||
173 | int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain); | 171 | int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain); |
174 | void vga_switcheroo_fini_domain_pm_ops(struct device *dev); | 172 | void vga_switcheroo_fini_domain_pm_ops(struct device *dev); |
175 | int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain); | ||
176 | #else | 173 | #else |
177 | 174 | ||
178 | static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} | 175 | static 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; } | |||
192 | static inline bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) { return false; } | 189 | static inline bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) { return false; } |
193 | static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } | 190 | static inline enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } |
194 | 191 | ||
195 | static inline void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic) {} | ||
196 | |||
197 | static inline int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; } | 192 | static inline int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; } |
198 | static inline void vga_switcheroo_fini_domain_pm_ops(struct device *dev) {} | 193 | static inline void vga_switcheroo_fini_domain_pm_ops(struct device *dev) {} |
199 | static 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 | ( |
65 | drm_mode_object_unreference@p(object) | ||
66 | | | ||
67 | drm_mode_object_reference@p(object) | ||
68 | | | ||
69 | drm_connector_unreference@p(object) | 59 | drm_connector_unreference@p(object) |
70 | | | 60 | | |
71 | drm_connector_reference@p(object) | 61 | drm_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 | ||
2285 | out_free: | 2299 | out_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 | ||