History

Merge tag 'drm-misc-next-2023-03-07' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v6.4-rc1: Note: Only changes since pull request from 2023-02-23 are included here. UAPI Changes: - Convert rockchip bindings to YAML. - Constify kobj_type structure in dma-buf. - FBDEV cmdline parser fixes, and other small fbdev fixes for mode parsing. Cross-subsystem Changes: - Add Neil Armstrong as linaro maintainer. - Actually signal the private stub dma-fence. Core Changes: - Add function for adding syncobj dep to sched_job and use it in panfrost, v3d. - Improve DisplayID 2.0 topology parsing and EDID parsing in general. - Add a gem eviction function and callback for generic GEM shrinker purposes. - Prepare to convert shmem helper to use the GEM reservation lock instead of own locking. (Actual commit itself got reverted for now) - Move the suballocator from radeon and amdgpu drivers to core in preparation for Xe. - Assorted small fixes and documentation. - Fixes to HPD polling. - Assorted small fixes in simpledrm, bridge, accel, shmem-helper, and the selftest of format-helper. - Remove dummy resource when ttm bo is created, and during pipelined gutting. Fix all drivers to accept a NULL ttm_bo->resource. - Handle pinned BO moving prevention in ttm core. - Set drm panel-bridge orientation before connector is registered. - Remove dumb_destroy callback. - Add documentation to GEM_CLOSE, PRIME_HANDLE_TO_FD, PRIME_FD_TO_HANDLE, GETFB2 ioctl's. - Add atomic enable_plane callback, use it in ast, mgag200, tidss. Driver Changes: - Use drm_gem_objects_lookup in vc4. - Assorted small fixes to virtio, ast, bridge/tc358762, meson, nouveau. - Allow virtio KMS to be disabled and compiled out. - Add Radxa 8/10HD, Samsung AMS495QA01 panels. - Fix ivpu compiler errors. - Assorted fixes to drm/panel, malidp, rockchip, ivpu, amdgpu, vgem, nouveau, vc4. - Assorted cleanups, simplifications and fixes to vmwgfx. Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 3 years ago

Commit faf0d832 parents eeac8ed 9228742155 files · +4430 −3332Browse files

Unified · Split

155 files
  1. Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml +63 −0
  2. Documentation/devicetree/bindings/display/bridge/analogix_dp.txt +0 −51
  3. Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml +3 −13
  4. Documentation/devicetree/bindings/display/dsi-controller.yaml +9 −9
  5. Documentation/devicetree/bindings/display/exynos/exynos_dp.txt +1 −1
  6. Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml +2 −0
  7. Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml +57 −0
  8. Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt +0 −98
  9. Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt +0 −94
  10. Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml +103 −0
  11. Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml +166 −0
  12. Documentation/devicetree/bindings/display/rockchip/rockchip,lvds.yaml +170 −0
  13. Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt +0 −92
  14. Documentation/devicetree/bindings/display/simple-framebuffer.yaml +9 −0
  15. Documentation/devicetree/bindings/soc/rockchip/grf.yaml +7 −3
  16. MAINTAINERS +1 −1
  17. drivers/accel/ivpu/ivpu_pm.c +0 −10
  18. drivers/dma-buf/dma-buf.c +1 −1
  19. drivers/gpu/drm/Kconfig +5 −1
  20. drivers/gpu/drm/Makefile +3 −0
  21. drivers/gpu/drm/amd/amdgpu/Kconfig +1 −0
  22. drivers/gpu/drm/amd/amdgpu/amdgpu.h +4 −22
  23. drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +2 −3
  24. drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +3 −6
  25. drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +15 −8
  26. drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +2 −1
  27. drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +21 −303
  28. drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +0 −4
  29. drivers/gpu/drm/arm/malidp_drv.c +1 −1
  30. drivers/gpu/drm/ast/ast_dp.c +5 −5
  31. drivers/gpu/drm/ast/ast_dp501.c +20 −20
  32. drivers/gpu/drm/ast/ast_drv.c +1 −1
  33. drivers/gpu/drm/ast/ast_drv.h +33 −51
  34. drivers/gpu/drm/ast/ast_i2c.c +4 −4
  35. drivers/gpu/drm/ast/ast_main.c +12 −12
  36. drivers/gpu/drm/ast/ast_mm.c +2 −2
  37. drivers/gpu/drm/ast/ast_mode.c +58 −46
  38. drivers/gpu/drm/ast/ast_post.c +47 −47
  39. drivers/gpu/drm/bridge/Kconfig +1 −1
  40. drivers/gpu/drm/bridge/panel.c +2 −0
  41. drivers/gpu/drm/bridge/tc358762.c +1 −0
  42. drivers/gpu/drm/drm_atomic_helper.c +16 −4
  43. drivers/gpu/drm/drm_connector.c +20 −8
  44. drivers/gpu/drm/drm_displayid.c +53 −9
  45. drivers/gpu/drm/drm_dumb_buffers.c +1 −4
  46. drivers/gpu/drm/drm_edid.c +56 −9
  47. drivers/gpu/drm/drm_gem.c +18 −7
  48. drivers/gpu/drm/drm_gem_shmem_helper.c +36 −29
  49. drivers/gpu/drm/drm_gem_vram_helper.c +11 −0
  50. drivers/gpu/drm/drm_internal.h +0 −3
  51. drivers/gpu/drm/drm_modes.c +1 −2
  52. drivers/gpu/drm/drm_of.c +51 −0
  53. drivers/gpu/drm/drm_probe_helper.c +3 −2
  54. drivers/gpu/drm/drm_suballoc.c +457 −0
  55. drivers/gpu/drm/i915/gem/i915_gem_ttm.c +11 −4
  56. drivers/gpu/drm/i915/gem/i915_gem_ttm.h +1 −1
  57. drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +4 −0
  58. drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c +5 −2
  59. drivers/gpu/drm/meson/meson_venc.c +2 −2
  60. drivers/gpu/drm/mgag200/mgag200_drv.h +3 −0
  61. drivers/gpu/drm/mgag200/mgag200_mode.c +12 −10
  62. drivers/gpu/drm/nouveau/nouveau_bo.c +0 −3
  63. drivers/gpu/drm/nouveau/nouveau_hwmon.c +5 −5
  64. drivers/gpu/drm/nouveau/nouveau_led.h +1 −1
  65. drivers/gpu/drm/panel/Kconfig +11 −0
  66. drivers/gpu/drm/panel/Makefile +1 −0
  67. drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +208 −1
  68. drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c +522 −0
  69. drivers/gpu/drm/panfrost/panfrost_drv.c +2 −9
  70. drivers/gpu/drm/qxl/qxl_ttm.c +11 −0
  71. drivers/gpu/drm/radeon/Kconfig +1 −0
  72. drivers/gpu/drm/radeon/radeon.h +8 −47
  73. drivers/gpu/drm/radeon/radeon_ib.c +5 −7
  74. drivers/gpu/drm/radeon/radeon_object.h +15 −10
  75. drivers/gpu/drm/radeon/radeon_sa.c +26 −290
  76. drivers/gpu/drm/radeon/radeon_semaphore.c +2 −2
  77. drivers/gpu/drm/radeon/radeon_ttm.c +2 −5
  78. drivers/gpu/drm/rockchip/rockchip_drm_gem.c +10 −6
  79. drivers/gpu/drm/rockchip/rockchip_drm_vop.c +2 −5
  80. drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +63 −17
  81. drivers/gpu/drm/rockchip/rockchip_rgb.c +10 −9
  82. drivers/gpu/drm/rockchip/rockchip_rgb.h +4 −2
  83. drivers/gpu/drm/scheduler/sched_main.c +29 −0
  84. drivers/gpu/drm/tests/drm_format_helper_test.c +5 −5
  85. drivers/gpu/drm/tidss/tidss_dispc.c +4 −8
  86. drivers/gpu/drm/tidss/tidss_dispc.h +4 −4
  87. drivers/gpu/drm/tidss/tidss_plane.c +11 −9
  88. drivers/gpu/drm/tiny/simpledrm.c +22 −9
  89. drivers/gpu/drm/ttm/ttm_bo.c +13 −17
  90. drivers/gpu/drm/ttm/ttm_bo_util.c +4 −15
  91. drivers/gpu/drm/ttm/ttm_resource.c +0 −1
  92. drivers/gpu/drm/v3d/v3d_gem.c +8 −18
  93. drivers/gpu/drm/vc4/vc4_drv.h +1 −1
  94. drivers/gpu/drm/vc4/vc4_gem.c +18 −60
  95. drivers/gpu/drm/vc4/vc4_hdmi.c +13 −33
  96. drivers/gpu/drm/vc4/vc4_hdmi.h +0 −1
  97. drivers/gpu/drm/vc4/vc4_validate.c +2 −2
  98. drivers/gpu/drm/vgem/vgem_fence.c +1 −0
  99. drivers/gpu/drm/virtio/Kconfig +11 −0
  100. drivers/gpu/drm/virtio/virtgpu_display.c +6 −0
  101. drivers/gpu/drm/virtio/virtgpu_drv.c +4 −0
  102. drivers/gpu/drm/virtio/virtgpu_kms.c +23 −16
  103. drivers/gpu/drm/virtio/virtgpu_vq.c +1 −2
  104. drivers/gpu/drm/vmwgfx/Makefile +1 −1
  105. drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +196 −211
  106. drivers/gpu/drm/vmwgfx/vmwgfx_bo.h +203 −0
  107. drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c +7 −7
  108. drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +20 −33
  109. drivers/gpu/drm/vmwgfx/vmwgfx_context.c +20 −16
  110. drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +38 −27
  111. drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +16 −10
  112. drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +48 −197
  113. drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +58 −47
  114. drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +1 −1
  115. drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +36 −55
  116. drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +77 −155
  117. drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +18 −25
  118. drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +49 −8
  119. drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +24 −21
  120. drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +11 −11
  121. drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +33 −35
  122. drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +128 −118
  123. drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h +6 −4
  124. drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +28 −25
  125. drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +38 −29
  126. drivers/gpu/drm/vmwgfx/vmwgfx_so.c +4 −2
  127. drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +45 −278
  128. drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c +11 −9
  129. drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +55 −52
  130. drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +34 −100
  131. drivers/gpu/drm/vmwgfx/vmwgfx_va.c +4 −2
  132. drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +56 −94
  133. drivers/gpu/drm/vmwgfx/vmwgfx_validation.h +3 −7
  134. drivers/ps3/ps3av.c +5 −4
  135. drivers/video/Kconfig +3 −0
  136. drivers/video/Makefile +1 −0
  137. drivers/video/cmdline.c +133 −0
  138. drivers/video/fbdev/Kconfig +1 −4
  139. drivers/video/fbdev/core/Makefile +1 −2
  140. drivers/video/fbdev/core/fb_cmdline.c +24 −70
  141. drivers/video/fbdev/core/modedb.c +6 −2
  142. include/drm/drm_atomic_helper.h +26 −0
  143. include/drm/drm_displayid.h +11 −1
  144. include/drm/drm_drv.h +0 −19
  145. include/drm/drm_edid.h +9 −3
  146. include/drm/drm_gem.h +12 −0
  147. include/drm/drm_gem_shmem_helper.h +15 −15
  148. include/drm/drm_modeset_helper_vtables.h +28 −1
  149. include/drm/drm_of.h +12 −0
  150. include/drm/drm_suballoc.h +108 −0
  151. include/drm/gpu_scheduler.h +6 −0
  152. include/drm/ttm/ttm_device.h +1 −1
  153. include/linux/fb.h +0 −1
  154. include/uapi/drm/drm.h +55 −2
  155. include/video/cmdline.h +20 −0
Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml+63−0
@@ -0,0 +1,63 @@
1+# SPDX-License-Identifier: GPL-2.0
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/display/bridge/analogix,dp.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Analogix Display Port bridge
8+
9+maintainers:
10+ - Rob Herring <robh@kernel.org>
11+
12+properties:
13+ reg:
14+ maxItems: 1
15+
16+ interrupts:
17+ maxItems: 1
18+
19+ clocks: true
20+
21+ clock-names: true
22+
23+ phys: true
24+
25+ phy-names:
26+ const: dp
27+
28+ force-hpd:
29+ description:
30+ Indicate driver need force hpd when hpd detect failed, this
31+ is used for some eDP screen which don not have a hpd signal.
32+
33+ hpd-gpios:
34+ description:
35+ Hotplug detect GPIO.
36+ Indicates which GPIO should be used for hotplug detection
37+
38+ ports:
39+ $ref: /schemas/graph.yaml#/properties/ports
40+
41+ properties:
42+ port@0:
43+ $ref: /schemas/graph.yaml#/properties/port
44+ description:
45+ Input node to receive pixel data.
46+
47+ port@1:
48+ $ref: /schemas/graph.yaml#/properties/port
49+ description:
50+ Port node with one endpoint connected to a dp-connector node.
51+
52+ required:
53+ - port@0
54+ - port@1
55+
56+required:
57+ - reg
58+ - interrupts
59+ - clock-names
60+ - clocks
61+ - ports
62+
63+additionalProperties: true
Documentation/devicetree/bindings/display/bridge/analogix_dp.txt+0−51
@@ -1,51 +0,0 @@
1−Analogix Display Port bridge bindings
2−
3−Required properties for dp-controller:
4− -compatible:
5− platform specific such as:
6− * "samsung,exynos5-dp"
7− * "rockchip,rk3288-dp"
8− * "rockchip,rk3399-edp"
9− -reg:
10− physical base address of the controller and length
11− of memory mapped region.
12− -interrupts:
13− interrupt combiner values.
14− -clocks:
15− from common clock binding: handle to dp clock.
16− -clock-names:
17− from common clock binding: Shall be "dp".
18− -phys:
19− from general PHY binding: the phandle for the PHY device.
20− -phy-names:
21− from general PHY binding: Should be "dp".
22−
23−Optional properties for dp-controller:
24− -force-hpd:
25− Indicate driver need force hpd when hpd detect failed, this
26− is used for some eDP screen which don't have hpd signal.
27− -hpd-gpios:
28− Hotplug detect GPIO.
29− Indicates which GPIO should be used for hotplug detection
30− -port@[X]: SoC specific port nodes with endpoint definitions as defined
31− in Documentation/devicetree/bindings/media/video-interfaces.txt,
32− please refer to the SoC specific binding document:
33− * Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
34− * Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
35−
36−[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
37−-------------------------------------------------------------------------------
38−
39−Example:
40−
41− dp-controller {
42− compatible = "samsung,exynos5-dp";
43− reg = <0x145b0000 0x10000>;
44− interrupts = <10 3>;
45− interrupt-parent = <&combiner>;
46− clocks = <&clock 342>;
47− clock-names = "dp";
48−
49− phys = <&dp_phy>;
50− phy-names = "dp";
51− };
Documentation/devicetree/bindings/display/bridge/snps,dw-mipi-dsi.yaml+3−13
@@ -26,19 +26,9 @@ properties: · 25 unmodified lines
2626 reg:
2727 maxItems: 1
2828
29− clocks:
30− items:
31− - description: Module clock
32− - description: DSI bus clock for either AHB and APB
33− - description: Pixel clock for the DPI/RGB input
34− minItems: 2
35−
36− clock-names:
37− items:
38− - const: ref
39− - const: pclk
40− - const: px_clk
41− minItems: 2
29+ clocks: true
30+
31+ clock-names: true
4232
4333 resets:
4434 maxItems: 1
Documentation/devicetree/bindings/display/dsi-controller.yaml+9−9
@@ -30,6 +30,15 @@ properties: · 29 unmodified lines
3030 $nodename:
3131 pattern: "^dsi(@.*)?$"
3232
33+ clock-master:
34+ type: boolean
35+ description:
36+ Should be enabled if the host is being used in conjunction with
37+ another DSI host to drive the same peripheral. Hardware supporting
38+ such a configuration generally requires the data on both the busses
39+ to be driven by the same clock. Only the DSI host instance
40+ controlling this clock should contain this property.
41+
3342 "#address-cells":
3443 const: 1
3544
@@ -52,15 +61,6 @@ patternProperties: · 16 unmodified lines
5261 case the reg property can take multiple entries, one for each virtual
5362 channel that the peripheral responds to.
5463
55− clock-master:
56− type: boolean
57− description:
58− Should be enabled if the host is being used in conjunction with
59− another DSI host to drive the same peripheral. Hardware supporting
60− such a configuration generally requires the data on both the busses
61− to be driven by the same clock. Only the DSI host instance
62− controlling this clock should contain this property.
63−
6464 enforce-video-mode:
6565 type: boolean
6666 description:
Documentation/devicetree/bindings/display/exynos/exynos_dp.txt+1−1
@@ -50,7 +50,7 @@ Optional properties for dp-controller: · 49 unmodified lines
5050 Documentation/devicetree/bindings/display/panel/display-timing.txt
5151
5252 For the below properties, please refer to Analogix DP binding document:
53− * Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
53+ * Documentation/devicetree/bindings/display/bridge/analogix,dp.yaml
5454 -phys (required)
5555 -phy-names (required)
5656 -hpd-gpios (optional)
Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml+2−0
@@ -17,6 +17,8 @@ properties: · 16 unmodified lines
1717 items:
1818 - enum:
1919 - chongzhou,cz101b4001
20+ - radxa,display-10hd-ad001
21+ - radxa,display-8hd-ad002
2022 - const: jadard,jd9365da-h3
2123
2224 reg: true
Documentation/devicetree/bindings/display/panel/samsung,ams495qa01.yaml+57−0
@@ -0,0 +1,57 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/display/panel/samsung,ams495qa01.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Samsung AMS495QA01 panel with Magnachip D53E6EA8966 controller
8+
9+maintainers:
10+ - Chris Morgan <macromorgan@hotmail.com>
11+
12+allOf:
13+ - $ref: panel-common.yaml#
14+
15+properties:
16+ compatible:
17+ const: samsung,ams495qa01
18+
19+ reg: true
20+ reset-gpios:
21+ description: reset gpio, must be GPIO_ACTIVE_LOW
22+ elvdd-supply:
23+ description: regulator that supplies voltage to the panel display
24+ enable-gpios: true
25+ port: true
26+ vdd-supply:
27+ description: regulator that supplies voltage to panel logic
28+
29+required:
30+ - compatible
31+ - reg
32+ - reset-gpios
33+ - vdd-supply
34+
35+additionalProperties: false
36+
37+examples:
38+ - |
39+ #include <dt-bindings/gpio/gpio.h>
40+ spi {
41+ #address-cells = <1>;
42+ #size-cells = <0>;
43+ panel@0 {
44+ compatible = "samsung,ams495qa01";
45+ reg = <0>;
46+ reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
47+ vdd-supply = <&vcc_3v3>;
48+
49+ port {
50+ mipi_in_panel: endpoint {
51+ remote-endpoint = <&mipi_out_panel>;
52+ };
53+ };
54+ };
55+ };
56+
57+...
Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt+0−98
@@ -1,98 +0,0 @@
1−Rockchip RK3288 specific extensions to the Analogix Display Port
2−================================
3−
4−Required properties:
5−- compatible: "rockchip,rk3288-dp",
6− "rockchip,rk3399-edp";
7−
8−- reg: physical base address of the controller and length
9−
10−- clocks: from common clock binding: handle to dp clock.
11− of memory mapped region.
12−
13−- clock-names: from common clock binding:
14− Required elements: "dp" "pclk"
15−
16−- resets: Must contain an entry for each entry in reset-names.
17− See ../reset/reset.txt for details.
18−
19−- pinctrl-names: Names corresponding to the chip hotplug pinctrl states.
20−- pinctrl-0: pin-control mode. should be <&edp_hpd>
21−
22−- reset-names: Must include the name "dp"
23−
24−- rockchip,grf: this soc should set GRF regs, so need get grf here.
25−
26−- ports: there are 2 port nodes with endpoint definitions as defined in
27− Documentation/devicetree/bindings/media/video-interfaces.txt.
28− Port 0: contained 2 endpoints, connecting to the output of vop.
29− Port 1: contained 1 endpoint, connecting to the input of panel.
30−
31−Optional property for different chips:
32−- clocks: from common clock binding: handle to grf_vio clock.
33−
34−- clock-names: from common clock binding:
35− Required elements: "grf"
36−
37−For the below properties, please refer to Analogix DP binding document:
38− * Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
39−- phys (required)
40−- phy-names (required)
41−- hpd-gpios (optional)
42−- force-hpd (optional)
43−-------------------------------------------------------------------------------
44−
45−Example:
46− dp-controller: dp@ff970000 {
47− compatible = "rockchip,rk3288-dp";
48− reg = <0xff970000 0x4000>;
49− interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
50− clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
51− clock-names = "dp", "pclk";
52− phys = <&dp_phy>;
53− phy-names = "dp";
54−
55− rockchip,grf = <&grf>;
56− resets = <&cru 111>;
57− reset-names = "dp";
58−
59− pinctrl-names = "default";
60− pinctrl-0 = <&edp_hpd>;
61−
62−
63− ports {
64− #address-cells = <1>;
65− #size-cells = <0>;
66− edp_in: port@0 {
67− reg = <0>;
68− #address-cells = <1>;
69− #size-cells = <0>;
70− edp_in_vopb: endpoint@0 {
71− reg = <0>;
72− remote-endpoint = <&vopb_out_edp>;
73− };
74− edp_in_vopl: endpoint@1 {
75− reg = <1>;
76− remote-endpoint = <&vopl_out_edp>;
77− };
78− };
79−
80− edp_out: port@1 {
81− reg = <1>;
82− #address-cells = <1>;
83− #size-cells = <0>;
84− edp_out_panel: endpoint {
85− reg = <0>;
86− remote-endpoint = <&panel_in_edp>
87− };
88− };
89− };
90− };
91−
92− pinctrl {
93− edp {
94− edp_hpd: edp-hpd {
95− rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_none>;
96− };
97− };
98− };
Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt+0−94
@@ -1,94 +0,0 @@
1−Rockchip specific extensions to the Synopsys Designware MIPI DSI
2−================================
3−
4−Required properties:
5−- #address-cells: Should be <1>.
6−- #size-cells: Should be <0>.
7−- compatible: one of
8− "rockchip,px30-mipi-dsi", "snps,dw-mipi-dsi"
9− "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"
10− "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi"
11− "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi"
12−- reg: Represent the physical address range of the controller.
13−- interrupts: Represent the controller's interrupt to the CPU(s).
14−- clocks, clock-names: Phandles to the controller's pll reference
15− clock(ref) when using an internal dphy and APB clock(pclk).
16− For RK3399, a phy config clock (phy_cfg) and a grf clock(grf)
17− are required. As described in [1].
18−- rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
19−- ports: contain a port node with endpoint definitions as defined in [2].
20− For vopb,set the reg = <0> and set the reg = <1> for vopl.
21−- video port 0 for the VOP input, the remote endpoint maybe vopb or vopl
22−- video port 1 for either a panel or subsequent encoder
23−
24−Optional properties:
25−- phys: from general PHY binding: the phandle for the PHY device.
26−- phy-names: Should be "dphy" if phys references an external phy.
27−- #phy-cells: Defined when used as ISP phy, should be 0.
28−- power-domains: a phandle to mipi dsi power domain node.
29−- resets: list of phandle + reset specifier pairs, as described in [3].
30−- reset-names: string reset name, must be "apb".
31−
32−[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
33−[2] Documentation/devicetree/bindings/media/video-interfaces.txt
34−[3] Documentation/devicetree/bindings/reset/reset.txt
35−
36−Example:
37− mipi_dsi: mipi@ff960000 {
38− #address-cells = <1>;
39− #size-cells = <0>;
40− compatible = "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi";
41− reg = <0xff960000 0x4000>;
42− interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
43− clocks = <&cru SCLK_MIPI_24M>, <&cru PCLK_MIPI_DSI0>;
44− clock-names = "ref", "pclk";
45− resets = <&cru SRST_MIPIDSI0>;
46− reset-names = "apb";
47− rockchip,grf = <&grf>;
48−
49− ports {
50− #address-cells = <1>;
51− #size-cells = <0>;
52−
53− mipi_in: port@0 {
54− reg = <0>;
55− #address-cells = <1>;
56− #size-cells = <0>;
57−
58− mipi_in_vopb: endpoint@0 {
59− reg = <0>;
60− remote-endpoint = <&vopb_out_mipi>;
61− };
62− mipi_in_vopl: endpoint@1 {
63− reg = <1>;
64− remote-endpoint = <&vopl_out_mipi>;
65− };
66− };
67−
68− mipi_out: port@1 {
69− reg = <1>;
70− #address-cells = <1>;
71− #size-cells = <0>;
72−
73− mipi_out_panel: endpoint {
74− remote-endpoint = <&panel_in_mipi>;
75− };
76− };
77− };
78−
79− panel {
80− compatible ="boe,tv080wum-nl0";
81− reg = <0>;
82−
83− enable-gpios = <&gpio7 3 GPIO_ACTIVE_HIGH>;
84− pinctrl-names = "default";
85− pinctrl-0 = <&lcd_en>;
86− backlight = <&backlight>;
87−
88− port {
89− panel_in_mipi: endpoint {
90− remote-endpoint = <&mipi_out_panel>;
91− };
92− };
93− };
94− };
Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml+103−0
@@ -0,0 +1,103 @@
1+# SPDX-License-Identifier: GPL-2.0
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/display/rockchip/rockchip,analogix-dp.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Rockchip specific extensions to the Analogix Display Port
8+
9+maintainers:
10+ - Sandy Huang <hjc@rock-chips.com>
11+ - Heiko Stuebner <heiko@sntech.de>
12+
13+properties:
14+ compatible:
15+ enum:
16+ - rockchip,rk3288-dp
17+ - rockchip,rk3399-edp
18+
19+ clocks:
20+ minItems: 2
21+ maxItems: 3
22+
23+ clock-names:
24+ minItems: 2
25+ items:
26+ - const: dp
27+ - const: pclk
28+ - const: grf
29+
30+ power-domains:
31+ maxItems: 1
32+
33+ resets:
34+ maxItems: 1
35+
36+ reset-names:
37+ const: dp
38+
39+ rockchip,grf:
40+ $ref: /schemas/types.yaml#/definitions/phandle
41+ description:
42+ This SoC makes use of GRF regs.
43+
44+required:
45+ - compatible
46+ - clocks
47+ - clock-names
48+ - resets
49+ - reset-names
50+ - rockchip,grf
51+
52+allOf:
53+ - $ref: /schemas/display/bridge/analogix,dp.yaml#
54+
55+unevaluatedProperties: false
56+
57+examples:
58+ - |
59+ #include <dt-bindings/clock/rk3288-cru.h>
60+ #include <dt-bindings/interrupt-controller/arm-gic.h>
61+ #include <dt-bindings/interrupt-controller/irq.h>
62+ dp@ff970000 {
63+ compatible = "rockchip,rk3288-dp";
64+ reg = <0xff970000 0x4000>;
65+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
66+ clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
67+ clock-names = "dp", "pclk";
68+ phys = <&dp_phy>;
69+ phy-names = "dp";
70+ resets = <&cru 111>;
71+ reset-names = "dp";
72+ rockchip,grf = <&grf>;
73+ pinctrl-0 = <&edp_hpd>;
74+ pinctrl-names = "default";
75+
76+ ports {
77+ #address-cells = <1>;
78+ #size-cells = <0>;
79+
80+ edp_in: port@0 {
81+ reg = <0>;
82+ #address-cells = <1>;
83+ #size-cells = <0>;
84+
85+ edp_in_vopb: endpoint@0 {
86+ reg = <0>;
87+ remote-endpoint = <&vopb_out_edp>;
88+ };
89+ edp_in_vopl: endpoint@1 {
90+ reg = <1>;
91+ remote-endpoint = <&vopl_out_edp>;
92+ };
93+ };
94+
95+ edp_out: port@1 {
96+ reg = <1>;
97+
98+ edp_out_panel: endpoint {
99+ remote-endpoint = <&panel_in_edp>;
100+ };
101+ };
102+ };
103+ };
Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml+166−0
@@ -0,0 +1,166 @@
1+# SPDX-License-Identifier: GPL-2.0
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/display/rockchip/rockchip,dw-mipi-dsi.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Rockchip specific extensions to the Synopsys Designware MIPI DSI
8+
9+maintainers:
10+ - Sandy Huang <hjc@rock-chips.com>
11+ - Heiko Stuebner <heiko@sntech.de>
12+
13+properties:
14+ compatible:
15+ items:
16+ - enum:
17+ - rockchip,px30-mipi-dsi
18+ - rockchip,rk3288-mipi-dsi
19+ - rockchip,rk3399-mipi-dsi
20+ - rockchip,rk3568-mipi-dsi
21+ - const: snps,dw-mipi-dsi
22+
23+ interrupts:
24+ maxItems: 1
25+
26+ clocks:
27+ minItems: 1
28+ maxItems: 4
29+
30+ clock-names:
31+ oneOf:
32+ - minItems: 2
33+ items:
34+ - const: ref
35+ - const: pclk
36+ - const: phy_cfg
37+ - const: grf
38+ - const: pclk
39+
40+ rockchip,grf:
41+ $ref: /schemas/types.yaml#/definitions/phandle
42+ description:
43+ This SoC uses GRF regs to switch between vopl/vopb.
44+
45+ phys:
46+ maxItems: 1
47+
48+ phy-names:
49+ const: dphy
50+
51+ "#phy-cells":
52+ const: 0
53+ description:
54+ Defined when in use as ISP phy.
55+
56+ power-domains:
57+ maxItems: 1
58+
59+ "#address-cells":
60+ const: 1
61+
62+ "#size-cells":
63+ const: 0
64+
65+required:
66+ - compatible
67+ - clocks
68+ - clock-names
69+ - rockchip,grf
70+
71+allOf:
72+ - $ref: /schemas/display/bridge/snps,dw-mipi-dsi.yaml#
73+ - if:
74+ properties:
75+ compatible:
76+ contains:
77+ enum:
78+ - rockchip,px30-mipi-dsi
79+ - rockchip,rk3568-mipi-dsi
80+
81+ then:
82+ properties:
83+ clocks:
84+ maxItems: 1
85+
86+ clock-names:
87+ maxItems: 1
88+
89+ required:
90+ - phys
91+ - phy-names
92+
93+ - if:
94+ properties:
95+ compatible:
96+ contains:
97+ const: rockchip,rk3288-mipi-dsi
98+
99+ then:
100+ properties:
101+ clocks:
102+ maxItems: 2
103+
104+ clock-names:
105+ maxItems: 2
106+
107+ - if:
108+ properties:
109+ compatible:
110+ contains:
111+ const: rockchip,rk3399-mipi-dsi
112+
113+ then:
114+ properties:
115+ clocks:
116+ minItems: 4
117+
118+ clock-names:
119+ minItems: 4
120+
121+unevaluatedProperties: false
122+
123+examples:
124+ - |
125+ #include <dt-bindings/clock/rk3288-cru.h>
126+ #include <dt-bindings/interrupt-controller/arm-gic.h>
127+ #include <dt-bindings/interrupt-controller/irq.h>
128+
129+ mipi_dsi: dsi@ff960000 {
130+ compatible = "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi";
131+ reg = <0xff960000 0x4000>;
132+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
133+ clocks = <&cru SCLK_MIPIDSI_24M>, <&cru PCLK_MIPI_DSI0>;
134+ clock-names = "ref", "pclk";
135+ resets = <&cru SRST_MIPIDSI0>;
136+ reset-names = "apb";
137+ rockchip,grf = <&grf>;
138+
139+ ports {
140+ #address-cells = <1>;
141+ #size-cells = <0>;
142+
143+ mipi_in: port@0 {
144+ reg = <0>;
145+ #address-cells = <1>;
146+ #size-cells = <0>;
147+
148+ mipi_in_vopb: endpoint@0 {
149+ reg = <0>;
150+ remote-endpoint = <&vopb_out_mipi>;
151+ };
152+ mipi_in_vopl: endpoint@1 {
153+ reg = <1>;
154+ remote-endpoint = <&vopl_out_mipi>;
155+ };
156+ };
157+
158+ mipi_out: port@1 {
159+ reg = <1>;
160+
161+ mipi_out_panel: endpoint {
162+ remote-endpoint = <&panel_in_mipi>;
163+ };
164+ };
165+ };
166+ };
Documentation/devicetree/bindings/display/rockchip/rockchip,lvds.yaml+170−0
@@ -0,0 +1,170 @@
1+# SPDX-License-Identifier: GPL-2.0
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/display/rockchip/rockchip,lvds.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Rockchip low-voltage differential signal (LVDS) transmitter
8+
9+maintainers:
10+ - Sandy Huang <hjc@rock-chips.com>
11+ - Heiko Stuebner <heiko@sntech.de>
12+
13+properties:
14+ compatible:
15+ enum:
16+ - rockchip,px30-lvds
17+ - rockchip,rk3288-lvds
18+
19+ reg:
20+ maxItems: 1
21+
22+ clocks:
23+ maxItems: 1
24+
25+ clock-names:
26+ const: pclk_lvds
27+
28+ avdd1v0-supply:
29+ description: 1.0V analog power.
30+
31+ avdd1v8-supply:
32+ description: 1.8V analog power.
33+
34+ avdd3v3-supply:
35+ description: 3.3V analog power.
36+
37+ rockchip,grf:
38+ $ref: /schemas/types.yaml#/definitions/phandle
39+ description: Phandle to the general register files syscon.
40+
41+ rockchip,output:
42+ $ref: /schemas/types.yaml#/definitions/string
43+ enum: [rgb, lvds, duallvds]
44+ description: This describes the output interface.
45+
46+ phys:
47+ maxItems: 1
48+
49+ phy-names:
50+ const: dphy
51+
52+ pinctrl-names:
53+ const: lcdc
54+
55+ pinctrl-0: true
56+
57+ power-domains:
58+ maxItems: 1
59+
60+ ports:
61+ $ref: /schemas/graph.yaml#/properties/ports
62+
63+ properties:
64+ port@0:
65+ $ref: /schemas/graph.yaml#/properties/port
66+ description:
67+ Video port 0 for the VOP input.
68+ The remote endpoint maybe vopb or vopl.
69+
70+ port@1:
71+ $ref: /schemas/graph.yaml#/properties/port
72+ description:
73+ Video port 1 for either a panel or subsequent encoder.
74+
75+ required:
76+ - port@0
77+ - port@1
78+
79+required:
80+ - compatible
81+ - rockchip,grf
82+ - rockchip,output
83+ - ports
84+
85+allOf:
86+ - if:
87+ properties:
88+ compatible:
89+ contains:
90+ const: rockchip,px30-lvds
91+
92+ then:
93+ properties:
94+ reg: false
95+ clocks: false
96+ clock-names: false
97+ avdd1v0-supply: false
98+ avdd1v8-supply: false
99+ avdd3v3-supply: false
100+
101+ required:
102+ - phys
103+ - phy-names
104+
105+ - if:
106+ properties:
107+ compatible:
108+ contains:
109+ const: rockchip,rk3288-lvds
110+
111+ then:
112+ properties:
113+ phys: false
114+ phy-names: false
115+
116+ required:
117+ - reg
118+ - clocks
119+ - clock-names
120+ - avdd1v0-supply
121+ - avdd1v8-supply
122+ - avdd3v3-supply
123+
124+additionalProperties: false
125+
126+examples:
127+ - |
128+ #include <dt-bindings/clock/rk3288-cru.h>
129+
130+ lvds: lvds@ff96c000 {
131+ compatible = "rockchip,rk3288-lvds";
132+ reg = <0xff96c000 0x4000>;
133+ clocks = <&cru PCLK_LVDS_PHY>;
134+ clock-names = "pclk_lvds";
135+ avdd1v0-supply = <&vdd10_lcd>;
136+ avdd1v8-supply = <&vcc18_lcd>;
137+ avdd3v3-supply = <&vcca_33>;
138+ pinctrl-names = "lcdc";
139+ pinctrl-0 = <&lcdc_ctl>;
140+ rockchip,grf = <&grf>;
141+ rockchip,output = "rgb";
142+
143+ ports {
144+ #address-cells = <1>;
145+ #size-cells = <0>;
146+
147+ lvds_in: port@0 {
148+ reg = <0>;
149+ #address-cells = <1>;
150+ #size-cells = <0>;
151+
152+ lvds_in_vopb: endpoint@0 {
153+ reg = <0>;
154+ remote-endpoint = <&vopb_out_lvds>;
155+ };
156+ lvds_in_vopl: endpoint@1 {
157+ reg = <1>;
158+ remote-endpoint = <&vopl_out_lvds>;
159+ };
160+ };
161+
162+ lvds_out: port@1 {
163+ reg = <1>;
164+
165+ lvds_out_panel: endpoint {
166+ remote-endpoint = <&panel_in_lvds>;
167+ };
168+ };
169+ };
170+ };
Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt+0−92
@@ -1,92 +0,0 @@
1−Rockchip RK3288 LVDS interface
2−================================
3−
4−Required properties:
5−- compatible: matching the soc type, one of
6− - "rockchip,rk3288-lvds";
7− - "rockchip,px30-lvds";
8−
9−- reg: physical base address of the controller and length
10− of memory mapped region.
11−- clocks: must include clock specifiers corresponding to entries in the
12− clock-names property.
13−- clock-names: must contain "pclk_lvds"
14−
15−- avdd1v0-supply: regulator phandle for 1.0V analog power
16−- avdd1v8-supply: regulator phandle for 1.8V analog power
17−- avdd3v3-supply: regulator phandle for 3.3V analog power
18−
19−- rockchip,grf: phandle to the general register files syscon
20−- rockchip,output: "rgb", "lvds" or "duallvds", This describes the output interface
21−
22−- phys: LVDS/DSI DPHY (px30 only)
23−- phy-names: name of the PHY, must be "dphy" (px30 only)
24−
25−Optional properties:
26−- pinctrl-names: must contain a "lcdc" entry.
27−- pinctrl-0: pin control group to be used for this controller.
28−
29−Required nodes:
30−
31−The lvds has two video ports as described by
32− Documentation/devicetree/bindings/media/video-interfaces.txt
33−Their connections are modeled using the OF graph bindings specified in
34− Documentation/devicetree/bindings/graph.txt.
35−
36−- video port 0 for the VOP input, the remote endpoint maybe vopb or vopl
37−- video port 1 for either a panel or subsequent encoder
38−
39−Example:
40−
41−lvds_panel: lvds-panel {
42− compatible = "auo,b101ean01";
43− enable-gpios = <&gpio7 21 GPIO_ACTIVE_HIGH>;
44− data-mapping = "jeida-24";
45−
46− ports {
47− panel_in_lvds: endpoint {
48− remote-endpoint = <&lvds_out_panel>;
49− };
50− };
51−};
52−
53−For Rockchip RK3288:
54−
55− lvds: lvds@ff96c000 {
56− compatible = "rockchip,rk3288-lvds";
57− rockchip,grf = <&grf>;
58− reg = <0xff96c000 0x4000>;
59− clocks = <&cru PCLK_LVDS_PHY>;
60− clock-names = "pclk_lvds";
61− pinctrl-names = "lcdc";
62− pinctrl-0 = <&lcdc_ctl>;
63− avdd1v0-supply = <&vdd10_lcd>;
64− avdd1v8-supply = <&vcc18_lcd>;
65− avdd3v3-supply = <&vcca_33>;
66− rockchip,output = "rgb";
67− ports {
68− #address-cells = <1>;
69− #size-cells = <0>;
70−
71− lvds_in: port@0 {
72− reg = <0>;
73−
74− lvds_in_vopb: endpoint@0 {
75− reg = <0>;
76− remote-endpoint = <&vopb_out_lvds>;
77− };
78− lvds_in_vopl: endpoint@1 {
79− reg = <1>;
80− remote-endpoint = <&vopl_out_lvds>;
81− };
82− };
83−
84− lvds_out: port@1 {
85− reg = <1>;
86−
87− lvds_out_panel: endpoint {
88− remote-endpoint = <&panel_in_lvds>;
89− };
90− };
91− };
92− };
Documentation/devicetree/bindings/display/simple-framebuffer.yaml+9−0
@@ -26,6 +26,11 @@ description: |+ · 25 unmodified lines
2626 over control to a driver for the real hardware. The bindings for the
2727 hw nodes must specify which node is considered the primary node.
2828
29+ If a panel node is given, then the driver uses this to configure the
30+ physical width and height of the display. If no panel node is given,
31+ then the driver uses the width and height properties of the simplefb
32+ node to estimate it.
33+
2934 It is advised to add display# aliases to help the OS determine how
3035 to number things. If display# aliases are used, then if the simplefb
3136 node contains a display property then the /aliases/display# path
@@ -117,6 +122,10 @@ properties: · 85 unmodified lines
117122 $ref: /schemas/types.yaml#/definitions/phandle
118123 description: Primary display hardware node
119124
125+ panel:
126+ $ref: /schemas/types.yaml#/definitions/phandle
127+ description: Display panel node
128+
120129 allwinner,pipeline:
121130 description: Pipeline used by the framebuffer on Allwinner SoCs
122131 enum:
Documentation/devicetree/bindings/soc/rockchip/grf.yaml+7−3
@@ -80,13 +80,17 @@ allOf: · 79 unmodified lines
8080 properties:
8181 compatible:
8282 contains:
83− const: rockchip,px30-grf
83+ enum:
84+ - rockchip,px30-grf
8485
8586 then:
8687 properties:
8788 lvds:
88− description:
89− Documentation/devicetree/bindings/display/rockchip/rockchip-lvds.txt
89+ type: object
90+
91+ $ref: /schemas/display/rockchip/rockchip,lvds.yaml#
92+
93+ unevaluatedProperties: false
9094
9195 - if:
9296 properties:
MAINTAINERS+1−1
@@ -7044,7 +7044,7 @@ F: Documentation/devicetree/bindings/display/xlnx/ · 7043 unmodified lines
70447044 F: drivers/gpu/drm/xlnx/
70457045
70467046 DRM PANEL DRIVERS
7047−M: Thierry Reding <thierry.reding@gmail.com>
7047+M: Neil Armstrong <neil.armstrong@linaro.org>
70487048 R: Sam Ravnborg <sam@ravnborg.org>
70497049 L: dri-devel@lists.freedesktop.org
70507050 S: Maintained
drivers/accel/ivpu/ivpu_pm.c+0−10
@@ -237,8 +237,6 @@ int ivpu_rpm_get(struct ivpu_device *vdev) · 236 unmodified lines
237237 {
238238 int ret;
239239
240− ivpu_dbg(vdev, RPM, "rpm_get count %d\n", atomic_read(&vdev->drm.dev->power.usage_count));
241−
242240 ret = pm_runtime_resume_and_get(vdev->drm.dev);
243241 if (!drm_WARN_ON(&vdev->drm, ret < 0))
244242 vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
@@ -248,8 +246,6 @@ int ivpu_rpm_get(struct ivpu_device *vdev) · 3 unmodified lines
248246
249247 void ivpu_rpm_put(struct ivpu_device *vdev)
250248 {
251− ivpu_dbg(vdev, RPM, "rpm_put count %d\n", atomic_read(&vdev->drm.dev->power.usage_count));
252−
253249 pm_runtime_mark_last_busy(vdev->drm.dev);
254250 pm_runtime_put_autosuspend(vdev->drm.dev);
255251 }
@@ -314,16 +310,10 @@ void ivpu_pm_enable(struct ivpu_device *vdev) · 58 unmodified lines
314310 pm_runtime_allow(dev);
315311 pm_runtime_mark_last_busy(dev);
316312 pm_runtime_put_autosuspend(dev);
317−
318− ivpu_dbg(vdev, RPM, "Enable RPM count %d\n", atomic_read(&dev->power.usage_count));
319313 }
320314
321315 void ivpu_pm_disable(struct ivpu_device *vdev)
322316 {
323− struct device *dev = vdev->drm.dev;
324−
325− ivpu_dbg(vdev, RPM, "Disable RPM count %d\n", atomic_read(&dev->power.usage_count));
326−
327317 pm_runtime_get_noresume(vdev->drm.dev);
328318 pm_runtime_forbid(vdev->drm.dev);
329319 }
drivers/dma-buf/dma-buf.c+1−1
@@ -828,7 +828,7 @@ static struct sg_table * __map_dma_buf(struct dma_buf_attachment *attach, · 827 unmodified lines
828828 * - dma_buf_attach()
829829 * - dma_buf_dynamic_attach()
830830 * - dma_buf_detach()
831− * - dma_buf_export(
831+ * - dma_buf_export()
832832 * - dma_buf_fd()
833833 * - dma_buf_get()
834834 * - dma_buf_put()
drivers/gpu/drm/Kconfig+5−1
@@ -10,13 +10,13 @@ menuconfig DRM · 9 unmodified lines
1010 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
1111 select DRM_PANEL_ORIENTATION_QUIRKS
1212 select HDMI
13− select FB_CMDLINE
1413 select I2C
1514 select DMA_SHARED_BUFFER
1615 select SYNC_FILE
1716 # gallium uses SYS_kcmp for os_same_file_description() to de-duplicate
1817 # device and dmabuf fd. Let's make sure that is available for our userspace.
1918 select KCMP
19+ select VIDEO_CMDLINE
2020 select VIDEO_NOMODESET
2121 help
2222 Kernel-level support for the Direct Rendering Infrastructure (DRI)
@@ -232,6 +232,10 @@ config DRM_GEM_SHMEM_HELPER · 209 unmodified lines
232232 help
233233 Choose this if you need the GEM shmem helper functions
234234
235+config DRM_SUBALLOC_HELPER
236+ tristate
237+ depends on DRM
238+
235239 config DRM_SCHED
236240 tristate
237241 depends on DRM
drivers/gpu/drm/Makefile+3−0
@@ -88,6 +88,9 @@ obj-$(CONFIG_DRM_GEM_DMA_HELPER) += drm_dma_helper.o · 87 unmodified lines
8888 drm_shmem_helper-y := drm_gem_shmem_helper.o
8989 obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o
9090
91+drm_suballoc_helper-y := drm_suballoc.o
92+obj-$(CONFIG_DRM_SUBALLOC_HELPER) += drm_suballoc_helper.o
93+
9194 drm_vram_helper-y := drm_gem_vram_helper.o
9295 obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
9396
drivers/gpu/drm/amd/amdgpu/Kconfig+1−0
@@ -19,6 +19,7 @@ config DRM_AMDGPU · 18 unmodified lines
1919 select BACKLIGHT_CLASS_DEVICE
2020 select INTERVAL_TREE
2121 select DRM_BUDDY
22+ select DRM_SUBALLOC_HELPER
2223 # amdgpu depends on ACPI_VIDEO when ACPI is enabled, for select to work
2324 # ACPI_VIDEO's dependencies must also be selected.
2425 select INPUT if ACPI
drivers/gpu/drm/amd/amdgpu/amdgpu.h+4−22
@@ -424,29 +424,11 @@ struct amdgpu_clock { · 423 unmodified lines
424424 * alignment).
425425 */
426426
427−#define AMDGPU_SA_NUM_FENCE_LISTS 32
428−
429427 struct amdgpu_sa_manager {
430− wait_queue_head_t wq;
431− struct amdgpu_bo *bo;
432− struct list_head *hole;
433− struct list_head flist[AMDGPU_SA_NUM_FENCE_LISTS];
434− struct list_head olist;
435− unsigned size;
436− uint64_t gpu_addr;
437− void *cpu_ptr;
438− uint32_t domain;
439− uint32_t align;
440−};
441−
442−/* sub-allocation buffer */
443−struct amdgpu_sa_bo {
444− struct list_head olist;
445− struct list_head flist;
446− struct amdgpu_sa_manager *manager;
447− unsigned soffset;
448− unsigned eoffset;
449− struct dma_fence *fence;
428+ struct drm_suballoc_manager base;
429+ struct amdgpu_bo *bo;
430+ uint64_t gpu_addr;
431+ void *cpu_ptr;
450432 };
451433
452434 int amdgpu_fence_slab_init(void);
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c+2−3
@@ -69,7 +69,7 @@ int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 68 unmodified lines
6969
7070 if (size) {
7171 r = amdgpu_sa_bo_new(&adev->ib_pools[pool_type],
72− &ib->sa_bo, size, 256);
72+ &ib->sa_bo, size);
7373 if (r) {
7474 dev_err(adev->dev, "failed to get a new IB (%d)\n", r);
7575 return r;
@@ -309,8 +309,7 @@ int amdgpu_ib_pool_init(struct amdgpu_device *adev) · 233 unmodified lines
309309
310310 for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) {
311311 r = amdgpu_sa_bo_manager_init(adev, &adev->ib_pools[i],
312− AMDGPU_IB_POOL_SIZE,
313− AMDGPU_GPU_PAGE_SIZE,
312+ AMDGPU_IB_POOL_SIZE, 256,
314313 AMDGPU_GEM_DOMAIN_GTT);
315314 if (r)
316315 goto error;
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c+3−6
@@ -600,7 +600,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev, · 599 unmodified lines
600600
601601 if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
602602 bo->tbo.resource->mem_type == TTM_PL_VRAM &&
603− bo->tbo.resource->start < adev->gmc.visible_vram_size >> PAGE_SHIFT)
603+ amdgpu_bo_in_cpu_visible_vram(bo))
604604 amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved,
605605 ctx.bytes_moved);
606606 else
@@ -1346,7 +1346,6 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) · 739 unmodified lines
13461346 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
13471347 struct ttm_operation_ctx ctx = { false, false };
13481348 struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
1349− unsigned long offset;
13501349 int r;
13511350
13521351 /* Remember that this BO was accessed by the CPU */
@@ -1355,8 +1354,7 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) · 2 unmodified lines
13551354 if (bo->resource->mem_type != TTM_PL_VRAM)
13561355 return 0;
13571356
1358− offset = bo->resource->start << PAGE_SHIFT;
1359− if ((offset + bo->base.size) <= adev->gmc.visible_vram_size)
1357+ if (amdgpu_bo_in_cpu_visible_vram(abo))
13601358 return 0;
13611359
13621360 /* Can't move a pinned BO to visible VRAM */
@@ -1378,10 +1376,9 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) · 15 unmodified lines
13781376 else if (unlikely(r))
13791377 return VM_FAULT_SIGBUS;
13801378
1381− offset = bo->resource->start << PAGE_SHIFT;
13821379 /* this should never happen */
13831380 if (bo->resource->mem_type == TTM_PL_VRAM &&
1384− (offset + bo->base.size) > adev->gmc.visible_vram_size)
1381+ !amdgpu_bo_in_cpu_visible_vram(abo))
13851382 return VM_FAULT_SIGBUS;
13861383
13871384 ttm_bo_move_to_lru_tail_unlocked(bo);
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h+15−8
@@ -336,15 +336,22 @@ uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev, · 335 unmodified lines
336336 /*
337337 * sub allocation
338338 */
339+static inline struct amdgpu_sa_manager *
340+to_amdgpu_sa_manager(struct drm_suballoc_manager *manager)
341+{
342+ return container_of(manager, struct amdgpu_sa_manager, base);
343+}
339344
340−static inline uint64_t amdgpu_sa_bo_gpu_addr(struct amdgpu_sa_bo *sa_bo)
345+static inline uint64_t amdgpu_sa_bo_gpu_addr(struct drm_suballoc *sa_bo)
341346 {
342− return sa_bo->manager->gpu_addr + sa_bo->soffset;
347+ return to_amdgpu_sa_manager(sa_bo->manager)->gpu_addr +
348+ drm_suballoc_soffset(sa_bo);
343349 }
344350
345−static inline void * amdgpu_sa_bo_cpu_addr(struct amdgpu_sa_bo *sa_bo)
351+static inline void *amdgpu_sa_bo_cpu_addr(struct drm_suballoc *sa_bo)
346352 {
347− return sa_bo->manager->cpu_ptr + sa_bo->soffset;
353+ return to_amdgpu_sa_manager(sa_bo->manager)->cpu_ptr +
354+ drm_suballoc_soffset(sa_bo);
348355 }
349356
350357 int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev,
@@ -355,11 +362,11 @@ void amdgpu_sa_bo_manager_fini(struct amdgpu_device *adev, · 4 unmodified lines
355362 int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev,
356363 struct amdgpu_sa_manager *sa_manager);
357364 int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
358− struct amdgpu_sa_bo **sa_bo,
359− unsigned size, unsigned align);
365+ struct drm_suballoc **sa_bo,
366+ unsigned int size);
360367 void amdgpu_sa_bo_free(struct amdgpu_device *adev,
361− struct amdgpu_sa_bo **sa_bo,
362− struct dma_fence *fence);
368+ struct drm_suballoc **sa_bo,
369+ struct dma_fence *fence);
363370 #if defined(CONFIG_DEBUG_FS)
364371 void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
365372 struct seq_file *m);
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h+2−1
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include <drm/amdgpu_drm.h>
2828 #include <drm/gpu_scheduler.h>
2929 #include <drm/drm_print.h>
30+#include <drm/drm_suballoc.h>
3031
3132 struct amdgpu_device;
3233 struct amdgpu_ring;
@@ -92,7 +93,7 @@ enum amdgpu_ib_pool_type { · 59 unmodified lines
9293 };
9394
9495 struct amdgpu_ib {
95− struct amdgpu_sa_bo *sa_bo;
96+ struct drm_suballoc *sa_bo;
9697 uint32_t length_dw;
9798 uint64_t gpu_addr;
9899 uint32_t *ptr;
drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c+21−303
@@ -44,327 +44,63 @@ · 43 unmodified lines
4444
4545 #include "amdgpu.h"
4646
47−static void amdgpu_sa_bo_remove_locked(struct amdgpu_sa_bo *sa_bo);
48−static void amdgpu_sa_bo_try_free(struct amdgpu_sa_manager *sa_manager);
49−
5047 int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev,
5148 struct amdgpu_sa_manager *sa_manager,
52− unsigned size, u32 align, u32 domain)
49+ unsigned int size, u32 suballoc_align, u32 domain)
5350 {
54− int i, r;
55−
56− init_waitqueue_head(&sa_manager->wq);
57− sa_manager->bo = NULL;
58− sa_manager->size = size;
59− sa_manager->domain = domain;
60− sa_manager->align = align;
61− sa_manager->hole = &sa_manager->olist;
62− INIT_LIST_HEAD(&sa_manager->olist);
63− for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i)
64− INIT_LIST_HEAD(&sa_manager->flist[i]);
51+ int r;
6552
66− r = amdgpu_bo_create_kernel(adev, size, align, domain, &sa_manager->bo,
67− &sa_manager->gpu_addr, &sa_manager->cpu_ptr);
53+ r = amdgpu_bo_create_kernel(adev, size, AMDGPU_GPU_PAGE_SIZE, domain,
54+ &sa_manager->bo, &sa_manager->gpu_addr,
55+ &sa_manager->cpu_ptr);
6856 if (r) {
6957 dev_err(adev->dev, "(%d) failed to allocate bo for manager\n", r);
7058 return r;
7159 }
7260
73− memset(sa_manager->cpu_ptr, 0, sa_manager->size);
61+ memset(sa_manager->cpu_ptr, 0, size);
62+ drm_suballoc_manager_init(&sa_manager->base, size, suballoc_align);
7463 return r;
7564 }
7665
7766 void amdgpu_sa_bo_manager_fini(struct amdgpu_device *adev,
7867 struct amdgpu_sa_manager *sa_manager)
7968 {
80− struct amdgpu_sa_bo *sa_bo, *tmp;
81−
8269 if (sa_manager->bo == NULL) {
8370 dev_err(adev->dev, "no bo for sa manager\n");
8471 return;
8572 }
8673
87− if (!list_empty(&sa_manager->olist)) {
88− sa_manager->hole = &sa_manager->olist,
89− amdgpu_sa_bo_try_free(sa_manager);
90− if (!list_empty(&sa_manager->olist)) {
91− dev_err(adev->dev, "sa_manager is not empty, clearing anyway\n");
92− }
93− }
94− list_for_each_entry_safe(sa_bo, tmp, &sa_manager->olist, olist) {
95− amdgpu_sa_bo_remove_locked(sa_bo);
96− }
74+ drm_suballoc_manager_fini(&sa_manager->base);
9775
9876 amdgpu_bo_free_kernel(&sa_manager->bo, &sa_manager->gpu_addr, &sa_manager->cpu_ptr);
99− sa_manager->size = 0;
10077 }
10178
102−static void amdgpu_sa_bo_remove_locked(struct amdgpu_sa_bo *sa_bo)
103−{
104− struct amdgpu_sa_manager *sa_manager = sa_bo->manager;
105− if (sa_manager->hole == &sa_bo->olist) {
106− sa_manager->hole = sa_bo->olist.prev;
107− }
108− list_del_init(&sa_bo->olist);
109− list_del_init(&sa_bo->flist);
110− dma_fence_put(sa_bo->fence);
111− kfree(sa_bo);
112−}
113−
114−static void amdgpu_sa_bo_try_free(struct amdgpu_sa_manager *sa_manager)
79+int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
80+ struct drm_suballoc **sa_bo,
81+ unsigned int size)
11582 {
116− struct amdgpu_sa_bo *sa_bo, *tmp;
83+ struct drm_suballoc *sa = drm_suballoc_new(&sa_manager->base, size,
84+ GFP_KERNEL, true, 0);
11785
118− if (sa_manager->hole->next == &sa_manager->olist)
119− return;
86+ if (IS_ERR(sa)) {
87+ *sa_bo = NULL;
12088
121− sa_bo = list_entry(sa_manager->hole->next, struct amdgpu_sa_bo, olist);
122− list_for_each_entry_safe_from(sa_bo, tmp, &sa_manager->olist, olist) {
123− if (sa_bo->fence == NULL ||
124− !dma_fence_is_signaled(sa_bo->fence)) {
125− return;
126− }
127− amdgpu_sa_bo_remove_locked(sa_bo);
89+ return PTR_ERR(sa);
12890 }
129−}
13091
131−static inline unsigned amdgpu_sa_bo_hole_soffset(struct amdgpu_sa_manager *sa_manager)
132−{
133− struct list_head *hole = sa_manager->hole;
134−
135− if (hole != &sa_manager->olist) {
136− return list_entry(hole, struct amdgpu_sa_bo, olist)->eoffset;
137− }
92+ *sa_bo = sa;
13893 return 0;
13994 }
14095
141−static inline unsigned amdgpu_sa_bo_hole_eoffset(struct amdgpu_sa_manager *sa_manager)
142−{
143− struct list_head *hole = sa_manager->hole;
144−
145− if (hole->next != &sa_manager->olist) {
146− return list_entry(hole->next, struct amdgpu_sa_bo, olist)->soffset;
147− }
148− return sa_manager->size;
149−}
150−
151−static bool amdgpu_sa_bo_try_alloc(struct amdgpu_sa_manager *sa_manager,
152− struct amdgpu_sa_bo *sa_bo,
153− unsigned size, unsigned align)
154−{
155− unsigned soffset, eoffset, wasted;
156−
157− soffset = amdgpu_sa_bo_hole_soffset(sa_manager);
158− eoffset = amdgpu_sa_bo_hole_eoffset(sa_manager);
159− wasted = (align - (soffset % align)) % align;
160−
161− if ((eoffset - soffset) >= (size + wasted)) {
162− soffset += wasted;
163−
164− sa_bo->manager = sa_manager;
165− sa_bo->soffset = soffset;
166− sa_bo->eoffset = soffset + size;
167− list_add(&sa_bo->olist, sa_manager->hole);
168− INIT_LIST_HEAD(&sa_bo->flist);
169− sa_manager->hole = &sa_bo->olist;
170− return true;
171− }
172− return false;
173−}
174−
175−/**
176− * amdgpu_sa_event - Check if we can stop waiting
177− *
178− * @sa_manager: pointer to the sa_manager
179− * @size: number of bytes we want to allocate
180− * @align: alignment we need to match
181− *
182− * Check if either there is a fence we can wait for or
183− * enough free memory to satisfy the allocation directly
184− */
185−static bool amdgpu_sa_event(struct amdgpu_sa_manager *sa_manager,
186− unsigned size, unsigned align)
187−{
188− unsigned soffset, eoffset, wasted;
189− int i;
190−
191− for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i)
192− if (!list_empty(&sa_manager->flist[i]))
193− return true;
194−
195− soffset = amdgpu_sa_bo_hole_soffset(sa_manager);
196− eoffset = amdgpu_sa_bo_hole_eoffset(sa_manager);
197− wasted = (align - (soffset % align)) % align;
198−
199− if ((eoffset - soffset) >= (size + wasted)) {
200− return true;
201− }
202−
203− return false;
204−}
205−
206−static bool amdgpu_sa_bo_next_hole(struct amdgpu_sa_manager *sa_manager,
207− struct dma_fence **fences,
208− unsigned *tries)
209−{
210− struct amdgpu_sa_bo *best_bo = NULL;
211− unsigned i, soffset, best, tmp;
212−
213− /* if hole points to the end of the buffer */
214− if (sa_manager->hole->next == &sa_manager->olist) {
215− /* try again with its beginning */
216− sa_manager->hole = &sa_manager->olist;
217− return true;
218− }
219−
220− soffset = amdgpu_sa_bo_hole_soffset(sa_manager);
221− /* to handle wrap around we add sa_manager->size */
222− best = sa_manager->size * 2;
223− /* go over all fence list and try to find the closest sa_bo
224− * of the current last
225− */
226− for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i) {
227− struct amdgpu_sa_bo *sa_bo;
228−
229− fences[i] = NULL;
230−
231− if (list_empty(&sa_manager->flist[i]))
232− continue;
233−
234− sa_bo = list_first_entry(&sa_manager->flist[i],
235− struct amdgpu_sa_bo, flist);
236−
237− if (!dma_fence_is_signaled(sa_bo->fence)) {
238− fences[i] = sa_bo->fence;
239− continue;
240− }
241−
242− /* limit the number of tries each ring gets */
243− if (tries[i] > 2) {
244− continue;
245− }
246−
247− tmp = sa_bo->soffset;
248− if (tmp < soffset) {
249− /* wrap around, pretend it's after */
250− tmp += sa_manager->size;
251− }
252− tmp -= soffset;
253− if (tmp < best) {
254− /* this sa bo is the closest one */
255− best = tmp;
256− best_bo = sa_bo;
257− }
258− }
259−
260− if (best_bo) {
261− uint32_t idx = best_bo->fence->context;
262−
263− idx %= AMDGPU_SA_NUM_FENCE_LISTS;
264− ++tries[idx];
265− sa_manager->hole = best_bo->olist.prev;
266−
267− /* we knew that this one is signaled,
268− so it's save to remote it */
269− amdgpu_sa_bo_remove_locked(best_bo);
270− return true;
271− }
272− return false;
273−}
274−
275−int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
276− struct amdgpu_sa_bo **sa_bo,
277− unsigned size, unsigned align)
278−{
279− struct dma_fence *fences[AMDGPU_SA_NUM_FENCE_LISTS];
280− unsigned tries[AMDGPU_SA_NUM_FENCE_LISTS];
281− unsigned count;
282− int i, r;
283− signed long t;
284−
285− if (WARN_ON_ONCE(align > sa_manager->align))
286− return -EINVAL;
287−
288− if (WARN_ON_ONCE(size > sa_manager->size))
289− return -EINVAL;
290−
291− *sa_bo = kmalloc(sizeof(struct amdgpu_sa_bo), GFP_KERNEL);
292− if (!(*sa_bo))
293− return -ENOMEM;
294− (*sa_bo)->manager = sa_manager;
295− (*sa_bo)->fence = NULL;
296− INIT_LIST_HEAD(&(*sa_bo)->olist);
297− INIT_LIST_HEAD(&(*sa_bo)->flist);
298−
299− spin_lock(&sa_manager->wq.lock);
300− do {
301− for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i)
302− tries[i] = 0;
303−
304− do {
305− amdgpu_sa_bo_try_free(sa_manager);
306−
307− if (amdgpu_sa_bo_try_alloc(sa_manager, *sa_bo,
308− size, align)) {
309− spin_unlock(&sa_manager->wq.lock);
310− return 0;
311− }
312−
313− /* see if we can skip over some allocations */
314− } while (amdgpu_sa_bo_next_hole(sa_manager, fences, tries));
315−
316− for (i = 0, count = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i)
317− if (fences[i])
318− fences[count++] = dma_fence_get(fences[i]);
319−
320− if (count) {
321− spin_unlock(&sa_manager->wq.lock);
322− t = dma_fence_wait_any_timeout(fences, count, false,
323− MAX_SCHEDULE_TIMEOUT,
324− NULL);
325− for (i = 0; i < count; ++i)
326− dma_fence_put(fences[i]);
327−
328− r = (t > 0) ? 0 : t;
329− spin_lock(&sa_manager->wq.lock);
330− } else {
331− /* if we have nothing to wait for block */
332− r = wait_event_interruptible_locked(
333− sa_manager->wq,
334− amdgpu_sa_event(sa_manager, size, align)
335− );
336− }
337−
338− } while (!r);
339−
340− spin_unlock(&sa_manager->wq.lock);
341− kfree(*sa_bo);
342− *sa_bo = NULL;
343− return r;
344−}
345−
346−void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo,
96+void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct drm_suballoc **sa_bo,
34797 struct dma_fence *fence)
34898 {
349− struct amdgpu_sa_manager *sa_manager;
350−
35199 if (sa_bo == NULL || *sa_bo == NULL) {
352100 return;
353101 }
354102
355− sa_manager = (*sa_bo)->manager;
356− spin_lock(&sa_manager->wq.lock);
357− if (fence && !dma_fence_is_signaled(fence)) {
358− uint32_t idx;
359−
360− (*sa_bo)->fence = dma_fence_get(fence);
361− idx = fence->context % AMDGPU_SA_NUM_FENCE_LISTS;
362− list_add_tail(&(*sa_bo)->flist, &sa_manager->flist[idx]);
363− } else {
364− amdgpu_sa_bo_remove_locked(*sa_bo);
365− }
366− wake_up_all_locked(&sa_manager->wq);
367− spin_unlock(&sa_manager->wq.lock);
103+ drm_suballoc_free(*sa_bo, fence);
368104 *sa_bo = NULL;
369105 }
370106
@@ -373,26 +109,8 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo, · 2 unmodified lines
373109 void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
374110 struct seq_file *m)
375111 {
376− struct amdgpu_sa_bo *i;
377−
378− spin_lock(&sa_manager->wq.lock);
379− list_for_each_entry(i, &sa_manager->olist, olist) {
380− uint64_t soffset = i->soffset + sa_manager->gpu_addr;
381− uint64_t eoffset = i->eoffset + sa_manager->gpu_addr;
382− if (&i->olist == sa_manager->hole) {
383− seq_printf(m, ">");
384− } else {
385− seq_printf(m, " ");
386− }
387− seq_printf(m, "[0x%010llx 0x%010llx] size %8lld",
388− soffset, eoffset, eoffset - soffset);
112+ struct drm_printer p = drm_seq_file_printer(m);
389113
390− if (i->fence)
391− seq_printf(m, " protected by 0x%016llx on context %llu",
392− i->fence->seqno, i->fence->context);
393−
394− seq_printf(m, "\n");
395− }
396− spin_unlock(&sa_manager->wq.lock);
114+ drm_suballoc_dump_debug_info(&sa_manager->base, &p, sa_manager->gpu_addr);
397115 }
398116 #endif
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c+0−4
@@ -466,11 +466,7 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict, · 465 unmodified lines
466466 return r;
467467 }
468468
469− /* Can't move a pinned BO */
470469 abo = ttm_to_amdgpu_bo(bo);
471− if (WARN_ON_ONCE(abo->tbo.pin_count > 0))
472− return -EINVAL;
473−
474470 adev = amdgpu_ttm_adev(bo->bdev);
475471
476472 if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM &&
drivers/gpu/drm/arm/malidp_drv.c+1−1
@@ -649,7 +649,7 @@ static ssize_t core_id_show(struct device *dev, struct device_attribute *attr, · 648 unmodified lines
649649 struct drm_device *drm = dev_get_drvdata(dev);
650650 struct malidp_drm *malidp = drm_to_malidp(drm);
651651
652− return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id);
652+ return sysfs_emit(buf, "%08x\n", malidp->core_id);
653653 }
654654
655655 static DEVICE_ATTR_RO(core_id);
drivers/gpu/drm/ast/ast_dp.c+5−5
@@ -9,7 +9,7 @@ · 8 unmodified lines
99
1010 int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
1111 {
12− struct ast_private *ast = to_ast_private(dev);
12+ struct ast_device *ast = to_ast_device(dev);
1313 u8 i = 0, j = 0;
1414
1515 /*
@@ -125,7 +125,7 @@ void ast_dp_launch(struct drm_device *dev, u8 bPower) · 109 unmodified lines
125125 u8 bDPTX = 0;
126126 u8 bDPExecute = 1;
127127
128− struct ast_private *ast = to_ast_private(dev);
128+ struct ast_device *ast = to_ast_device(dev);
129129 // S3 come back, need more time to wait BMC ready.
130130 if (bPower)
131131 WaitCount = 300;
@@ -172,7 +172,7 @@ void ast_dp_launch(struct drm_device *dev, u8 bPower) · 40 unmodified lines
172172
173173 void ast_dp_power_on_off(struct drm_device *dev, bool on)
174174 {
175− struct ast_private *ast = to_ast_private(dev);
175+ struct ast_device *ast = to_ast_device(dev);
176176 // Read and Turn off DP PHY sleep
177177 u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, AST_DP_VIDEO_ENABLE);
178178
@@ -188,7 +188,7 @@ void ast_dp_power_on_off(struct drm_device *dev, bool on) · 9 unmodified lines
188188
189189 void ast_dp_set_on_off(struct drm_device *dev, bool on)
190190 {
191− struct ast_private *ast = to_ast_private(dev);
191+ struct ast_device *ast = to_ast_device(dev);
192192 u8 video_on_off = on;
193193
194194 // Video On/Off
@@ -208,7 +208,7 @@ void ast_dp_set_on_off(struct drm_device *dev, bool on) · 13 unmodified lines
208208
209209 void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode)
210210 {
211− struct ast_private *ast = to_ast_private(crtc->dev);
211+ struct ast_device *ast = to_ast_device(crtc->dev);
212212
213213 u32 ulRefreshRateIndex;
214214 u8 ModeIdx;
drivers/gpu/drm/ast/ast_dp501.c+20−20
@@ -10,7 +10,7 @@ MODULE_FIRMWARE("ast_dp501_fw.bin"); · 9 unmodified lines
1010
1111 static void ast_release_firmware(void *data)
1212 {
13− struct ast_private *ast = data;
13+ struct ast_device *ast = data;
1414
1515 release_firmware(ast->dp501_fw);
1616 ast->dp501_fw = NULL;
@@ -18,7 +18,7 @@ static void ast_release_firmware(void *data) · 1 unmodified line
1818
1919 static int ast_load_dp501_microcode(struct drm_device *dev)
2020 {
21− struct ast_private *ast = to_ast_private(dev);
21+ struct ast_device *ast = to_ast_device(dev);
2222 int ret;
2323
2424 ret = request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);
@@ -28,7 +28,7 @@ static int ast_load_dp501_microcode(struct drm_device *dev) · 3 unmodified lines
2828 return devm_add_action_or_reset(dev->dev, ast_release_firmware, ast);
2929 }
3030
31−static void send_ack(struct ast_private *ast)
31+static void send_ack(struct ast_device *ast)
3232 {
3333 u8 sendack;
3434 sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
@@ -36,7 +36,7 @@ static void send_ack(struct ast_private *ast) · 1 unmodified line
3636 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
3737 }
3838
39−static void send_nack(struct ast_private *ast)
39+static void send_nack(struct ast_device *ast)
4040 {
4141 u8 sendack;
4242 sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
@@ -44,7 +44,7 @@ static void send_nack(struct ast_private *ast) · 1 unmodified line
4444 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
4545 }
4646
47−static bool wait_ack(struct ast_private *ast)
47+static bool wait_ack(struct ast_device *ast)
4848 {
4949 u8 waitack;
5050 u32 retry = 0;
@@ -60,7 +60,7 @@ static bool wait_ack(struct ast_private *ast) · 9 unmodified lines
6060 return false;
6161 }
6262
63−static bool wait_nack(struct ast_private *ast)
63+static bool wait_nack(struct ast_device *ast)
6464 {
6565 u8 waitack;
6666 u32 retry = 0;
@@ -76,18 +76,18 @@ static bool wait_nack(struct ast_private *ast) · 9 unmodified lines
7676 return false;
7777 }
7878
79−static void set_cmd_trigger(struct ast_private *ast)
79+static void set_cmd_trigger(struct ast_device *ast)
8080 {
8181 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40);
8282 }
8383
84−static void clear_cmd_trigger(struct ast_private *ast)
84+static void clear_cmd_trigger(struct ast_device *ast)
8585 {
8686 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00);
8787 }
8888
8989 #if 0
90−static bool wait_fw_ready(struct ast_private *ast)
90+static bool wait_fw_ready(struct ast_device *ast)
9191 {
9292 u8 waitready;
9393 u32 retry = 0;
@@ -106,7 +106,7 @@ static bool wait_fw_ready(struct ast_private *ast) · 12 unmodified lines
106106
107107 static bool ast_write_cmd(struct drm_device *dev, u8 data)
108108 {
109− struct ast_private *ast = to_ast_private(dev);
109+ struct ast_device *ast = to_ast_device(dev);
110110 int retry = 0;
111111 if (wait_nack(ast)) {
112112 send_nack(ast);
@@ -128,7 +128,7 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data) · 15 unmodified lines
128128
129129 static bool ast_write_data(struct drm_device *dev, u8 data)
130130 {
131− struct ast_private *ast = to_ast_private(dev);
131+ struct ast_device *ast = to_ast_device(dev);
132132
133133 if (wait_nack(ast)) {
134134 send_nack(ast);
@@ -146,7 +146,7 @@ static bool ast_write_data(struct drm_device *dev, u8 data) · 11 unmodified lines
146146 #if 0
147147 static bool ast_read_data(struct drm_device *dev, u8 *data)
148148 {
149− struct ast_private *ast = to_ast_private(dev);
149+ struct ast_device *ast = to_ast_device(dev);
150150 u8 tmp;
151151
152152 *data = 0;
@@ -163,7 +163,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data) · 10 unmodified lines
163163 return true;
164164 }
165165
166−static void clear_cmd(struct ast_private *ast)
166+static void clear_cmd(struct ast_device *ast)
167167 {
168168 send_nack(ast);
169169 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00);
@@ -178,14 +178,14 @@ void ast_set_dp501_video_output(struct drm_device *dev, u8 mode) · 8 unmodified lines
178178 msleep(10);
179179 }
180180
181−static u32 get_fw_base(struct ast_private *ast)
181+static u32 get_fw_base(struct ast_device *ast)
182182 {
183183 return ast_mindwm(ast, 0x1e6e2104) & 0x7fffffff;
184184 }
185185
186186 bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
187187 {
188− struct ast_private *ast = to_ast_private(dev);
188+ struct ast_device *ast = to_ast_device(dev);
189189 u32 i, data;
190190 u32 boot_address;
191191
@@ -204,7 +204,7 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) · 12 unmodified lines
204204
205205 static bool ast_launch_m68k(struct drm_device *dev)
206206 {
207− struct ast_private *ast = to_ast_private(dev);
207+ struct ast_device *ast = to_ast_device(dev);
208208 u32 i, data, len = 0;
209209 u32 boot_address;
210210 u8 *fw_addr = NULL;
@@ -274,7 +274,7 @@ static bool ast_launch_m68k(struct drm_device *dev) · 63 unmodified lines
274274
275275 bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
276276 {
277− struct ast_private *ast = to_ast_private(dev);
277+ struct ast_device *ast = to_ast_device(dev);
278278 u32 i, boot_address, offset, data;
279279 u32 *pEDIDidx;
280280
@@ -334,7 +334,7 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata) · 53 unmodified lines
334334
335335 static bool ast_init_dvo(struct drm_device *dev)
336336 {
337− struct ast_private *ast = to_ast_private(dev);
337+ struct ast_device *ast = to_ast_device(dev);
338338 u8 jreg;
339339 u32 data;
340340 ast_write32(ast, 0xf004, 0x1e6e0000);
@@ -407,7 +407,7 @@ static bool ast_init_dvo(struct drm_device *dev) · 66 unmodified lines
407407
408408 static void ast_init_analog(struct drm_device *dev)
409409 {
410− struct ast_private *ast = to_ast_private(dev);
410+ struct ast_device *ast = to_ast_device(dev);
411411 u32 data;
412412
413413 /*
@@ -434,7 +434,7 @@ static void ast_init_analog(struct drm_device *dev) · 20 unmodified lines
434434
435435 void ast_init_3rdtx(struct drm_device *dev)
436436 {
437− struct ast_private *ast = to_ast_private(dev);
437+ struct ast_device *ast = to_ast_device(dev);
438438 u8 jreg;
439439
440440 if (ast->chip == AST2300 || ast->chip == AST2400) {
drivers/gpu/drm/ast/ast_drv.c+1−1
@@ -105,7 +105,7 @@ static int ast_remove_conflicting_framebuffers(struct pci_dev *pdev) · 104 unmodified lines
105105
106106 static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
107107 {
108− struct ast_private *ast;
108+ struct ast_device *ast;
109109 struct drm_device *dev;
110110 int ret;
111111
drivers/gpu/drm/ast/ast_drv.h+33−51
@@ -157,7 +157,7 @@ to_ast_sil164_connector(struct drm_connector *connector) · 156 unmodified lines
157157 * Device
158158 */
159159
160−struct ast_private {
160+struct ast_device {
161161 struct drm_device base;
162162
163163 struct mutex ioregs_lock; /* Protects access to I/O registers in ioregs */
@@ -210,14 +210,14 @@ struct ast_private { · 46 unmodified lines
210210 const struct firmware *dp501_fw; /* dp501 fw */
211211 };
212212
213−static inline struct ast_private *to_ast_private(struct drm_device *dev)
213+static inline struct ast_device *to_ast_device(struct drm_device *dev)
214214 {
215− return container_of(dev, struct ast_private, base);
215+ return container_of(dev, struct ast_device, base);
216216 }
217217
218−struct ast_private *ast_device_create(const struct drm_driver *drv,
219− struct pci_dev *pdev,
220− unsigned long flags);
218+struct ast_device *ast_device_create(const struct drm_driver *drv,
219+ struct pci_dev *pdev,
220+ unsigned long flags);
221221
222222 #define AST_IO_AR_PORT_WRITE (0x40)
223223 #define AST_IO_MISC_PORT_WRITE (0x42)
@@ -238,62 +238,44 @@ struct ast_private *ast_device_create(const struct drm_driver *drv, · 14 unmodified lines
238238 #define AST_IO_VGACRCB_HWC_ENABLED BIT(1)
239239 #define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */
240240
241−#define __ast_read(x) \
242−static inline u##x ast_read##x(struct ast_private *ast, u32 reg) { \
243−u##x val = 0;\
244−val = ioread##x(ast->regs + reg); \
245−return val;\
241+static inline u32 ast_read32(struct ast_device *ast, u32 reg)
242+{
243+ return ioread32(ast->regs + reg);
246244 }
247245
248−__ast_read(8);
249−__ast_read(16);
250−__ast_read(32)
251−
252−#define __ast_io_read(x) \
253−static inline u##x ast_io_read##x(struct ast_private *ast, u32 reg) { \
254−u##x val = 0;\
255−val = ioread##x(ast->ioregs + reg); \
256−return val;\
246+static inline void ast_write32(struct ast_device *ast, u32 reg, u32 val)
247+{
248+ iowrite32(val, ast->regs + reg);
257249 }
258250
259−__ast_io_read(8);
260−__ast_io_read(16);
261−__ast_io_read(32);
262−
263−#define __ast_write(x) \
264−static inline void ast_write##x(struct ast_private *ast, u32 reg, u##x val) {\
265− iowrite##x(val, ast->regs + reg);\
266− }
267−
268−__ast_write(8);
269−__ast_write(16);
270−__ast_write(32);
271−
272−#define __ast_io_write(x) \
273−static inline void ast_io_write##x(struct ast_private *ast, u32 reg, u##x val) {\
274− iowrite##x(val, ast->ioregs + reg);\
275− }
251+static inline u8 ast_io_read8(struct ast_device *ast, u32 reg)
252+{
253+ return ioread8(ast->ioregs + reg);
254+}
276255
277−__ast_io_write(8);
278−__ast_io_write(16);
279−#undef __ast_io_write
256+static inline void ast_io_write8(struct ast_device *ast, u32 reg, u8 val)
257+{
258+ iowrite8(val, ast->ioregs + reg);
259+}
280260
281−static inline void ast_set_index_reg(struct ast_private *ast,
261+static inline void ast_set_index_reg(struct ast_device *ast,
282262 uint32_t base, uint8_t index,
283263 uint8_t val)
284264 {
285− ast_io_write16(ast, base, ((u16)val << 8) | index);
265+ ast_io_write8(ast, base, index);
266+ ++base;
267+ ast_io_write8(ast, base, val);
286268 }
287269
288−void ast_set_index_reg_mask(struct ast_private *ast,
270+void ast_set_index_reg_mask(struct ast_device *ast,
289271 uint32_t base, uint8_t index,
290272 uint8_t mask, uint8_t val);
291−uint8_t ast_get_index_reg(struct ast_private *ast,
273+uint8_t ast_get_index_reg(struct ast_device *ast,
292274 uint32_t base, uint8_t index);
293−uint8_t ast_get_index_reg_mask(struct ast_private *ast,
275+uint8_t ast_get_index_reg_mask(struct ast_device *ast,
294276 uint32_t base, uint8_t index, uint8_t mask);
295277
296−static inline void ast_open_key(struct ast_private *ast)
278+static inline void ast_open_key(struct ast_device *ast)
297279 {
298280 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8);
299281 }
@@ -352,7 +334,7 @@ struct ast_crtc_state { · 52 unmodified lines
352334
353335 #define to_ast_crtc_state(state) container_of(state, struct ast_crtc_state, base)
354336
355−int ast_mode_config_init(struct ast_private *ast);
337+int ast_mode_config_init(struct ast_device *ast);
356338
357339 #define AST_MM_ALIGN_SHIFT 4
358340 #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1)
@@ -476,16 +458,16 @@ int ast_mode_config_init(struct ast_private *ast); · 117 unmodified lines
476458 #define ASTDP_1366x768_60 0x1E
477459 #define ASTDP_1152x864_75 0x1F
478460
479−int ast_mm_init(struct ast_private *ast);
461+int ast_mm_init(struct ast_device *ast);
480462
481463 /* ast post */
482464 void ast_enable_vga(struct drm_device *dev);
483465 void ast_enable_mmio(struct drm_device *dev);
484466 bool ast_is_vga_enabled(struct drm_device *dev);
485467 void ast_post_gpu(struct drm_device *dev);
486−u32 ast_mindwm(struct ast_private *ast, u32 r);
487−void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
488−void ast_patch_ahb_2500(struct ast_private *ast);
468+u32 ast_mindwm(struct ast_device *ast, u32 r);
469+void ast_moutdwm(struct ast_device *ast, u32 r, u32 v);
470+void ast_patch_ahb_2500(struct ast_device *ast);
489471 /* ast dp501 */
490472 void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
491473 bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
drivers/gpu/drm/ast/ast_i2c.c+4−4
@@ -29,7 +29,7 @@ · 28 unmodified lines
2929 static void ast_i2c_setsda(void *i2c_priv, int data)
3030 {
3131 struct ast_i2c_chan *i2c = i2c_priv;
32− struct ast_private *ast = to_ast_private(i2c->dev);
32+ struct ast_device *ast = to_ast_device(i2c->dev);
3333 int i;
3434 u8 ujcrb7, jtemp;
3535
@@ -45,7 +45,7 @@ static void ast_i2c_setsda(void *i2c_priv, int data) · 9 unmodified lines
4545 static void ast_i2c_setscl(void *i2c_priv, int clock)
4646 {
4747 struct ast_i2c_chan *i2c = i2c_priv;
48− struct ast_private *ast = to_ast_private(i2c->dev);
48+ struct ast_device *ast = to_ast_device(i2c->dev);
4949 int i;
5050 u8 ujcrb7, jtemp;
5151
@@ -61,7 +61,7 @@ static void ast_i2c_setscl(void *i2c_priv, int clock) · 9 unmodified lines
6161 static int ast_i2c_getsda(void *i2c_priv)
6262 {
6363 struct ast_i2c_chan *i2c = i2c_priv;
64− struct ast_private *ast = to_ast_private(i2c->dev);
64+ struct ast_device *ast = to_ast_device(i2c->dev);
6565 uint32_t val, val2, count, pass;
6666
6767 count = 0;
@@ -83,7 +83,7 @@ static int ast_i2c_getsda(void *i2c_priv) · 15 unmodified lines
8383 static int ast_i2c_getscl(void *i2c_priv)
8484 {
8585 struct ast_i2c_chan *i2c = i2c_priv;
86− struct ast_private *ast = to_ast_private(i2c->dev);
86+ struct ast_device *ast = to_ast_device(i2c->dev);
8787 uint32_t val, val2, count, pass;
8888
8989 count = 0;
drivers/gpu/drm/ast/ast_main.c+12−12
@@ -35,7 +35,7 @@ · 34 unmodified lines
3535
3636 #include "ast_drv.h"
3737
38−void ast_set_index_reg_mask(struct ast_private *ast,
38+void ast_set_index_reg_mask(struct ast_device *ast,
3939 uint32_t base, uint8_t index,
4040 uint8_t mask, uint8_t val)
4141 {
@@ -45,7 +45,7 @@ void ast_set_index_reg_mask(struct ast_private *ast, · 3 unmodified lines
4545 ast_set_index_reg(ast, base, index, tmp);
4646 }
4747
48−uint8_t ast_get_index_reg(struct ast_private *ast,
48+uint8_t ast_get_index_reg(struct ast_device *ast,
4949 uint32_t base, uint8_t index)
5050 {
5151 uint8_t ret;
@@ -54,7 +54,7 @@ uint8_t ast_get_index_reg(struct ast_private *ast, · 2 unmodified lines
5454 return ret;
5555 }
5656
57−uint8_t ast_get_index_reg_mask(struct ast_private *ast,
57+uint8_t ast_get_index_reg_mask(struct ast_device *ast,
5858 uint32_t base, uint8_t index, uint8_t mask)
5959 {
6060 uint8_t ret;
@@ -66,7 +66,7 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast, · 5 unmodified lines
6666 static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
6767 {
6868 struct device_node *np = dev->dev->of_node;
69− struct ast_private *ast = to_ast_private(dev);
69+ struct ast_device *ast = to_ast_device(dev);
7070 struct pci_dev *pdev = to_pci_dev(dev->dev);
7171 uint32_t data, jregd0, jregd1;
7272
@@ -122,7 +122,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) · 49 unmodified lines
122122
123123 static int ast_detect_chip(struct drm_device *dev, bool *need_post)
124124 {
125− struct ast_private *ast = to_ast_private(dev);
125+ struct ast_device *ast = to_ast_device(dev);
126126 struct pci_dev *pdev = to_pci_dev(dev->dev);
127127 uint32_t jreg, scu_rev;
128128
@@ -271,7 +271,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) · 142 unmodified lines
271271 static int ast_get_dram_info(struct drm_device *dev)
272272 {
273273 struct device_node *np = dev->dev->of_node;
274− struct ast_private *ast = to_ast_private(dev);
274+ struct ast_device *ast = to_ast_device(dev);
275275 uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap;
276276 uint32_t denum, num, div, ref_pll, dsel;
277277
@@ -394,22 +394,22 @@ static int ast_get_dram_info(struct drm_device *dev) · 116 unmodified lines
394394 */
395395 static void ast_device_release(void *data)
396396 {
397− struct ast_private *ast = data;
397+ struct ast_device *ast = data;
398398
399399 /* enable standard VGA decode */
400400 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04);
401401 }
402402
403−struct ast_private *ast_device_create(const struct drm_driver *drv,
404− struct pci_dev *pdev,
405− unsigned long flags)
403+struct ast_device *ast_device_create(const struct drm_driver *drv,
404+ struct pci_dev *pdev,
405+ unsigned long flags)
406406 {
407407 struct drm_device *dev;
408− struct ast_private *ast;
408+ struct ast_device *ast;
409409 bool need_post;
410410 int ret = 0;
411411
412− ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_private, base);
412+ ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_device, base);
413413 if (IS_ERR(ast))
414414 return ast;
415415 dev = &ast->base;
drivers/gpu/drm/ast/ast_mm.c+2−2
@@ -33,7 +33,7 @@ · 32 unmodified lines
3333
3434 #include "ast_drv.h"
3535
36−static u32 ast_get_vram_size(struct ast_private *ast)
36+static u32 ast_get_vram_size(struct ast_device *ast)
3737 {
3838 u8 jreg;
3939 u32 vram_size;
@@ -73,7 +73,7 @@ static u32 ast_get_vram_size(struct ast_private *ast) · 33 unmodified lines
7373 return vram_size;
7474 }
7575
76−int ast_mm_init(struct ast_private *ast)
76+int ast_mm_init(struct ast_device *ast)
7777 {
7878 struct drm_device *dev = &ast->base;
7979 struct pci_dev *pdev = to_pci_dev(dev->dev);
drivers/gpu/drm/ast/ast_mode.c+58−46
@@ -51,7 +51,7 @@ · 50 unmodified lines
5151
5252 #define AST_LUT_SIZE 256
5353
54−static inline void ast_load_palette_index(struct ast_private *ast,
54+static inline void ast_load_palette_index(struct ast_device *ast,
5555 u8 index, u8 red, u8 green,
5656 u8 blue)
5757 {
@@ -65,7 +65,7 @@ static inline void ast_load_palette_index(struct ast_private *ast, · 7 unmodified lines
6565 ast_io_read8(ast, AST_IO_SEQ_PORT);
6666 }
6767
68−static void ast_crtc_set_gamma_linear(struct ast_private *ast,
68+static void ast_crtc_set_gamma_linear(struct ast_device *ast,
6969 const struct drm_format_info *format)
7070 {
7171 int i;
@@ -84,7 +84,7 @@ static void ast_crtc_set_gamma_linear(struct ast_private *ast, · 12 unmodified lines
8484 }
8585 }
8686
87−static void ast_crtc_set_gamma(struct ast_private *ast,
87+static void ast_crtc_set_gamma(struct ast_device *ast,
8888 const struct drm_format_info *format,
8989 struct drm_color_lut *lut)
9090 {
@@ -232,7 +232,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, · 141 unmodified lines
232232 return true;
233233 }
234234
235−static void ast_set_vbios_color_reg(struct ast_private *ast,
235+static void ast_set_vbios_color_reg(struct ast_device *ast,
236236 const struct drm_format_info *format,
237237 const struct ast_vbios_mode_info *vbios_mode)
238238 {
@@ -263,7 +263,7 @@ static void ast_set_vbios_color_reg(struct ast_private *ast, · 24 unmodified lines
263263 }
264264 }
265265
266−static void ast_set_vbios_mode_reg(struct ast_private *ast,
266+static void ast_set_vbios_mode_reg(struct ast_device *ast,
267267 const struct drm_display_mode *adjusted_mode,
268268 const struct ast_vbios_mode_info *vbios_mode)
269269 {
@@ -287,7 +287,7 @@ static void ast_set_vbios_mode_reg(struct ast_private *ast, · 17 unmodified lines
287287 }
288288 }
289289
290−static void ast_set_std_reg(struct ast_private *ast,
290+static void ast_set_std_reg(struct ast_device *ast,
291291 struct drm_display_mode *mode,
292292 struct ast_vbios_mode_info *vbios_mode)
293293 {
@@ -335,7 +335,7 @@ static void ast_set_std_reg(struct ast_private *ast, · 41 unmodified lines
335335 ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]);
336336 }
337337
338−static void ast_set_crtc_reg(struct ast_private *ast,
338+static void ast_set_crtc_reg(struct ast_device *ast,
339339 struct drm_display_mode *mode,
340340 struct ast_vbios_mode_info *vbios_mode)
341341 {
@@ -450,7 +450,7 @@ static void ast_set_crtc_reg(struct ast_private *ast, · 108 unmodified lines
450450 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
451451 }
452452
453−static void ast_set_offset_reg(struct ast_private *ast,
453+static void ast_set_offset_reg(struct ast_device *ast,
454454 struct drm_framebuffer *fb)
455455 {
456456 u16 offset;
@@ -460,7 +460,7 @@ static void ast_set_offset_reg(struct ast_private *ast, · 3 unmodified lines
460460 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
461461 }
462462
463−static void ast_set_dclk_reg(struct ast_private *ast,
463+static void ast_set_dclk_reg(struct ast_device *ast,
464464 struct drm_display_mode *mode,
465465 struct ast_vbios_mode_info *vbios_mode)
466466 {
@@ -478,7 +478,7 @@ static void ast_set_dclk_reg(struct ast_private *ast, · 11 unmodified lines
478478 ((clk_info->param3 & 0x3) << 4));
479479 }
480480
481−static void ast_set_color_reg(struct ast_private *ast,
481+static void ast_set_color_reg(struct ast_device *ast,
482482 const struct drm_format_info *format)
483483 {
484484 u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
@@ -507,7 +507,7 @@ static void ast_set_color_reg(struct ast_private *ast, · 22 unmodified lines
507507 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
508508 }
509509
510−static void ast_set_crtthd_reg(struct ast_private *ast)
510+static void ast_set_crtthd_reg(struct ast_device *ast)
511511 {
512512 /* Set Threshold */
513513 if (ast->chip == AST2600) {
@@ -529,7 +529,7 @@ static void ast_set_crtthd_reg(struct ast_private *ast) · 15 unmodified lines
529529 }
530530 }
531531
532−static void ast_set_sync_reg(struct ast_private *ast,
532+static void ast_set_sync_reg(struct ast_device *ast,
533533 struct drm_display_mode *mode,
534534 struct ast_vbios_mode_info *vbios_mode)
535535 {
@@ -544,7 +544,7 @@ static void ast_set_sync_reg(struct ast_private *ast, · 8 unmodified lines
544544 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
545545 }
546546
547−static void ast_set_start_address_crt1(struct ast_private *ast,
547+static void ast_set_start_address_crt1(struct ast_device *ast,
548548 unsigned int offset)
549549 {
550550 u32 addr;
@@ -556,7 +556,7 @@ static void ast_set_start_address_crt1(struct ast_private *ast, · 5 unmodified lines
556556
557557 }
558558
559−static void ast_wait_for_vretrace(struct ast_private *ast)
559+static void ast_wait_for_vretrace(struct ast_device *ast)
560560 {
561561 unsigned long timeout = jiffies + HZ;
562562 u8 vgair1;
@@ -645,7 +645,7 @@ static void ast_primary_plane_helper_atomic_update(struct drm_plane *plane, · 82 unmodified lines
645645 struct drm_atomic_state *state)
646646 {
647647 struct drm_device *dev = plane->dev;
648− struct ast_private *ast = to_ast_private(dev);
648+ struct ast_device *ast = to_ast_device(dev);
649649 struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
650650 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
651651 struct drm_framebuffer *fb = plane_state->fb;
@@ -672,23 +672,34 @@ static void ast_primary_plane_helper_atomic_update(struct drm_plane *plane, · 20 unmodified lines
672672
673673 /*
674674 * Some BMCs stop scanning out the video signal after the driver
675− * reprogrammed the offset or scanout address. This stalls display
676− * output for several seconds and makes the display unusable.
677− * Therefore only update the offset if it changes and reprogram the
678− * address after enabling the plane.
675+ * reprogrammed the offset. This stalls display output for several
676+ * seconds and makes the display unusable. Therefore only update
677+ * the offset if it changes.
679678 */
680679 if (!old_fb || old_fb->pitches[0] != fb->pitches[0])
681680 ast_set_offset_reg(ast, fb);
682− if (!old_fb) {
683− ast_set_start_address_crt1(ast, (u32)ast_plane->offset);
684− ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
685− }
681+}
682+
683+static void ast_primary_plane_helper_atomic_enable(struct drm_plane *plane,
684+ struct drm_atomic_state *state)
685+{
686+ struct ast_device *ast = to_ast_device(plane->dev);
687+ struct ast_plane *ast_plane = to_ast_plane(plane);
688+
689+ /*
690+ * Some BMCs stop scanning out the video signal after the driver
691+ * reprogrammed the scanout address. This stalls display
692+ * output for several seconds and makes the display unusable.
693+ * Therefore only reprogram the address after enabling the plane.
694+ */
695+ ast_set_start_address_crt1(ast, (u32)ast_plane->offset);
696+ ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
686697 }
687698
688699 static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
689700 struct drm_atomic_state *state)
690701 {
691− struct ast_private *ast = to_ast_private(plane->dev);
702+ struct ast_device *ast = to_ast_device(plane->dev);
692703
693704 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
694705 }
@@ -697,6 +708,7 @@ static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = { · 2 unmodified lines
697708 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
698709 .atomic_check = ast_primary_plane_helper_atomic_check,
699710 .atomic_update = ast_primary_plane_helper_atomic_update,
711+ .atomic_enable = ast_primary_plane_helper_atomic_enable,
700712 .atomic_disable = ast_primary_plane_helper_atomic_disable,
701713 };
702714
@@ -707,7 +719,7 @@ static const struct drm_plane_funcs ast_primary_plane_funcs = { · 4 unmodified lines
707719 DRM_GEM_SHADOW_PLANE_FUNCS,
708720 };
709721
710−static int ast_primary_plane_init(struct ast_private *ast)
722+static int ast_primary_plane_init(struct ast_device *ast)
711723 {
712724 struct drm_device *dev = &ast->base;
713725 struct ast_plane *ast_primary_plane = &ast->primary_plane;
@@ -800,7 +812,7 @@ static void ast_update_cursor_image(u8 __iomem *dst, const u8 *src, int width, i · 86 unmodified lines
800812 writel(0, dst + AST_HWC_SIGNATURE_HOTSPOTY);
801813 }
802814
803−static void ast_set_cursor_base(struct ast_private *ast, u64 address)
815+static void ast_set_cursor_base(struct ast_device *ast, u64 address)
804816 {
805817 u8 addr0 = (address >> 3) & 0xff;
806818 u8 addr1 = (address >> 11) & 0xff;
@@ -811,7 +823,7 @@ static void ast_set_cursor_base(struct ast_private *ast, u64 address) · 4 unmodified lines
811823 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2);
812824 }
813825
814−static void ast_set_cursor_location(struct ast_private *ast, u16 x, u16 y,
826+static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y,
815827 u8 x_offset, u8 y_offset)
816828 {
817829 u8 x0 = (x & 0x00ff);
@@ -827,7 +839,7 @@ static void ast_set_cursor_location(struct ast_private *ast, u16 x, u16 y, · 9 unmodified lines
827839 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
828840 }
829841
830−static void ast_set_cursor_enabled(struct ast_private *ast, bool enabled)
842+static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled)
831843 {
832844 static const u8 mask = (u8)~(AST_IO_VGACRCB_HWC_16BPP |
833845 AST_IO_VGACRCB_HWC_ENABLED);
@@ -876,7 +888,7 @@ static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, · 42 unmodified lines
876888 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
877889 struct drm_framebuffer *fb = plane_state->fb;
878890 struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
879− struct ast_private *ast = to_ast_private(plane->dev);
891+ struct ast_device *ast = to_ast_device(plane->dev);
880892 struct iosys_map src_map = shadow_plane_state->data[0];
881893 struct drm_rect damage;
882894 const u8 *src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
@@ -931,7 +943,7 @@ static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, · 48 unmodified lines
931943 static void ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
932944 struct drm_atomic_state *state)
933945 {
934− struct ast_private *ast = to_ast_private(plane->dev);
946+ struct ast_device *ast = to_ast_device(plane->dev);
935947
936948 ast_set_cursor_enabled(ast, false);
937949 }
@@ -950,7 +962,7 @@ static const struct drm_plane_funcs ast_cursor_plane_funcs = { · 12 unmodified lines
950962 DRM_GEM_SHADOW_PLANE_FUNCS,
951963 };
952964
953−static int ast_cursor_plane_init(struct ast_private *ast)
965+static int ast_cursor_plane_init(struct ast_device *ast)
954966 {
955967 struct drm_device *dev = &ast->base;
956968 struct ast_plane *ast_cursor_plane = &ast->cursor_plane;
@@ -995,7 +1007,7 @@ static int ast_cursor_plane_init(struct ast_private *ast) · 38 unmodified lines
9951007
9961008 static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
9971009 {
998− struct ast_private *ast = to_ast_private(crtc->dev);
1010+ struct ast_device *ast = to_ast_device(crtc->dev);
9991011 u8 ch = AST_DPMS_VSYNC_OFF | AST_DPMS_HSYNC_OFF;
10001012 struct ast_crtc_state *ast_state;
10011013 const struct drm_format_info *format;
@@ -1052,7 +1064,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) · 50 unmodified lines
10521064 static enum drm_mode_status
10531065 ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
10541066 {
1055− struct ast_private *ast = to_ast_private(crtc->dev);
1067+ struct ast_device *ast = to_ast_device(crtc->dev);
10561068 enum drm_mode_status status;
10571069 uint32_t jtemp;
10581070
@@ -1177,7 +1189,7 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, · 118 unmodified lines
11771189 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
11781190 crtc);
11791191 struct drm_device *dev = crtc->dev;
1180− struct ast_private *ast = to_ast_private(dev);
1192+ struct ast_device *ast = to_ast_device(dev);
11811193 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
11821194 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
11831195
@@ -1202,7 +1214,7 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, · 18 unmodified lines
12021214 static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
12031215 {
12041216 struct drm_device *dev = crtc->dev;
1205− struct ast_private *ast = to_ast_private(dev);
1217+ struct ast_device *ast = to_ast_device(dev);
12061218 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
12071219 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
12081220 struct ast_vbios_mode_info *vbios_mode_info =
@@ -1224,7 +1236,7 @@ static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_ato · 15 unmodified lines
12241236 {
12251237 struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
12261238 struct drm_device *dev = crtc->dev;
1227− struct ast_private *ast = to_ast_private(dev);
1239+ struct ast_device *ast = to_ast_device(dev);
12281240
12291241 ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
12301242
@@ -1312,7 +1324,7 @@ static const struct drm_crtc_funcs ast_crtc_funcs = { · 81 unmodified lines
13121324
13131325 static int ast_crtc_init(struct drm_device *dev)
13141326 {
1315− struct ast_private *ast = to_ast_private(dev);
1327+ struct ast_device *ast = to_ast_device(dev);
13161328 struct drm_crtc *crtc = &ast->crtc;
13171329 int ret;
13181330
@@ -1338,7 +1350,7 @@ static int ast_vga_connector_helper_get_modes(struct drm_connector *connector) · 19 unmodified lines
13381350 {
13391351 struct ast_vga_connector *ast_vga_connector = to_ast_vga_connector(connector);
13401352 struct drm_device *dev = connector->dev;
1341− struct ast_private *ast = to_ast_private(dev);
1353+ struct ast_device *ast = to_ast_device(dev);
13421354 struct edid *edid;
13431355 int count;
13441356
@@ -1411,7 +1423,7 @@ static int ast_vga_connector_init(struct drm_device *dev, · 66 unmodified lines
14111423 return 0;
14121424 }
14131425
1414−static int ast_vga_output_init(struct ast_private *ast)
1426+static int ast_vga_output_init(struct ast_device *ast)
14151427 {
14161428 struct drm_device *dev = &ast->base;
14171429 struct drm_crtc *crtc = &ast->crtc;
@@ -1444,7 +1456,7 @@ static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector · 26 unmodified lines
14441456 {
14451457 struct ast_sil164_connector *ast_sil164_connector = to_ast_sil164_connector(connector);
14461458 struct drm_device *dev = connector->dev;
1447− struct ast_private *ast = to_ast_private(dev);
1459+ struct ast_device *ast = to_ast_device(dev);
14481460 struct edid *edid;
14491461 int count;
14501462
@@ -1517,7 +1529,7 @@ static int ast_sil164_connector_init(struct drm_device *dev, · 66 unmodified lines
15171529 return 0;
15181530 }
15191531
1520−static int ast_sil164_output_init(struct ast_private *ast)
1532+static int ast_sil164_output_init(struct ast_device *ast)
15211533 {
15221534 struct drm_device *dev = &ast->base;
15231535 struct drm_crtc *crtc = &ast->crtc;
@@ -1604,7 +1616,7 @@ static int ast_dp501_connector_init(struct drm_device *dev, struct drm_connector · 80 unmodified lines
16041616 return 0;
16051617 }
16061618
1607−static int ast_dp501_output_init(struct ast_private *ast)
1619+static int ast_dp501_output_init(struct ast_device *ast)
16081620 {
16091621 struct drm_device *dev = &ast->base;
16101622 struct drm_crtc *crtc = &ast->crtc;
@@ -1691,7 +1703,7 @@ static int ast_astdp_connector_init(struct drm_device *dev, struct drm_connector · 80 unmodified lines
16911703 return 0;
16921704 }
16931705
1694−static int ast_astdp_output_init(struct ast_private *ast)
1706+static int ast_astdp_output_init(struct ast_device *ast)
16951707 {
16961708 struct drm_device *dev = &ast->base;
16971709 struct drm_crtc *crtc = &ast->crtc;
@@ -1721,7 +1733,7 @@ static int ast_astdp_output_init(struct ast_private *ast) · 23 unmodified lines
17211733
17221734 static void ast_mode_config_helper_atomic_commit_tail(struct drm_atomic_state *state)
17231735 {
1724− struct ast_private *ast = to_ast_private(state->dev);
1736+ struct ast_device *ast = to_ast_device(state->dev);
17251737
17261738 /*
17271739 * Concurrent operations could possibly trigger a call to
@@ -1742,7 +1754,7 @@ static enum drm_mode_status ast_mode_config_mode_valid(struct drm_device *dev, · 14 unmodified lines
17421754 const struct drm_display_mode *mode)
17431755 {
17441756 static const unsigned long max_bpp = 4; /* DRM_FORMAT_XRGB8888 */
1745− struct ast_private *ast = to_ast_private(dev);
1757+ struct ast_device *ast = to_ast_device(dev);
17461758 unsigned long fbsize, fbpages, max_fbpages;
17471759
17481760 max_fbpages = (ast->vram_fb_available) >> PAGE_SHIFT;
@@ -1763,7 +1775,7 @@ static const struct drm_mode_config_funcs ast_mode_config_funcs = { · 14 unmodified lines
17631775 .atomic_commit = drm_atomic_helper_commit,
17641776 };
17651777
1766−int ast_mode_config_init(struct ast_private *ast)
1778+int ast_mode_config_init(struct ast_device *ast)
17671779 {
17681780 struct drm_device *dev = &ast->base;
17691781 int ret;
drivers/gpu/drm/ast/ast_post.c+47−47
@@ -39,7 +39,7 @@ static void ast_post_chip_2500(struct drm_device *dev); · 38 unmodified lines
3939
4040 void ast_enable_vga(struct drm_device *dev)
4141 {
42− struct ast_private *ast = to_ast_private(dev);
42+ struct ast_device *ast = to_ast_device(dev);
4343
4444 ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01);
4545 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01);
@@ -47,7 +47,7 @@ void ast_enable_vga(struct drm_device *dev) · 1 unmodified line
4747
4848 void ast_enable_mmio(struct drm_device *dev)
4949 {
50− struct ast_private *ast = to_ast_private(dev);
50+ struct ast_device *ast = to_ast_device(dev);
5151
5252 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
5353 }
@@ -55,7 +55,7 @@ void ast_enable_mmio(struct drm_device *dev) · 1 unmodified line
5555
5656 bool ast_is_vga_enabled(struct drm_device *dev)
5757 {
58− struct ast_private *ast = to_ast_private(dev);
58+ struct ast_device *ast = to_ast_device(dev);
5959 u8 ch;
6060
6161 ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT);
@@ -70,7 +70,7 @@ static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff }; · 8 unmodified lines
7070 static void
7171 ast_set_def_ext_reg(struct drm_device *dev)
7272 {
73− struct ast_private *ast = to_ast_private(dev);
73+ struct ast_device *ast = to_ast_device(dev);
7474 struct pci_dev *pdev = to_pci_dev(dev->dev);
7575 u8 i, index, reg;
7676 const u8 *ext_reg_info;
@@ -110,7 +110,7 @@ ast_set_def_ext_reg(struct drm_device *dev) · 33 unmodified lines
110110 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
111111 }
112112
113−u32 ast_mindwm(struct ast_private *ast, u32 r)
113+u32 ast_mindwm(struct ast_device *ast, u32 r)
114114 {
115115 uint32_t data;
116116
@@ -123,7 +123,7 @@ u32 ast_mindwm(struct ast_private *ast, u32 r) · 6 unmodified lines
123123 return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
124124 }
125125
126−void ast_moutdwm(struct ast_private *ast, u32 r, u32 v)
126+void ast_moutdwm(struct ast_device *ast, u32 r, u32 v)
127127 {
128128 uint32_t data;
129129 ast_write32(ast, 0xf004, r & 0xffff0000);
@@ -162,7 +162,7 @@ static const u32 pattern_AST2150[14] = { · 32 unmodified lines
162162 0x20F050E0
163163 };
164164
165−static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
165+static u32 mmctestburst2_ast2150(struct ast_device *ast, u32 datagen)
166166 {
167167 u32 data, timeout;
168168
@@ -192,7 +192,7 @@ static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen) · 23 unmodified lines
192192 }
193193
194194 #if 0 /* unused in DDX driver - here for completeness */
195−static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen)
195+static u32 mmctestsingle2_ast2150(struct ast_device *ast, u32 datagen)
196196 {
197197 u32 data, timeout;
198198
@@ -212,7 +212,7 @@ static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen) · 13 unmodified lines
212212 }
213213 #endif
214214
215−static int cbrtest_ast2150(struct ast_private *ast)
215+static int cbrtest_ast2150(struct ast_device *ast)
216216 {
217217 int i;
218218
@@ -222,7 +222,7 @@ static int cbrtest_ast2150(struct ast_private *ast) · 3 unmodified lines
222222 return 1;
223223 }
224224
225−static int cbrscan_ast2150(struct ast_private *ast, int busw)
225+static int cbrscan_ast2150(struct ast_device *ast, int busw)
226226 {
227227 u32 patcnt, loop;
228228
@@ -239,7 +239,7 @@ static int cbrscan_ast2150(struct ast_private *ast, int busw) · 10 unmodified lines
239239 }
240240
241241
242−static void cbrdlli_ast2150(struct ast_private *ast, int busw)
242+static void cbrdlli_ast2150(struct ast_device *ast, int busw)
243243 {
244244 u32 dll_min[4], dll_max[4], dlli, data, passcnt;
245245
@@ -273,7 +273,7 @@ cbr_start: · 27 unmodified lines
273273
274274 static void ast_init_dram_reg(struct drm_device *dev)
275275 {
276− struct ast_private *ast = to_ast_private(dev);
276+ struct ast_device *ast = to_ast_device(dev);
277277 u8 j;
278278 u32 data, temp, i;
279279 const struct ast_dramstruct *dram_reg_info;
@@ -366,7 +366,7 @@ static void ast_init_dram_reg(struct drm_device *dev) · 86 unmodified lines
366366
367367 void ast_post_gpu(struct drm_device *dev)
368368 {
369− struct ast_private *ast = to_ast_private(dev);
369+ struct ast_device *ast = to_ast_device(dev);
370370 struct pci_dev *pdev = to_pci_dev(dev->dev);
371371 u32 reg;
372372
@@ -449,7 +449,7 @@ static const u32 pattern[8] = { · 76 unmodified lines
449449 0x7C61D253
450450 };
451451
452−static bool mmc_test(struct ast_private *ast, u32 datagen, u8 test_ctl)
452+static bool mmc_test(struct ast_device *ast, u32 datagen, u8 test_ctl)
453453 {
454454 u32 data, timeout;
455455
@@ -469,7 +469,7 @@ static bool mmc_test(struct ast_private *ast, u32 datagen, u8 test_ctl) · 13 unmodified lines
469469 return true;
470470 }
471471
472−static u32 mmc_test2(struct ast_private *ast, u32 datagen, u8 test_ctl)
472+static u32 mmc_test2(struct ast_device *ast, u32 datagen, u8 test_ctl)
473473 {
474474 u32 data, timeout;
475475
@@ -490,32 +490,32 @@ static u32 mmc_test2(struct ast_private *ast, u32 datagen, u8 test_ctl) · 14 unmodified lines
490490 }
491491
492492
493−static bool mmc_test_burst(struct ast_private *ast, u32 datagen)
493+static bool mmc_test_burst(struct ast_device *ast, u32 datagen)
494494 {
495495 return mmc_test(ast, datagen, 0xc1);
496496 }
497497
498−static u32 mmc_test_burst2(struct ast_private *ast, u32 datagen)
498+static u32 mmc_test_burst2(struct ast_device *ast, u32 datagen)
499499 {
500500 return mmc_test2(ast, datagen, 0x41);
501501 }
502502
503−static bool mmc_test_single(struct ast_private *ast, u32 datagen)
503+static bool mmc_test_single(struct ast_device *ast, u32 datagen)
504504 {
505505 return mmc_test(ast, datagen, 0xc5);
506506 }
507507
508−static u32 mmc_test_single2(struct ast_private *ast, u32 datagen)
508+static u32 mmc_test_single2(struct ast_device *ast, u32 datagen)
509509 {
510510 return mmc_test2(ast, datagen, 0x05);
511511 }
512512
513−static bool mmc_test_single_2500(struct ast_private *ast, u32 datagen)
513+static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen)
514514 {
515515 return mmc_test(ast, datagen, 0x85);
516516 }
517517
518−static int cbr_test(struct ast_private *ast)
518+static int cbr_test(struct ast_device *ast)
519519 {
520520 u32 data;
521521 int i;
@@ -534,7 +534,7 @@ static int cbr_test(struct ast_private *ast) · 12 unmodified lines
534534 return 1;
535535 }
536536
537−static int cbr_scan(struct ast_private *ast)
537+static int cbr_scan(struct ast_device *ast)
538538 {
539539 u32 data, data2, patcnt, loop;
540540
@@ -555,7 +555,7 @@ static int cbr_scan(struct ast_private *ast) · 14 unmodified lines
555555 return data2;
556556 }
557557
558−static u32 cbr_test2(struct ast_private *ast)
558+static u32 cbr_test2(struct ast_device *ast)
559559 {
560560 u32 data;
561561
@@ -569,7 +569,7 @@ static u32 cbr_test2(struct ast_private *ast) · 7 unmodified lines
569569 return ~data & 0xffff;
570570 }
571571
572−static u32 cbr_scan2(struct ast_private *ast)
572+static u32 cbr_scan2(struct ast_device *ast)
573573 {
574574 u32 data, data2, patcnt, loop;
575575
@@ -590,7 +590,7 @@ static u32 cbr_scan2(struct ast_private *ast) · 14 unmodified lines
590590 return data2;
591591 }
592592
593−static bool cbr_test3(struct ast_private *ast)
593+static bool cbr_test3(struct ast_device *ast)
594594 {
595595 if (!mmc_test_burst(ast, 0))
596596 return false;
@@ -599,7 +599,7 @@ static bool cbr_test3(struct ast_private *ast) · 2 unmodified lines
599599 return true;
600600 }
601601
602−static bool cbr_scan3(struct ast_private *ast)
602+static bool cbr_scan3(struct ast_device *ast)
603603 {
604604 u32 patcnt, loop;
605605
@@ -615,7 +615,7 @@ static bool cbr_scan3(struct ast_private *ast) · 9 unmodified lines
615615 return true;
616616 }
617617
618−static bool finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
618+static bool finetuneDQI_L(struct ast_device *ast, struct ast2300_dram_param *param)
619619 {
620620 u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0;
621621 bool status = false;
@@ -714,7 +714,7 @@ FINETUNE_DONE: · 92 unmodified lines
714714 return status;
715715 } /* finetuneDQI_L */
716716
717−static void finetuneDQSI(struct ast_private *ast)
717+static void finetuneDQSI(struct ast_device *ast)
718718 {
719719 u32 dlli, dqsip, dqidly;
720720 u32 reg_mcr18, reg_mcr0c, passcnt[2], diff;
@@ -804,7 +804,7 @@ static void finetuneDQSI(struct ast_private *ast) · 83 unmodified lines
804804 ast_moutdwm(ast, 0x1E6E0018, reg_mcr18);
805805
806806 }
807−static bool cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
807+static bool cbr_dll2(struct ast_device *ast, struct ast2300_dram_param *param)
808808 {
809809 u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0;
810810 bool status = false;
@@ -860,7 +860,7 @@ CBR_DONE2: · 49 unmodified lines
860860 return status;
861861 } /* CBRDLL2 */
862862
863−static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
863+static void get_ddr3_info(struct ast_device *ast, struct ast2300_dram_param *param)
864864 {
865865 u32 trap, trap_AC2, trap_MRS;
866866
@@ -1102,7 +1102,7 @@ static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *pa · 235 unmodified lines
11021102
11031103 }
11041104
1105−static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
1105+static void ddr3_init(struct ast_device *ast, struct ast2300_dram_param *param)
11061106 {
11071107 u32 data, data2, retry = 0;
11081108
@@ -1225,7 +1225,7 @@ ddr3_init_start: · 116 unmodified lines
12251225
12261226 }
12271227
1228−static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
1228+static void get_ddr2_info(struct ast_device *ast, struct ast2300_dram_param *param)
12291229 {
12301230 u32 trap, trap_AC2, trap_MRS;
12311231
@@ -1472,7 +1472,7 @@ static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *pa · 240 unmodified lines
14721472 }
14731473 }
14741474
1475−static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
1475+static void ddr2_init(struct ast_device *ast, struct ast2300_dram_param *param)
14761476 {
14771477 u32 data, data2, retry = 0;
14781478
@@ -1600,7 +1600,7 @@ ddr2_init_start: · 121 unmodified lines
16001600
16011601 static void ast_post_chip_2300(struct drm_device *dev)
16021602 {
1603− struct ast_private *ast = to_ast_private(dev);
1603+ struct ast_device *ast = to_ast_device(dev);
16041604 struct ast2300_dram_param param;
16051605 u32 temp;
16061606 u8 reg;
@@ -1681,7 +1681,7 @@ static void ast_post_chip_2300(struct drm_device *dev) · 74 unmodified lines
16811681 } while ((reg & 0x40) == 0);
16821682 }
16831683
1684−static bool cbr_test_2500(struct ast_private *ast)
1684+static bool cbr_test_2500(struct ast_device *ast)
16851685 {
16861686 ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
16871687 ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
@@ -1692,7 +1692,7 @@ static bool cbr_test_2500(struct ast_private *ast) · 4 unmodified lines
16921692 return true;
16931693 }
16941694
1695−static bool ddr_test_2500(struct ast_private *ast)
1695+static bool ddr_test_2500(struct ast_device *ast)
16961696 {
16971697 ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF);
16981698 ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00);
@@ -1709,7 +1709,7 @@ static bool ddr_test_2500(struct ast_private *ast) · 10 unmodified lines
17091709 return true;
17101710 }
17111711
1712−static void ddr_init_common_2500(struct ast_private *ast)
1712+static void ddr_init_common_2500(struct ast_device *ast)
17131713 {
17141714 ast_moutdwm(ast, 0x1E6E0034, 0x00020080);
17151715 ast_moutdwm(ast, 0x1E6E0008, 0x2003000F);
@@ -1732,7 +1732,7 @@ static void ddr_init_common_2500(struct ast_private *ast) · 16 unmodified lines
17321732 ast_moutdwm(ast, 0x1E6E024C, 0x80808080);
17331733 }
17341734
1735−static void ddr_phy_init_2500(struct ast_private *ast)
1735+static void ddr_phy_init_2500(struct ast_device *ast)
17361736 {
17371737 u32 data, pass, timecnt;
17381738
@@ -1766,7 +1766,7 @@ static void ddr_phy_init_2500(struct ast_private *ast) · 27 unmodified lines
17661766 * 4Gb : 0x80000000 ~ 0x9FFFFFFF
17671767 * 8Gb : 0x80000000 ~ 0xBFFFFFFF
17681768 */
1769−static void check_dram_size_2500(struct ast_private *ast, u32 tRFC)
1769+static void check_dram_size_2500(struct ast_device *ast, u32 tRFC)
17701770 {
17711771 u32 reg_04, reg_14;
17721772
@@ -1797,7 +1797,7 @@ static void check_dram_size_2500(struct ast_private *ast, u32 tRFC) · 24 unmodified lines
17971797 ast_moutdwm(ast, 0x1E6E0014, reg_14);
17981798 }
17991799
1800−static void enable_cache_2500(struct ast_private *ast)
1800+static void enable_cache_2500(struct ast_device *ast)
18011801 {
18021802 u32 reg_04, data;
18031803
@@ -1810,7 +1810,7 @@ static void enable_cache_2500(struct ast_private *ast) · 6 unmodified lines
18101810 ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x400);
18111811 }
18121812
1813−static void set_mpll_2500(struct ast_private *ast)
1813+static void set_mpll_2500(struct ast_device *ast)
18141814 {
18151815 u32 addr, data, param;
18161816
@@ -1837,7 +1837,7 @@ static void set_mpll_2500(struct ast_private *ast) · 20 unmodified lines
18371837 udelay(100);
18381838 }
18391839
1840−static void reset_mmc_2500(struct ast_private *ast)
1840+static void reset_mmc_2500(struct ast_device *ast)
18411841 {
18421842 ast_moutdwm(ast, 0x1E78505C, 0x00000004);
18431843 ast_moutdwm(ast, 0x1E785044, 0x00000001);
@@ -1848,7 +1848,7 @@ static void reset_mmc_2500(struct ast_private *ast) · 4 unmodified lines
18481848 ast_moutdwm(ast, 0x1E6E0000, 0xFC600309);
18491849 }
18501850
1851−static void ddr3_init_2500(struct ast_private *ast, const u32 *ddr_table)
1851+static void ddr3_init_2500(struct ast_device *ast, const u32 *ddr_table)
18521852 {
18531853
18541854 ast_moutdwm(ast, 0x1E6E0004, 0x00000303);
@@ -1892,7 +1892,7 @@ static void ddr3_init_2500(struct ast_private *ast, const u32 *ddr_table) · 37 unmodified lines
18921892 ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
18931893 }
18941894
1895−static void ddr4_init_2500(struct ast_private *ast, const u32 *ddr_table)
1895+static void ddr4_init_2500(struct ast_device *ast, const u32 *ddr_table)
18961896 {
18971897 u32 data, data2, pass, retrycnt;
18981898 u32 ddr_vref, phy_vref;
@@ -2002,7 +2002,7 @@ static void ddr4_init_2500(struct ast_private *ast, const u32 *ddr_table) · 103 unmodified lines
20022002 ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00);
20032003 }
20042004
2005−static bool ast_dram_init_2500(struct ast_private *ast)
2005+static bool ast_dram_init_2500(struct ast_device *ast)
20062006 {
20072007 u32 data;
20082008 u32 max_tries = 5;
@@ -2030,7 +2030,7 @@ static bool ast_dram_init_2500(struct ast_private *ast) · 21 unmodified lines
20302030 return true;
20312031 }
20322032
2033−void ast_patch_ahb_2500(struct ast_private *ast)
2033+void ast_patch_ahb_2500(struct ast_device *ast)
20342034 {
20352035 u32 data;
20362036
@@ -2066,7 +2066,7 @@ void ast_patch_ahb_2500(struct ast_private *ast) · 29 unmodified lines
20662066
20672067 void ast_post_chip_2500(struct drm_device *dev)
20682068 {
2069− struct ast_private *ast = to_ast_private(dev);
2069+ struct ast_device *ast = to_ast_device(dev);
20702070 u32 temp;
20712071 u8 reg;
20722072
drivers/gpu/drm/bridge/Kconfig+1−1
@@ -326,7 +326,7 @@ config DRM_TI_DLPC3433 · 325 unmodified lines
326326 input that produces a DMD output in RGB565, RGB666, RGB888
327327 formats.
328328
329− It supports upto 720p resolution with 60 and 120 Hz refresh
329+ It supports up to 720p resolution with 60 and 120 Hz refresh
330330 rates.
331331
332332 config DRM_TI_TFP410
drivers/gpu/drm/bridge/panel.c+2−0
@@ -81,6 +81,8 @@ static int panel_bridge_attach(struct drm_bridge *bridge, · 80 unmodified lines
8181 return ret;
8282 }
8383
84+ drm_panel_bridge_set_orientation(connector, bridge);
85+
8486 drm_connector_attach_encoder(&panel_bridge->connector,
8587 bridge->encoder);
8688
drivers/gpu/drm/bridge/tc358762.c+1−0
@@ -229,6 +229,7 @@ static int tc358762_probe(struct mipi_dsi_device *dsi) · 228 unmodified lines
229229 ctx->bridge.funcs = &tc358762_bridge_funcs;
230230 ctx->bridge.type = DRM_MODE_CONNECTOR_DPI;
231231 ctx->bridge.of_node = dev->of_node;
232+ ctx->bridge.pre_enable_prev_first = true;
232233
233234 drm_bridge_add(&ctx->bridge);
234235
drivers/gpu/drm/drm_atomic_helper.c+16−4
@@ -2702,6 +2702,11 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, · 2701 unmodified lines
27022702 funcs->atomic_disable(plane, old_state);
27032703 } else if (new_plane_state->crtc || disabling) {
27042704 funcs->atomic_update(plane, old_state);
2705+
2706+ if (!disabling && funcs->atomic_enable) {
2707+ if (drm_atomic_plane_enabling(old_plane_state, new_plane_state))
2708+ funcs->atomic_enable(plane, old_state);
2709+ }
27052710 }
27062711 }
27072712
@@ -2762,6 +2767,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state) · 54 unmodified lines
27622767 struct drm_plane_state *new_plane_state =
27632768 drm_atomic_get_new_plane_state(old_state, plane);
27642769 const struct drm_plane_helper_funcs *plane_funcs;
2770+ bool disabling;
27652771
27662772 plane_funcs = plane->helper_private;
27672773
@@ -2771,12 +2777,18 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state) · 3 unmodified lines
27712777 WARN_ON(new_plane_state->crtc &&
27722778 new_plane_state->crtc != crtc);
27732779
2774− if (drm_atomic_plane_disabling(old_plane_state, new_plane_state) &&
2775− plane_funcs->atomic_disable)
2780+ disabling = drm_atomic_plane_disabling(old_plane_state, new_plane_state);
2781+
2782+ if (disabling && plane_funcs->atomic_disable) {
27762783 plane_funcs->atomic_disable(plane, old_state);
2777− else if (new_plane_state->crtc ||
2778− drm_atomic_plane_disabling(old_plane_state, new_plane_state))
2784+ } else if (new_plane_state->crtc || disabling) {
27792785 plane_funcs->atomic_update(plane, old_state);
2786+
2787+ if (!disabling && plane_funcs->atomic_enable) {
2788+ if (drm_atomic_plane_enabling(old_plane_state, new_plane_state))
2789+ plane_funcs->atomic_enable(plane, old_state);
2790+ }
2791+ }
27802792 }
27812793
27822794 if (crtc_funcs && crtc_funcs->atomic_flush)
drivers/gpu/drm/drm_connector.c+20−8
@@ -33,9 +33,11 @@ · 32 unmodified lines
3333 #include <drm/drm_sysfs.h>
3434 #include <drm/drm_utils.h>
3535
36−#include <linux/fb.h>
36+#include <linux/property.h>
3737 #include <linux/uaccess.h>
3838
39+#include <video/cmdline.h>
40+
3941 #include "drm_crtc_internal.h"
4042 #include "drm_internal.h"
4143
@@ -154,9 +156,10 @@ EXPORT_SYMBOL(drm_get_connector_type_name); · 112 unmodified lines
154156 static void drm_connector_get_cmdline_mode(struct drm_connector *connector)
155157 {
156158 struct drm_cmdline_mode *mode = &connector->cmdline_mode;
157− char *option = NULL;
159+ const char *option;
158160
159− if (fb_get_options(connector->name, &option))
161+ option = video_get_options(connector->name);
162+ if (!option)
160163 return;
161164
162165 if (!drm_mode_parse_command_line_for_connector(option,
@@ -1446,6 +1449,20 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { · 1283 unmodified lines
14461449 * a firmware handled hotkey. Therefor userspace must not include the
14471450 * privacy-screen sw-state in an atomic commit unless it wants to change
14481451 * its value.
1452+ *
1453+ * left margin, right margin, top margin, bottom margin:
1454+ * Add margins to the connector's viewport. This is typically used to
1455+ * mitigate underscan on TVs.
1456+ *
1457+ * The value is the size in pixels of the black border which will be
1458+ * added. The attached CRTC's content will be scaled to fill the whole
1459+ * area inside the margin.
1460+ *
1461+ * The margins configuration might be sent to the sink, e.g. via HDMI AVI
1462+ * InfoFrames.
1463+ *
1464+ * Drivers can set up these properties by calling
1465+ * drm_mode_create_tv_margin_properties().
14491466 */
14501467
14511468 int drm_connector_create_standard_properties(struct drm_device *dev)
@@ -1590,10 +1607,6 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property); · 138 unmodified lines
15901607
15911608 /*
15921609 * TODO: Document the properties:
1593− * - left margin
1594− * - right margin
1595− * - top margin
1596− * - bottom margin
15971610 * - brightness
15981611 * - contrast
15991612 * - flicker reduction
@@ -1602,7 +1615,6 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property); · 2 unmodified lines
16021615 * - overscan
16031616 * - saturation
16041617 * - select subconnector
1605− * - subconnector
16061618 */
16071619 /**
16081620 * DOC: Analog TV Connector Properties
drivers/gpu/drm/drm_displayid.c+53−9
@@ -7,13 +7,29 @@ · 6 unmodified lines
77 #include <drm/drm_edid.h>
88 #include <drm/drm_print.h>
99
10−static int validate_displayid(const u8 *displayid, int length, int idx)
10+static const struct displayid_header *
11+displayid_get_header(const u8 *displayid, int length, int index)
12+{
13+ const struct displayid_header *base;
14+
15+ if (sizeof(*base) > length - index)
16+ return ERR_PTR(-EINVAL);
17+
18+ base = (const struct displayid_header *)&displayid[index];
19+
20+ return base;
21+}
22+
23+static const struct displayid_header *
24+validate_displayid(const u8 *displayid, int length, int idx)
1125 {
1226 int i, dispid_length;
1327 u8 csum = 0;
1428 const struct displayid_header *base;
1529
16− base = (const struct displayid_header *)&displayid[idx];
30+ base = displayid_get_header(displayid, length, idx);
31+ if (IS_ERR(base))
32+ return base;
1733
1834 DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
1935 base->rev, base->bytes, base->prod_id, base->ext_count);
@@ -21,16 +37,16 @@ static int validate_displayid(const u8 *displayid, int length, int idx) · 1 unmodified line
2137 /* +1 for DispID checksum */
2238 dispid_length = sizeof(*base) + base->bytes + 1;
2339 if (dispid_length > length - idx)
24− return -EINVAL;
40+ return ERR_PTR(-EINVAL);
2541
2642 for (i = 0; i < dispid_length; i++)
2743 csum += displayid[idx + i];
2844 if (csum) {
2945 DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", csum);
30− return -EINVAL;
46+ return ERR_PTR(-EINVAL);
3147 }
3248
33− return 0;
49+ return base;
3450 }
3551
3652 static const u8 *drm_find_displayid_extension(const struct drm_edid *drm_edid,
@@ -39,7 +55,6 @@ static const u8 *drm_find_displayid_extension(const struct drm_edid *drm_edid, · 2 unmodified lines
3955 {
4056 const u8 *displayid = drm_find_edid_extension(drm_edid, DISPLAYID_EXT, ext_index);
4157 const struct displayid_header *base;
42− int ret;
4358
4459 if (!displayid)
4560 return NULL;
@@ -48,11 +63,10 @@ static const u8 *drm_find_displayid_extension(const struct drm_edid *drm_edid, · 2 unmodified lines
4863 *length = EDID_LENGTH - 1;
4964 *idx = 1;
5065
51− ret = validate_displayid(displayid, *length, *idx);
52− if (ret)
66+ base = validate_displayid(displayid, *length, *idx);
67+ if (IS_ERR(base))
5368 return NULL;
5469
55− base = (const struct displayid_header *)&displayid[*idx];
5670 *length = *idx + sizeof(*base) + base->bytes;
5771
5872 return displayid;
@@ -109,6 +123,9 @@ __displayid_iter_next(struct displayid_iter *iter) · 50 unmodified lines
109123 }
110124
111125 for (;;) {
126+ /* The first section we encounter is the base section */
127+ bool base_section = !iter->section;
128+
112129 iter->section = drm_find_displayid_extension(iter->drm_edid,
113130 &iter->length,
114131 &iter->idx,
@@ -118,6 +135,18 @@ __displayid_iter_next(struct displayid_iter *iter) · 3 unmodified lines
118135 return NULL;
119136 }
120137
138+ /* Save the structure version and primary use case. */
139+ if (base_section) {
140+ const struct displayid_header *base;
141+
142+ base = displayid_get_header(iter->section, iter->length,
143+ iter->idx);
144+ if (!IS_ERR(base)) {
145+ iter->version = base->rev;
146+ iter->primary_use = base->prod_id;
147+ }
148+ }
149+
121150 iter->idx += sizeof(struct displayid_header);
122151
123152 block = displayid_iter_block(iter);
@@ -130,3 +159,18 @@ void displayid_iter_end(struct displayid_iter *iter) · 6 unmodified lines
130159 {
131160 memset(iter, 0, sizeof(*iter));
132161 }
162+
163+/* DisplayID Structure Version/Revision from the Base Section. */
164+u8 displayid_version(const struct displayid_iter *iter)
165+{
166+ return iter->version;
167+}
168+
169+/*
170+ * DisplayID Primary Use Case (2.0+) or Product Type Identifier (1.0-1.3) from
171+ * the Base Section.
172+ */
173+u8 displayid_primary_use(const struct displayid_iter *iter)
174+{
175+ return iter->primary_use;
176+}
drivers/gpu/drm/drm_dumb_buffers.c+1−4
@@ -139,10 +139,7 @@ int drm_mode_destroy_dumb(struct drm_device *dev, u32 handle, · 138 unmodified lines
139139 if (!dev->driver->dumb_create)
140140 return -ENOSYS;
141141
142− if (dev->driver->dumb_destroy)
143− return dev->driver->dumb_destroy(file_priv, dev, handle);
144− else
145− return drm_gem_dumb_destroy(file_priv, dev, handle);
142+ return drm_gem_handle_delete(file_priv, handle);
146143 }
147144
148145 int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
drivers/gpu/drm/drm_edid.c+56−9
@@ -3424,10 +3424,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto · 3423 unmodified lines
34243424 connector->base.id, connector->name);
34253425 return NULL;
34263426 }
3427− if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
3428− drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Composite sync not supported\n",
3429− connector->base.id, connector->name);
3430− }
34313427
34323428 /* it is incorrect if hsync/vsync width is zero */
34333429 if (!hsync_pulse_width || !vsync_pulse_width) {
@@ -3474,10 +3470,27 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connecto · 40 unmodified lines
34743470 if (info->quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
34753471 mode->flags |= DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC;
34763472 } else {
3477− mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
3478− DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
3479− mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
3480− DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
3473+ switch (pt->misc & DRM_EDID_PT_SYNC_MASK) {
3474+ case DRM_EDID_PT_ANALOG_CSYNC:
3475+ case DRM_EDID_PT_BIPOLAR_ANALOG_CSYNC:
3476+ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Analog composite sync!\n",
3477+ connector->base.id, connector->name);
3478+ mode->flags |= DRM_MODE_FLAG_CSYNC | DRM_MODE_FLAG_NCSYNC;
3479+ break;
3480+ case DRM_EDID_PT_DIGITAL_CSYNC:
3481+ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Digital composite sync!\n",
3482+ connector->base.id, connector->name);
3483+ mode->flags |= DRM_MODE_FLAG_CSYNC;
3484+ mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
3485+ DRM_MODE_FLAG_PCSYNC : DRM_MODE_FLAG_NCSYNC;
3486+ break;
3487+ case DRM_EDID_PT_DIGITAL_SEPARATE_SYNC:
3488+ mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ?
3489+ DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
3490+ mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ?
3491+ DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
3492+ break;
3493+ }
34813494 }
34823495
34833496 set_size:
@@ -6433,6 +6446,29 @@ static void drm_reset_display_info(struct drm_connector *connector) · 2949 unmodified lines
64336446 info->quirks = 0;
64346447 }
64356448
6449+static void update_displayid_info(struct drm_connector *connector,
6450+ const struct drm_edid *drm_edid)
6451+{
6452+ struct drm_display_info *info = &connector->display_info;
6453+ const struct displayid_block *block;
6454+ struct displayid_iter iter;
6455+
6456+ displayid_iter_edid_begin(drm_edid, &iter);
6457+ displayid_iter_for_each(block, &iter) {
6458+ if (displayid_version(&iter) == DISPLAY_ID_STRUCTURE_VER_20 &&
6459+ (displayid_primary_use(&iter) == PRIMARY_USE_HEAD_MOUNTED_VR ||
6460+ displayid_primary_use(&iter) == PRIMARY_USE_HEAD_MOUNTED_AR))
6461+ info->non_desktop = true;
6462+
6463+ /*
6464+ * We're only interested in the base section here, no need to
6465+ * iterate further.
6466+ */
6467+ break;
6468+ }
6469+ displayid_iter_end(&iter);
6470+}
6471+
64366472 static void update_display_info(struct drm_connector *connector,
64376473 const struct drm_edid *drm_edid)
64386474 {
@@ -6463,6 +6499,8 @@ static void update_display_info(struct drm_connector *connector, · 24 unmodified lines
64636499 info->color_formats |= DRM_COLOR_FORMAT_RGB444;
64646500 drm_parse_cea_ext(connector, drm_edid);
64656501
6502+ update_displayid_info(connector, drm_edid);
6503+
64666504 /*
64676505 * Digital sink with "DFP 1.x compliant TMDS" according to EDID 1.3?
64686506 *
@@ -7242,6 +7280,15 @@ static void drm_parse_tiled_block(struct drm_connector *connector, · 773 unmodified lines
72427280 }
72437281 }
72447282
7283+static bool displayid_is_tiled_block(const struct displayid_iter *iter,
7284+ const struct displayid_block *block)
7285+{
7286+ return (displayid_version(iter) == DISPLAY_ID_STRUCTURE_VER_12 &&
7287+ block->tag == DATA_BLOCK_TILED_DISPLAY) ||
7288+ (displayid_version(iter) == DISPLAY_ID_STRUCTURE_VER_20 &&
7289+ block->tag == DATA_BLOCK_2_TILED_DISPLAY_TOPOLOGY);
7290+}
7291+
72457292 static void _drm_update_tile_info(struct drm_connector *connector,
72467293 const struct drm_edid *drm_edid)
72477294 {
@@ -7252,7 +7299,7 @@ static void _drm_update_tile_info(struct drm_connector *connector, · 4 unmodified lines
72527299
72537300 displayid_iter_edid_begin(drm_edid, &iter);
72547301 displayid_iter_for_each(block, &iter) {
7255− if (block->tag == DATA_BLOCK_TILED_DISPLAY)
7302+ if (displayid_is_tiled_block(&iter, block))
72567303 drm_parse_tiled_block(connector, block);
72577304 }
72587305 displayid_iter_end(&iter);
drivers/gpu/drm/drm_gem.c+18−7
@@ -336,13 +336,6 @@ out: · 335 unmodified lines
336336 }
337337 EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset);
338338
339−int drm_gem_dumb_destroy(struct drm_file *file,
340− struct drm_device *dev,
341− u32 handle)
342−{
343− return drm_gem_handle_delete(file, handle);
344−}
345−
346339 /**
347340 * drm_gem_handle_create_tail - internal functions to create a handle
348341 * @file_priv: drm file-private structure to register the handle for
@@ -1466,3 +1459,21 @@ tail: · 1117 unmodified lines
14661459 return freed;
14671460 }
14681461 EXPORT_SYMBOL(drm_gem_lru_scan);
1462+
1463+/**
1464+ * drm_gem_evict - helper to evict backing pages for a GEM object
1465+ * @obj: obj in question
1466+ */
1467+int drm_gem_evict(struct drm_gem_object *obj)
1468+{
1469+ dma_resv_assert_held(obj->resv);
1470+
1471+ if (!dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ))
1472+ return -EBUSY;
1473+
1474+ if (obj->funcs->evict)
1475+ return obj->funcs->evict(obj);
1476+
1477+ return 0;
1478+}
1479+EXPORT_SYMBOL(drm_gem_evict);
drivers/gpu/drm/drm_gem_shmem_helper.c+36−29
@@ -141,7 +141,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) · 140 unmodified lines
141141 {
142142 struct drm_gem_object *obj = &shmem->base;
143143
144− WARN_ON(shmem->vmap_use_count);
144+ drm_WARN_ON(obj->dev, shmem->vmap_use_count);
145145
146146 if (obj->import_attach) {
147147 drm_prime_gem_destroy(obj, shmem->sgt);
@@ -156,7 +156,7 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) · 8 unmodified lines
156156 drm_gem_shmem_put_pages(shmem);
157157 }
158158
159− WARN_ON(shmem->pages_use_count);
159+ drm_WARN_ON(obj->dev, shmem->pages_use_count);
160160
161161 drm_gem_object_release(obj);
162162 mutex_destroy(&shmem->pages_lock);
@@ -175,7 +175,8 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) · 12 unmodified lines
175175
176176 pages = drm_gem_get_pages(obj);
177177 if (IS_ERR(pages)) {
178− DRM_DEBUG_KMS("Failed to get pages (%ld)\n", PTR_ERR(pages));
178+ drm_dbg_kms(obj->dev, "Failed to get pages (%ld)\n",
179+ PTR_ERR(pages));
179180 shmem->pages_use_count = 0;
180181 return PTR_ERR(pages);
181182 }
@@ -207,9 +208,10 @@ static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) · 25 unmodified lines
207208 */
208209 int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
209210 {
211+ struct drm_gem_object *obj = &shmem->base;
210212 int ret;
211213
212− WARN_ON(shmem->base.import_attach);
214+ drm_WARN_ON(obj->dev, obj->import_attach);
213215
214216 ret = mutex_lock_interruptible(&shmem->pages_lock);
215217 if (ret)
@@ -225,7 +227,7 @@ static void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) · 9 unmodified lines
225227 {
226228 struct drm_gem_object *obj = &shmem->base;
227229
228− if (WARN_ON_ONCE(!shmem->pages_use_count))
230+ if (drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count))
229231 return;
230232
231233 if (--shmem->pages_use_count > 0)
@@ -268,7 +270,9 @@ EXPORT_SYMBOL(drm_gem_shmem_put_pages); · 36 unmodified lines
268270 */
269271 int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
270272 {
271− WARN_ON(shmem->base.import_attach);
273+ struct drm_gem_object *obj = &shmem->base;
274+
275+ drm_WARN_ON(obj->dev, obj->import_attach);
272276
273277 return drm_gem_shmem_get_pages(shmem);
274278 }
@@ -283,7 +287,9 @@ EXPORT_SYMBOL(drm_gem_shmem_pin); · 8 unmodified lines
283287 */
284288 void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
285289 {
286− WARN_ON(shmem->base.import_attach);
290+ struct drm_gem_object *obj = &shmem->base;
291+
292+ drm_WARN_ON(obj->dev, obj->import_attach);
287293
288294 drm_gem_shmem_put_pages(shmem);
289295 }
@@ -295,24 +301,22 @@ static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, · 5 unmodified lines
295301 struct drm_gem_object *obj = &shmem->base;
296302 int ret = 0;
297303
298− if (shmem->vmap_use_count++ > 0) {
299− iosys_map_set_vaddr(map, shmem->vaddr);
300− return 0;
301− }
302−
303304 if (obj->import_attach) {
304305 ret = dma_buf_vmap(obj->import_attach->dmabuf, map);
305306 if (!ret) {
306− if (WARN_ON(map->is_iomem)) {
307+ if (drm_WARN_ON(obj->dev, map->is_iomem)) {
307308 dma_buf_vunmap(obj->import_attach->dmabuf, map);
308− ret = -EIO;
309− goto err_put_pages;
309+ return -EIO;
310310 }
311− shmem->vaddr = map->vaddr;
312311 }
313312 } else {
314313 pgprot_t prot = PAGE_KERNEL;
315314
315+ if (shmem->vmap_use_count++ > 0) {
316+ iosys_map_set_vaddr(map, shmem->vaddr);
317+ return 0;
318+ }
319+
316320 ret = drm_gem_shmem_get_pages(shmem);
317321 if (ret)
318322 goto err_zero_use;
@@ -328,7 +332,7 @@ static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, · 9 unmodified lines
328332 }
329333
330334 if (ret) {
331− DRM_DEBUG_KMS("Failed to vmap pages, error %d\n", ret);
335+ drm_dbg_kms(obj->dev, "Failed to vmap pages, error %d\n", ret);
332336 goto err_put_pages;
333337 }
334338
@@ -378,15 +382,15 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, · 43 unmodified lines
378382 {
379383 struct drm_gem_object *obj = &shmem->base;
380384
381− if (WARN_ON_ONCE(!shmem->vmap_use_count))
382− return;
383−
384− if (--shmem->vmap_use_count > 0)
385− return;
386−
387385 if (obj->import_attach) {
388386 dma_buf_vunmap(obj->import_attach->dmabuf, map);
389387 } else {
388+ if (drm_WARN_ON_ONCE(obj->dev, !shmem->vmap_use_count))
389+ return;
390+
391+ if (--shmem->vmap_use_count > 0)
392+ return;
393+
390394 vunmap(shmem->vaddr);
391395 drm_gem_shmem_put_pages(shmem);
392396 }
@@ -461,7 +465,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) · 68 unmodified lines
461465 struct drm_gem_object *obj = &shmem->base;
462466 struct drm_device *dev = obj->dev;
463467
464− WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
468+ drm_WARN_ON(obj->dev, !drm_gem_shmem_is_purgeable(shmem));
465469
466470 dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
467471 sg_free_table(shmem->sgt);
@@ -550,7 +554,7 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) · 82 unmodified lines
550554 mutex_lock(&shmem->pages_lock);
551555
552556 if (page_offset >= num_pages ||
553− WARN_ON_ONCE(!shmem->pages) ||
557+ drm_WARN_ON_ONCE(obj->dev, !shmem->pages) ||
554558 shmem->madv < 0) {
555559 ret = VM_FAULT_SIGBUS;
556560 } else {
@@ -569,7 +573,7 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) · 12 unmodified lines
569573 struct drm_gem_object *obj = vma->vm_private_data;
570574 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
571575
572− WARN_ON(shmem->base.import_attach);
576+ drm_WARN_ON(obj->dev, obj->import_attach);
573577
574578 mutex_lock(&shmem->pages_lock);
575579
@@ -578,7 +582,7 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) · 2 unmodified lines
578582 * mmap'd, vm_open() just grabs an additional reference for the new
579583 * mm the vma is getting copied into (ie. on fork()).
580584 */
581− if (!WARN_ON_ONCE(!shmem->pages_use_count))
585+ if (!drm_WARN_ON_ONCE(obj->dev, !shmem->pages_use_count))
582586 shmem->pages_use_count++;
583587
584588 mutex_unlock(&shmem->pages_lock);
@@ -648,6 +652,9 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap); · 63 unmodified lines
648652 void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
649653 struct drm_printer *p, unsigned int indent)
650654 {
655+ if (shmem->base.import_attach)
656+ return;
657+
651658 drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count);
652659 drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count);
653660 drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
@@ -672,7 +679,7 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) · 18 unmodified lines
672679 {
673680 struct drm_gem_object *obj = &shmem->base;
674681
675− WARN_ON(shmem->base.import_attach);
682+ drm_WARN_ON(obj->dev, obj->import_attach);
676683
677684 return drm_prime_pages_to_sg(obj->dev, shmem->pages, obj->size >> PAGE_SHIFT);
678685 }
@@ -687,7 +694,7 @@ static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_ · 8 unmodified lines
687694 if (shmem->sgt)
688695 return shmem->sgt;
689696
690− WARN_ON(obj->import_attach);
697+ drm_WARN_ON(obj->dev, obj->import_attach);
691698
692699 ret = drm_gem_shmem_get_pages_locked(shmem);
693700 if (ret)
drivers/gpu/drm/drm_gem_vram_helper.c+11−0
@@ -916,6 +916,17 @@ static int bo_driver_move(struct ttm_buffer_object *bo, · 915 unmodified lines
916916 {
917917 struct drm_gem_vram_object *gbo;
918918
919+ if (!bo->resource) {
920+ if (new_mem->mem_type != TTM_PL_SYSTEM) {
921+ hop->mem_type = TTM_PL_SYSTEM;
922+ hop->flags = TTM_PL_FLAG_TEMPORARY;
923+ return -EMULTIHOP;
924+ }
925+
926+ ttm_bo_move_null(bo, new_mem);
927+ return 0;
928+ }
929+
919930 gbo = drm_gem_vram_of_bo(bo);
920931
921932 return drm_gem_vram_bo_driver_move(gbo, evict, ctx, new_mem);
drivers/gpu/drm/drm_internal.h+0−3
@@ -178,9 +178,6 @@ void drm_gem_unpin(struct drm_gem_object *obj); · 177 unmodified lines
178178 int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map);
179179 void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
180180
181−int drm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
182− u32 handle);
183−
184181 /* drm_debugfs.c drm_debugfs_crc.c */
185182 #if defined(CONFIG_DEBUG_FS)
186183 int drm_debugfs_init(struct drm_minor *minor, int minor_id,
drivers/gpu/drm/drm_modes.c+1−2
@@ -2339,8 +2339,7 @@ static int drm_mode_parse_cmdline_named_mode(const char *name, · 2338 unmodified lines
23392339 * @mode: preallocated drm_cmdline_mode structure to fill out
23402340 *
23412341 * This parses @mode_option command line modeline for modes and options to
2342− * configure the connector. If @mode_option is NULL the default command line
2343− * modeline in fb_mode_option will be parsed instead.
2342+ * configure the connector.
23442343 *
23452344 * This uses the same parameters as the fb modedb.c, except for an extra
23462345 * force-enable, force-enable-digital and force-disable bit at the end::
drivers/gpu/drm/drm_of.c+51−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <drm/drm_crtc.h>
1111 #include <drm/drm_device.h>
1212 #include <drm/drm_encoder.h>
13+#include <drm/drm_mipi_dsi.h>
1314 #include <drm/drm_of.h>
1415 #include <drm/drm_panel.h>
1516
@@ -493,3 +494,53 @@ int drm_of_get_data_lanes_count_ep(const struct device_node *port, · 477 unmodified lines
493494 return ret;
494495 }
495496 EXPORT_SYMBOL_GPL(drm_of_get_data_lanes_count_ep);
497+
498+#if IS_ENABLED(CONFIG_DRM_MIPI_DSI)
499+
500+/**
501+ * drm_of_get_dsi_bus - find the DSI bus for a given device
502+ * @dev: parent device of display (SPI, I2C)
503+ *
504+ * Gets parent DSI bus for a DSI device controlled through a bus other
505+ * than MIPI-DCS (SPI, I2C, etc.) using the Device Tree.
506+ *
507+ * Returns pointer to mipi_dsi_host if successful, -EINVAL if the
508+ * request is unsupported, -EPROBE_DEFER if the DSI host is found but
509+ * not available, or -ENODEV otherwise.
510+ */
511+struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev)
512+{
513+ struct mipi_dsi_host *dsi_host;
514+ struct device_node *endpoint, *dsi_host_node;
515+
516+ /*
517+ * Get first endpoint child from device.
518+ */
519+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
520+ if (!endpoint)
521+ return ERR_PTR(-ENODEV);
522+
523+ /*
524+ * Follow the first endpoint to get the DSI host node and then
525+ * release the endpoint since we no longer need it.
526+ */
527+ dsi_host_node = of_graph_get_remote_port_parent(endpoint);
528+ of_node_put(endpoint);
529+ if (!dsi_host_node)
530+ return ERR_PTR(-ENODEV);
531+
532+ /*
533+ * Get the DSI host from the DSI host node. If we get an error
534+ * or the return is null assume we're not ready to probe just
535+ * yet. Release the DSI host node since we're done with it.
536+ */
537+ dsi_host = of_find_mipi_dsi_host_by_node(dsi_host_node);
538+ of_node_put(dsi_host_node);
539+ if (IS_ERR_OR_NULL(dsi_host))
540+ return ERR_PTR(-EPROBE_DEFER);
541+
542+ return dsi_host;
543+}
544+EXPORT_SYMBOL_GPL(drm_of_get_dsi_bus);
545+
546+#endif /* CONFIG_DRM_MIPI_DSI */
drivers/gpu/drm/drm_probe_helper.c+3−2
@@ -590,8 +590,9 @@ retry: · 589 unmodified lines
590590 */
591591 dev->mode_config.delayed_event = true;
592592 if (dev->mode_config.poll_enabled)
593− schedule_delayed_work(&dev->mode_config.output_poll_work,
594− 0);
593+ mod_delayed_work(system_wq,
594+ &dev->mode_config.output_poll_work,
595+ 0);
595596 }
596597
597598 /* Re-enable polling in case the global poll config changed. */
drivers/gpu/drm/drm_suballoc.c+457−0
@@ -0,0 +1,457 @@
1+// SPDX-License-Identifier: GPL-2.0 OR MIT
2+/*
3+ * Copyright 2011 Red Hat Inc.
4+ * Copyright 2023 Intel Corporation.
5+ * All Rights Reserved.
6+ *
7+ * Permission is hereby granted, free of charge, to any person obtaining a
8+ * copy of this software and associated documentation files (the
9+ * "Software"), to deal in the Software without restriction, including
10+ * without limitation the rights to use, copy, modify, merge, publish,
11+ * distribute, sub license, and/or sell copies of the Software, and to
12+ * permit persons to whom the Software is furnished to do so, subject to
13+ * the following conditions:
14+ *
15+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
19+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
22+ *
23+ * The above copyright notice and this permission notice (including the
24+ * next paragraph) shall be included in all copies or substantial portions
25+ * of the Software.
26+ *
27+ */
28+/* Algorithm:
29+ *
30+ * We store the last allocated bo in "hole", we always try to allocate
31+ * after the last allocated bo. Principle is that in a linear GPU ring
32+ * progression was is after last is the oldest bo we allocated and thus
33+ * the first one that should no longer be in use by the GPU.
34+ *
35+ * If it's not the case we skip over the bo after last to the closest
36+ * done bo if such one exist. If none exist and we are not asked to
37+ * block we report failure to allocate.
38+ *
39+ * If we are asked to block we wait on all the oldest fence of all
40+ * rings. We just wait for any of those fence to complete.
41+ */
42+
43+#include <drm/drm_suballoc.h>
44+#include <drm/drm_print.h>
45+#include <linux/slab.h>
46+#include <linux/sched.h>
47+#include <linux/wait.h>
48+#include <linux/dma-fence.h>
49+
50+static void drm_suballoc_remove_locked(struct drm_suballoc *sa);
51+static void drm_suballoc_try_free(struct drm_suballoc_manager *sa_manager);
52+
53+/**
54+ * drm_suballoc_manager_init() - Initialise the drm_suballoc_manager
55+ * @sa_manager: pointer to the sa_manager
56+ * @size: number of bytes we want to suballocate
57+ * @align: alignment for each suballocated chunk
58+ *
59+ * Prepares the suballocation manager for suballocations.
60+ */
61+void drm_suballoc_manager_init(struct drm_suballoc_manager *sa_manager,
62+ size_t size, size_t align)
63+{
64+ unsigned int i;
65+
66+ BUILD_BUG_ON(!is_power_of_2(DRM_SUBALLOC_MAX_QUEUES));
67+
68+ if (!align)
69+ align = 1;
70+
71+ /* alignment must be a power of 2 */
72+ if (WARN_ON_ONCE(align & (align - 1)))
73+ align = roundup_pow_of_two(align);
74+
75+ init_waitqueue_head(&sa_manager->wq);
76+ sa_manager->size = size;
77+ sa_manager->align = align;
78+ sa_manager->hole = &sa_manager->olist;
79+ INIT_LIST_HEAD(&sa_manager->olist);
80+ for (i = 0; i < DRM_SUBALLOC_MAX_QUEUES; ++i)
81+ INIT_LIST_HEAD(&sa_manager->flist[i]);
82+}
83+EXPORT_SYMBOL(drm_suballoc_manager_init);
84+
85+/**
86+ * drm_suballoc_manager_fini() - Destroy the drm_suballoc_manager
87+ * @sa_manager: pointer to the sa_manager
88+ *
89+ * Cleans up the suballocation manager after use. All fences added
90+ * with drm_suballoc_free() must be signaled, or we cannot clean up
91+ * the entire manager.
92+ */
93+void drm_suballoc_manager_fini(struct drm_suballoc_manager *sa_manager)
94+{
95+ struct drm_suballoc *sa, *tmp;
96+
97+ if (!sa_manager->size)
98+ return;
99+
100+ if (!list_empty(&sa_manager->olist)) {
101+ sa_manager->hole = &sa_manager->olist;
102+ drm_suballoc_try_free(sa_manager);
103+ if (!list_empty(&sa_manager->olist))
104+ DRM_ERROR("sa_manager is not empty, clearing anyway\n");
105+ }
106+ list_for_each_entry_safe(sa, tmp, &sa_manager->olist, olist) {
107+ drm_suballoc_remove_locked(sa);
108+ }
109+
110+ sa_manager->size = 0;
111+}
112+EXPORT_SYMBOL(drm_suballoc_manager_fini);
113+
114+static void drm_suballoc_remove_locked(struct drm_suballoc *sa)
115+{
116+ struct drm_suballoc_manager *sa_manager = sa->manager;
117+
118+ if (sa_manager->hole == &sa->olist)
119+ sa_manager->hole = sa->olist.prev;
120+
121+ list_del_init(&sa->olist);
122+ list_del_init(&sa->flist);
123+ dma_fence_put(sa->fence);
124+ kfree(sa);
125+}
126+
127+static void drm_suballoc_try_free(struct drm_suballoc_manager *sa_manager)
128+{
129+ struct drm_suballoc *sa, *tmp;
130+
131+ if (sa_manager->hole->next == &sa_manager->olist)
132+ return;
133+
134+ sa = list_entry(sa_manager->hole->next, struct drm_suballoc, olist);
135+ list_for_each_entry_safe_from(sa, tmp, &sa_manager->olist, olist) {
136+ if (!sa->fence || !dma_fence_is_signaled(sa->fence))
137+ return;
138+
139+ drm_suballoc_remove_locked(sa);
140+ }
141+}
142+
143+static size_t drm_suballoc_hole_soffset(struct drm_suballoc_manager *sa_manager)
144+{
145+ struct list_head *hole = sa_manager->hole;
146+
147+ if (hole != &sa_manager->olist)
148+ return list_entry(hole, struct drm_suballoc, olist)->eoffset;
149+
150+ return 0;
151+}
152+
153+static size_t drm_suballoc_hole_eoffset(struct drm_suballoc_manager *sa_manager)
154+{
155+ struct list_head *hole = sa_manager->hole;
156+
157+ if (hole->next != &sa_manager->olist)
158+ return list_entry(hole->next, struct drm_suballoc, olist)->soffset;
159+ return sa_manager->size;
160+}
161+
162+static bool drm_suballoc_try_alloc(struct drm_suballoc_manager *sa_manager,
163+ struct drm_suballoc *sa,
164+ size_t size, size_t align)
165+{
166+ size_t soffset, eoffset, wasted;
167+
168+ soffset = drm_suballoc_hole_soffset(sa_manager);
169+ eoffset = drm_suballoc_hole_eoffset(sa_manager);
170+ wasted = round_up(soffset, align) - soffset;
171+
172+ if ((eoffset - soffset) >= (size + wasted)) {
173+ soffset += wasted;
174+
175+ sa->manager = sa_manager;
176+ sa->soffset = soffset;
177+ sa->eoffset = soffset + size;
178+ list_add(&sa->olist, sa_manager->hole);
179+ INIT_LIST_HEAD(&sa->flist);
180+ sa_manager->hole = &sa->olist;
181+ return true;
182+ }
183+ return false;
184+}
185+
186+static bool __drm_suballoc_event(struct drm_suballoc_manager *sa_manager,
187+ size_t size, size_t align)
188+{
189+ size_t soffset, eoffset, wasted;
190+ unsigned int i;
191+
192+ for (i = 0; i < DRM_SUBALLOC_MAX_QUEUES; ++i)
193+ if (!list_empty(&sa_manager->flist[i]))
194+ return true;
195+
196+ soffset = drm_suballoc_hole_soffset(sa_manager);
197+ eoffset = drm_suballoc_hole_eoffset(sa_manager);
198+ wasted = round_up(soffset, align) - soffset;
199+
200+ return ((eoffset - soffset) >= (size + wasted));
201+}
202+
203+/**
204+ * drm_suballoc_event() - Check if we can stop waiting
205+ * @sa_manager: pointer to the sa_manager
206+ * @size: number of bytes we want to allocate
207+ * @align: alignment we need to match
208+ *
209+ * Return: true if either there is a fence we can wait for or
210+ * enough free memory to satisfy the allocation directly.
211+ * false otherwise.
212+ */
213+static bool drm_suballoc_event(struct drm_suballoc_manager *sa_manager,
214+ size_t size, size_t align)
215+{
216+ bool ret;
217+
218+ spin_lock(&sa_manager->wq.lock);
219+ ret = __drm_suballoc_event(sa_manager, size, align);
220+ spin_unlock(&sa_manager->wq.lock);
221+ return ret;
222+}
223+
224+static bool drm_suballoc_next_hole(struct drm_suballoc_manager *sa_manager,
225+ struct dma_fence **fences,
226+ unsigned int *tries)
227+{
228+ struct drm_suballoc *best_bo = NULL;
229+ unsigned int i, best_idx;
230+ size_t soffset, best, tmp;
231+
232+ /* if hole points to the end of the buffer */
233+ if (sa_manager->hole->next == &sa_manager->olist) {
234+ /* try again with its beginning */
235+ sa_manager->hole = &sa_manager->olist;
236+ return true;
237+ }
238+
239+ soffset = drm_suballoc_hole_soffset(sa_manager);
240+ /* to handle wrap around we add sa_manager->size */
241+ best = sa_manager->size * 2;
242+ /* go over all fence list and try to find the closest sa
243+ * of the current last
244+ */
245+ for (i = 0; i < DRM_SUBALLOC_MAX_QUEUES; ++i) {
246+ struct drm_suballoc *sa;
247+
248+ fences[i] = NULL;
249+
250+ if (list_empty(&sa_manager->flist[i]))
251+ continue;
252+
253+ sa = list_first_entry(&sa_manager->flist[i],
254+ struct drm_suballoc, flist);
255+
256+ if (!dma_fence_is_signaled(sa->fence)) {
257+ fences[i] = sa->fence;
258+ continue;
259+ }
260+
261+ /* limit the number of tries each freelist gets */
262+ if (tries[i] > 2)
263+ continue;
264+
265+ tmp = sa->soffset;
266+ if (tmp < soffset) {
267+ /* wrap around, pretend it's after */
268+ tmp += sa_manager->size;
269+ }
270+ tmp -= soffset;
271+ if (tmp < best) {
272+ /* this sa bo is the closest one */
273+ best = tmp;
274+ best_idx = i;
275+ best_bo = sa;
276+ }
277+ }
278+
279+ if (best_bo) {
280+ ++tries[best_idx];
281+ sa_manager->hole = best_bo->olist.prev;
282+
283+ /*
284+ * We know that this one is signaled,
285+ * so it's safe to remove it.
286+ */
287+ drm_suballoc_remove_locked(best_bo);
288+ return true;
289+ }
290+ return false;
291+}
292+
293+/**
294+ * drm_suballoc_new() - Make a suballocation.
295+ * @sa_manager: pointer to the sa_manager
296+ * @size: number of bytes we want to suballocate.
297+ * @gfp: gfp flags used for memory allocation. Typically GFP_KERNEL but
298+ * the argument is provided for suballocations from reclaim context or
299+ * where the caller wants to avoid pipelining rather than wait for
300+ * reclaim.
301+ * @intr: Whether to perform waits interruptible. This should typically
302+ * always be true, unless the caller needs to propagate a
303+ * non-interruptible context from above layers.
304+ * @align: Alignment. Must not exceed the default manager alignment.
305+ * If @align is zero, then the manager alignment is used.
306+ *
307+ * Try to make a suballocation of size @size, which will be rounded
308+ * up to the alignment specified in specified in drm_suballoc_manager_init().
309+ *
310+ * Return: a new suballocated bo, or an ERR_PTR.
311+ */
312+struct drm_suballoc *
313+drm_suballoc_new(struct drm_suballoc_manager *sa_manager, size_t size,
314+ gfp_t gfp, bool intr, size_t align)
315+{
316+ struct dma_fence *fences[DRM_SUBALLOC_MAX_QUEUES];
317+ unsigned int tries[DRM_SUBALLOC_MAX_QUEUES];
318+ unsigned int count;
319+ int i, r;
320+ struct drm_suballoc *sa;
321+
322+ if (WARN_ON_ONCE(align > sa_manager->align))
323+ return ERR_PTR(-EINVAL);
324+ if (WARN_ON_ONCE(size > sa_manager->size || !size))
325+ return ERR_PTR(-EINVAL);
326+
327+ if (!align)
328+ align = sa_manager->align;
329+
330+ sa = kmalloc(sizeof(*sa), gfp);
331+ if (!sa)
332+ return ERR_PTR(-ENOMEM);
333+ sa->manager = sa_manager;
334+ sa->fence = NULL;
335+ INIT_LIST_HEAD(&sa->olist);
336+ INIT_LIST_HEAD(&sa->flist);
337+
338+ spin_lock(&sa_manager->wq.lock);
339+ do {
340+ for (i = 0; i < DRM_SUBALLOC_MAX_QUEUES; ++i)
341+ tries[i] = 0;
342+
343+ do {
344+ drm_suballoc_try_free(sa_manager);
345+
346+ if (drm_suballoc_try_alloc(sa_manager, sa,
347+ size, align)) {
348+ spin_unlock(&sa_manager->wq.lock);
349+ return sa;
350+ }
351+
352+ /* see if we can skip over some allocations */
353+ } while (drm_suballoc_next_hole(sa_manager, fences, tries));
354+
355+ for (i = 0, count = 0; i < DRM_SUBALLOC_MAX_QUEUES; ++i)
356+ if (fences[i])
357+ fences[count++] = dma_fence_get(fences[i]);
358+
359+ if (count) {
360+ long t;
361+
362+ spin_unlock(&sa_manager->wq.lock);
363+ t = dma_fence_wait_any_timeout(fences, count, intr,
364+ MAX_SCHEDULE_TIMEOUT,
365+ NULL);
366+ for (i = 0; i < count; ++i)
367+ dma_fence_put(fences[i]);
368+
369+ r = (t > 0) ? 0 : t;
370+ spin_lock(&sa_manager->wq.lock);
371+ } else if (intr) {
372+ /* if we have nothing to wait for block */
373+ r = wait_event_interruptible_locked
374+ (sa_manager->wq,
375+ __drm_suballoc_event(sa_manager, size, align));
376+ } else {
377+ spin_unlock(&sa_manager->wq.lock);
378+ wait_event(sa_manager->wq,
379+ drm_suballoc_event(sa_manager, size, align));
380+ r = 0;
381+ spin_lock(&sa_manager->wq.lock);
382+ }
383+ } while (!r);
384+
385+ spin_unlock(&sa_manager->wq.lock);
386+ kfree(sa);
387+ return ERR_PTR(r);
388+}
389+EXPORT_SYMBOL(drm_suballoc_new);
390+
391+/**
392+ * drm_suballoc_free - Free a suballocation
393+ * @suballoc: pointer to the suballocation
394+ * @fence: fence that signals when suballocation is idle
395+ *
396+ * Free the suballocation. The suballocation can be re-used after @fence signals.
397+ */
398+void drm_suballoc_free(struct drm_suballoc *suballoc,
399+ struct dma_fence *fence)
400+{
401+ struct drm_suballoc_manager *sa_manager;
402+
403+ if (!suballoc)
404+ return;
405+
406+ sa_manager = suballoc->manager;
407+
408+ spin_lock(&sa_manager->wq.lock);
409+ if (fence && !dma_fence_is_signaled(fence)) {
410+ u32 idx;
411+
412+ suballoc->fence = dma_fence_get(fence);
413+ idx = fence->context & (DRM_SUBALLOC_MAX_QUEUES - 1);
414+ list_add_tail(&suballoc->flist, &sa_manager->flist[idx]);
415+ } else {
416+ drm_suballoc_remove_locked(suballoc);
417+ }
418+ wake_up_all_locked(&sa_manager->wq);
419+ spin_unlock(&sa_manager->wq.lock);
420+}
421+EXPORT_SYMBOL(drm_suballoc_free);
422+
423+#ifdef CONFIG_DEBUG_FS
424+void drm_suballoc_dump_debug_info(struct drm_suballoc_manager *sa_manager,
425+ struct drm_printer *p,
426+ unsigned long long suballoc_base)
427+{
428+ struct drm_suballoc *i;
429+
430+ spin_lock(&sa_manager->wq.lock);
431+ list_for_each_entry(i, &sa_manager->olist, olist) {
432+ unsigned long long soffset = i->soffset;
433+ unsigned long long eoffset = i->eoffset;
434+
435+ if (&i->olist == sa_manager->hole)
436+ drm_puts(p, ">");
437+ else
438+ drm_puts(p, " ");
439+
440+ drm_printf(p, "[0x%010llx 0x%010llx] size %8lld",
441+ suballoc_base + soffset, suballoc_base + eoffset,
442+ eoffset - soffset);
443+
444+ if (i->fence)
445+ drm_printf(p, " protected by 0x%016llx on context %llu",
446+ (unsigned long long)i->fence->seqno,
447+ (unsigned long long)i->fence->context);
448+
449+ drm_puts(p, "\n");
450+ }
451+ spin_unlock(&sa_manager->wq.lock);
452+}
453+EXPORT_SYMBOL(drm_suballoc_dump_debug_info);
454+#endif
455+MODULE_AUTHOR("Multiple");
456+MODULE_DESCRIPTION("Range suballocator helper");
457+MODULE_LICENSE("Dual MIT/GPL");
drivers/gpu/drm/i915/gem/i915_gem_ttm.c+11−4
@@ -472,7 +472,7 @@ static int i915_ttm_shrink(struct drm_i915_gem_object *obj, unsigned int flags) · 471 unmodified lines
472472 struct ttm_placement place = {};
473473 int ret;
474474
475− if (!bo->ttm || bo->resource->mem_type != TTM_PL_SYSTEM)
475+ if (!bo->ttm || i915_ttm_cpu_maps_iomem(bo->resource))
476476 return 0;
477477
478478 GEM_BUG_ON(!i915_tt->is_shmem);
@@ -511,7 +511,13 @@ static void i915_ttm_delete_mem_notify(struct ttm_buffer_object *bo) · 32 unmodified lines
511511 {
512512 struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo);
513513
514− if (bo->resource && !i915_ttm_is_ghost_object(bo)) {
514+ /*
515+ * This gets called twice by ttm, so long as we have a ttm resource or
516+ * ttm_tt then we can still safely call this. Due to pipeline-gutting,
517+ * we maybe have NULL bo->resource, but in that case we should always
518+ * have a ttm alive (like if the pages are swapped out).
519+ */
520+ if ((bo->resource || bo->ttm) && !i915_ttm_is_ghost_object(bo)) {
515521 __i915_gem_object_pages_fini(obj);
516522 i915_ttm_free_cached_io_rsgt(obj);
517523 }
@@ -1067,11 +1073,12 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) · 549 unmodified lines
10671073 .interruptible = true,
10681074 .no_wait_gpu = true, /* should be idle already */
10691075 };
1076+ int err;
10701077
10711078 GEM_BUG_ON(!bo->ttm || !(bo->ttm->page_flags & TTM_TT_FLAG_SWAPPED));
10721079
1073− ret = ttm_bo_validate(bo, i915_ttm_sys_placement(), &ctx);
1074− if (ret) {
1080+ err = ttm_bo_validate(bo, i915_ttm_sys_placement(), &ctx);
1081+ if (err) {
10751082 dma_resv_unlock(bo->base.resv);
10761083 return VM_FAULT_SIGBUS;
10771084 }
drivers/gpu/drm/i915/gem/i915_gem_ttm.h+1−1
@@ -98,7 +98,7 @@ static inline bool i915_ttm_gtt_binds_lmem(struct ttm_resource *mem) · 97 unmodified lines
9898 static inline bool i915_ttm_cpu_maps_iomem(struct ttm_resource *mem)
9999 {
100100 /* Once / if we support GGTT, this is also false for cached ttm_tts */
101− return mem->mem_type != I915_PL_SYSTEM;
101+ return mem && mem->mem_type != I915_PL_SYSTEM;
102102 }
103103
104104 bool i915_ttm_resource_mappable(struct ttm_resource *res);
drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c+4−0
@@ -711,6 +711,10 @@ int i915_gem_obj_copy_ttm(struct drm_i915_gem_object *dst, · 710 unmodified lines
711711
712712 assert_object_held(dst);
713713 assert_object_held(src);
714+
715+ if (GEM_WARN_ON(!src_bo->resource || !dst_bo->resource))
716+ return -EINVAL;
717+
714718 i915_deps_init(&deps, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
715719
716720 ret = dma_resv_reserve_fences(src_bo->base.resv, 1);
drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c+5−2
@@ -53,7 +53,7 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region *apply, · 52 unmodified lines
5353 unsigned int flags;
5454 int err = 0;
5555
56− if (bo->resource->mem_type == I915_PL_SYSTEM || obj->ttm.backup)
56+ if (!i915_ttm_cpu_maps_iomem(bo->resource) || obj->ttm.backup)
5757 return 0;
5858
5959 if (pm_apply->allow_gpu && i915_gem_object_evictable(obj))
@@ -187,7 +187,10 @@ static int i915_ttm_restore(struct i915_gem_apply_to_region *apply, · 127 unmodified lines
187187 return err;
188188
189189 /* Content may have been swapped. */
190− err = ttm_tt_populate(backup_bo->bdev, backup_bo->ttm, &ctx);
190+ if (!backup_bo->resource)
191+ err = ttm_bo_validate(backup_bo, i915_ttm_sys_placement(), &ctx);
192+ if (!err)
193+ err = ttm_tt_populate(backup_bo->bdev, backup_bo->ttm, &ctx);
191194 if (!err) {
192195 err = i915_gem_obj_copy_ttm(obj, backup, pm_apply->allow_gpu,
193196 false);
drivers/gpu/drm/meson/meson_venc.c+2−2
@@ -866,10 +866,10 @@ meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode) · 865 unmodified lines
866866 DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))
867867 return MODE_BAD;
868868
869− if (mode->hdisplay < 640 || mode->hdisplay > 1920)
869+ if (mode->hdisplay < 400 || mode->hdisplay > 1920)
870870 return MODE_BAD_HVALUE;
871871
872− if (mode->vdisplay < 480 || mode->vdisplay > 1200)
872+ if (mode->vdisplay < 480 || mode->vdisplay > 1920)
873873 return MODE_BAD_VVALUE;
874874
875875 return MODE_OK;
drivers/gpu/drm/mgag200/mgag200_drv.h+3−0
@@ -375,12 +375,15 @@ int mgag200_primary_plane_helper_atomic_check(struct drm_plane *plane, · 374 unmodified lines
375375 struct drm_atomic_state *new_state);
376376 void mgag200_primary_plane_helper_atomic_update(struct drm_plane *plane,
377377 struct drm_atomic_state *old_state);
378+void mgag200_primary_plane_helper_atomic_enable(struct drm_plane *plane,
379+ struct drm_atomic_state *state);
378380 void mgag200_primary_plane_helper_atomic_disable(struct drm_plane *plane,
379381 struct drm_atomic_state *old_state);
380382 #define MGAG200_PRIMARY_PLANE_HELPER_FUNCS \
381383 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, \
382384 .atomic_check = mgag200_primary_plane_helper_atomic_check, \
383385 .atomic_update = mgag200_primary_plane_helper_atomic_update, \
386+ .atomic_enable = mgag200_primary_plane_helper_atomic_enable, \
384387 .atomic_disable = mgag200_primary_plane_helper_atomic_disable
385388
386389 #define MGAG200_PRIMARY_PLANE_FUNCS \
drivers/gpu/drm/mgag200/mgag200_mode.c+12−10
@@ -501,10 +501,6 @@ void mgag200_primary_plane_helper_atomic_update(struct drm_plane *plane, · 500 unmodified lines
501501 struct drm_framebuffer *fb = plane_state->fb;
502502 struct drm_atomic_helper_damage_iter iter;
503503 struct drm_rect damage;
504− u8 seq1;
505−
506− if (!fb)
507− return;
508504
509505 drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
510506 drm_atomic_for_each_plane_damage(&iter, &damage) {
@@ -514,13 +510,19 @@ void mgag200_primary_plane_helper_atomic_update(struct drm_plane *plane, · 3 unmodified lines
514510 /* Always scanout image at VRAM offset 0 */
515511 mgag200_set_startadd(mdev, (u32)0);
516512 mgag200_set_offset(mdev, fb);
513+}
517514
518− if (!old_plane_state->crtc && plane_state->crtc) { // enabling
519− RREG_SEQ(0x01, seq1);
520− seq1 &= ~MGAREG_SEQ1_SCROFF;
521− WREG_SEQ(0x01, seq1);
522− msleep(20);
523− }
515+void mgag200_primary_plane_helper_atomic_enable(struct drm_plane *plane,
516+ struct drm_atomic_state *state)
517+{
518+ struct drm_device *dev = plane->dev;
519+ struct mga_device *mdev = to_mga_device(dev);
520+ u8 seq1;
521+
522+ RREG_SEQ(0x01, seq1);
523+ seq1 &= ~MGAREG_SEQ1_SCROFF;
524+ WREG_SEQ(0x01, seq1);
525+ msleep(20);
524526 }
525527
526528 void mgag200_primary_plane_helper_atomic_disable(struct drm_plane *plane,
drivers/gpu/drm/nouveau/nouveau_bo.c+0−3
@@ -1015,9 +1015,6 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, · 1014 unmodified lines
10151015 if (ret)
10161016 goto out_ntfy;
10171017
1018− if (nvbo->bo.pin_count)
1019− NV_WARN(drm, "Moving pinned object %p!\n", nvbo);
1020−
10211018 if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) {
10221019 ret = nouveau_bo_vm_bind(bo, new_reg, &new_tile);
10231020 if (ret)
drivers/gpu/drm/nouveau/nouveau_hwmon.c+5−5
@@ -41,7 +41,7 @@ static ssize_t · 40 unmodified lines
4141 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
4242 struct device_attribute *a, char *buf)
4343 {
44− return snprintf(buf, PAGE_SIZE, "%d\n", 100);
44+ return sysfs_emit(buf, "%d\n", 100);
4545 }
4646 static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
4747 nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
@@ -54,8 +54,8 @@ nouveau_hwmon_temp1_auto_point1_temp(struct device *d, · 6 unmodified lines
5454 struct nouveau_drm *drm = nouveau_drm(dev);
5555 struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
5656
57− return snprintf(buf, PAGE_SIZE, "%d\n",
58− therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000);
57+ return sysfs_emit(buf, "%d\n",
58+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST) * 1000);
5959 }
6060 static ssize_t
6161 nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
@@ -87,8 +87,8 @@ nouveau_hwmon_temp1_auto_point1_temp_hyst(struct device *d, · 25 unmodified lines
8787 struct nouveau_drm *drm = nouveau_drm(dev);
8888 struct nvkm_therm *therm = nvxx_therm(&drm->client.device);
8989
90− return snprintf(buf, PAGE_SIZE, "%d\n",
91− therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
90+ return sysfs_emit(buf, "%d\n",
91+ therm->attr_get(therm, NVKM_THERM_ATTR_THRS_FAN_BOOST_HYST) * 1000);
9292 }
9393 static ssize_t
9494 nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device *d,
drivers/gpu/drm/nouveau/nouveau_led.h+1−1
@@ -27,7 +27,7 @@ · 26 unmodified lines
2727
2828 #include "nouveau_drv.h"
2929
30−struct led_classdev;
30+#include <linux/leds.h>
3131
3232 struct nouveau_led {
3333 struct drm_device *dev;
drivers/gpu/drm/panel/Kconfig+11−0
@@ -318,6 +318,17 @@ config DRM_PANEL_LG_LG4573 · 317 unmodified lines
318318 Say Y here if you want to enable support for LG4573 RGB panel.
319319 To compile this driver as a module, choose M here.
320320
321+config DRM_PANEL_MAGNACHIP_D53E6EA8966
322+ tristate "Magnachip D53E6EA8966 DSI panel"
323+ depends on OF && SPI
324+ depends on DRM_MIPI_DSI
325+ depends on BACKLIGHT_CLASS_DEVICE
326+ select DRM_MIPI_DBI
327+ help
328+ DRM panel driver for the Samsung AMS495QA01 panel controlled
329+ with the Magnachip D53E6EA8966 panel IC. This panel receives
330+ video data via DSI but commands via 9-bit SPI using DBI.
331+
321332 config DRM_PANEL_NEC_NL8048HL11
322333 tristate "NEC NL8048HL11 RGB panel"
323334 depends on GPIOLIB && OF && SPI
drivers/gpu/drm/panel/Makefile+1−0
@@ -29,6 +29,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o · 28 unmodified lines
2929 obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o
3030 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
3131 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
32+obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += panel-magnachip-d53e6ea8966.o
3233 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
3334 obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o
3435 obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o
drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c+208−1
@@ -167,6 +167,202 @@ static const struct drm_panel_funcs jadard_funcs = { · 166 unmodified lines
167167 .get_modes = jadard_get_modes,
168168 };
169169
170+static const struct jadard_init_cmd radxa_display_8hd_ad002_init_cmds[] = {
171+ { .data = { 0xE0, 0x00 } },
172+ { .data = { 0xE1, 0x93 } },
173+ { .data = { 0xE2, 0x65 } },
174+ { .data = { 0xE3, 0xF8 } },
175+ { .data = { 0x80, 0x03 } },
176+ { .data = { 0xE0, 0x01 } },
177+ { .data = { 0x00, 0x00 } },
178+ { .data = { 0x01, 0x7E } },
179+ { .data = { 0x03, 0x00 } },
180+ { .data = { 0x04, 0x65 } },
181+ { .data = { 0x0C, 0x74 } },
182+ { .data = { 0x17, 0x00 } },
183+ { .data = { 0x18, 0xB7 } },
184+ { .data = { 0x19, 0x00 } },
185+ { .data = { 0x1A, 0x00 } },
186+ { .data = { 0x1B, 0xB7 } },
187+ { .data = { 0x1C, 0x00 } },
188+ { .data = { 0x24, 0xFE } },
189+ { .data = { 0x37, 0x19 } },
190+ { .data = { 0x38, 0x05 } },
191+ { .data = { 0x39, 0x00 } },
192+ { .data = { 0x3A, 0x01 } },
193+ { .data = { 0x3B, 0x01 } },
194+ { .data = { 0x3C, 0x70 } },
195+ { .data = { 0x3D, 0xFF } },
196+ { .data = { 0x3E, 0xFF } },
197+ { .data = { 0x3F, 0xFF } },
198+ { .data = { 0x40, 0x06 } },
199+ { .data = { 0x41, 0xA0 } },
200+ { .data = { 0x43, 0x1E } },
201+ { .data = { 0x44, 0x0F } },
202+ { .data = { 0x45, 0x28 } },
203+ { .data = { 0x4B, 0x04 } },
204+ { .data = { 0x55, 0x02 } },
205+ { .data = { 0x56, 0x01 } },
206+ { .data = { 0x57, 0xA9 } },
207+ { .data = { 0x58, 0x0A } },
208+ { .data = { 0x59, 0x0A } },
209+ { .data = { 0x5A, 0x37 } },
210+ { .data = { 0x5B, 0x19 } },
211+ { .data = { 0x5D, 0x78 } },
212+ { .data = { 0x5E, 0x63 } },
213+ { .data = { 0x5F, 0x54 } },
214+ { .data = { 0x60, 0x49 } },
215+ { .data = { 0x61, 0x45 } },
216+ { .data = { 0x62, 0x38 } },
217+ { .data = { 0x63, 0x3D } },
218+ { .data = { 0x64, 0x28 } },
219+ { .data = { 0x65, 0x43 } },
220+ { .data = { 0x66, 0x41 } },
221+ { .data = { 0x67, 0x43 } },
222+ { .data = { 0x68, 0x62 } },
223+ { .data = { 0x69, 0x50 } },
224+ { .data = { 0x6A, 0x57 } },
225+ { .data = { 0x6B, 0x49 } },
226+ { .data = { 0x6C, 0x44 } },
227+ { .data = { 0x6D, 0x37 } },
228+ { .data = { 0x6E, 0x23 } },
229+ { .data = { 0x6F, 0x10 } },
230+ { .data = { 0x70, 0x78 } },
231+ { .data = { 0x71, 0x63 } },
232+ { .data = { 0x72, 0x54 } },
233+ { .data = { 0x73, 0x49 } },
234+ { .data = { 0x74, 0x45 } },
235+ { .data = { 0x75, 0x38 } },
236+ { .data = { 0x76, 0x3D } },
237+ { .data = { 0x77, 0x28 } },
238+ { .data = { 0x78, 0x43 } },
239+ { .data = { 0x79, 0x41 } },
240+ { .data = { 0x7A, 0x43 } },
241+ { .data = { 0x7B, 0x62 } },
242+ { .data = { 0x7C, 0x50 } },
243+ { .data = { 0x7D, 0x57 } },
244+ { .data = { 0x7E, 0x49 } },
245+ { .data = { 0x7F, 0x44 } },
246+ { .data = { 0x80, 0x37 } },
247+ { .data = { 0x81, 0x23 } },
248+ { .data = { 0x82, 0x10 } },
249+ { .data = { 0xE0, 0x02 } },
250+ { .data = { 0x00, 0x47 } },
251+ { .data = { 0x01, 0x47 } },
252+ { .data = { 0x02, 0x45 } },
253+ { .data = { 0x03, 0x45 } },
254+ { .data = { 0x04, 0x4B } },
255+ { .data = { 0x05, 0x4B } },
256+ { .data = { 0x06, 0x49 } },
257+ { .data = { 0x07, 0x49 } },
258+ { .data = { 0x08, 0x41 } },
259+ { .data = { 0x09, 0x1F } },
260+ { .data = { 0x0A, 0x1F } },
261+ { .data = { 0x0B, 0x1F } },
262+ { .data = { 0x0C, 0x1F } },
263+ { .data = { 0x0D, 0x1F } },
264+ { .data = { 0x0E, 0x1F } },
265+ { .data = { 0x0F, 0x5F } },
266+ { .data = { 0x10, 0x5F } },
267+ { .data = { 0x11, 0x57 } },
268+ { .data = { 0x12, 0x77 } },
269+ { .data = { 0x13, 0x35 } },
270+ { .data = { 0x14, 0x1F } },
271+ { .data = { 0x15, 0x1F } },
272+ { .data = { 0x16, 0x46 } },
273+ { .data = { 0x17, 0x46 } },
274+ { .data = { 0x18, 0x44 } },
275+ { .data = { 0x19, 0x44 } },
276+ { .data = { 0x1A, 0x4A } },
277+ { .data = { 0x1B, 0x4A } },
278+ { .data = { 0x1C, 0x48 } },
279+ { .data = { 0x1D, 0x48 } },
280+ { .data = { 0x1E, 0x40 } },
281+ { .data = { 0x1F, 0x1F } },
282+ { .data = { 0x20, 0x1F } },
283+ { .data = { 0x21, 0x1F } },
284+ { .data = { 0x22, 0x1F } },
285+ { .data = { 0x23, 0x1F } },
286+ { .data = { 0x24, 0x1F } },
287+ { .data = { 0x25, 0x5F } },
288+ { .data = { 0x26, 0x5F } },
289+ { .data = { 0x27, 0x57 } },
290+ { .data = { 0x28, 0x77 } },
291+ { .data = { 0x29, 0x35 } },
292+ { .data = { 0x2A, 0x1F } },
293+ { .data = { 0x2B, 0x1F } },
294+ { .data = { 0x58, 0x40 } },
295+ { .data = { 0x59, 0x00 } },
296+ { .data = { 0x5A, 0x00 } },
297+ { .data = { 0x5B, 0x10 } },
298+ { .data = { 0x5C, 0x06 } },
299+ { .data = { 0x5D, 0x40 } },
300+ { .data = { 0x5E, 0x01 } },
301+ { .data = { 0x5F, 0x02 } },
302+ { .data = { 0x60, 0x30 } },
303+ { .data = { 0x61, 0x01 } },
304+ { .data = { 0x62, 0x02 } },
305+ { .data = { 0x63, 0x03 } },
306+ { .data = { 0x64, 0x6B } },
307+ { .data = { 0x65, 0x05 } },
308+ { .data = { 0x66, 0x0C } },
309+ { .data = { 0x67, 0x73 } },
310+ { .data = { 0x68, 0x09 } },
311+ { .data = { 0x69, 0x03 } },
312+ { .data = { 0x6A, 0x56 } },
313+ { .data = { 0x6B, 0x08 } },
314+ { .data = { 0x6C, 0x00 } },
315+ { .data = { 0x6D, 0x04 } },
316+ { .data = { 0x6E, 0x04 } },
317+ { .data = { 0x6F, 0x88 } },
318+ { .data = { 0x70, 0x00 } },
319+ { .data = { 0x71, 0x00 } },
320+ { .data = { 0x72, 0x06 } },
321+ { .data = { 0x73, 0x7B } },
322+ { .data = { 0x74, 0x00 } },
323+ { .data = { 0x75, 0xF8 } },
324+ { .data = { 0x76, 0x00 } },
325+ { .data = { 0x77, 0xD5 } },
326+ { .data = { 0x78, 0x2E } },
327+ { .data = { 0x79, 0x12 } },
328+ { .data = { 0x7A, 0x03 } },
329+ { .data = { 0x7B, 0x00 } },
330+ { .data = { 0x7C, 0x00 } },
331+ { .data = { 0x7D, 0x03 } },
332+ { .data = { 0x7E, 0x7B } },
333+ { .data = { 0xE0, 0x04 } },
334+ { .data = { 0x00, 0x0E } },
335+ { .data = { 0x02, 0xB3 } },
336+ { .data = { 0x09, 0x60 } },
337+ { .data = { 0x0E, 0x2A } },
338+ { .data = { 0x36, 0x59 } },
339+ { .data = { 0xE0, 0x00 } },
340+};
341+
342+static const struct jadard_panel_desc radxa_display_8hd_ad002_desc = {
343+ .mode = {
344+ .clock = 70000,
345+
346+ .hdisplay = 800,
347+ .hsync_start = 800 + 40,
348+ .hsync_end = 800 + 40 + 18,
349+ .htotal = 800 + 40 + 18 + 20,
350+
351+ .vdisplay = 1280,
352+ .vsync_start = 1280 + 20,
353+ .vsync_end = 1280 + 20 + 4,
354+ .vtotal = 1280 + 20 + 4 + 20,
355+
356+ .width_mm = 127,
357+ .height_mm = 199,
358+ .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
359+ },
360+ .lanes = 4,
361+ .format = MIPI_DSI_FMT_RGB888,
362+ .init_cmds = radxa_display_8hd_ad002_init_cmds,
363+ .num_init_cmds = ARRAY_SIZE(radxa_display_8hd_ad002_init_cmds),
364+};
365+
170366 static const struct jadard_init_cmd cz101b4001_init_cmds[] = {
171367 { .data = { 0xE0, 0x00 } },
172368 { .data = { 0xE1, 0x93 } },
@@ -452,7 +648,18 @@ static void jadard_dsi_remove(struct mipi_dsi_device *dsi) · 279 unmodified lines
452648 }
453649
454650 static const struct of_device_id jadard_of_match[] = {
455− { .compatible = "chongzhou,cz101b4001", .data = &cz101b4001_desc },
651+ {
652+ .compatible = "chongzhou,cz101b4001",
653+ .data = &cz101b4001_desc
654+ },
655+ {
656+ .compatible = "radxa,display-10hd-ad001",
657+ .data = &cz101b4001_desc
658+ },
659+ {
660+ .compatible = "radxa,display-8hd-ad002",
661+ .data = &radxa_display_8hd_ad002_desc
662+ },
456663 { /* sentinel */ }
457664 };
458665 MODULE_DEVICE_TABLE(of, jadard_of_match);
drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c+522−0
@@ -0,0 +1,522 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Magnachip d53e6ea8966 MIPI-DSI panel driver
4+ * Copyright (C) 2023 Chris Morgan
5+ */
6+
7+#include <drm/drm_mipi_dbi.h>
8+#include <drm/drm_mipi_dsi.h>
9+#include <drm/drm_modes.h>
10+#include <drm/drm_of.h>
11+#include <drm/drm_panel.h>
12+
13+#include <linux/backlight.h>
14+#include <linux/delay.h>
15+#include <linux/gpio/consumer.h>
16+#include <linux/init.h>
17+#include <linux/kernel.h>
18+#include <linux/media-bus-format.h>
19+#include <linux/module.h>
20+#include <linux/of.h>
21+#include <linux/of_device.h>
22+#include <linux/regulator/consumer.h>
23+#include <linux/spi/spi.h>
24+
25+#include <video/mipi_display.h>
26+
27+/* Forward declaration for use in backlight function */
28+struct d53e6ea8966;
29+
30+/* Panel info, unique to each panel */
31+struct d53e6ea8966_panel_info {
32+ /** @display_modes: the supported display modes */
33+ const struct drm_display_mode *display_modes;
34+ /** @num_modes: the number of supported display modes */
35+ unsigned int num_modes;
36+ /** @width_mm: panel width in mm */
37+ u16 width_mm;
38+ /** @height_mm: panel height in mm */
39+ u16 height_mm;
40+ /** @bus_flags: drm bus flags for panel */
41+ u32 bus_flags;
42+ /** @panel_init_seq: panel specific init sequence */
43+ void (*panel_init_seq)(struct d53e6ea8966 *db);
44+ /** @backlight_register: panel backlight registration or NULL */
45+ int (*backlight_register)(struct d53e6ea8966 *db);
46+};
47+
48+struct d53e6ea8966 {
49+ /** @dev: the container device */
50+ struct device *dev;
51+ /** @dbi: the DBI bus abstraction handle */
52+ struct mipi_dbi dbi;
53+ /** @panel: the DRM panel instance for this device */
54+ struct drm_panel panel;
55+ /** @reset: reset GPIO line */
56+ struct gpio_desc *reset;
57+ /** @enable: enable GPIO line */
58+ struct gpio_desc *enable;
59+ /** @reg_vdd: VDD supply regulator for panel logic */
60+ struct regulator *reg_vdd;
61+ /** @reg_elvdd: ELVDD supply regulator for panel display */
62+ struct regulator *reg_elvdd;
63+ /** @dsi_dev: DSI child device (panel) */
64+ struct mipi_dsi_device *dsi_dev;
65+ /** @bl_dev: pseudo-backlight device for oled panel */
66+ struct backlight_device *bl_dev;
67+ /** @panel_info: struct containing panel timing and info */
68+ const struct d53e6ea8966_panel_info *panel_info;
69+};
70+
71+#define NUM_GAMMA_LEVELS 16
72+#define GAMMA_TABLE_COUNT 23
73+#define MAX_BRIGHTNESS (NUM_GAMMA_LEVELS - 1)
74+
75+#define MCS_ELVSS_ON 0xb1
76+#define MCS_TEMP_SWIRE 0xb2
77+#define MCS_PASSWORD_0 0xf0
78+#define MCS_PASSWORD_1 0xf1
79+#define MCS_ANALOG_PWR_CTL_0 0xf4
80+#define MCS_ANALOG_PWR_CTL_1 0xf5
81+#define MCS_GTCON_SET 0xf7
82+#define MCS_GATELESS_SIGNAL_SET 0xf8
83+#define MCS_SET_GAMMA 0xf9
84+
85+static inline struct d53e6ea8966 *to_d53e6ea8966(struct drm_panel *panel)
86+{
87+ return container_of(panel, struct d53e6ea8966, panel);
88+}
89+
90+/* Table of gamma values provided in datasheet */
91+static u8 ams495qa01_gamma[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = {
92+ {0x01, 0x79, 0x78, 0x8d, 0xd9, 0xdf, 0xd5, 0xcb, 0xcf, 0xc5,
93+ 0xe5, 0xe0, 0xe4, 0xdc, 0xb8, 0xd4, 0xfa, 0xed, 0xe6, 0x2f,
94+ 0x00, 0x2f},
95+ {0x01, 0x7d, 0x7c, 0x92, 0xd7, 0xdd, 0xd2, 0xcb, 0xd0, 0xc6,
96+ 0xe5, 0xe1, 0xe3, 0xda, 0xbd, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
97+ 0x00, 0x2f},
98+ {0x01, 0x7f, 0x7e, 0x95, 0xd7, 0xde, 0xd2, 0xcb, 0xcf, 0xc5,
99+ 0xe5, 0xe3, 0xe3, 0xda, 0xbf, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
100+ 0x00, 0x2f},
101+ {0x01, 0x82, 0x81, 0x99, 0xd6, 0xdd, 0xd1, 0xca, 0xcf, 0xc3,
102+ 0xe4, 0xe3, 0xe3, 0xda, 0xc2, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
103+ 0x00, 0x2f},
104+ {0x01, 0x84, 0x83, 0x9b, 0xd7, 0xde, 0xd2, 0xc8, 0xce, 0xc2,
105+ 0xe4, 0xe3, 0xe2, 0xd9, 0xc3, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
106+ 0x00, 0x2f},
107+ {0x01, 0x87, 0x86, 0x9f, 0xd6, 0xdd, 0xd1, 0xc7, 0xce, 0xc1,
108+ 0xe4, 0xe3, 0xe2, 0xd9, 0xc6, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
109+ 0x00, 0x2f},
110+ {0x01, 0x89, 0x89, 0xa2, 0xd5, 0xdb, 0xcf, 0xc8, 0xcf, 0xc2,
111+ 0xe3, 0xe3, 0xe1, 0xd9, 0xc7, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
112+ 0x00, 0x2f},
113+ {0x01, 0x8b, 0x8b, 0xa5, 0xd5, 0xdb, 0xcf, 0xc7, 0xce, 0xc0,
114+ 0xe3, 0xe3, 0xe1, 0xd8, 0xc7, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
115+ 0x00, 0x2f},
116+ {0x01, 0x8d, 0x8d, 0xa7, 0xd5, 0xdb, 0xcf, 0xc6, 0xce, 0xc0,
117+ 0xe4, 0xe4, 0xe1, 0xd7, 0xc8, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
118+ 0x00, 0x2f},
119+ {0x01, 0x8f, 0x8f, 0xaa, 0xd4, 0xdb, 0xce, 0xc6, 0xcd, 0xbf,
120+ 0xe3, 0xe3, 0xe1, 0xd7, 0xca, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
121+ 0x00, 0x2f},
122+ {0x01, 0x91, 0x91, 0xac, 0xd3, 0xda, 0xce, 0xc5, 0xcd, 0xbe,
123+ 0xe3, 0xe3, 0xe0, 0xd7, 0xca, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
124+ 0x00, 0x2f},
125+ {0x01, 0x93, 0x93, 0xaf, 0xd3, 0xda, 0xcd, 0xc5, 0xcd, 0xbe,
126+ 0xe2, 0xe3, 0xdf, 0xd6, 0xca, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
127+ 0x00, 0x2f},
128+ {0x01, 0x95, 0x95, 0xb1, 0xd2, 0xd9, 0xcc, 0xc4, 0xcd, 0xbe,
129+ 0xe2, 0xe3, 0xdf, 0xd7, 0xcc, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
130+ 0x00, 0x2f},
131+ {0x01, 0x99, 0x99, 0xb6, 0xd1, 0xd9, 0xcc, 0xc3, 0xcb, 0xbc,
132+ 0xe2, 0xe4, 0xdf, 0xd6, 0xcc, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
133+ 0x00, 0x2f},
134+ {0x01, 0x9c, 0x9c, 0xba, 0xd0, 0xd8, 0xcb, 0xc3, 0xcb, 0xbb,
135+ 0xe2, 0xe4, 0xdf, 0xd6, 0xce, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
136+ 0x00, 0x2f},
137+ {0x01, 0x9f, 0x9f, 0xbe, 0xcf, 0xd7, 0xc9, 0xc2, 0xcb, 0xbb,
138+ 0xe1, 0xe3, 0xde, 0xd6, 0xd0, 0xd3, 0xfa, 0xed, 0xe6, 0x2f,
139+ 0x00, 0x2f},
140+};
141+
142+/*
143+ * Table of elvss values provided in datasheet and corresponds to
144+ * gamma values.
145+ */
146+static u8 ams495qa01_elvss[NUM_GAMMA_LEVELS] = {
147+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
148+ 0x15, 0x15, 0x14, 0x14, 0x13, 0x12,
149+};
150+
151+static int ams495qa01_update_gamma(struct mipi_dbi *dbi, int brightness)
152+{
153+ int tmp = brightness;
154+
155+ mipi_dbi_command_buf(dbi, MCS_SET_GAMMA, ams495qa01_gamma[tmp],
156+ ARRAY_SIZE(ams495qa01_gamma[tmp]));
157+ mipi_dbi_command(dbi, MCS_SET_GAMMA, 0x00);
158+
159+ /* Undocumented command */
160+ mipi_dbi_command(dbi, 0x26, 0x00);
161+
162+ mipi_dbi_command(dbi, MCS_TEMP_SWIRE, ams495qa01_elvss[tmp]);
163+
164+ return 0;
165+}
166+
167+static void ams495qa01_panel_init(struct d53e6ea8966 *db)
168+{
169+ struct mipi_dbi *dbi = &db->dbi;
170+
171+ mipi_dbi_command(dbi, MCS_PASSWORD_0, 0x5a, 0x5a);
172+ mipi_dbi_command(dbi, MCS_PASSWORD_1, 0x5a, 0x5a);
173+
174+ /* Undocumented commands */
175+ mipi_dbi_command(dbi, 0xb0, 0x02);
176+ mipi_dbi_command(dbi, 0xf3, 0x3b);
177+
178+ mipi_dbi_command(dbi, MCS_ANALOG_PWR_CTL_0, 0x33, 0x42, 0x00, 0x08);
179+ mipi_dbi_command(dbi, MCS_ANALOG_PWR_CTL_1, 0x00, 0x06, 0x26, 0x35, 0x03);
180+
181+ /* Undocumented commands */
182+ mipi_dbi_command(dbi, 0xf6, 0x02);
183+ mipi_dbi_command(dbi, 0xc6, 0x0b, 0x00, 0x00, 0x3c, 0x00, 0x22,
184+ 0x00, 0x00, 0x00, 0x00);
185+
186+ mipi_dbi_command(dbi, MCS_GTCON_SET, 0x20);
187+ mipi_dbi_command(dbi, MCS_TEMP_SWIRE, 0x06, 0x06, 0x06, 0x06);
188+ mipi_dbi_command(dbi, MCS_ELVSS_ON, 0x07, 0x00, 0x10);
189+ mipi_dbi_command(dbi, MCS_GATELESS_SIGNAL_SET, 0x7f, 0x7a,
190+ 0x89, 0x67, 0x26, 0x38, 0x00, 0x00, 0x09,
191+ 0x67, 0x70, 0x88, 0x7a, 0x76, 0x05, 0x09,
192+ 0x23, 0x23, 0x23);
193+
194+ /* Undocumented commands */
195+ mipi_dbi_command(dbi, 0xb5, 0xff, 0xef, 0x35, 0x42, 0x0d, 0xd7,
196+ 0xff, 0x07, 0xff, 0xff, 0xfd, 0x00, 0x01,
197+ 0xff, 0x05, 0x12, 0x0f, 0xff, 0xff, 0xff,
198+ 0xff);
199+ mipi_dbi_command(dbi, 0xb4, 0x15);
200+ mipi_dbi_command(dbi, 0xb3, 0x00);
201+
202+ ams495qa01_update_gamma(dbi, MAX_BRIGHTNESS);
203+}
204+
205+static int d53e6ea8966_prepare(struct drm_panel *panel)
206+{
207+ struct d53e6ea8966 *db = to_d53e6ea8966(panel);
208+ int ret;
209+
210+ /* Power up */
211+ ret = regulator_enable(db->reg_vdd);
212+ if (ret) {
213+ dev_err(db->dev, "failed to enable vdd regulator: %d\n", ret);
214+ return ret;
215+ }
216+
217+ if (db->reg_elvdd) {
218+ ret = regulator_enable(db->reg_elvdd);
219+ if (ret) {
220+ dev_err(db->dev,
221+ "failed to enable elvdd regulator: %d\n", ret);
222+ regulator_disable(db->reg_vdd);
223+ return ret;
224+ }
225+ }
226+
227+ /* Enable */
228+ if (db->enable)
229+ gpiod_set_value_cansleep(db->enable, 1);
230+
231+ msleep(50);
232+
233+ /* Reset */
234+ gpiod_set_value_cansleep(db->reset, 1);
235+ usleep_range(1000, 5000);
236+ gpiod_set_value_cansleep(db->reset, 0);
237+ msleep(20);
238+
239+ db->panel_info->panel_init_seq(db);
240+
241+ return 0;
242+}
243+
244+static int d53e6ea8966_enable(struct drm_panel *panel)
245+{
246+ struct d53e6ea8966 *db = to_d53e6ea8966(panel);
247+ struct mipi_dbi *dbi = &db->dbi;
248+
249+ mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
250+ msleep(200);
251+ mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
252+ usleep_range(10000, 15000);
253+
254+ return 0;
255+}
256+
257+static int d53e6ea8966_disable(struct drm_panel *panel)
258+{
259+ struct d53e6ea8966 *db = to_d53e6ea8966(panel);
260+ struct mipi_dbi *dbi = &db->dbi;
261+
262+ mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
263+ msleep(20);
264+ mipi_dbi_command(dbi, MIPI_DCS_ENTER_SLEEP_MODE);
265+ msleep(100);
266+
267+ return 0;
268+}
269+
270+static int d53e6ea8966_unprepare(struct drm_panel *panel)
271+{
272+ struct d53e6ea8966 *db = to_d53e6ea8966(panel);
273+
274+ if (db->enable)
275+ gpiod_set_value_cansleep(db->enable, 0);
276+
277+ gpiod_set_value_cansleep(db->reset, 1);
278+
279+ if (db->reg_elvdd)
280+ regulator_disable(db->reg_elvdd);
281+
282+ regulator_disable(db->reg_vdd);
283+ msleep(100);
284+
285+ return 0;
286+}
287+
288+static int d53e6ea8966_get_modes(struct drm_panel *panel,
289+ struct drm_connector *connector)
290+{
291+ struct d53e6ea8966 *db = to_d53e6ea8966(panel);
292+ const struct d53e6ea8966_panel_info *panel_info = db->panel_info;
293+ struct drm_display_mode *mode;
294+ static const u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
295+ unsigned int i;
296+
297+ for (i = 0; i < panel_info->num_modes; i++) {
298+ mode = drm_mode_duplicate(connector->dev,
299+ &panel_info->display_modes[i]);
300+ if (!mode)
301+ return -ENOMEM;
302+
303+ drm_mode_set_name(mode);
304+ drm_mode_probed_add(connector, mode);
305+ }
306+
307+ connector->display_info.bpc = 8;
308+ connector->display_info.width_mm = panel_info->width_mm;
309+ connector->display_info.height_mm = panel_info->height_mm;
310+ connector->display_info.bus_flags = panel_info->bus_flags;
311+
312+ drm_display_info_set_bus_formats(&connector->display_info,
313+ &bus_format, 1);
314+
315+ return 1;
316+}
317+
318+static const struct drm_panel_funcs d53e6ea8966_panel_funcs = {
319+ .disable = d53e6ea8966_disable,
320+ .enable = d53e6ea8966_enable,
321+ .get_modes = d53e6ea8966_get_modes,
322+ .prepare = d53e6ea8966_prepare,
323+ .unprepare = d53e6ea8966_unprepare,
324+};
325+
326+static int ams495qa01_set_brightness(struct backlight_device *bd)
327+{
328+ struct d53e6ea8966 *db = bl_get_data(bd);
329+ struct mipi_dbi *dbi = &db->dbi;
330+ int brightness = backlight_get_brightness(bd);
331+
332+ ams495qa01_update_gamma(dbi, brightness);
333+
334+ return 0;
335+}
336+
337+static const struct backlight_ops ams495qa01_backlight_ops = {
338+ .update_status = ams495qa01_set_brightness,
339+};
340+
341+static int ams495qa01_backlight_register(struct d53e6ea8966 *db)
342+{
343+ struct backlight_properties props = {
344+ .type = BACKLIGHT_RAW,
345+ .brightness = MAX_BRIGHTNESS,
346+ .max_brightness = MAX_BRIGHTNESS,
347+ };
348+ struct device *dev = db->dev;
349+ int ret = 0;
350+
351+ db->bl_dev = devm_backlight_device_register(dev, "panel", dev, db,
352+ &ams495qa01_backlight_ops,
353+ &props);
354+ if (IS_ERR(db->bl_dev)) {
355+ ret = PTR_ERR(db->bl_dev);
356+ dev_err(dev, "error registering backlight device (%d)\n", ret);
357+ }
358+
359+ return ret;
360+}
361+
362+static int d53e6ea8966_probe(struct spi_device *spi)
363+{
364+ struct device *dev = &spi->dev;
365+ struct mipi_dsi_host *dsi_host;
366+ struct d53e6ea8966 *db;
367+ int ret;
368+ struct mipi_dsi_device_info info = {
369+ .type = "d53e6ea8966",
370+ .channel = 0,
371+ .node = NULL,
372+ };
373+
374+ db = devm_kzalloc(dev, sizeof(*db), GFP_KERNEL);
375+ if (!db)
376+ return -ENOMEM;
377+
378+ spi_set_drvdata(spi, db);
379+
380+ db->dev = dev;
381+
382+ db->panel_info = of_device_get_match_data(dev);
383+ if (!db->panel_info)
384+ return -EINVAL;
385+
386+ db->reg_vdd = devm_regulator_get(dev, "vdd");
387+ if (IS_ERR(db->reg_vdd))
388+ return dev_err_probe(dev, PTR_ERR(db->reg_vdd),
389+ "Failed to get vdd supply\n");
390+
391+ db->reg_elvdd = devm_regulator_get_optional(dev, "elvdd");
392+ if (IS_ERR(db->reg_elvdd))
393+ db->reg_elvdd = NULL;
394+
395+ db->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
396+ if (IS_ERR(db->reset)) {
397+ ret = PTR_ERR(db->reset);
398+ return dev_err_probe(dev, ret, "no RESET GPIO\n");
399+ }
400+
401+ db->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
402+ if (IS_ERR(db->enable)) {
403+ ret = PTR_ERR(db->enable);
404+ return dev_err_probe(dev, ret, "cannot get ENABLE GPIO\n");
405+ }
406+
407+ ret = mipi_dbi_spi_init(spi, &db->dbi, NULL);
408+ if (ret)
409+ return dev_err_probe(dev, ret, "MIPI DBI init failed\n");
410+
411+ dsi_host = drm_of_get_dsi_bus(dev);
412+ if (IS_ERR(dsi_host)) {
413+ ret = PTR_ERR(dsi_host);
414+ return dev_err_probe(dev, ret, "Error attaching DSI bus\n");
415+ }
416+
417+ db->dsi_dev = devm_mipi_dsi_device_register_full(dev, dsi_host, &info);
418+ if (IS_ERR(db->dsi_dev)) {
419+ dev_err(dev, "failed to register dsi device: %ld\n",
420+ PTR_ERR(db->dsi_dev));
421+ ret = PTR_ERR(db->dsi_dev);
422+ }
423+
424+ db->dsi_dev->lanes = 2;
425+ db->dsi_dev->format = MIPI_DSI_FMT_RGB888;
426+ db->dsi_dev->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
427+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET;
428+
429+ drm_panel_init(&db->panel, dev, &d53e6ea8966_panel_funcs,
430+ DRM_MODE_CONNECTOR_DSI);
431+
432+ if (db->panel_info->backlight_register) {
433+ ret = db->panel_info->backlight_register(db);
434+ if (ret < 0)
435+ return ret;
436+ db->panel.backlight = db->bl_dev;
437+ }
438+
439+ drm_panel_add(&db->panel);
440+
441+ ret = devm_mipi_dsi_attach(dev, db->dsi_dev);
442+ if (ret < 0) {
443+ dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
444+ drm_panel_remove(&db->panel);
445+ return ret;
446+ }
447+
448+ return 0;
449+}
450+
451+static void d53e6ea8966_remove(struct spi_device *spi)
452+{
453+ struct d53e6ea8966 *db = spi_get_drvdata(spi);
454+
455+ drm_panel_remove(&db->panel);
456+}
457+
458+static const struct drm_display_mode ams495qa01_modes[] = {
459+ { /* 60hz */
460+ .clock = 33500,
461+ .hdisplay = 960,
462+ .hsync_start = 960 + 10,
463+ .hsync_end = 960 + 10 + 2,
464+ .htotal = 960 + 10 + 2 + 10,
465+ .vdisplay = 544,
466+ .vsync_start = 544 + 10,
467+ .vsync_end = 544 + 10 + 2,
468+ .vtotal = 544 + 10 + 2 + 10,
469+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
470+ .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
471+ },
472+ { /* 50hz */
473+ .clock = 27800,
474+ .hdisplay = 960,
475+ .hsync_start = 960 + 10,
476+ .hsync_end = 960 + 10 + 2,
477+ .htotal = 960 + 10 + 2 + 10,
478+ .vdisplay = 544,
479+ .vsync_start = 544 + 10,
480+ .vsync_end = 544 + 10 + 2,
481+ .vtotal = 544 + 10 + 2 + 10,
482+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
483+ .type = DRM_MODE_TYPE_DRIVER,
484+ },
485+};
486+
487+static const struct d53e6ea8966_panel_info ams495qa01_info = {
488+ .display_modes = ams495qa01_modes,
489+ .num_modes = ARRAY_SIZE(ams495qa01_modes),
490+ .width_mm = 117,
491+ .height_mm = 74,
492+ .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
493+ .panel_init_seq = ams495qa01_panel_init,
494+ .backlight_register = ams495qa01_backlight_register,
495+};
496+
497+static const struct of_device_id d53e6ea8966_match[] = {
498+ { .compatible = "samsung,ams495qa01", .data = &ams495qa01_info },
499+ { /* sentinel */ },
500+};
501+MODULE_DEVICE_TABLE(of, d53e6ea8966_match);
502+
503+static const struct spi_device_id d53e6ea8966_ids[] = {
504+ { "ams495qa01", 0 },
505+ { /* sentinel */ },
506+};
507+MODULE_DEVICE_TABLE(spi, d53e6ea8966_ids);
508+
509+static struct spi_driver d53e6ea8966_driver = {
510+ .driver = {
511+ .name = "d53e6ea8966-panel",
512+ .of_match_table = d53e6ea8966_match,
513+ },
514+ .id_table = d53e6ea8966_ids,
515+ .probe = d53e6ea8966_probe,
516+ .remove = d53e6ea8966_remove,
517+};
518+module_spi_driver(d53e6ea8966_driver);
519+
520+MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>");
521+MODULE_DESCRIPTION("Magnachip d53e6ea8966 panel driver");
522+MODULE_LICENSE("GPL");
drivers/gpu/drm/panfrost/panfrost_drv.c+2−9
@@ -220,15 +220,8 @@ panfrost_copy_in_sync(struct drm_device *dev, · 219 unmodified lines
220220 }
221221
222222 for (i = 0; i < in_fence_count; i++) {
223− struct dma_fence *fence;
224−
225− ret = drm_syncobj_find_fence(file_priv, handles[i], 0, 0,
226− &fence);
227− if (ret)
228− goto fail;
229−
230− ret = drm_sched_job_add_dependency(&job->base, fence);
231−
223+ ret = drm_sched_job_add_syncobj_dependency(&job->base, file_priv,
224+ handles[i], 0);
232225 if (ret)
233226 goto fail;
234227 }
drivers/gpu/drm/qxl/qxl_ttm.c+11−0
@@ -143,6 +143,17 @@ static int qxl_bo_move(struct ttm_buffer_object *bo, bool evict, · 142 unmodified lines
143143 struct ttm_resource *old_mem = bo->resource;
144144 int ret;
145145
146+ if (!old_mem) {
147+ if (new_mem->mem_type != TTM_PL_SYSTEM) {
148+ hop->mem_type = TTM_PL_SYSTEM;
149+ hop->flags = TTM_PL_FLAG_TEMPORARY;
150+ return -EMULTIHOP;
151+ }
152+
153+ ttm_bo_move_null(bo, new_mem);
154+ return 0;
155+ }
156+
146157 qxl_bo_move_notify(bo, new_mem);
147158
148159 ret = ttm_bo_wait_ctx(bo, ctx);
drivers/gpu/drm/radeon/Kconfig+1−0
@@ -8,6 +8,7 @@ config DRM_RADEON · 7 unmodified lines
88 select DRM_DISPLAY_DP_HELPER
99 select DRM_DISPLAY_HELPER
1010 select DRM_KMS_HELPER
11+ select DRM_SUBALLOC_HELPER
1112 select DRM_TTM
1213 select DRM_TTM_HELPER
1314 select SND_HDA_COMPONENT if SND_HDA_CORE
drivers/gpu/drm/radeon/radeon.h+8−47
@@ -79,6 +79,7 @@ · 78 unmodified lines
7979
8080 #include <drm/drm_gem.h>
8181 #include <drm/drm_audio_component.h>
82+#include <drm/drm_suballoc.h>
8283
8384 #include "radeon_family.h"
8485 #include "radeon_mode.h"
@@ -511,52 +512,12 @@ struct radeon_bo { · 426 unmodified lines
511512 };
512513 #define gem_to_radeon_bo(gobj) container_of((gobj), struct radeon_bo, tbo.base)
513514
514−/* sub-allocation manager, it has to be protected by another lock.
515− * By conception this is an helper for other part of the driver
516− * like the indirect buffer or semaphore, which both have their
517− * locking.
518− *
519− * Principe is simple, we keep a list of sub allocation in offset
520− * order (first entry has offset == 0, last entry has the highest
521− * offset).
522− *
523− * When allocating new object we first check if there is room at
524− * the end total_size - (last_object_offset + last_object_size) >=
525− * alloc_size. If so we allocate new object there.
526− *
527− * When there is not enough room at the end, we start waiting for
528− * each sub object until we reach object_offset+object_size >=
529− * alloc_size, this object then become the sub object we return.
530− *
531− * Alignment can't be bigger than page size.
532− *
533− * Hole are not considered for allocation to keep things simple.
534− * Assumption is that there won't be hole (all object on same
535− * alignment).
536− */
537515 struct radeon_sa_manager {
538− wait_queue_head_t wq;
539− struct radeon_bo *bo;
540− struct list_head *hole;
541− struct list_head flist[RADEON_NUM_RINGS];
542− struct list_head olist;
543− unsigned size;
544− uint64_t gpu_addr;
545− void *cpu_ptr;
546− uint32_t domain;
547− uint32_t align;
548−};
549−
550−struct radeon_sa_bo;
551−
552−/* sub-allocation buffer */
553−struct radeon_sa_bo {
554− struct list_head olist;
555− struct list_head flist;
556− struct radeon_sa_manager *manager;
557− unsigned soffset;
558− unsigned eoffset;
559− struct radeon_fence *fence;
516+ struct drm_suballoc_manager base;
517+ struct radeon_bo *bo;
518+ uint64_t gpu_addr;
519+ void *cpu_ptr;
520+ u32 domain;
560521 };
561522
562523 /*
@@ -587,7 +548,7 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, · 24 unmodified lines
587548 * Semaphores.
588549 */
589550 struct radeon_semaphore {
590− struct radeon_sa_bo *sa_bo;
551+ struct drm_suballoc *sa_bo;
591552 signed waiters;
592553 uint64_t gpu_addr;
593554 };
@@ -816,7 +777,7 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask); · 222 unmodified lines
816777 */
817778
818779 struct radeon_ib {
819− struct radeon_sa_bo *sa_bo;
780+ struct drm_suballoc *sa_bo;
820781 uint32_t length_dw;
821782 uint64_t gpu_addr;
822783 uint32_t *ptr;
drivers/gpu/drm/radeon/radeon_ib.c+5−7
@@ -61,7 +61,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, · 60 unmodified lines
6161 {
6262 int r;
6363
64− r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256);
64+ r = radeon_sa_bo_new(&rdev->ring_tmp_bo, &ib->sa_bo, size, 256);
6565 if (r) {
6666 dev_err(rdev->dev, "failed to get a new IB (%d)\n", r);
6767 return r;
@@ -77,7 +77,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, · 9 unmodified lines
7777 /* ib pool is bound at RADEON_VA_IB_OFFSET in virtual address
7878 * space and soffset is the offset inside the pool bo
7979 */
80− ib->gpu_addr = ib->sa_bo->soffset + RADEON_VA_IB_OFFSET;
80+ ib->gpu_addr = drm_suballoc_soffset(ib->sa_bo) + RADEON_VA_IB_OFFSET;
8181 } else {
8282 ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo);
8383 }
@@ -97,7 +97,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, · 13 unmodified lines
9797 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
9898 {
9999 radeon_sync_free(rdev, &ib->sync, ib->fence);
100− radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence);
100+ radeon_sa_bo_free(&ib->sa_bo, ib->fence);
101101 radeon_fence_unref(&ib->fence);
102102 }
103103
@@ -201,8 +201,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) · 97 unmodified lines
201201
202202 if (rdev->family >= CHIP_BONAIRE) {
203203 r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
204− RADEON_IB_POOL_SIZE*64*1024,
205− RADEON_GPU_PAGE_SIZE,
204+ RADEON_IB_POOL_SIZE*64*1024, 256,
206205 RADEON_GEM_DOMAIN_GTT,
207206 RADEON_GEM_GTT_WC);
208207 } else {
@@ -210,8 +209,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) · 1 unmodified line
210209 * to the command stream checking
211210 */
212211 r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
213− RADEON_IB_POOL_SIZE*64*1024,
214− RADEON_GPU_PAGE_SIZE,
212+ RADEON_IB_POOL_SIZE*64*1024, 256,
215213 RADEON_GEM_DOMAIN_GTT, 0);
216214 }
217215 if (r) {
drivers/gpu/drm/radeon/radeon_object.h+15−10
@@ -169,15 +169,22 @@ extern void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence, · 168 unmodified lines
169169 /*
170170 * sub allocation
171171 */
172+static inline struct radeon_sa_manager *
173+to_radeon_sa_manager(struct drm_suballoc_manager *manager)
174+{
175+ return container_of(manager, struct radeon_sa_manager, base);
176+}
172177
173−static inline uint64_t radeon_sa_bo_gpu_addr(struct radeon_sa_bo *sa_bo)
178+static inline uint64_t radeon_sa_bo_gpu_addr(struct drm_suballoc *sa_bo)
174179 {
175− return sa_bo->manager->gpu_addr + sa_bo->soffset;
180+ return to_radeon_sa_manager(sa_bo->manager)->gpu_addr +
181+ drm_suballoc_soffset(sa_bo);
176182 }
177183
178−static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo)
184+static inline void *radeon_sa_bo_cpu_addr(struct drm_suballoc *sa_bo)
179185 {
180− return sa_bo->manager->cpu_ptr + sa_bo->soffset;
186+ return to_radeon_sa_manager(sa_bo->manager)->cpu_ptr +
187+ drm_suballoc_soffset(sa_bo);
181188 }
182189
183190 extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
@@ -190,12 +197,10 @@ extern int radeon_sa_bo_manager_start(struct radeon_device *rdev, · 6 unmodified lines
190197 struct radeon_sa_manager *sa_manager);
191198 extern int radeon_sa_bo_manager_suspend(struct radeon_device *rdev,
192199 struct radeon_sa_manager *sa_manager);
193−extern int radeon_sa_bo_new(struct radeon_device *rdev,
194− struct radeon_sa_manager *sa_manager,
195− struct radeon_sa_bo **sa_bo,
196− unsigned size, unsigned align);
197−extern void radeon_sa_bo_free(struct radeon_device *rdev,
198− struct radeon_sa_bo **sa_bo,
200+extern int radeon_sa_bo_new(struct radeon_sa_manager *sa_manager,
201+ struct drm_suballoc **sa_bo,
202+ unsigned int size, unsigned int align);
203+extern void radeon_sa_bo_free(struct drm_suballoc **sa_bo,
199204 struct radeon_fence *fence);
200205 #if defined(CONFIG_DEBUG_FS)
201206 extern void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
drivers/gpu/drm/radeon/radeon_sa.c+26−290
@@ -44,53 +44,32 @@ · 43 unmodified lines
4444
4545 #include "radeon.h"
4646
47−static void radeon_sa_bo_remove_locked(struct radeon_sa_bo *sa_bo);
48−static void radeon_sa_bo_try_free(struct radeon_sa_manager *sa_manager);
49−
5047 int radeon_sa_bo_manager_init(struct radeon_device *rdev,
5148 struct radeon_sa_manager *sa_manager,
52− unsigned size, u32 align, u32 domain, u32 flags)
49+ unsigned int size, u32 sa_align, u32 domain,
50+ u32 flags)
5351 {
54− int i, r;
55−
56− init_waitqueue_head(&sa_manager->wq);
57− sa_manager->bo = NULL;
58− sa_manager->size = size;
59− sa_manager->domain = domain;
60− sa_manager->align = align;
61− sa_manager->hole = &sa_manager->olist;
62− INIT_LIST_HEAD(&sa_manager->olist);
63− for (i = 0; i < RADEON_NUM_RINGS; ++i) {
64− INIT_LIST_HEAD(&sa_manager->flist[i]);
65− }
52+ int r;
6653
67− r = radeon_bo_create(rdev, size, align, true,
54+ r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true,
6855 domain, flags, NULL, NULL, &sa_manager->bo);
6956 if (r) {
7057 dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r);
7158 return r;
7259 }
7360
61+ sa_manager->domain = domain;
62+
63+ drm_suballoc_manager_init(&sa_manager->base, size, sa_align);
64+
7465 return r;
7566 }
7667
7768 void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
7869 struct radeon_sa_manager *sa_manager)
7970 {
80− struct radeon_sa_bo *sa_bo, *tmp;
81−
82− if (!list_empty(&sa_manager->olist)) {
83− sa_manager->hole = &sa_manager->olist,
84− radeon_sa_bo_try_free(sa_manager);
85− if (!list_empty(&sa_manager->olist)) {
86− dev_err(rdev->dev, "sa_manager is not empty, clearing anyway\n");
87− }
88− }
89− list_for_each_entry_safe(sa_bo, tmp, &sa_manager->olist, olist) {
90− radeon_sa_bo_remove_locked(sa_bo);
91− }
71+ drm_suballoc_manager_fini(&sa_manager->base);
9272 radeon_bo_unref(&sa_manager->bo);
93− sa_manager->size = 0;
9473 }
9574
9675 int radeon_sa_bo_manager_start(struct radeon_device *rdev,
@@ -139,260 +118,34 @@ int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, · 42 unmodified lines
139118 return r;
140119 }
141120
142−static void radeon_sa_bo_remove_locked(struct radeon_sa_bo *sa_bo)
121+int radeon_sa_bo_new(struct radeon_sa_manager *sa_manager,
122+ struct drm_suballoc **sa_bo,
123+ unsigned int size, unsigned int align)
143124 {
144− struct radeon_sa_manager *sa_manager = sa_bo->manager;
145− if (sa_manager->hole == &sa_bo->olist) {
146− sa_manager->hole = sa_bo->olist.prev;
147− }
148− list_del_init(&sa_bo->olist);
149− list_del_init(&sa_bo->flist);
150− radeon_fence_unref(&sa_bo->fence);
151− kfree(sa_bo);
152−}
153−
154−static void radeon_sa_bo_try_free(struct radeon_sa_manager *sa_manager)
155−{
156− struct radeon_sa_bo *sa_bo, *tmp;
157−
158− if (sa_manager->hole->next == &sa_manager->olist)
159− return;
125+ struct drm_suballoc *sa = drm_suballoc_new(&sa_manager->base, size,
126+ GFP_KERNEL, true, align);
160127
161− sa_bo = list_entry(sa_manager->hole->next, struct radeon_sa_bo, olist);
162− list_for_each_entry_safe_from(sa_bo, tmp, &sa_manager->olist, olist) {
163− if (sa_bo->fence == NULL || !radeon_fence_signaled(sa_bo->fence)) {
164− return;
165− }
166− radeon_sa_bo_remove_locked(sa_bo);
128+ if (IS_ERR(sa)) {
129+ *sa_bo = NULL;
130+ return PTR_ERR(sa);
167131 }
168−}
169132
170−static inline unsigned radeon_sa_bo_hole_soffset(struct radeon_sa_manager *sa_manager)
171−{
172− struct list_head *hole = sa_manager->hole;
173−
174− if (hole != &sa_manager->olist) {
175− return list_entry(hole, struct radeon_sa_bo, olist)->eoffset;
176− }
133+ *sa_bo = sa;
177134 return 0;
178135 }
179136
180−static inline unsigned radeon_sa_bo_hole_eoffset(struct radeon_sa_manager *sa_manager)
181−{
182− struct list_head *hole = sa_manager->hole;
183−
184− if (hole->next != &sa_manager->olist) {
185− return list_entry(hole->next, struct radeon_sa_bo, olist)->soffset;
186− }
187− return sa_manager->size;
188−}
189−
190−static bool radeon_sa_bo_try_alloc(struct radeon_sa_manager *sa_manager,
191− struct radeon_sa_bo *sa_bo,
192− unsigned size, unsigned align)
193−{
194− unsigned soffset, eoffset, wasted;
195−
196− soffset = radeon_sa_bo_hole_soffset(sa_manager);
197− eoffset = radeon_sa_bo_hole_eoffset(sa_manager);
198− wasted = (align - (soffset % align)) % align;
199−
200− if ((eoffset - soffset) >= (size + wasted)) {
201− soffset += wasted;
202−
203− sa_bo->manager = sa_manager;
204− sa_bo->soffset = soffset;
205− sa_bo->eoffset = soffset + size;
206− list_add(&sa_bo->olist, sa_manager->hole);
207− INIT_LIST_HEAD(&sa_bo->flist);
208− sa_manager->hole = &sa_bo->olist;
209− return true;
210− }
211− return false;
212−}
213−
214−/**
215− * radeon_sa_event - Check if we can stop waiting
216− *
217− * @sa_manager: pointer to the sa_manager
218− * @size: number of bytes we want to allocate
219− * @align: alignment we need to match
220− *
221− * Check if either there is a fence we can wait for or
222− * enough free memory to satisfy the allocation directly
223− */
224−static bool radeon_sa_event(struct radeon_sa_manager *sa_manager,
225− unsigned size, unsigned align)
226−{
227− unsigned soffset, eoffset, wasted;
228− int i;
229−
230− for (i = 0; i < RADEON_NUM_RINGS; ++i) {
231− if (!list_empty(&sa_manager->flist[i])) {
232− return true;
233− }
234− }
235−
236− soffset = radeon_sa_bo_hole_soffset(sa_manager);
237− eoffset = radeon_sa_bo_hole_eoffset(sa_manager);
238− wasted = (align - (soffset % align)) % align;
239−
240− if ((eoffset - soffset) >= (size + wasted)) {
241− return true;
242− }
243−
244− return false;
245−}
246−
247−static bool radeon_sa_bo_next_hole(struct radeon_sa_manager *sa_manager,
248− struct radeon_fence **fences,
249− unsigned *tries)
250−{
251− struct radeon_sa_bo *best_bo = NULL;
252− unsigned i, soffset, best, tmp;
253−
254− /* if hole points to the end of the buffer */
255− if (sa_manager->hole->next == &sa_manager->olist) {
256− /* try again with its beginning */
257− sa_manager->hole = &sa_manager->olist;
258− return true;
259− }
260−
261− soffset = radeon_sa_bo_hole_soffset(sa_manager);
262− /* to handle wrap around we add sa_manager->size */
263− best = sa_manager->size * 2;
264− /* go over all fence list and try to find the closest sa_bo
265− * of the current last
266− */
267− for (i = 0; i < RADEON_NUM_RINGS; ++i) {
268− struct radeon_sa_bo *sa_bo;
269−
270− fences[i] = NULL;
271−
272− if (list_empty(&sa_manager->flist[i])) {
273− continue;
274− }
275−
276− sa_bo = list_first_entry(&sa_manager->flist[i],
277− struct radeon_sa_bo, flist);
278−
279− if (!radeon_fence_signaled(sa_bo->fence)) {
280− fences[i] = sa_bo->fence;
281− continue;
282− }
283−
284− /* limit the number of tries each ring gets */
285− if (tries[i] > 2) {
286− continue;
287− }
288−
289− tmp = sa_bo->soffset;
290− if (tmp < soffset) {
291− /* wrap around, pretend it's after */
292− tmp += sa_manager->size;
293− }
294− tmp -= soffset;
295− if (tmp < best) {
296− /* this sa bo is the closest one */
297− best = tmp;
298− best_bo = sa_bo;
299− }
300− }
301−
302− if (best_bo) {
303− ++tries[best_bo->fence->ring];
304− sa_manager->hole = best_bo->olist.prev;
305−
306− /* we knew that this one is signaled,
307− so it's save to remote it */
308− radeon_sa_bo_remove_locked(best_bo);
309− return true;
310− }
311− return false;
312−}
313−
314−int radeon_sa_bo_new(struct radeon_device *rdev,
315− struct radeon_sa_manager *sa_manager,
316− struct radeon_sa_bo **sa_bo,
317− unsigned size, unsigned align)
318−{
319− struct radeon_fence *fences[RADEON_NUM_RINGS];
320− unsigned tries[RADEON_NUM_RINGS];
321− int i, r;
322−
323− BUG_ON(align > sa_manager->align);
324− BUG_ON(size > sa_manager->size);
325−
326− *sa_bo = kmalloc(sizeof(struct radeon_sa_bo), GFP_KERNEL);
327− if ((*sa_bo) == NULL) {
328− return -ENOMEM;
329− }
330− (*sa_bo)->manager = sa_manager;
331− (*sa_bo)->fence = NULL;
332− INIT_LIST_HEAD(&(*sa_bo)->olist);
333− INIT_LIST_HEAD(&(*sa_bo)->flist);
334−
335− spin_lock(&sa_manager->wq.lock);
336− do {
337− for (i = 0; i < RADEON_NUM_RINGS; ++i)
338− tries[i] = 0;
339−
340− do {
341− radeon_sa_bo_try_free(sa_manager);
342−
343− if (radeon_sa_bo_try_alloc(sa_manager, *sa_bo,
344− size, align)) {
345− spin_unlock(&sa_manager->wq.lock);
346− return 0;
347− }
348−
349− /* see if we can skip over some allocations */
350− } while (radeon_sa_bo_next_hole(sa_manager, fences, tries));
351−
352− for (i = 0; i < RADEON_NUM_RINGS; ++i)
353− radeon_fence_ref(fences[i]);
354−
355− spin_unlock(&sa_manager->wq.lock);
356− r = radeon_fence_wait_any(rdev, fences, false);
357− for (i = 0; i < RADEON_NUM_RINGS; ++i)
358− radeon_fence_unref(&fences[i]);
359− spin_lock(&sa_manager->wq.lock);
360− /* if we have nothing to wait for block */
361− if (r == -ENOENT) {
362− r = wait_event_interruptible_locked(
363− sa_manager->wq,
364− radeon_sa_event(sa_manager, size, align)
365− );
366− }
367−
368− } while (!r);
369−
370− spin_unlock(&sa_manager->wq.lock);
371− kfree(*sa_bo);
372− *sa_bo = NULL;
373− return r;
374−}
375−
376−void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo **sa_bo,
137+void radeon_sa_bo_free(struct drm_suballoc **sa_bo,
377138 struct radeon_fence *fence)
378139 {
379− struct radeon_sa_manager *sa_manager;
380−
381140 if (sa_bo == NULL || *sa_bo == NULL) {
382141 return;
383142 }
384143
385− sa_manager = (*sa_bo)->manager;
386− spin_lock(&sa_manager->wq.lock);
387− if (fence && !radeon_fence_signaled(fence)) {
388− (*sa_bo)->fence = radeon_fence_ref(fence);
389− list_add_tail(&(*sa_bo)->flist,
390− &sa_manager->flist[fence->ring]);
391− } else {
392− radeon_sa_bo_remove_locked(*sa_bo);
393− }
394− wake_up_all_locked(&sa_manager->wq);
395− spin_unlock(&sa_manager->wq.lock);
144+ if (fence)
145+ drm_suballoc_free(*sa_bo, &fence->base);
146+ else
147+ drm_suballoc_free(*sa_bo, NULL);
148+
396149 *sa_bo = NULL;
397150 }
398151
@@ -400,25 +153,8 @@ void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo **sa_bo, · 1 unmodified line
400153 void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
401154 struct seq_file *m)
402155 {
403− struct radeon_sa_bo *i;
156+ struct drm_printer p = drm_seq_file_printer(m);
404157
405− spin_lock(&sa_manager->wq.lock);
406− list_for_each_entry(i, &sa_manager->olist, olist) {
407− uint64_t soffset = i->soffset + sa_manager->gpu_addr;
408− uint64_t eoffset = i->eoffset + sa_manager->gpu_addr;
409− if (&i->olist == sa_manager->hole) {
410− seq_printf(m, ">");
411− } else {
412− seq_printf(m, " ");
413− }
414− seq_printf(m, "[0x%010llx 0x%010llx] size %8lld",
415− soffset, eoffset, eoffset - soffset);
416− if (i->fence) {
417− seq_printf(m, " protected by 0x%016llx on ring %d",
418− i->fence->seq, i->fence->ring);
419− }
420− seq_printf(m, "\n");
421− }
422− spin_unlock(&sa_manager->wq.lock);
158+ drm_suballoc_dump_debug_info(&sa_manager->base, &p, sa_manager->gpu_addr);
423159 }
424160 #endif
drivers/gpu/drm/radeon/radeon_semaphore.c+2−2
@@ -40,7 +40,7 @@ int radeon_semaphore_create(struct radeon_device *rdev, · 39 unmodified lines
4040 if (*semaphore == NULL) {
4141 return -ENOMEM;
4242 }
43− r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo,
43+ r = radeon_sa_bo_new(&rdev->ring_tmp_bo,
4444 &(*semaphore)->sa_bo, 8, 8);
4545 if (r) {
4646 kfree(*semaphore);
@@ -100,7 +100,7 @@ void radeon_semaphore_free(struct radeon_device *rdev, · 53 unmodified lines
100100 dev_err(rdev->dev, "semaphore %p has more waiters than signalers,"
101101 " hardware lockup imminent!\n", *semaphore);
102102 }
103− radeon_sa_bo_free(rdev, &(*semaphore)->sa_bo, fence);
103+ radeon_sa_bo_free(&(*semaphore)->sa_bo, fence);
104104 kfree(*semaphore);
105105 *semaphore = NULL;
106106 }
drivers/gpu/drm/radeon/radeon_ttm.c+2−5
@@ -211,13 +211,10 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict, · 210 unmodified lines
211211 if (r)
212212 return r;
213213
214− /* Can't move a pinned BO */
215214 rbo = container_of(bo, struct radeon_bo, tbo);
216− if (WARN_ON_ONCE(rbo->tbo.pin_count > 0))
217− return -EINVAL;
218−
219215 rdev = radeon_get_rdev(bo->bdev);
220− if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {
216+ if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM &&
217+ bo->ttm == NULL)) {
221218 ttm_bo_move_null(bo, new_mem);
222219 goto out;
223220 }
drivers/gpu/drm/rockchip/rockchip_drm_gem.c+10−6
@@ -261,9 +261,6 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, · 260 unmodified lines
261261 else
262262 ret = rockchip_drm_gem_object_mmap_dma(obj, vma);
263263
264− if (ret)
265− drm_gem_vm_close(vma);
266−
267264 return ret;
268265 }
269266
@@ -518,8 +515,14 @@ int rockchip_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) · 248 unmodified lines
518515 struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
519516
520517 if (rk_obj->pages) {
521− void *vaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP,
522− pgprot_writecombine(PAGE_KERNEL));
518+ void *vaddr;
519+
520+ if (rk_obj->kvaddr)
521+ vaddr = rk_obj->kvaddr;
522+ else
523+ vaddr = vmap(rk_obj->pages, rk_obj->num_pages, VM_MAP,
524+ pgprot_writecombine(PAGE_KERNEL));
525+
523526 if (!vaddr)
524527 return -ENOMEM;
525528 iosys_map_set_vaddr(map, vaddr);
@@ -539,7 +542,8 @@ void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, · 13 unmodified lines
539542 struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
540543
541544 if (rk_obj->pages) {
542− vunmap(map->vaddr);
545+ if (map->vaddr != rk_obj->kvaddr)
546+ vunmap(map->vaddr);
543547 return;
544548 }
545549
drivers/gpu/drm/rockchip/rockchip_drm_vop.c+2−5
@@ -316,13 +316,10 @@ static int vop_convert_afbc_format(uint32_t format) · 315 unmodified lines
316316 case DRM_FORMAT_RGB565:
317317 case DRM_FORMAT_BGR565:
318318 return AFBC_FMT_RGB565;
319− /* either of the below should not be reachable */
320319 default:
321− DRM_WARN_ONCE("unsupported AFBC format[%08x]\n", format);
320+ DRM_DEBUG_KMS("unsupported AFBC format[%08x]\n", format);
322321 return -EINVAL;
323322 }
324−
325− return -EINVAL;
326323 }
327324
328325 static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
@@ -2221,7 +2218,7 @@ static int vop_bind(struct device *dev, struct device *master, void *data) · 1892 unmodified lines
22212218 goto err_disable_pm_runtime;
22222219
22232220 if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) {
2224− vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev);
2221+ vop->rgb = rockchip_rgb_init(dev, &vop->crtc, vop->drm_dev, 0);
22252222 if (IS_ERR(vop->rgb)) {
22262223 ret = PTR_ERR(vop->rgb);
22272224 goto err_disable_pm_runtime;
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c+63−17
@@ -38,6 +38,7 @@ · 37 unmodified lines
3838 #include "rockchip_drm_gem.h"
3939 #include "rockchip_drm_fb.h"
4040 #include "rockchip_drm_vop2.h"
41+#include "rockchip_rgb.h"
4142
4243 /*
4344 * VOP2 architecture
@@ -211,6 +212,9 @@ struct vop2 { · 167 unmodified lines
211212 struct clk *hclk;
212213 struct clk *aclk;
213214
215+ /* optional internal rgb encoder */
216+ struct rockchip_rgb *rgb;
217+
214218 /* must be put at the end of the struct */
215219 struct vop2_win win[];
216220 };
@@ -2245,7 +2249,7 @@ static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2) · 2028 unmodified lines
22452249
22462250 #define NR_LAYERS 6
22472251
2248−static int vop2_create_crtc(struct vop2 *vop2)
2252+static int vop2_create_crtcs(struct vop2 *vop2)
22492253 {
22502254 const struct vop2_data *vop2_data = vop2->data;
22512255 struct drm_device *drm = vop2->drm;
@@ -2321,10 +2325,11 @@ static int vop2_create_crtc(struct vop2 *vop2) · 69 unmodified lines
23212325 /* change the unused primary window to overlay window */
23222326 win->type = DRM_PLANE_TYPE_OVERLAY;
23232327 }
2324− }
2325−
2326− if (win->type == DRM_PLANE_TYPE_OVERLAY)
2328+ } else if (win->type == DRM_PLANE_TYPE_OVERLAY) {
23272329 possible_crtcs = (1 << nvps) - 1;
2330+ } else {
2331+ possible_crtcs = 0;
2332+ }
23282333
23292334 ret = vop2_plane_init(vop2, win, possible_crtcs);
23302335 if (ret) {
@@ -2370,15 +2375,44 @@ static int vop2_create_crtc(struct vop2 *vop2) · 39 unmodified lines
23702375 return 0;
23712376 }
23722377
2373−static void vop2_destroy_crtc(struct drm_crtc *crtc)
2378+static void vop2_destroy_crtcs(struct vop2 *vop2)
23742379 {
2375− of_node_put(crtc->port);
2380+ struct drm_device *drm = vop2->drm;
2381+ struct list_head *crtc_list = &drm->mode_config.crtc_list;
2382+ struct list_head *plane_list = &drm->mode_config.plane_list;
2383+ struct drm_crtc *crtc, *tmpc;
2384+ struct drm_plane *plane, *tmpp;
2385+
2386+ list_for_each_entry_safe(plane, tmpp, plane_list, head)
2387+ drm_plane_cleanup(plane);
23762388
23772389 /*
23782390 * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane()
23792391 * references the CRTC.
23802392 */
2381− drm_crtc_cleanup(crtc);
2393+ list_for_each_entry_safe(crtc, tmpc, crtc_list, head) {
2394+ of_node_put(crtc->port);
2395+ drm_crtc_cleanup(crtc);
2396+ }
2397+}
2398+
2399+static int vop2_find_rgb_encoder(struct vop2 *vop2)
2400+{
2401+ struct device_node *node = vop2->dev->of_node;
2402+ struct device_node *endpoint;
2403+ int i;
2404+
2405+ for (i = 0; i < vop2->data->nr_vps; i++) {
2406+ endpoint = of_graph_get_endpoint_by_regs(node, i,
2407+ ROCKCHIP_VOP2_EP_RGB0);
2408+ if (!endpoint)
2409+ continue;
2410+
2411+ of_node_put(endpoint);
2412+ return i;
2413+ }
2414+
2415+ return -ENOENT;
23822416 }
23832417
23842418 static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
@@ -2682,33 +2716,45 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) · 297 unmodified lines
26822716 if (ret)
26832717 return ret;
26842718
2685− ret = vop2_create_crtc(vop2);
2719+ ret = vop2_create_crtcs(vop2);
26862720 if (ret)
26872721 return ret;
26882722
2723+ ret = vop2_find_rgb_encoder(vop2);
2724+ if (ret >= 0) {
2725+ vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
2726+ vop2->drm, ret);
2727+ if (IS_ERR(vop2->rgb)) {
2728+ if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) {
2729+ ret = PTR_ERR(vop2->rgb);
2730+ goto err_crtcs;
2731+ }
2732+ vop2->rgb = NULL;
2733+ }
2734+ }
2735+
26892736 rockchip_drm_dma_init_device(vop2->drm, vop2->dev);
26902737
26912738 pm_runtime_enable(&pdev->dev);
26922739
26932740 return 0;
2741+
2742+err_crtcs:
2743+ vop2_destroy_crtcs(vop2);
2744+
2745+ return ret;
26942746 }
26952747
26962748 static void vop2_unbind(struct device *dev, struct device *master, void *data)
26972749 {
26982750 struct vop2 *vop2 = dev_get_drvdata(dev);
2699− struct drm_device *drm = vop2->drm;
2700− struct list_head *plane_list = &drm->mode_config.plane_list;
2701− struct list_head *crtc_list = &drm->mode_config.crtc_list;
2702− struct drm_crtc *crtc, *tmpc;
2703− struct drm_plane *plane, *tmpp;
27042751
27052752 pm_runtime_disable(dev);
27062753
2707− list_for_each_entry_safe(plane, tmpp, plane_list, head)
2708− drm_plane_cleanup(plane);
2754+ if (vop2->rgb)
2755+ rockchip_rgb_fini(vop2->rgb);
27092756
2710− list_for_each_entry_safe(crtc, tmpc, crtc_list, head)
2711− vop2_destroy_crtc(crtc);
2757+ vop2_destroy_crtcs(vop2);
27122758 }
27132759
27142760 const struct component_ops vop2_component_ops = {
drivers/gpu/drm/rockchip/rockchip_rgb.c+10−9
@@ -22,13 +22,11 @@ · 21 unmodified lines
2222 #include "rockchip_drm_vop.h"
2323 #include "rockchip_rgb.h"
2424
25−#define encoder_to_rgb(c) container_of(c, struct rockchip_rgb, encoder)
26−
2725 struct rockchip_rgb {
2826 struct device *dev;
2927 struct drm_device *drm_dev;
3028 struct drm_bridge *bridge;
31− struct drm_encoder encoder;
29+ struct rockchip_encoder encoder;
3230 struct drm_connector connector;
3331 int output_mode;
3432 };
@@ -74,7 +72,8 @@ struct drm_encoder_helper_funcs rockchip_rgb_encoder_helper_funcs = { · 39 unmodified lines
7472
7573 struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
7674 struct drm_crtc *crtc,
77− struct drm_device *drm_dev)
75+ struct drm_device *drm_dev,
76+ int video_port)
7877 {
7978 struct rockchip_rgb *rgb;
8079 struct drm_encoder *encoder;
@@ -92,7 +91,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, · 11 unmodified lines
9291 rgb->dev = dev;
9392 rgb->drm_dev = drm_dev;
9493
95− port = of_graph_get_port_by_id(dev->of_node, 0);
94+ port = of_graph_get_port_by_id(dev->of_node, video_port);
9695 if (!port)
9796 return ERR_PTR(-EINVAL);
9897
@@ -105,8 +104,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, · 6 unmodified lines
105104 continue;
106105
107106 child_count++;
108− ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id,
109− &panel, &bridge);
107+ ret = drm_of_find_panel_or_bridge(dev->of_node, video_port,
108+ endpoint_id, &panel, &bridge);
110109 if (!ret) {
111110 of_node_put(endpoint);
112111 break;
@@ -125,7 +124,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, · 12 unmodified lines
125124 return ERR_PTR(ret);
126125 }
127126
128− encoder = &rgb->encoder;
127+ encoder = &rgb->encoder.encoder;
129128 encoder->possible_crtcs = drm_crtc_mask(crtc);
130129
131130 ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_NONE);
@@ -161,6 +160,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, · 29 unmodified lines
161160 goto err_free_encoder;
162161 }
163162
163+ rgb->encoder.crtc_endpoint_id = endpoint_id;
164+
164165 ret = drm_connector_attach_encoder(connector, encoder);
165166 if (ret < 0) {
166167 DRM_DEV_ERROR(drm_dev->dev,
@@ -182,6 +183,6 @@ void rockchip_rgb_fini(struct rockchip_rgb *rgb) · 15 unmodified lines
182183 {
183184 drm_panel_bridge_remove(rgb->bridge);
184185 drm_connector_cleanup(&rgb->connector);
185− drm_encoder_cleanup(&rgb->encoder);
186+ drm_encoder_cleanup(&rgb->encoder.encoder);
186187 }
187188 EXPORT_SYMBOL_GPL(rockchip_rgb_fini);
drivers/gpu/drm/rockchip/rockchip_rgb.h+4−2
@@ -8,12 +8,14 @@ · 7 unmodified lines
88 #ifdef CONFIG_ROCKCHIP_RGB
99 struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
1010 struct drm_crtc *crtc,
11− struct drm_device *drm_dev);
11+ struct drm_device *drm_dev,
12+ int video_port);
1213 void rockchip_rgb_fini(struct rockchip_rgb *rgb);
1314 #else
1415 static inline struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
1516 struct drm_crtc *crtc,
16− struct drm_device *drm_dev)
17+ struct drm_device *drm_dev,
18+ int video_port)
1719 {
1820 return NULL;
1921 }
drivers/gpu/drm/scheduler/sched_main.c+29−0
@@ -53,6 +53,7 @@ · 52 unmodified lines
5353
5454 #include <drm/drm_print.h>
5555 #include <drm/drm_gem.h>
56+#include <drm/drm_syncobj.h>
5657 #include <drm/gpu_scheduler.h>
5758 #include <drm/spsc_queue.h>
5859
@@ -718,6 +719,34 @@ int drm_sched_job_add_dependency(struct drm_sched_job *job, · 659 unmodified lines
718719 }
719720 EXPORT_SYMBOL(drm_sched_job_add_dependency);
720721
722+/**
723+ * drm_sched_job_add_syncobj_dependency - adds a syncobj's fence as a job dependency
724+ * @job: scheduler job to add the dependencies to
725+ * @file_private: drm file private pointer
726+ * @handle: syncobj handle to lookup
727+ * @point: timeline point
728+ *
729+ * This adds the fence matching the given syncobj to @job.
730+ *
731+ * Returns:
732+ * 0 on success, or an error on failing to expand the array.
733+ */
734+int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
735+ struct drm_file *file,
736+ u32 handle,
737+ u32 point)
738+{
739+ struct dma_fence *fence;
740+ int ret;
741+
742+ ret = drm_syncobj_find_fence(file, handle, point, 0, &fence);
743+ if (ret)
744+ return ret;
745+
746+ return drm_sched_job_add_dependency(job, fence);
747+}
748+EXPORT_SYMBOL(drm_sched_job_add_syncobj_dependency);
749+
721750 /**
722751 * drm_sched_job_add_resv_dependencies - add all fences from the resv to the job
723752 * @job: scheduler job to add the dependencies to
drivers/gpu/drm/tests/drm_format_helper_test.c+5−5
@@ -597,7 +597,7 @@ static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test) · 596 unmodified lines
597597
598598 drm_fb_xrgb8888_to_xrgb1555(&dst, &result->dst_pitch, &src, &fb, &params->clip);
599599 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
600− KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
600+ KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
601601 }
602602
603603 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
@@ -628,7 +628,7 @@ static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test) · 24 unmodified lines
628628
629629 drm_fb_xrgb8888_to_argb1555(&dst, &result->dst_pitch, &src, &fb, &params->clip);
630630 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
631− KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
631+ KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
632632 }
633633
634634 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
@@ -659,7 +659,7 @@ static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test) · 24 unmodified lines
659659
660660 drm_fb_xrgb8888_to_rgba5551(&dst, &result->dst_pitch, &src, &fb, &params->clip);
661661 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
662− KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
662+ KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
663663 }
664664
665665 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
@@ -724,7 +724,7 @@ static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test) · 58 unmodified lines
724724
725725 drm_fb_xrgb8888_to_argb8888(&dst, &result->dst_pitch, &src, &fb, &params->clip);
726726 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
727− KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
727+ KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
728728 }
729729
730730 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
@@ -786,7 +786,7 @@ static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test) · 55 unmodified lines
786786
787787 drm_fb_xrgb8888_to_argb2101010(&dst, &result->dst_pitch, &src, &fb, &params->clip);
788788 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
789− KUNIT_EXPECT_EQ(test, memcmp(buf, result->expected, dst_size), 0);
789+ KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
790790 }
791791
792792 static struct kunit_case drm_format_helper_test_cases[] = {
drivers/gpu/drm/tidss/tidss_dispc.c+4−8
@@ -1985,9 +1985,9 @@ dma_addr_t dispc_plane_state_p_uv_addr(const struct drm_plane_state *state) · 1984 unmodified lines
19851985 (y * fb->pitches[1] / fb->format->vsub);
19861986 }
19871987
1988−int dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane,
1989− const struct drm_plane_state *state,
1990− u32 hw_videoport)
1988+void dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane,
1989+ const struct drm_plane_state *state,
1990+ u32 hw_videoport)
19911991 {
19921992 bool lite = dispc->feat->vid_lite[hw_plane];
19931993 u32 fourcc = state->fb->format->format;
@@ -2066,15 +2066,11 @@ int dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane, · 72 unmodified lines
20662066 else
20672067 VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES, 0,
20682068 28, 28);
2069−
2070− return 0;
20712069 }
20722070
2073−int dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool enable)
2071+void dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool enable)
20742072 {
20752073 VID_REG_FLD_MOD(dispc, hw_plane, DISPC_VID_ATTRIBUTES, !!enable, 0, 0);
2076−
2077− return 0;
20782074 }
20792075
20802076 static u32 dispc_vid_get_fifo_size(struct dispc_device *dispc, u32 hw_plane)
drivers/gpu/drm/tidss/tidss_dispc.h+4−4
@@ -123,10 +123,10 @@ int dispc_runtime_resume(struct dispc_device *dispc); · 122 unmodified lines
123123 int dispc_plane_check(struct dispc_device *dispc, u32 hw_plane,
124124 const struct drm_plane_state *state,
125125 u32 hw_videoport);
126−int dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane,
127− const struct drm_plane_state *state,
128− u32 hw_videoport);
129−int dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool enable);
126+void dispc_plane_setup(struct dispc_device *dispc, u32 hw_plane,
127+ const struct drm_plane_state *state,
128+ u32 hw_videoport);
129+void dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool enable);
130130 const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *len);
131131
132132 int dispc_init(struct tidss_device *tidss);
drivers/gpu/drm/tidss/tidss_plane.c+11−9
@@ -113,7 +113,6 @@ static void tidss_plane_atomic_update(struct drm_plane *plane, · 112 unmodified lines
113113 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
114114 plane);
115115 u32 hw_videoport;
116− int ret;
117116
118117 dev_dbg(ddev->dev, "%s\n", __func__);
119118
@@ -124,15 +123,17 @@ static void tidss_plane_atomic_update(struct drm_plane *plane, · 4 unmodified lines
124123
125124 hw_videoport = to_tidss_crtc(new_state->crtc)->hw_videoport;
126125
127− ret = dispc_plane_setup(tidss->dispc, tplane->hw_plane_id,
128− new_state, hw_videoport);
126+ dispc_plane_setup(tidss->dispc, tplane->hw_plane_id, new_state, hw_videoport);
127+}
129128
130− if (ret) {
131− dev_err(plane->dev->dev, "%s: Failed to setup plane %d\n",
132− __func__, tplane->hw_plane_id);
133− dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, false);
134− return;
135− }
129+static void tidss_plane_atomic_enable(struct drm_plane *plane,
130+ struct drm_atomic_state *state)
131+{
132+ struct drm_device *ddev = plane->dev;
133+ struct tidss_device *tidss = to_tidss(ddev);
134+ struct tidss_plane *tplane = to_tidss_plane(plane);
135+
136+ dev_dbg(ddev->dev, "%s\n", __func__);
136137
137138 dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, true);
138139 }
@@ -160,6 +161,7 @@ static void drm_plane_destroy(struct drm_plane *plane) · 21 unmodified lines
160161 static const struct drm_plane_helper_funcs tidss_plane_helper_funcs = {
161162 .atomic_check = tidss_plane_atomic_check,
162163 .atomic_update = tidss_plane_atomic_update,
164+ .atomic_enable = tidss_plane_atomic_enable,
163165 .atomic_disable = tidss_plane_atomic_disable,
164166 };
165167
drivers/gpu/drm/tiny/simpledrm.c+22−9
@@ -606,16 +606,12 @@ static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = { · 605 unmodified lines
606606 */
607607
608608 static struct drm_display_mode simpledrm_mode(unsigned int width,
609− unsigned int height)
609+ unsigned int height,
610+ unsigned int width_mm,
611+ unsigned int height_mm)
610612 {
611− /*
612− * Assume a monitor resolution of 96 dpi to
613− * get a somewhat reasonable screen size.
614− */
615613 const struct drm_display_mode mode = {
616− DRM_MODE_INIT(60, width, height,
617− DRM_MODE_RES_MM(width, 96ul),
618− DRM_MODE_RES_MM(height, 96ul))
614+ DRM_MODE_INIT(60, width, height, width_mm, height_mm)
619615 };
620616
621617 return mode;
@@ -629,6 +625,8 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, · 7 unmodified lines
629625 struct simpledrm_device *sdev;
630626 struct drm_device *dev;
631627 int width, height, stride;
628+ int width_mm = 0, height_mm = 0;
629+ struct device_node *panel_node;
632630 const struct drm_format_info *format;
633631 struct resource *res, *mem = NULL;
634632 struct drm_plane *primary_plane;
@@ -685,6 +683,12 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, · 50 unmodified lines
685683 mem = simplefb_get_memory_of(dev, of_node);
686684 if (IS_ERR(mem))
687685 return ERR_CAST(mem);
686+ panel_node = of_parse_phandle(of_node, "panel", 0);
687+ if (panel_node) {
688+ simplefb_read_u32_of(dev, panel_node, "width-mm", &width_mm);
689+ simplefb_read_u32_of(dev, panel_node, "height-mm", &height_mm);
690+ of_node_put(panel_node);
691+ }
688692 } else {
689693 drm_err(dev, "no simplefb configuration found\n");
690694 return ERR_PTR(-ENODEV);
@@ -695,7 +699,16 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv, · 4 unmodified lines
695699 return ERR_PTR(-EINVAL);
696700 }
697701
698− sdev->mode = simpledrm_mode(width, height);
702+ /*
703+ * Assume a monitor resolution of 96 dpi if physical dimensions
704+ * are not specified to get a somewhat reasonable screen size.
705+ */
706+ if (!width_mm)
707+ width_mm = DRM_MODE_RES_MM(width, 96ul);
708+ if (!height_mm)
709+ height_mm = DRM_MODE_RES_MM(height, 96ul);
710+
711+ sdev->mode = simpledrm_mode(width, height, width_mm, height_mm);
699712 sdev->format = format;
700713 sdev->pitch = stride;
701714
drivers/gpu/drm/ttm/ttm_bo.c+13−17
@@ -120,8 +120,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, · 119 unmodified lines
120120 bool old_use_tt, new_use_tt;
121121 int ret;
122122
123− old_use_tt = bo->resource &&
124− ttm_manager_type(bdev, bo->resource->mem_type)->use_tt;
123+ old_use_tt = !bo->resource || ttm_manager_type(bdev, bo->resource->mem_type)->use_tt;
125124 new_use_tt = ttm_manager_type(bdev, mem->mem_type)->use_tt;
126125
127126 ttm_bo_unmap_virtual(bo);
@@ -894,14 +893,18 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, · 766 unmodified lines
894893 if (!placement->num_placement && !placement->num_busy_placement)
895894 return ttm_bo_pipeline_gutting(bo);
896895
897− /*
898− * Check whether we need to move buffer.
899− */
900− if (!bo->resource || !ttm_resource_compat(bo->resource, placement)) {
901− ret = ttm_bo_move_buffer(bo, placement, ctx);
902− if (ret)
903− return ret;
904− }
896+ /* Check whether we need to move buffer. */
897+ if (bo->resource && ttm_resource_compat(bo->resource, placement))
898+ return 0;
899+
900+ /* Moving of pinned BOs is forbidden */
901+ if (bo->pin_count)
902+ return -EINVAL;
903+
904+ ret = ttm_bo_move_buffer(bo, placement, ctx);
905+ if (ret)
906+ return ret;
907+
905908 /*
906909 * We might need to add a TTM.
907910 */
@@ -953,7 +956,6 @@ int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo, · 45 unmodified lines
953956 struct sg_table *sg, struct dma_resv *resv,
954957 void (*destroy) (struct ttm_buffer_object *))
955958 {
956− static const struct ttm_place sys_mem = { .mem_type = TTM_PL_SYSTEM };
957959 int ret;
958960
959961 kref_init(&bo->kref);
@@ -970,12 +972,6 @@ int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo, · 10 unmodified lines
970972 bo->base.resv = &bo->base._resv;
971973 atomic_inc(&ttm_glob.bo_count);
972974
973− ret = ttm_resource_alloc(bo, &sys_mem, &bo->resource);
974− if (unlikely(ret)) {
975− ttm_bo_put(bo);
976− return ret;
977− }
978−
979975 /*
980976 * For ttm_bo_type_device buffers, allocate
981977 * address space from the device.
drivers/gpu/drm/ttm/ttm_bo_util.c+4−15
@@ -157,8 +157,8 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, · 156 unmodified lines
157157 bool clear;
158158 int ret = 0;
159159
160− if (!src_mem)
161− return 0;
160+ if (WARN_ON(!src_mem))
161+ return -EINVAL;
162162
163163 src_man = ttm_manager_type(bdev, src_mem->mem_type);
164164 if (ttm && ((ttm->page_flags & TTM_TT_FLAG_SWAPPED) ||
@@ -704,30 +704,23 @@ EXPORT_SYMBOL(ttm_bo_move_sync_cleanup); · 539 unmodified lines
704704 */
705705 int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo)
706706 {
707− static const struct ttm_place sys_mem = { .mem_type = TTM_PL_SYSTEM };
708707 struct ttm_buffer_object *ghost;
709− struct ttm_resource *sys_res;
710708 struct ttm_tt *ttm;
711709 int ret;
712710
713− ret = ttm_resource_alloc(bo, &sys_mem, &sys_res);
714− if (ret)
715− return ret;
716−
717711 /* If already idle, no need for ghost object dance. */
718712 if (dma_resv_test_signaled(bo->base.resv, DMA_RESV_USAGE_BOOKKEEP)) {
719713 if (!bo->ttm) {
720714 /* See comment below about clearing. */
721715 ret = ttm_tt_create(bo, true);
722716 if (ret)
723− goto error_free_sys_mem;
717+ return ret;
724718 } else {
725719 ttm_tt_unpopulate(bo->bdev, bo->ttm);
726720 if (bo->type == ttm_bo_type_device)
727721 ttm_tt_mark_for_clear(bo->ttm);
728722 }
729723 ttm_resource_free(bo, &bo->resource);
730− ttm_bo_assign_mem(bo, sys_res);
731724 return 0;
732725 }
733726
@@ -744,7 +737,7 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo) · 10 unmodified lines
744737 ret = ttm_tt_create(bo, true);
745738 swap(bo->ttm, ttm);
746739 if (ret)
747− goto error_free_sys_mem;
740+ return ret;
748741
749742 ret = ttm_buffer_object_transfer(bo, &ghost);
750743 if (ret)
@@ -760,13 +753,9 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo) · 9 unmodified lines
760753 dma_resv_unlock(&ghost->base._resv);
761754 ttm_bo_put(ghost);
762755 bo->ttm = ttm;
763− ttm_bo_assign_mem(bo, sys_res);
764756 return 0;
765757
766758 error_destroy_tt:
767759 ttm_tt_destroy(bo->bdev, ttm);
768−
769−error_free_sys_mem:
770− ttm_resource_free(bo, &sys_res);
771760 return ret;
772761 }
drivers/gpu/drm/ttm/ttm_resource.c+0−1
@@ -361,7 +361,6 @@ bool ttm_resource_compat(struct ttm_resource *res, · 360 unmodified lines
361361
362362 return false;
363363 }
364−EXPORT_SYMBOL(ttm_resource_compat);
365364
366365 void ttm_resource_set_bo(struct ttm_resource *res,
367366 struct ttm_buffer_object *bo)
drivers/gpu/drm/v3d/v3d_gem.c+8−18
@@ -396,20 +396,6 @@ v3d_wait_bo_ioctl(struct drm_device *dev, void *data, · 395 unmodified lines
396396 return ret;
397397 }
398398
399−static int
400−v3d_job_add_deps(struct drm_file *file_priv, struct v3d_job *job,
401− u32 in_sync, u32 point)
402−{
403− struct dma_fence *in_fence = NULL;
404− int ret;
405−
406− ret = drm_syncobj_find_fence(file_priv, in_sync, point, 0, &in_fence);
407− if (ret == -EINVAL)
408− return ret;
409−
410− return drm_sched_job_add_dependency(&job->base, in_fence);
411−}
412−
413399 static int
414400 v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
415401 void **container, size_t size, void (*free)(struct kref *ref),
@@ -447,14 +433,18 @@ v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, · 31 unmodified lines
447433 DRM_DEBUG("Failed to copy wait dep handle.\n");
448434 goto fail_deps;
449435 }
450− ret = v3d_job_add_deps(file_priv, job, in.handle, 0);
451− if (ret)
436+ ret = drm_sched_job_add_syncobj_dependency(&job->base, file_priv, in.handle, 0);
437+
438+ // TODO: Investigate why this was filtered out for the IOCTL.
439+ if (ret && ret != -ENOENT)
452440 goto fail_deps;
453441 }
454442 }
455443 } else {
456− ret = v3d_job_add_deps(file_priv, job, in_sync, 0);
457− if (ret)
444+ ret = drm_sched_job_add_syncobj_dependency(&job->base, file_priv, in_sync, 0);
445+
446+ // TODO: Investigate why this was filtered out for the IOCTL.
447+ if (ret && ret != -ENOENT)
458448 goto fail_deps;
459449 }
460450
drivers/gpu/drm/vc4/vc4_drv.h+1−1
@@ -690,7 +690,7 @@ struct vc4_exec_info { · 689 unmodified lines
690690 /* This is the array of BOs that were looked up at the start of exec.
691691 * Command validation will use indices into this array.
692692 */
693− struct drm_gem_dma_object **bo;
693+ struct drm_gem_object **bo;
694694 uint32_t bo_count;
695695
696696 /* List of BOs that are being written by the RCL. Other than
drivers/gpu/drm/vc4/vc4_gem.c+18−60
@@ -199,7 +199,7 @@ vc4_save_hang_state(struct drm_device *dev) · 198 unmodified lines
199199 continue;
200200
201201 for (j = 0; j < exec[i]->bo_count; j++) {
202− bo = to_vc4_bo(&exec[i]->bo[j]->base);
202+ bo = to_vc4_bo(exec[i]->bo[j]);
203203
204204 /* Retain BOs just in case they were marked purgeable.
205205 * This prevents the BO from being purged before
@@ -207,8 +207,8 @@ vc4_save_hang_state(struct drm_device *dev) · 1 unmodified line
207207 */
208208 WARN_ON(!refcount_read(&bo->usecnt));
209209 refcount_inc(&bo->usecnt);
210− drm_gem_object_get(&exec[i]->bo[j]->base);
211− kernel_state->bo[k++] = &exec[i]->bo[j]->base;
210+ drm_gem_object_get(exec[i]->bo[j]);
211+ kernel_state->bo[k++] = exec[i]->bo[j];
212212 }
213213
214214 list_for_each_entry(bo, &exec[i]->unref_list, unref_head) {
@@ -558,7 +558,7 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno) · 343 unmodified lines
558558 unsigned i;
559559
560560 for (i = 0; i < exec->bo_count; i++) {
561− bo = to_vc4_bo(&exec->bo[i]->base);
561+ bo = to_vc4_bo(exec->bo[i]);
562562 bo->seqno = seqno;
563563
564564 dma_resv_add_fence(bo->base.base.resv, exec->fence,
@@ -585,11 +585,8 @@ vc4_unlock_bo_reservations(struct drm_device *dev, · 20 unmodified lines
585585 {
586586 int i;
587587
588− for (i = 0; i < exec->bo_count; i++) {
589− struct drm_gem_object *bo = &exec->bo[i]->base;
590−
591− dma_resv_unlock(bo->resv);
592− }
588+ for (i = 0; i < exec->bo_count; i++)
589+ dma_resv_unlock(exec->bo[i]->resv);
593590
594591 ww_acquire_fini(acquire_ctx);
595592 }
@@ -614,7 +611,7 @@ vc4_lock_bo_reservations(struct drm_device *dev, · 18 unmodified lines
614611
615612 retry:
616613 if (contended_lock != -1) {
617− bo = &exec->bo[contended_lock]->base;
614+ bo = exec->bo[contended_lock];
618615 ret = dma_resv_lock_slow_interruptible(bo->resv, acquire_ctx);
619616 if (ret) {
620617 ww_acquire_done(acquire_ctx);
@@ -626,19 +623,19 @@ retry: · 5 unmodified lines
626623 if (i == contended_lock)
627624 continue;
628625
629− bo = &exec->bo[i]->base;
626+ bo = exec->bo[i];
630627
631628 ret = dma_resv_lock_interruptible(bo->resv, acquire_ctx);
632629 if (ret) {
633630 int j;
634631
635632 for (j = 0; j < i; j++) {
636− bo = &exec->bo[j]->base;
633+ bo = exec->bo[j];
637634 dma_resv_unlock(bo->resv);
638635 }
639636
640637 if (contended_lock != -1 && contended_lock >= i) {
641− bo = &exec->bo[contended_lock]->base;
638+ bo = exec->bo[contended_lock];
642639
643640 dma_resv_unlock(bo->resv);
644641 }
@@ -659,7 +656,7 @@ retry: · 14 unmodified lines
659656 * before we commit the CL to the hardware.
660657 */
661658 for (i = 0; i < exec->bo_count; i++) {
662− bo = &exec->bo[i]->base;
659+ bo = exec->bo[i];
663660
664661 ret = dma_resv_reserve_fences(bo->resv, 1);
665662 if (ret) {
@@ -749,7 +746,6 @@ vc4_cl_lookup_bos(struct drm_device *dev, · 83 unmodified lines
749746 struct vc4_exec_info *exec)
750747 {
751748 struct drm_vc4_submit_cl *args = exec->args;
752− uint32_t *handles;
753749 int ret = 0;
754750 int i;
755751
@@ -763,54 +759,18 @@ vc4_cl_lookup_bos(struct drm_device *dev, · 7 unmodified lines
763759 return -EINVAL;
764760 }
765761
766− exec->bo = kvmalloc_array(exec->bo_count,
767− sizeof(struct drm_gem_dma_object *),
768− GFP_KERNEL | __GFP_ZERO);
769− if (!exec->bo) {
770− DRM_ERROR("Failed to allocate validated BO pointers\n");
771− return -ENOMEM;
772− }
773−
774− handles = kvmalloc_array(exec->bo_count, sizeof(uint32_t), GFP_KERNEL);
775− if (!handles) {
776− ret = -ENOMEM;
777− DRM_ERROR("Failed to allocate incoming GEM handles\n");
778− goto fail;
779− }
780−
781− if (copy_from_user(handles, u64_to_user_ptr(args->bo_handles),
782− exec->bo_count * sizeof(uint32_t))) {
783− ret = -EFAULT;
784− DRM_ERROR("Failed to copy in GEM handles\n");
785− goto fail;
786− }
787−
788− spin_lock(&file_priv->table_lock);
789− for (i = 0; i < exec->bo_count; i++) {
790− struct drm_gem_object *bo = idr_find(&file_priv->object_idr,
791− handles[i]);
792− if (!bo) {
793− DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
794− i, handles[i]);
795− ret = -EINVAL;
796− break;
797− }
798−
799− drm_gem_object_get(bo);
800− exec->bo[i] = (struct drm_gem_dma_object *)bo;
801− }
802− spin_unlock(&file_priv->table_lock);
762+ ret = drm_gem_objects_lookup(file_priv, u64_to_user_ptr(args->bo_handles),
763+ exec->bo_count, &exec->bo);
803764
804765 if (ret)
805766 goto fail_put_bo;
806767
807768 for (i = 0; i < exec->bo_count; i++) {
808− ret = vc4_bo_inc_usecnt(to_vc4_bo(&exec->bo[i]->base));
769+ ret = vc4_bo_inc_usecnt(to_vc4_bo(exec->bo[i]));
809770 if (ret)
810771 goto fail_dec_usecnt;
811772 }
812773
813− kvfree(handles);
814774 return 0;
815775
816776 fail_dec_usecnt:
@@ -823,15 +783,13 @@ fail_dec_usecnt: · 6 unmodified lines
823783 * step.
824784 */
825785 for (i-- ; i >= 0; i--)
826− vc4_bo_dec_usecnt(to_vc4_bo(&exec->bo[i]->base));
786+ vc4_bo_dec_usecnt(to_vc4_bo(exec->bo[i]));
827787
828788 fail_put_bo:
829789 /* Release any reference to acquired objects. */
830790 for (i = 0; i < exec->bo_count && exec->bo[i]; i++)
831− drm_gem_object_put(&exec->bo[i]->base);
791+ drm_gem_object_put(exec->bo[i]);
832792
833−fail:
834− kvfree(handles);
835793 kvfree(exec->bo);
836794 exec->bo = NULL;
837795 return ret;
@@ -974,10 +932,10 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) · 136 unmodified lines
974932
975933 if (exec->bo) {
976934 for (i = 0; i < exec->bo_count; i++) {
977− struct vc4_bo *bo = to_vc4_bo(&exec->bo[i]->base);
935+ struct vc4_bo *bo = to_vc4_bo(exec->bo[i]);
978936
979937 vc4_bo_dec_usecnt(bo);
980− drm_gem_object_put(&exec->bo[i]->base);
938+ drm_gem_object_put(exec->bo[i]);
981939 }
982940 kvfree(exec->bo);
983941 }
drivers/gpu/drm/vc4/vc4_hdmi.c+13−33
@@ -1466,6 +1466,12 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, · 1465 unmodified lines
14661466 if (!drm_dev_enter(drm, &idx))
14671467 goto out;
14681468
1469+ ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
1470+ if (ret < 0) {
1471+ DRM_ERROR("Failed to retain power domain: %d\n", ret);
1472+ goto err_dev_exit;
1473+ }
1474+
14691475 /*
14701476 * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must
14711477 * be faster than pixel clock, infinitesimally faster, tested in
@@ -1482,17 +1488,13 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, · 10 unmodified lines
14821488 * Additionally, the AXI clock needs to be at least 25% of
14831489 * pixel clock, but HSM ends up being the limiting factor.
14841490 */
1485− hsm_rate = max_t(unsigned long, 120000000, (tmds_char_rate / 100) * 101);
1491+ hsm_rate = max_t(unsigned long,
1492+ HSM_MIN_CLOCK_FREQ,
1493+ (tmds_char_rate / 100) * 101);
14861494 ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate);
14871495 if (ret) {
14881496 DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
1489− goto err_dev_exit;
1490− }
1491−
1492− ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
1493− if (ret < 0) {
1494− DRM_ERROR("Failed to retain power domain: %d\n", ret);
1495− goto err_dev_exit;
1497+ goto err_put_runtime_pm;
14961498 }
14971499
14981500 ret = clk_set_rate(vc4_hdmi->pixel_clock, tmds_char_rate);
@@ -3188,16 +3190,9 @@ static int vc4_hdmi_init_resources(struct drm_device *drm, · 1689 unmodified lines
31883190 DRM_ERROR("Failed to get HDMI state machine clock\n");
31893191 return PTR_ERR(vc4_hdmi->hsm_clock);
31903192 }
3191−
31923193 vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock;
31933194 vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock;
31943195
3195− vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi");
3196− if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) {
3197− DRM_ERROR("Failed to get HDMI state machine clock\n");
3198− return PTR_ERR(vc4_hdmi->hsm_rpm_clock);
3199− }
3200−
32013196 return 0;
32023197 }
32033198
@@ -3280,12 +3275,6 @@ static int vc5_hdmi_init_resources(struct drm_device *drm, · 76 unmodified lines
32803275 return PTR_ERR(vc4_hdmi->hsm_clock);
32813276 }
32823277
3283− vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi");
3284− if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) {
3285− DRM_ERROR("Failed to get HDMI state machine clock\n");
3286− return PTR_ERR(vc4_hdmi->hsm_rpm_clock);
3287− }
3288−
32893278 vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb");
32903279 if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) {
32913280 DRM_ERROR("Failed to get pixel bvb clock\n");
@@ -3349,7 +3338,7 @@ static int vc4_hdmi_runtime_suspend(struct device *dev) · 57 unmodified lines
33493338 {
33503339 struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
33513340
3352− clk_disable_unprepare(vc4_hdmi->hsm_rpm_clock);
3341+ clk_disable_unprepare(vc4_hdmi->hsm_clock);
33533342
33543343 return 0;
33553344 }
@@ -3362,16 +3351,7 @@ static int vc4_hdmi_runtime_resume(struct device *dev) · 6 unmodified lines
33623351 unsigned long rate;
33633352 int ret;
33643353
3365− /*
3366− * The HSM clock is in the HDMI power domain, so we need to set
3367− * its frequency while the power domain is active so that it
3368− * keeps its rate.
3369− */
3370− ret = clk_set_min_rate(vc4_hdmi->hsm_rpm_clock, HSM_MIN_CLOCK_FREQ);
3371− if (ret)
3372− return ret;
3373−
3374− ret = clk_prepare_enable(vc4_hdmi->hsm_rpm_clock);
3354+ ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
33753355 if (ret)
33763356 return ret;
33773357
@@ -3384,7 +3364,7 @@ static int vc4_hdmi_runtime_resume(struct device *dev) · 6 unmodified lines
33843364 * case, it will lead to a silent CPU stall. Let's make sure we
33853365 * prevent such a case.
33863366 */
3387− rate = clk_get_rate(vc4_hdmi->hsm_rpm_clock);
3367+ rate = clk_get_rate(vc4_hdmi->hsm_clock);
33883368 if (!rate) {
33893369 ret = -EINVAL;
33903370 goto err_disable_clk;
drivers/gpu/drm/vc4/vc4_hdmi.h+0−1
@@ -164,7 +164,6 @@ struct vc4_hdmi { · 163 unmodified lines
164164 struct clk *cec_clock;
165165 struct clk *pixel_clock;
166166 struct clk *hsm_clock;
167− struct clk *hsm_rpm_clock;
168167 struct clk *audio_clock;
169168 struct clk *pixel_bvb_clock;
170169
drivers/gpu/drm/vc4/vc4_validate.c+2−2
@@ -117,7 +117,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex) · 116 unmodified lines
117117 hindex, exec->bo_count);
118118 return NULL;
119119 }
120− obj = exec->bo[hindex];
120+ obj = to_drm_gem_dma_obj(exec->bo[hindex]);
121121 bo = to_vc4_bo(&obj->base);
122122
123123 if (bo->validated_shader) {
@@ -810,7 +810,7 @@ validate_gl_shader_rec(struct drm_device *dev, · 686 unmodified lines
810810 return -EINVAL;
811811 }
812812
813− bo[i] = exec->bo[src_handles[i]];
813+ bo[i] = to_drm_gem_dma_obj(exec->bo[src_handles[i]]);
814814 if (!bo[i])
815815 return -EINVAL;
816816 }
drivers/gpu/drm/vgem/vgem_fence.c+1−0
@@ -249,4 +249,5 @@ void vgem_fence_close(struct vgem_file *vfile) · 248 unmodified lines
249249 {
250250 idr_for_each(&vfile->fence_idr, __vgem_fence_idr_fini, vfile);
251251 idr_destroy(&vfile->fence_idr);
252+ mutex_destroy(&vfile->fence_mutex);
252253 }
drivers/gpu/drm/virtio/Kconfig+11−0
@@ -11,3 +11,14 @@ config DRM_VIRTIO_GPU · 10 unmodified lines
1111 QEMU based VMMs (like KVM or Xen).
1212
1313 If unsure say M.
14+
15+config DRM_VIRTIO_GPU_KMS
16+ bool "Virtio GPU driver modesetting support"
17+ depends on DRM_VIRTIO_GPU
18+ default y
19+ help
20+ Enable modesetting support for virtio GPU driver. This can be
21+ disabled in cases where only "headless" usage of the GPU is
22+ required.
23+
24+ If unsure, say Y.
drivers/gpu/drm/virtio/virtgpu_display.c+6−0
@@ -336,6 +336,9 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) · 335 unmodified lines
336336 {
337337 int i, ret;
338338
339+ if (!vgdev->num_scanouts)
340+ return 0;
341+
339342 ret = drmm_mode_config_init(vgdev->ddev);
340343 if (ret)
341344 return ret;
@@ -362,6 +365,9 @@ void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) · 20 unmodified lines
362365 {
363366 int i;
364367
368+ if (!vgdev->num_scanouts)
369+ return;
370+
365371 for (i = 0 ; i < vgdev->num_scanouts; ++i)
366372 kfree(vgdev->outputs[i].edid);
367373 }
drivers/gpu/drm/virtio/virtgpu_drv.c+4−0
@@ -172,6 +172,10 @@ MODULE_AUTHOR("Alon Levy"); · 171 unmodified lines
172172 DEFINE_DRM_GEM_FOPS(virtio_gpu_driver_fops);
173173
174174 static const struct drm_driver driver = {
175+ /*
176+ * If KMS is disabled DRIVER_MODESET and DRIVER_ATOMIC are masked
177+ * out via drm_device::driver_features:
178+ */
175179 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC,
176180 .open = virtio_gpu_driver_open,
177181 .postclose = virtio_gpu_driver_postclose,
drivers/gpu/drm/virtio/virtgpu_kms.c+23−16
@@ -43,11 +43,13 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) · 42 unmodified lines
4343 virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
4444 events_read, &events_read);
4545 if (events_read & VIRTIO_GPU_EVENT_DISPLAY) {
46− if (vgdev->has_edid)
47− virtio_gpu_cmd_get_edids(vgdev);
48− virtio_gpu_cmd_get_display_info(vgdev);
49− virtio_gpu_notify(vgdev);
50− drm_helper_hpd_irq_event(vgdev->ddev);
46+ if (vgdev->num_scanouts) {
47+ if (vgdev->has_edid)
48+ virtio_gpu_cmd_get_edids(vgdev);
49+ virtio_gpu_cmd_get_display_info(vgdev);
50+ virtio_gpu_notify(vgdev);
51+ drm_helper_hpd_irq_event(vgdev->ddev);
52+ }
5153 events_clear |= VIRTIO_GPU_EVENT_DISPLAY;
5254 }
5355 virtio_cwrite_le(vgdev->vdev, struct virtio_gpu_config,
@@ -223,12 +225,15 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) · 169 unmodified lines
223225 num_scanouts, &num_scanouts);
224226 vgdev->num_scanouts = min_t(uint32_t, num_scanouts,
225227 VIRTIO_GPU_MAX_SCANOUTS);
226− if (!vgdev->num_scanouts) {
227− DRM_ERROR("num_scanouts is zero\n");
228− ret = -EINVAL;
229− goto err_scanouts;
228+
229+ if (!IS_ENABLED(CONFIG_DRM_VIRTIO_GPU_KMS) || !vgdev->num_scanouts) {
230+ DRM_INFO("KMS disabled\n");
231+ vgdev->num_scanouts = 0;
232+ vgdev->has_edid = false;
233+ dev->driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC);
234+ } else {
235+ DRM_INFO("number of scanouts: %d\n", num_scanouts);
230236 }
231− DRM_INFO("number of scanouts: %d\n", num_scanouts);
232237
233238 virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
234239 num_capsets, &num_capsets);
@@ -244,12 +249,14 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) · 9 unmodified lines
244249
245250 if (num_capsets)
246251 virtio_gpu_get_capsets(vgdev, num_capsets);
247− if (vgdev->has_edid)
248− virtio_gpu_cmd_get_edids(vgdev);
249− virtio_gpu_cmd_get_display_info(vgdev);
250− virtio_gpu_notify(vgdev);
251− wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending,
252− 5 * HZ);
252+ if (vgdev->num_scanouts) {
253+ if (vgdev->has_edid)
254+ virtio_gpu_cmd_get_edids(vgdev);
255+ virtio_gpu_cmd_get_display_info(vgdev);
256+ virtio_gpu_notify(vgdev);
257+ wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending,
258+ 5 * HZ);
259+ }
253260 return 0;
254261
255262 err_scanouts:
drivers/gpu/drm/virtio/virtgpu_vq.c+1−2
@@ -923,8 +923,7 @@ void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id, · 922 unmodified lines
923923 cmd_p->hdr.ctx_id = cpu_to_le32(id);
924924 cmd_p->nlen = cpu_to_le32(nlen);
925925 cmd_p->context_init = cpu_to_le32(context_init);
926− strncpy(cmd_p->debug_name, name, sizeof(cmd_p->debug_name) - 1);
927− cmd_p->debug_name[sizeof(cmd_p->debug_name) - 1] = 0;
926+ strscpy(cmd_p->debug_name, name, sizeof(cmd_p->debug_name));
928927 virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
929928 }
930929
drivers/gpu/drm/vmwgfx/Makefile+1−1
@@ -1,7 +1,7 @@
11 # SPDX-License-Identifier: GPL-2.0
22 vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
33 vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_ttm_buffer.o \
4− vmwgfx_cmd.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
4+ vmwgfx_cmd.o vmwgfx_irq.o vmwgfx_ldu.o \
55 vmwgfx_overlay.o vmwgfx_gmrid_manager.o vmwgfx_fence.o \
66 vmwgfx_bo.o vmwgfx_scrn.o vmwgfx_context.o \
77 vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c+196−211
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright © 2011-2018 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright © 2011-2023 VMware, Inc., Palo Alto, CA., USA
55 * All Rights Reserved.
66 *
77 * Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,40 +26,31 @@ · 18 unmodified lines
2626 *
2727 **************************************************************************/
2828
29−#include <drm/ttm/ttm_placement.h>
30−
29+#include "vmwgfx_bo.h"
3130 #include "vmwgfx_drv.h"
32−#include "ttm_object.h"
3331
3432
35−/**
36− * vmw_buffer_object - Convert a struct ttm_buffer_object to a struct
37− * vmw_buffer_object.
38− *
39− * @bo: Pointer to the TTM buffer object.
40− * Return: Pointer to the struct vmw_buffer_object embedding the
41− * TTM buffer object.
42− */
43−static struct vmw_buffer_object *
44−vmw_buffer_object(struct ttm_buffer_object *bo)
33+#include <drm/ttm/ttm_placement.h>
34+
35+static void vmw_bo_release(struct vmw_bo *vbo)
4536 {
46− return container_of(bo, struct vmw_buffer_object, base);
37+ vmw_bo_unmap(vbo);
38+ drm_gem_object_release(&vbo->tbo.base);
4739 }
4840
4941 /**
50− * bo_is_vmw - check if the buffer object is a &vmw_buffer_object
51− * @bo: ttm buffer object to be checked
42+ * vmw_bo_free - vmw_bo destructor
5243 *
53− * Uses destroy function associated with the object to determine if this is
54− * a &vmw_buffer_object.
55− *
56− * Returns:
57− * true if the object is of &vmw_buffer_object type, false if not.
44+ * @bo: Pointer to the embedded struct ttm_buffer_object
5845 */
59−static bool bo_is_vmw(struct ttm_buffer_object *bo)
46+static void vmw_bo_free(struct ttm_buffer_object *bo)
6047 {
61− return bo->destroy == &vmw_bo_bo_free ||
62− bo->destroy == &vmw_gem_destroy;
48+ struct vmw_bo *vbo = to_vmw_bo(&bo->base);
49+
50+ WARN_ON(vbo->dirty);
51+ WARN_ON(!RB_EMPTY_ROOT(&vbo->res_tree));
52+ vmw_bo_release(vbo);
53+ kfree(vbo);
6354 }
6455
6556 /**
@@ -72,13 +63,13 @@ static bool bo_is_vmw(struct ttm_buffer_object *bo) · 6 unmodified lines
7263 * Return: Zero on success, Negative error code on failure. In particular
7364 * -ERESTARTSYS if interrupted by a signal
7465 */
75−int vmw_bo_pin_in_placement(struct vmw_private *dev_priv,
76− struct vmw_buffer_object *buf,
77− struct ttm_placement *placement,
78− bool interruptible)
66+static int vmw_bo_pin_in_placement(struct vmw_private *dev_priv,
67+ struct vmw_bo *buf,
68+ struct ttm_placement *placement,
69+ bool interruptible)
7970 {
8071 struct ttm_operation_ctx ctx = {interruptible, false };
81− struct ttm_buffer_object *bo = &buf->base;
72+ struct ttm_buffer_object *bo = &buf->tbo;
8273 int ret;
8374
8475 vmw_execbuf_release_pinned_bo(dev_priv);
@@ -87,12 +78,7 @@ int vmw_bo_pin_in_placement(struct vmw_private *dev_priv, · 2 unmodified lines
8778 if (unlikely(ret != 0))
8879 goto err;
8980
90− if (buf->base.pin_count > 0)
91− ret = ttm_resource_compat(bo->resource, placement)
92− ? 0 : -EINVAL;
93− else
94− ret = ttm_bo_validate(bo, placement, &ctx);
95−
81+ ret = ttm_bo_validate(bo, placement, &ctx);
9682 if (!ret)
9783 vmw_bo_pin_reserved(buf, true);
9884
@@ -115,11 +101,11 @@ err: · 16 unmodified lines
115101 * -ERESTARTSYS if interrupted by a signal
116102 */
117103 int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
118− struct vmw_buffer_object *buf,
104+ struct vmw_bo *buf,
119105 bool interruptible)
120106 {
121107 struct ttm_operation_ctx ctx = {interruptible, false };
122− struct ttm_buffer_object *bo = &buf->base;
108+ struct ttm_buffer_object *bo = &buf->tbo;
123109 int ret;
124110
125111 vmw_execbuf_release_pinned_bo(dev_priv);
@@ -128,17 +114,17 @@ int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv, · 2 unmodified lines
128114 if (unlikely(ret != 0))
129115 goto err;
130116
131− if (buf->base.pin_count > 0) {
132− ret = ttm_resource_compat(bo->resource, &vmw_vram_gmr_placement)
133− ? 0 : -EINVAL;
134− goto out_unreserve;
135− }
136−
137− ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, &ctx);
117+ vmw_bo_placement_set(buf,
118+ VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
119+ VMW_BO_DOMAIN_GMR);
120+ ret = ttm_bo_validate(bo, &buf->placement, &ctx);
138121 if (likely(ret == 0) || ret == -ERESTARTSYS)
139122 goto out_unreserve;
140123
141− ret = ttm_bo_validate(bo, &vmw_vram_placement, &ctx);
124+ vmw_bo_placement_set(buf,
125+ VMW_BO_DOMAIN_VRAM,
126+ VMW_BO_DOMAIN_VRAM);
127+ ret = ttm_bo_validate(bo, &buf->placement, &ctx);
142128
143129 out_unreserve:
144130 if (!ret)
@@ -163,7 +149,7 @@ err: · 18 unmodified lines
163149 * -ERESTARTSYS if interrupted by a signal
164150 */
165151 int vmw_bo_pin_in_vram(struct vmw_private *dev_priv,
166− struct vmw_buffer_object *buf,
152+ struct vmw_bo *buf,
167153 bool interruptible)
168154 {
169155 return vmw_bo_pin_in_placement(dev_priv, buf, &vmw_vram_placement,
@@ -184,22 +170,13 @@ int vmw_bo_pin_in_vram(struct vmw_private *dev_priv, · 14 unmodified lines
184170 * -ERESTARTSYS if interrupted by a signal
185171 */
186172 int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv,
187− struct vmw_buffer_object *buf,
173+ struct vmw_bo *buf,
188174 bool interruptible)
189175 {
190176 struct ttm_operation_ctx ctx = {interruptible, false };
191− struct ttm_buffer_object *bo = &buf->base;
192− struct ttm_placement placement;
193− struct ttm_place place;
177+ struct ttm_buffer_object *bo = &buf->tbo;
194178 int ret = 0;
195179
196− place = vmw_vram_placement.placement[0];
197− place.lpfn = PFN_UP(bo->resource->size);
198− placement.num_placement = 1;
199− placement.placement = &place;
200− placement.num_busy_placement = 1;
201− placement.busy_placement = &place;
202−
203180 vmw_execbuf_release_pinned_bo(dev_priv);
204181 ret = ttm_bo_reserve(bo, interruptible, false, NULL);
205182 if (unlikely(ret != 0))
@@ -213,16 +190,19 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv, · 7 unmodified lines
213190 if (bo->resource->mem_type == TTM_PL_VRAM &&
214191 bo->resource->start < PFN_UP(bo->resource->size) &&
215192 bo->resource->start > 0 &&
216− buf->base.pin_count == 0) {
193+ buf->tbo.pin_count == 0) {
217194 ctx.interruptible = false;
218− (void) ttm_bo_validate(bo, &vmw_sys_placement, &ctx);
195+ vmw_bo_placement_set(buf,
196+ VMW_BO_DOMAIN_SYS,
197+ VMW_BO_DOMAIN_SYS);
198+ (void)ttm_bo_validate(bo, &buf->placement, &ctx);
219199 }
220200
221− if (buf->base.pin_count > 0)
222− ret = ttm_resource_compat(bo->resource, &placement)
223− ? 0 : -EINVAL;
224− else
225− ret = ttm_bo_validate(bo, &placement, &ctx);
201+ vmw_bo_placement_set(buf,
202+ VMW_BO_DOMAIN_VRAM,
203+ VMW_BO_DOMAIN_VRAM);
204+ buf->places[0].lpfn = PFN_UP(bo->resource->size);
205+ ret = ttm_bo_validate(bo, &buf->placement, &ctx);
226206
227207 /* For some reason we didn't end up at the start of vram */
228208 WARN_ON(ret == 0 && bo->resource->start != 0);
@@ -248,10 +228,10 @@ err_unlock: · 19 unmodified lines
248228 * -ERESTARTSYS if interrupted by a signal
249229 */
250230 int vmw_bo_unpin(struct vmw_private *dev_priv,
251− struct vmw_buffer_object *buf,
231+ struct vmw_bo *buf,
252232 bool interruptible)
253233 {
254− struct ttm_buffer_object *bo = &buf->base;
234+ struct ttm_buffer_object *bo = &buf->tbo;
255235 int ret;
256236
257237 ret = ttm_bo_reserve(bo, interruptible, false, NULL);
@@ -293,12 +273,12 @@ void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *bo, · 35 unmodified lines
293273 * @pin: Whether to pin or unpin.
294274 *
295275 */
296−void vmw_bo_pin_reserved(struct vmw_buffer_object *vbo, bool pin)
276+void vmw_bo_pin_reserved(struct vmw_bo *vbo, bool pin)
297277 {
298278 struct ttm_operation_ctx ctx = { false, true };
299279 struct ttm_place pl;
300280 struct ttm_placement placement;
301− struct ttm_buffer_object *bo = &vbo->base;
281+ struct ttm_buffer_object *bo = &vbo->tbo;
302282 uint32_t old_mem_type = bo->resource->mem_type;
303283 int ret;
304284
@@ -341,9 +321,9 @@ void vmw_bo_pin_reserved(struct vmw_buffer_object *vbo, bool pin) · 36 unmodified lines
341321 * 3) Buffer object destruction
342322 *
343323 */
344−void *vmw_bo_map_and_cache(struct vmw_buffer_object *vbo)
324+void *vmw_bo_map_and_cache(struct vmw_bo *vbo)
345325 {
346− struct ttm_buffer_object *bo = &vbo->base;
326+ struct ttm_buffer_object *bo = &vbo->tbo;
347327 bool not_used;
348328 void *virtual;
349329 int ret;
@@ -366,96 +346,70 @@ void *vmw_bo_map_and_cache(struct vmw_buffer_object *vbo) · 16 unmodified lines
366346 * @vbo: The buffer object whose map we are tearing down.
367347 *
368348 * This function tears down a cached map set up using
369− * vmw_buffer_object_map_and_cache().
349+ * vmw_bo_map_and_cache().
370350 */
371−void vmw_bo_unmap(struct vmw_buffer_object *vbo)
351+void vmw_bo_unmap(struct vmw_bo *vbo)
372352 {
373353 if (vbo->map.bo == NULL)
374354 return;
375355
376356 ttm_bo_kunmap(&vbo->map);
357+ vbo->map.bo = NULL;
377358 }
378359
379360
380361 /**
381− * vmw_bo_bo_free - vmw buffer object destructor
382− *
383− * @bo: Pointer to the embedded struct ttm_buffer_object
384− */
385−void vmw_bo_bo_free(struct ttm_buffer_object *bo)
386−{
387− struct vmw_buffer_object *vmw_bo = vmw_buffer_object(bo);
388−
389− WARN_ON(vmw_bo->dirty);
390− WARN_ON(!RB_EMPTY_ROOT(&vmw_bo->res_tree));
391− vmw_bo_unmap(vmw_bo);
392− drm_gem_object_release(&bo->base);
393− kfree(vmw_bo);
394−}
395−
396−/* default destructor */
397−static void vmw_bo_default_destroy(struct ttm_buffer_object *bo)
398−{
399− kfree(bo);
400−}
401−
402−/**
403− * vmw_bo_create_kernel - Create a pinned BO for internal kernel use.
362+ * vmw_bo_init - Initialize a vmw buffer object
404363 *
405364 * @dev_priv: Pointer to the device private struct
406− * @size: size of the BO we need
407− * @placement: where to put it
408− * @p_bo: resulting BO
365+ * @vmw_bo: Buffer object to initialize
366+ * @params: Parameters used to initialize the buffer object
367+ * @destroy: The function used to delete the buffer object
368+ * Returns: Zero on success, negative error code on error.
409369 *
410− * Creates and pin a simple BO for in kernel use.
411370 */
412−int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size,
413− struct ttm_placement *placement,
414− struct ttm_buffer_object **p_bo)
371+static int vmw_bo_init(struct vmw_private *dev_priv,
372+ struct vmw_bo *vmw_bo,
373+ struct vmw_bo_params *params,
374+ void (*destroy)(struct ttm_buffer_object *))
415375 {
416376 struct ttm_operation_ctx ctx = {
417− .interruptible = false,
377+ .interruptible = params->bo_type != ttm_bo_type_kernel,
418378 .no_wait_gpu = false
419379 };
420− struct ttm_buffer_object *bo;
380+ struct ttm_device *bdev = &dev_priv->bdev;
421381 struct drm_device *vdev = &dev_priv->drm;
422382 int ret;
423383
424− bo = kzalloc(sizeof(*bo), GFP_KERNEL);
425− if (unlikely(!bo))
426− return -ENOMEM;
384+ memset(vmw_bo, 0, sizeof(*vmw_bo));
427385
428− size = ALIGN(size, PAGE_SIZE);
386+ BUILD_BUG_ON(TTM_MAX_BO_PRIORITY <= 3);
387+ vmw_bo->tbo.priority = 3;
388+ vmw_bo->res_tree = RB_ROOT;
429389
430− drm_gem_private_object_init(vdev, &bo->base, size);
390+ params->size = ALIGN(params->size, PAGE_SIZE);
391+ drm_gem_private_object_init(vdev, &vmw_bo->tbo.base, params->size);
431392
432− ret = ttm_bo_init_reserved(&dev_priv->bdev, bo, ttm_bo_type_kernel,
433− placement, 0, &ctx, NULL, NULL,
434− vmw_bo_default_destroy);
393+ vmw_bo_placement_set(vmw_bo, params->domain, params->busy_domain);
394+ ret = ttm_bo_init_reserved(bdev, &vmw_bo->tbo, params->bo_type,
395+ &vmw_bo->placement, 0, &ctx, NULL,
396+ NULL, destroy);
435397 if (unlikely(ret))
436− goto error_free;
398+ return ret;
437399
438− ttm_bo_pin(bo);
439− ttm_bo_unreserve(bo);
440− *p_bo = bo;
400+ if (params->pin)
401+ ttm_bo_pin(&vmw_bo->tbo);
402+ ttm_bo_unreserve(&vmw_bo->tbo);
441403
442404 return 0;
443−
444−error_free:
445− kfree(bo);
446− return ret;
447405 }
448406
449407 int vmw_bo_create(struct vmw_private *vmw,
450− size_t size, struct ttm_placement *placement,
451− bool interruptible, bool pin,
452− void (*bo_free)(struct ttm_buffer_object *bo),
453− struct vmw_buffer_object **p_bo)
408+ struct vmw_bo_params *params,
409+ struct vmw_bo **p_bo)
454410 {
455411 int ret;
456412
457− BUG_ON(!bo_free);
458−
459413 *p_bo = kmalloc(sizeof(**p_bo), GFP_KERNEL);
460414 if (unlikely(!*p_bo)) {
461415 DRM_ERROR("Failed to allocate a buffer.\n");
@@ -465,9 +419,7 @@ int vmw_bo_create(struct vmw_private *vmw, · 3 unmodified lines
465419 /*
466420 * vmw_bo_init will delete the *p_bo object if it fails
467421 */
468− ret = vmw_bo_init(vmw, *p_bo, size,
469− placement, interruptible, pin,
470− bo_free);
422+ ret = vmw_bo_init(vmw, *p_bo, params, vmw_bo_free);
471423 if (unlikely(ret != 0))
472424 goto out_error;
473425
@@ -478,57 +430,7 @@ out_error: · 4 unmodified lines
478430 }
479431
480432 /**
481− * vmw_bo_init - Initialize a vmw buffer object
482− *
483− * @dev_priv: Pointer to the device private struct
484− * @vmw_bo: Pointer to the struct vmw_buffer_object to initialize.
485− * @size: Buffer object size in bytes.
486− * @placement: Initial placement.
487− * @interruptible: Whether waits should be performed interruptible.
488− * @pin: If the BO should be created pinned at a fixed location.
489− * @bo_free: The buffer object destructor.
490− * Returns: Zero on success, negative error code on error.
491− *
492− * Note that on error, the code will free the buffer object.
493− */
494−int vmw_bo_init(struct vmw_private *dev_priv,
495− struct vmw_buffer_object *vmw_bo,
496− size_t size, struct ttm_placement *placement,
497− bool interruptible, bool pin,
498− void (*bo_free)(struct ttm_buffer_object *bo))
499−{
500− struct ttm_operation_ctx ctx = {
501− .interruptible = interruptible,
502− .no_wait_gpu = false
503− };
504− struct ttm_device *bdev = &dev_priv->bdev;
505− struct drm_device *vdev = &dev_priv->drm;
506− int ret;
507−
508− WARN_ON_ONCE(!bo_free);
509− memset(vmw_bo, 0, sizeof(*vmw_bo));
510− BUILD_BUG_ON(TTM_MAX_BO_PRIORITY <= 3);
511− vmw_bo->base.priority = 3;
512− vmw_bo->res_tree = RB_ROOT;
513−
514− size = ALIGN(size, PAGE_SIZE);
515− drm_gem_private_object_init(vdev, &vmw_bo->base.base, size);
516−
517− ret = ttm_bo_init_reserved(bdev, &vmw_bo->base, ttm_bo_type_device,
518− placement, 0, &ctx, NULL, NULL, bo_free);
519− if (unlikely(ret)) {
520− return ret;
521− }
522−
523− if (pin)
524− ttm_bo_pin(&vmw_bo->base);
525− ttm_bo_unreserve(&vmw_bo->base);
526−
527− return 0;
528−}
529−
530−/**
531− * vmw_user_bo_synccpu_grab - Grab a struct vmw_buffer_object for cpu
433+ * vmw_user_bo_synccpu_grab - Grab a struct vmw_bo for cpu
532434 * access, idling previous GPU operations on the buffer and optionally
533435 * blocking it for further command submissions.
534436 *
@@ -541,11 +443,11 @@ int vmw_bo_init(struct vmw_private *dev_priv, · 6 unmodified lines
541443 *
542444 * A blocking grab will be automatically released when @tfile is closed.
543445 */
544−static int vmw_user_bo_synccpu_grab(struct vmw_buffer_object *vmw_bo,
446+static int vmw_user_bo_synccpu_grab(struct vmw_bo *vmw_bo,
545447 uint32_t flags)
546448 {
547449 bool nonblock = !!(flags & drm_vmw_synccpu_dontblock);
548− struct ttm_buffer_object *bo = &vmw_bo->base;
450+ struct ttm_buffer_object *bo = &vmw_bo->tbo;
549451 int ret;
550452
551453 if (flags & drm_vmw_synccpu_allow_cs) {
@@ -588,17 +490,17 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp, · 36 unmodified lines
588490 uint32_t handle,
589491 uint32_t flags)
590492 {
591− struct vmw_buffer_object *vmw_bo;
493+ struct vmw_bo *vmw_bo;
592494 int ret = vmw_user_bo_lookup(filp, handle, &vmw_bo);
593495
594496 if (!ret) {
595497 if (!(flags & drm_vmw_synccpu_allow_cs)) {
596498 atomic_dec(&vmw_bo->cpu_writers);
597499 }
598− ttm_bo_put(&vmw_bo->base);
500+ ttm_bo_put(&vmw_bo->tbo);
599501 }
600502
601− drm_gem_object_put(&vmw_bo->base.base);
503+ drm_gem_object_put(&vmw_bo->tbo.base);
602504 return ret;
603505 }
604506
@@ -620,7 +522,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data, · 15 unmodified lines
620522 {
621523 struct drm_vmw_synccpu_arg *arg =
622524 (struct drm_vmw_synccpu_arg *) data;
623− struct vmw_buffer_object *vbo;
525+ struct vmw_bo *vbo;
624526 int ret;
625527
626528 if ((arg->flags & (drm_vmw_synccpu_read | drm_vmw_synccpu_write)) == 0
@@ -639,7 +541,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data, · 12 unmodified lines
639541
640542 ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
641543 vmw_bo_unreference(&vbo);
642− drm_gem_object_put(&vbo->base.base);
544+ drm_gem_object_put(&vbo->tbo.base);
643545 if (unlikely(ret != 0)) {
644546 if (ret == -ERESTARTSYS || ret == -EBUSY)
645547 return -EBUSY;
@@ -683,8 +585,7 @@ int vmw_bo_unref_ioctl(struct drm_device *dev, void *data, · 37 unmodified lines
683585 struct drm_vmw_unref_dmabuf_arg *arg =
684586 (struct drm_vmw_unref_dmabuf_arg *)data;
685587
686− drm_gem_handle_delete(file_priv, arg->handle);
687− return 0;
588+ return drm_gem_handle_delete(file_priv, arg->handle);
688589 }
689590
690591
@@ -694,14 +595,14 @@ int vmw_bo_unref_ioctl(struct drm_device *dev, void *data, · 3 unmodified lines
694595 * @filp: The file the handle is registered with.
695596 * @handle: The user buffer object handle
696597 * @out: Pointer to a where a pointer to the embedded
697− * struct vmw_buffer_object should be placed.
598+ * struct vmw_bo should be placed.
698599 * Return: Zero on success, Negative error code on error.
699600 *
700601 * The vmw buffer object pointer will be refcounted (both ttm and gem)
701602 */
702603 int vmw_user_bo_lookup(struct drm_file *filp,
703− uint32_t handle,
704− struct vmw_buffer_object **out)
604+ u32 handle,
605+ struct vmw_bo **out)
705606 {
706607 struct drm_gem_object *gobj;
707608
@@ -712,8 +613,8 @@ int vmw_user_bo_lookup(struct drm_file *filp, · 4 unmodified lines
712613 return -ESRCH;
713614 }
714615
715− *out = gem_to_vmw_bo(gobj);
716− ttm_bo_get(&(*out)->base);
616+ *out = to_vmw_bo(gobj);
617+ ttm_bo_get(&(*out)->tbo);
717618
718619 return 0;
719620 }
@@ -734,8 +635,7 @@ void vmw_bo_fence_single(struct ttm_buffer_object *bo, · 14 unmodified lines
734635 struct vmw_fence_obj *fence)
735636 {
736637 struct ttm_device *bdev = bo->bdev;
737− struct vmw_private *dev_priv =
738− container_of(bdev, struct vmw_private, bdev);
638+ struct vmw_private *dev_priv = vmw_priv_from_ttm(bdev);
739639 int ret;
740640
741641 if (fence == NULL)
@@ -771,7 +671,7 @@ int vmw_dumb_create(struct drm_file *file_priv, · 29 unmodified lines
771671 struct drm_mode_create_dumb *args)
772672 {
773673 struct vmw_private *dev_priv = vmw_priv(dev);
774− struct vmw_buffer_object *vbo;
674+ struct vmw_bo *vbo;
775675 int cpp = DIV_ROUND_UP(args->bpp, 8);
776676 int ret;
777677
@@ -795,7 +695,7 @@ int vmw_dumb_create(struct drm_file *file_priv, · 17 unmodified lines
795695 args->size, &args->handle,
796696 &vbo);
797697 /* drop reference from allocate - handle holds it now */
798− drm_gem_object_put(&vbo->base.base);
698+ drm_gem_object_put(&vbo->tbo.base);
799699 return ret;
800700 }
801701
@@ -806,12 +706,8 @@ int vmw_dumb_create(struct drm_file *file_priv, · 4 unmodified lines
806706 */
807707 void vmw_bo_swap_notify(struct ttm_buffer_object *bo)
808708 {
809− /* Is @bo embedded in a struct vmw_buffer_object? */
810− if (!bo_is_vmw(bo))
811− return;
812−
813709 /* Kill any cached kernel maps before swapout */
814− vmw_bo_unmap(vmw_buffer_object(bo));
710+ vmw_bo_unmap(to_vmw_bo(&bo->base));
815711 }
816712
817713
@@ -828,13 +724,7 @@ void vmw_bo_swap_notify(struct ttm_buffer_object *bo) · 10 unmodified lines
828724 void vmw_bo_move_notify(struct ttm_buffer_object *bo,
829725 struct ttm_resource *mem)
830726 {
831− struct vmw_buffer_object *vbo;
832−
833− /* Make sure @bo is embedded in a struct vmw_buffer_object? */
834− if (!bo_is_vmw(bo))
835− return;
836−
837− vbo = container_of(bo, struct vmw_buffer_object, base);
727+ struct vmw_bo *vbo = to_vmw_bo(&bo->base);
838728
839729 /*
840730 * Kill any cached kernel maps before move to or from VRAM.
@@ -852,3 +742,98 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, · 11 unmodified lines
852742 if (mem->mem_type != VMW_PL_MOB && bo->resource->mem_type == VMW_PL_MOB)
853743 vmw_resource_unbind_list(vbo);
854744 }
745+
746+static u32
747+set_placement_list(struct ttm_place *pl, u32 domain)
748+{
749+ u32 n = 0;
750+
751+ /*
752+ * The placements are ordered according to our preferences
753+ */
754+ if (domain & VMW_BO_DOMAIN_MOB) {
755+ pl[n].mem_type = VMW_PL_MOB;
756+ pl[n].flags = 0;
757+ pl[n].fpfn = 0;
758+ pl[n].lpfn = 0;
759+ n++;
760+ }
761+ if (domain & VMW_BO_DOMAIN_GMR) {
762+ pl[n].mem_type = VMW_PL_GMR;
763+ pl[n].flags = 0;
764+ pl[n].fpfn = 0;
765+ pl[n].lpfn = 0;
766+ n++;
767+ }
768+ if (domain & VMW_BO_DOMAIN_VRAM) {
769+ pl[n].mem_type = TTM_PL_VRAM;
770+ pl[n].flags = 0;
771+ pl[n].fpfn = 0;
772+ pl[n].lpfn = 0;
773+ n++;
774+ }
775+ if (domain & VMW_BO_DOMAIN_WAITABLE_SYS) {
776+ pl[n].mem_type = VMW_PL_SYSTEM;
777+ pl[n].flags = 0;
778+ pl[n].fpfn = 0;
779+ pl[n].lpfn = 0;
780+ n++;
781+ }
782+ if (domain & VMW_BO_DOMAIN_SYS) {
783+ pl[n].mem_type = TTM_PL_SYSTEM;
784+ pl[n].flags = 0;
785+ pl[n].fpfn = 0;
786+ pl[n].lpfn = 0;
787+ n++;
788+ }
789+
790+ WARN_ON(!n);
791+ if (!n) {
792+ pl[n].mem_type = TTM_PL_SYSTEM;
793+ pl[n].flags = 0;
794+ pl[n].fpfn = 0;
795+ pl[n].lpfn = 0;
796+ n++;
797+ }
798+ return n;
799+}
800+
801+void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain)
802+{
803+ struct ttm_device *bdev = bo->tbo.bdev;
804+ struct vmw_private *vmw = vmw_priv_from_ttm(bdev);
805+ struct ttm_placement *pl = &bo->placement;
806+ bool mem_compatible = false;
807+ u32 i;
808+
809+ pl->placement = bo->places;
810+ pl->num_placement = set_placement_list(bo->places, domain);
811+
812+ if (drm_debug_enabled(DRM_UT_DRIVER) && bo->tbo.resource) {
813+ for (i = 0; i < pl->num_placement; ++i) {
814+ if (bo->tbo.resource->mem_type == TTM_PL_SYSTEM ||
815+ bo->tbo.resource->mem_type == pl->placement[i].mem_type)
816+ mem_compatible = true;
817+ }
818+ if (!mem_compatible)
819+ drm_warn(&vmw->drm,
820+ "%s: Incompatible transition from "
821+ "bo->base.resource->mem_type = %u to domain = %u\n",
822+ __func__, bo->tbo.resource->mem_type, domain);
823+ }
824+
825+ pl->busy_placement = bo->busy_places;
826+ pl->num_busy_placement = set_placement_list(bo->busy_places, busy_domain);
827+}
828+
829+void vmw_bo_placement_set_default_accelerated(struct vmw_bo *bo)
830+{
831+ struct ttm_device *bdev = bo->tbo.bdev;
832+ struct vmw_private *vmw = vmw_priv_from_ttm(bdev);
833+ u32 domain = VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM;
834+
835+ if (vmw->has_mob)
836+ domain = VMW_BO_DOMAIN_MOB;
837+
838+ vmw_bo_placement_set(bo, domain, domain);
839+}
drivers/gpu/drm/vmwgfx/vmwgfx_bo.h+203−0
@@ -0,0 +1,203 @@
1+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
2+/**************************************************************************
3+ *
4+ * Copyright 2023 VMware, Inc., Palo Alto, CA., USA
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a
7+ * copy of this software and associated documentation files (the
8+ * "Software"), to deal in the Software without restriction, including
9+ * without limitation the rights to use, copy, modify, merge, publish,
10+ * distribute, sub license, and/or sell copies of the Software, and to
11+ * permit persons to whom the Software is furnished to do so, subject to
12+ * the following conditions:
13+ *
14+ * The above copyright notice and this permission notice (including the
15+ * next paragraph) shall be included in all copies or substantial portions
16+ * of the Software.
17+ *
18+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
25+ *
26+ **************************************************************************/
27+
28+#ifndef VMWGFX_BO_H
29+#define VMWGFX_BO_H
30+
31+#include "device_include/svga_reg.h"
32+
33+#include <drm/ttm/ttm_bo.h>
34+#include <drm/ttm/ttm_placement.h>
35+
36+#include <linux/rbtree_types.h>
37+#include <linux/types.h>
38+
39+struct vmw_bo_dirty;
40+struct vmw_fence_obj;
41+struct vmw_private;
42+struct vmw_resource;
43+
44+enum vmw_bo_domain {
45+ VMW_BO_DOMAIN_SYS = BIT(0),
46+ VMW_BO_DOMAIN_WAITABLE_SYS = BIT(1),
47+ VMW_BO_DOMAIN_VRAM = BIT(2),
48+ VMW_BO_DOMAIN_GMR = BIT(3),
49+ VMW_BO_DOMAIN_MOB = BIT(4),
50+};
51+
52+struct vmw_bo_params {
53+ u32 domain;
54+ u32 busy_domain;
55+ enum ttm_bo_type bo_type;
56+ size_t size;
57+ bool pin;
58+};
59+
60+/**
61+ * struct vmw_bo - TTM buffer object with vmwgfx additions
62+ * @tbo: The TTM buffer object
63+ * @placement: The preferred placement for this buffer object
64+ * @places: The chosen places for the preferred placement.
65+ * @busy_places: Chosen busy places for the preferred placement
66+ * @map: Kmap object for semi-persistent mappings
67+ * @res_tree: RB tree of resources using this buffer object as a backing MOB
68+ * @res_prios: Eviction priority counts for attached resources
69+ * @cpu_writers: Number of synccpu write grabs. Protected by reservation when
70+ * increased. May be decreased without reservation.
71+ * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB
72+ * @dirty: structure for user-space dirty-tracking
73+ */
74+struct vmw_bo {
75+ struct ttm_buffer_object tbo;
76+
77+ struct ttm_placement placement;
78+ struct ttm_place places[5];
79+ struct ttm_place busy_places[5];
80+
81+ /* Protected by reservation */
82+ struct ttm_bo_kmap_obj map;
83+
84+ struct rb_root res_tree;
85+ u32 res_prios[TTM_MAX_BO_PRIORITY];
86+
87+ atomic_t cpu_writers;
88+ /* Not ref-counted. Protected by binding_mutex */
89+ struct vmw_resource *dx_query_ctx;
90+ struct vmw_bo_dirty *dirty;
91+};
92+
93+void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain);
94+void vmw_bo_placement_set_default_accelerated(struct vmw_bo *bo);
95+
96+int vmw_bo_create(struct vmw_private *dev_priv,
97+ struct vmw_bo_params *params,
98+ struct vmw_bo **p_bo);
99+
100+int vmw_bo_unref_ioctl(struct drm_device *dev, void *data,
101+ struct drm_file *file_priv);
102+
103+int vmw_bo_pin_in_vram(struct vmw_private *dev_priv,
104+ struct vmw_bo *buf,
105+ bool interruptible);
106+int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
107+ struct vmw_bo *buf,
108+ bool interruptible);
109+int vmw_bo_pin_in_start_of_vram(struct vmw_private *vmw_priv,
110+ struct vmw_bo *bo,
111+ bool interruptible);
112+void vmw_bo_pin_reserved(struct vmw_bo *bo, bool pin);
113+int vmw_bo_unpin(struct vmw_private *vmw_priv,
114+ struct vmw_bo *bo,
115+ bool interruptible);
116+
117+void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *buf,
118+ SVGAGuestPtr *ptr);
119+int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data,
120+ struct drm_file *file_priv);
121+void vmw_bo_fence_single(struct ttm_buffer_object *bo,
122+ struct vmw_fence_obj *fence);
123+
124+void *vmw_bo_map_and_cache(struct vmw_bo *vbo);
125+void vmw_bo_unmap(struct vmw_bo *vbo);
126+
127+void vmw_bo_move_notify(struct ttm_buffer_object *bo,
128+ struct ttm_resource *mem);
129+void vmw_bo_swap_notify(struct ttm_buffer_object *bo);
130+
131+int vmw_user_bo_lookup(struct drm_file *filp,
132+ u32 handle,
133+ struct vmw_bo **out);
134+/**
135+ * vmw_bo_adjust_prio - Adjust the buffer object eviction priority
136+ * according to attached resources
137+ * @vbo: The struct vmw_bo
138+ */
139+static inline void vmw_bo_prio_adjust(struct vmw_bo *vbo)
140+{
141+ int i = ARRAY_SIZE(vbo->res_prios);
142+
143+ while (i--) {
144+ if (vbo->res_prios[i]) {
145+ vbo->tbo.priority = i;
146+ return;
147+ }
148+ }
149+
150+ vbo->tbo.priority = 3;
151+}
152+
153+/**
154+ * vmw_bo_prio_add - Notify a buffer object of a newly attached resource
155+ * eviction priority
156+ * @vbo: The struct vmw_bo
157+ * @prio: The resource priority
158+ *
159+ * After being notified, the code assigns the highest resource eviction priority
160+ * to the backing buffer object (mob).
161+ */
162+static inline void vmw_bo_prio_add(struct vmw_bo *vbo, int prio)
163+{
164+ if (vbo->res_prios[prio]++ == 0)
165+ vmw_bo_prio_adjust(vbo);
166+}
167+
168+/**
169+ * vmw_bo_used_prio_del - Notify a buffer object of a resource with a certain
170+ * priority being removed
171+ * @vbo: The struct vmw_bo
172+ * @prio: The resource priority
173+ *
174+ * After being notified, the code assigns the highest resource eviction priority
175+ * to the backing buffer object (mob).
176+ */
177+static inline void vmw_bo_prio_del(struct vmw_bo *vbo, int prio)
178+{
179+ if (--vbo->res_prios[prio] == 0)
180+ vmw_bo_prio_adjust(vbo);
181+}
182+
183+static inline void vmw_bo_unreference(struct vmw_bo **buf)
184+{
185+ struct vmw_bo *tmp_buf = *buf;
186+
187+ *buf = NULL;
188+ if (tmp_buf)
189+ ttm_bo_put(&tmp_buf->tbo);
190+}
191+
192+static inline struct vmw_bo *vmw_bo_reference(struct vmw_bo *buf)
193+{
194+ ttm_bo_get(&buf->tbo);
195+ return buf;
196+}
197+
198+static inline struct vmw_bo *to_vmw_bo(struct drm_gem_object *gobj)
199+{
200+ return container_of((gobj), struct vmw_bo, tbo.base);
201+}
202+
203+#endif // VMWGFX_BO_H
drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c+7−7
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2020 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -24,13 +24,13 @@ · 16 unmodified lines
2424 * USE OR OTHER DEALINGS IN THE SOFTWARE.
2525 *
2626 **************************************************************************/
27−
28−#include <linux/sched/signal.h>
27+#include "vmwgfx_bo.h"
28+#include "vmwgfx_drv.h"
29+#include "vmwgfx_devcaps.h"
2930
3031 #include <drm/ttm/ttm_placement.h>
3132
32−#include "vmwgfx_drv.h"
33−#include "vmwgfx_devcaps.h"
33+#include <linux/sched/signal.h>
3434
3535 bool vmw_supports_3d(struct vmw_private *dev_priv)
3636 {
@@ -567,7 +567,7 @@ static int vmw_cmd_emit_dummy_legacy_query(struct vmw_private *dev_priv, · 530 unmodified lines
567567 * without writing to the query result structure.
568568 */
569569
570− struct ttm_buffer_object *bo = &dev_priv->dummy_query_bo->base;
570+ struct ttm_buffer_object *bo = &dev_priv->dummy_query_bo->tbo;
571571 struct {
572572 SVGA3dCmdHeader header;
573573 SVGA3dCmdWaitForQuery body;
@@ -613,7 +613,7 @@ static int vmw_cmd_emit_dummy_gb_query(struct vmw_private *dev_priv, · 39 unmodified lines
613613 * without writing to the query result structure.
614614 */
615615
616− struct ttm_buffer_object *bo = &dev_priv->dummy_query_bo->base;
616+ struct ttm_buffer_object *bo = &dev_priv->dummy_query_bo->tbo;
617617 struct {
618618 SVGA3dCmdHeader header;
619619 SVGA3dCmdWaitForGBQuery body;
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c+20−33
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2015 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2015-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -25,12 +25,13 @@ · 17 unmodified lines
2525 *
2626 **************************************************************************/
2727
28−#include <linux/dmapool.h>
29−#include <linux/pci.h>
28+#include "vmwgfx_bo.h"
29+#include "vmwgfx_drv.h"
3030
3131 #include <drm/ttm/ttm_bo.h>
3232
33−#include "vmwgfx_drv.h"
33+#include <linux/dmapool.h>
34+#include <linux/pci.h>
3435
3536 /*
3637 * Size of inline command buffers. Try to make sure that a page size is a
@@ -79,7 +80,6 @@ struct vmw_cmdbuf_context { · 42 unmodified lines
7980 * frees are protected by @lock.
8081 * @cmd_space: Buffer object for the command buffer space, unless we were
8182 * able to make a contigous coherent DMA memory allocation, @handle. Immutable.
82− * @map_obj: Mapping state for @cmd_space. Immutable.
8383 * @map: Pointer to command buffer space. May be a mapped buffer object or
8484 * a contigous coherent DMA memory allocation. Immutable.
8585 * @cur: Command buffer for small kernel command submissions. Protected by
@@ -116,8 +116,7 @@ struct vmw_cmdbuf_man { · 30 unmodified lines
116116 struct vmw_cmdbuf_context ctx[SVGA_CB_CONTEXT_MAX];
117117 struct list_head error;
118118 struct drm_mm mm;
119− struct ttm_buffer_object *cmd_space;
120− struct ttm_bo_kmap_obj map_obj;
119+ struct vmw_bo *cmd_space;
121120 u8 *map;
122121 struct vmw_cmdbuf_header *cur;
123122 size_t cur_pos;
@@ -888,7 +887,7 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man *man, · 764 unmodified lines
888887 header->cmd = man->map + offset;
889888 if (man->using_mob) {
890889 cb_hdr->flags = SVGA_CB_FLAG_MOB;
891− cb_hdr->ptr.mob.mobid = man->cmd_space->resource->start;
890+ cb_hdr->ptr.mob.mobid = man->cmd_space->tbo.resource->start;
892891 cb_hdr->ptr.mob.mobOffset = offset;
893892 } else {
894893 cb_hdr->ptr.pa = (u64)man->handle + (u64)offset;
@@ -1221,7 +1220,6 @@ static int vmw_cmdbuf_startstop(struct vmw_cmdbuf_man *man, u32 context, · 326 unmodified lines
12211220 int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man, size_t size)
12221221 {
12231222 struct vmw_private *dev_priv = man->dev_priv;
1224− bool dummy;
12251223 int ret;
12261224
12271225 if (man->has_pool)
@@ -1234,6 +1232,13 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man, size_t size) · 6 unmodified lines
12341232 if (man->map) {
12351233 man->using_mob = false;
12361234 } else {
1235+ struct vmw_bo_params bo_params = {
1236+ .domain = VMW_BO_DOMAIN_MOB,
1237+ .busy_domain = VMW_BO_DOMAIN_MOB,
1238+ .bo_type = ttm_bo_type_kernel,
1239+ .size = size,
1240+ .pin = true
1241+ };
12371242 /*
12381243 * DMA memory failed. If we can have command buffers in a
12391244 * MOB, try to use that instead. Note that this will
@@ -1244,19 +1249,12 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man, size_t size) · 4 unmodified lines
12441249 !dev_priv->has_mob)
12451250 return -ENOMEM;
12461251
1247− ret = vmw_bo_create_kernel(dev_priv, size,
1248− &vmw_mob_placement,
1249− &man->cmd_space);
1252+ ret = vmw_bo_create(dev_priv, &bo_params, &man->cmd_space);
12501253 if (ret)
12511254 return ret;
12521255
1253− man->using_mob = true;
1254− ret = ttm_bo_kmap(man->cmd_space, 0, size >> PAGE_SHIFT,
1255− &man->map_obj);
1256− if (ret)
1257− goto out_no_map;
1258−
1259− man->map = ttm_kmap_obj_virtual(&man->map_obj, &dummy);
1256+ man->map = vmw_bo_map_and_cache(man->cmd_space);
1257+ man->using_mob = man->map;
12601258 }
12611259
12621260 man->size = size;
@@ -1276,14 +1274,6 @@ int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man, size_t size) · 13 unmodified lines
12761274 (man->using_mob) ? "MOB" : "DMA");
12771275
12781276 return 0;
1279−
1280−out_no_map:
1281− if (man->using_mob) {
1282− ttm_bo_put(man->cmd_space);
1283− man->cmd_space = NULL;
1284− }
1285−
1286− return ret;
12871277 }
12881278
12891279 /**
@@ -1382,14 +1372,11 @@ void vmw_cmdbuf_remove_pool(struct vmw_cmdbuf_man *man) · 92 unmodified lines
13821372 man->has_pool = false;
13831373 man->default_size = VMW_CMDBUF_INLINE_SIZE;
13841374 (void) vmw_cmdbuf_idle(man, false, 10*HZ);
1385− if (man->using_mob) {
1386− (void) ttm_bo_kunmap(&man->map_obj);
1387− ttm_bo_put(man->cmd_space);
1388− man->cmd_space = NULL;
1389− } else {
1375+ if (man->using_mob)
1376+ vmw_bo_unreference(&man->cmd_space);
1377+ else
13901378 dma_free_coherent(man->dev_priv->drm.dev,
13911379 man->size, man->map, man->handle);
1392− }
13931380 }
13941381
13951382 /**
drivers/gpu/drm/vmwgfx/vmwgfx_context.c+20−16
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -27,9 +27,10 @@ · 19 unmodified lines
2727
2828 #include <drm/ttm/ttm_placement.h>
2929
30+#include "vmwgfx_binding.h"
31+#include "vmwgfx_bo.h"
3032 #include "vmwgfx_drv.h"
3133 #include "vmwgfx_resource_priv.h"
32−#include "vmwgfx_binding.h"
3334
3435 struct vmw_user_context {
3536 struct ttm_base_object base;
@@ -38,7 +39,7 @@ struct vmw_user_context { · 2 unmodified lines
3839 struct vmw_cmdbuf_res_manager *man;
3940 struct vmw_resource *cotables[SVGA_COTABLE_MAX];
4041 spinlock_t cotable_lock;
41− struct vmw_buffer_object *dx_query_mob;
42+ struct vmw_bo *dx_query_mob;
4243 };
4344
4445 static void vmw_user_context_free(struct vmw_resource *res);
@@ -72,10 +73,11 @@ const struct vmw_user_resource_conv *user_context_converter = · 27 unmodified lines
7273
7374 static const struct vmw_res_func vmw_legacy_context_func = {
7475 .res_type = vmw_res_context,
75− .needs_backup = false,
76+ .needs_guest_memory = false,
7677 .may_evict = false,
7778 .type_name = "legacy contexts",
78− .backup_placement = NULL,
79+ .domain = VMW_BO_DOMAIN_SYS,
80+ .busy_domain = VMW_BO_DOMAIN_SYS,
7981 .create = NULL,
8082 .destroy = NULL,
8183 .bind = NULL,
@@ -84,12 +86,13 @@ static const struct vmw_res_func vmw_legacy_context_func = { · 2 unmodified lines
8486
8587 static const struct vmw_res_func vmw_gb_context_func = {
8688 .res_type = vmw_res_context,
87− .needs_backup = true,
89+ .needs_guest_memory = true,
8890 .may_evict = true,
8991 .prio = 3,
9092 .dirty_prio = 3,
9193 .type_name = "guest backed contexts",
92− .backup_placement = &vmw_mob_placement,
94+ .domain = VMW_BO_DOMAIN_MOB,
95+ .busy_domain = VMW_BO_DOMAIN_MOB,
9396 .create = vmw_gb_context_create,
9497 .destroy = vmw_gb_context_destroy,
9598 .bind = vmw_gb_context_bind,
@@ -98,12 +101,13 @@ static const struct vmw_res_func vmw_gb_context_func = { · 2 unmodified lines
98101
99102 static const struct vmw_res_func vmw_dx_context_func = {
100103 .res_type = vmw_res_dx_context,
101− .needs_backup = true,
104+ .needs_guest_memory = true,
102105 .may_evict = true,
103106 .prio = 3,
104107 .dirty_prio = 3,
105108 .type_name = "dx contexts",
106− .backup_placement = &vmw_mob_placement,
109+ .domain = VMW_BO_DOMAIN_MOB,
110+ .busy_domain = VMW_BO_DOMAIN_MOB,
107111 .create = vmw_dx_context_create,
108112 .destroy = vmw_dx_context_destroy,
109113 .bind = vmw_dx_context_bind,
@@ -182,7 +186,7 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv, · 72 unmodified lines
182186 struct vmw_user_context *uctx =
183187 container_of(res, struct vmw_user_context, res);
184188
185− res->backup_size = (dx ? sizeof(SVGADXContextMobFormat) :
189+ res->guest_memory_size = (dx ? sizeof(SVGADXContextMobFormat) :
186190 sizeof(SVGAGBContextData));
187191 ret = vmw_resource_init(dev_priv, res, true,
188192 res_free,
@@ -354,8 +358,8 @@ static int vmw_gb_context_bind(struct vmw_resource *res, · 165 unmodified lines
354358 cmd->header.size = sizeof(cmd->body);
355359 cmd->body.cid = res->id;
356360 cmd->body.mobid = bo->resource->start;
357− cmd->body.validContents = res->backup_dirty;
358− res->backup_dirty = false;
361+ cmd->body.validContents = res->guest_memory_dirty;
362+ res->guest_memory_dirty = false;
359363 vmw_cmd_commit(dev_priv, sizeof(*cmd));
360364
361365 return 0;
@@ -521,8 +525,8 @@ static int vmw_dx_context_bind(struct vmw_resource *res, · 159 unmodified lines
521525 cmd->header.size = sizeof(cmd->body);
522526 cmd->body.cid = res->id;
523527 cmd->body.mobid = bo->resource->start;
524− cmd->body.validContents = res->backup_dirty;
525− res->backup_dirty = false;
528+ cmd->body.validContents = res->guest_memory_dirty;
529+ res->guest_memory_dirty = false;
526530 vmw_cmd_commit(dev_priv, sizeof(*cmd));
527531
528532
@@ -853,7 +857,7 @@ vmw_context_binding_state(struct vmw_resource *ctx) · 324 unmodified lines
853857 * specified in the parameter. 0 otherwise.
854858 */
855859 int vmw_context_bind_dx_query(struct vmw_resource *ctx_res,
856− struct vmw_buffer_object *mob)
860+ struct vmw_bo *mob)
857861 {
858862 struct vmw_user_context *uctx =
859863 container_of(ctx_res, struct vmw_user_context, res);
@@ -885,7 +889,7 @@ int vmw_context_bind_dx_query(struct vmw_resource *ctx_res, · 25 unmodified lines
885889 *
886890 * @ctx_res: The context resource
887891 */
888−struct vmw_buffer_object *
892+struct vmw_bo *
889893 vmw_context_get_dx_query_mob(struct vmw_resource *ctx_res)
890894 {
891895 struct vmw_user_context *uctx =
drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c+38−27
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2014-2015 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2014-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -30,13 +30,14 @@ · 22 unmodified lines
3030 * whenever the backing MOB is evicted.
3131 */
3232
33−#include <drm/ttm/ttm_placement.h>
34−
33+#include "vmwgfx_bo.h"
3534 #include "vmwgfx_drv.h"
3635 #include "vmwgfx_mksstat.h"
3736 #include "vmwgfx_resource_priv.h"
3837 #include "vmwgfx_so.h"
3938
39+#include <drm/ttm/ttm_placement.h>
40+
4041 /**
4142 * struct vmw_cotable - Context Object Table resource
4243 *
@@ -130,12 +131,13 @@ static int vmw_cotable_destroy(struct vmw_resource *res); · 87 unmodified lines
130131
131132 static const struct vmw_res_func vmw_cotable_func = {
132133 .res_type = vmw_res_cotable,
133− .needs_backup = true,
134+ .needs_guest_memory = true,
134135 .may_evict = true,
135136 .prio = 3,
136137 .dirty_prio = 3,
137138 .type_name = "context guest backed object tables",
138− .backup_placement = &vmw_mob_placement,
139+ .domain = VMW_BO_DOMAIN_MOB,
140+ .busy_domain = VMW_BO_DOMAIN_MOB,
139141 .create = vmw_cotable_create,
140142 .destroy = vmw_cotable_destroy,
141143 .bind = vmw_cotable_bind,
@@ -180,7 +182,7 @@ static int vmw_cotable_unscrub(struct vmw_resource *res) · 38 unmodified lines
180182 {
181183 struct vmw_cotable *vcotbl = vmw_cotable(res);
182184 struct vmw_private *dev_priv = res->dev_priv;
183− struct ttm_buffer_object *bo = &res->backup->base;
185+ struct ttm_buffer_object *bo = &res->guest_memory_bo->tbo;
184186 struct {
185187 SVGA3dCmdHeader header;
186188 SVGA3dCmdDXSetCOTable body;
@@ -228,7 +230,7 @@ static int vmw_cotable_bind(struct vmw_resource *res, · 41 unmodified lines
228230 * take the opportunity to correct the value here so that it's not
229231 * misused in the future.
230232 */
231− val_buf->bo = &res->backup->base;
233+ val_buf->bo = &res->guest_memory_bo->tbo;
232234
233235 return vmw_cotable_unscrub(res);
234236 }
@@ -289,7 +291,7 @@ int vmw_cotable_scrub(struct vmw_resource *res, bool readback) · 54 unmodified lines
289291 cmd0->body.cid = vcotbl->ctx->id;
290292 cmd0->body.type = vcotbl->type;
291293 cmd1 = (void *) &cmd0[1];
292− vcotbl->size_read_back = res->backup_size;
294+ vcotbl->size_read_back = res->guest_memory_size;
293295 }
294296 cmd1->header.id = SVGA_3D_CMD_DX_SET_COTABLE;
295297 cmd1->header.size = sizeof(cmd1->body);
@@ -371,12 +373,12 @@ static int vmw_cotable_readback(struct vmw_resource *res) · 75 unmodified lines
371373 cmd->header.size = sizeof(cmd->body);
372374 cmd->body.cid = vcotbl->ctx->id;
373375 cmd->body.type = vcotbl->type;
374− vcotbl->size_read_back = res->backup_size;
376+ vcotbl->size_read_back = res->guest_memory_size;
375377 vmw_cmd_commit(dev_priv, sizeof(*cmd));
376378 }
377379
378380 (void) vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL);
379− vmw_bo_fence_single(&res->backup->base, fence);
381+ vmw_bo_fence_single(&res->guest_memory_bo->tbo, fence);
380382 vmw_fence_obj_unreference(&fence);
381383
382384 return 0;
@@ -399,14 +401,21 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) · 16 unmodified lines
399401 struct ttm_operation_ctx ctx = { false, false };
400402 struct vmw_private *dev_priv = res->dev_priv;
401403 struct vmw_cotable *vcotbl = vmw_cotable(res);
402− struct vmw_buffer_object *buf, *old_buf = res->backup;
403− struct ttm_buffer_object *bo, *old_bo = &res->backup->base;
404− size_t old_size = res->backup_size;
404+ struct vmw_bo *buf, *old_buf = res->guest_memory_bo;
405+ struct ttm_buffer_object *bo, *old_bo = &res->guest_memory_bo->tbo;
406+ size_t old_size = res->guest_memory_size;
405407 size_t old_size_read_back = vcotbl->size_read_back;
406408 size_t cur_size_read_back;
407409 struct ttm_bo_kmap_obj old_map, new_map;
408410 int ret;
409411 size_t i;
412+ struct vmw_bo_params bo_params = {
413+ .domain = VMW_BO_DOMAIN_MOB,
414+ .busy_domain = VMW_BO_DOMAIN_MOB,
415+ .bo_type = ttm_bo_type_device,
416+ .size = new_size,
417+ .pin = true
418+ };
410419
411420 MKS_STAT_TIME_DECL(MKSSTAT_KERN_COTABLE_RESIZE);
412421 MKS_STAT_TIME_PUSH(MKSSTAT_KERN_COTABLE_RESIZE);
@@ -423,14 +432,13 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) · 10 unmodified lines
423432 * for the new COTable. Initially pin the buffer object to make sure
424433 * we can use tryreserve without failure.
425434 */
426− ret = vmw_bo_create(dev_priv, new_size, &vmw_mob_placement,
427− true, true, vmw_bo_bo_free, &buf);
435+ ret = vmw_bo_create(dev_priv, &bo_params, &buf);
428436 if (ret) {
429437 DRM_ERROR("Failed initializing new cotable MOB.\n");
430438 goto out_done;
431439 }
432440
433− bo = &buf->base;
441+ bo = &buf->tbo;
434442 WARN_ON_ONCE(ttm_bo_reserve(bo, false, true, NULL));
435443
436444 ret = ttm_bo_wait(old_bo, false, false);
@@ -464,15 +472,18 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) · 27 unmodified lines
464472 }
465473
466474 /* Unpin new buffer, and switch backup buffers. */
467− ret = ttm_bo_validate(bo, &vmw_mob_placement, &ctx);
475+ vmw_bo_placement_set(buf,
476+ VMW_BO_DOMAIN_MOB,
477+ VMW_BO_DOMAIN_MOB);
478+ ret = ttm_bo_validate(bo, &buf->placement, &ctx);
468479 if (unlikely(ret != 0)) {
469480 DRM_ERROR("Failed validating new COTable backup buffer.\n");
470481 goto out_wait;
471482 }
472483
473484 vmw_resource_mob_detach(res);
474− res->backup = buf;
475− res->backup_size = new_size;
485+ res->guest_memory_bo = buf;
486+ res->guest_memory_size = new_size;
476487 vcotbl->size_read_back = cur_size_read_back;
477488
478489 /*
@@ -482,8 +493,8 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) · 3 unmodified lines
482493 ret = vmw_cotable_unscrub(res);
483494 if (ret) {
484495 DRM_ERROR("Failed switching COTable backup buffer.\n");
485− res->backup = old_buf;
486− res->backup_size = old_size;
496+ res->guest_memory_bo = old_buf;
497+ res->guest_memory_size = old_size;
487498 vcotbl->size_read_back = old_size_read_back;
488499 vmw_resource_mob_attach(res);
489500 goto out_wait;
@@ -498,7 +509,7 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) · 8 unmodified lines
498509 if (unlikely(ret))
499510 goto out_wait;
500511
501− /* Release the pin acquired in vmw_bo_init */
512+ /* Release the pin acquired in vmw_bo_create */
502513 ttm_bo_unpin(bo);
503514
504515 MKS_STAT_TIME_POP(MKSSTAT_KERN_COTABLE_RESIZE);
@@ -533,7 +544,7 @@ out_done: · 28 unmodified lines
533544 static int vmw_cotable_create(struct vmw_resource *res)
534545 {
535546 struct vmw_cotable *vcotbl = vmw_cotable(res);
536− size_t new_size = res->backup_size;
547+ size_t new_size = res->guest_memory_size;
537548 size_t needed_size;
538549 int ret;
539550
@@ -542,7 +553,7 @@ static int vmw_cotable_create(struct vmw_resource *res) · 2 unmodified lines
542553 while (needed_size > new_size)
543554 new_size *= 2;
544555
545− if (likely(new_size <= res->backup_size)) {
556+ if (likely(new_size <= res->guest_memory_size)) {
546557 if (vcotbl->scrubbed && vmw_resource_mob_attached(res)) {
547558 ret = vmw_cotable_unscrub(res);
548559 if (ret)
@@ -606,12 +617,12 @@ struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv, · 57 unmodified lines
606617
607618 INIT_LIST_HEAD(&vcotbl->resource_list);
608619 vcotbl->res.id = type;
609− vcotbl->res.backup_size = PAGE_SIZE;
620+ vcotbl->res.guest_memory_size = PAGE_SIZE;
610621 num_entries = PAGE_SIZE / co_info[type].size;
611622 if (num_entries < co_info[type].min_initial_entries) {
612− vcotbl->res.backup_size = co_info[type].min_initial_entries *
623+ vcotbl->res.guest_memory_size = co_info[type].min_initial_entries *
613624 co_info[type].size;
614− vcotbl->res.backup_size = PFN_ALIGN(vcotbl->res.backup_size);
625+ vcotbl->res.guest_memory_size = PFN_ALIGN(vcotbl->res.guest_memory_size);
615626 }
616627
617628 vcotbl->scrubbed = true;
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c+16−10
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -28,9 +28,10 @@ · 20 unmodified lines
2828
2929 #include "vmwgfx_drv.h"
3030
31+#include "vmwgfx_bo.h"
32+#include "vmwgfx_binding.h"
3133 #include "vmwgfx_devcaps.h"
3234 #include "vmwgfx_mksstat.h"
33−#include "vmwgfx_binding.h"
3435 #include "ttm_object.h"
3536
3637 #include <drm/drm_aperture.h>
@@ -386,27 +387,32 @@ static void vmw_print_sm_type(struct vmw_private *dev_priv) · 349 unmodified lines
386387 static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv)
387388 {
388389 int ret;
389− struct vmw_buffer_object *vbo;
390+ struct vmw_bo *vbo;
390391 struct ttm_bo_kmap_obj map;
391392 volatile SVGA3dQueryResult *result;
392393 bool dummy;
394+ struct vmw_bo_params bo_params = {
395+ .domain = VMW_BO_DOMAIN_SYS,
396+ .busy_domain = VMW_BO_DOMAIN_SYS,
397+ .bo_type = ttm_bo_type_kernel,
398+ .size = PAGE_SIZE,
399+ .pin = true
400+ };
393401
394402 /*
395403 * Create the vbo as pinned, so that a tryreserve will
396404 * immediately succeed. This is because we're the only
397405 * user of the bo currently.
398406 */
399− ret = vmw_bo_create(dev_priv, PAGE_SIZE,
400− &vmw_sys_placement, false, true,
401− &vmw_bo_bo_free, &vbo);
407+ ret = vmw_bo_create(dev_priv, &bo_params, &vbo);
402408 if (unlikely(ret != 0))
403409 return ret;
404410
405− ret = ttm_bo_reserve(&vbo->base, false, true, NULL);
411+ ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
406412 BUG_ON(ret != 0);
407413 vmw_bo_pin_reserved(vbo, true);
408414
409− ret = ttm_bo_kmap(&vbo->base, 0, 1, &map);
415+ ret = ttm_bo_kmap(&vbo->tbo, 0, 1, &map);
410416 if (likely(ret == 0)) {
411417 result = ttm_kmap_obj_virtual(&map, &dummy);
412418 result->totalSize = sizeof(*result);
@@ -415,7 +421,7 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) · 2 unmodified lines
415421 ttm_bo_kunmap(&map);
416422 }
417423 vmw_bo_pin_reserved(vbo, false);
418− ttm_bo_unreserve(&vbo->base);
424+ ttm_bo_unreserve(&vbo->tbo);
419425
420426 if (unlikely(ret != 0)) {
421427 DRM_ERROR("Dummy query buffer map failed.\n");
@@ -1565,7 +1571,7 @@ static const struct file_operations vmwgfx_driver_fops = { · 1143 unmodified lines
15651571 .open = drm_open,
15661572 .release = drm_release,
15671573 .unlocked_ioctl = vmw_unlocked_ioctl,
1568− .mmap = vmw_mmap,
1574+ .mmap = drm_gem_mmap,
15691575 .poll = drm_poll,
15701576 .read = drm_read,
15711577 #if defined(CONFIG_COMPAT)
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h+48−197
@@ -1,7 +1,7 @@
11 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
22 /**************************************************************************
33 *
4− * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -117,32 +117,6 @@ struct vmwgfx_hash_item { · 109 unmodified lines
117117 unsigned long key;
118118 };
119119
120−/**
121− * struct vmw_buffer_object - TTM buffer object with vmwgfx additions
122− * @base: The TTM buffer object
123− * @res_tree: RB tree of resources using this buffer object as a backing MOB
124− * @base_mapped_count: ttm BO mapping count; used by KMS atomic helpers.
125− * @cpu_writers: Number of synccpu write grabs. Protected by reservation when
126− * increased. May be decreased without reservation.
127− * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB
128− * @map: Kmap object for semi-persistent mappings
129− * @res_prios: Eviction priority counts for attached resources
130− * @dirty: structure for user-space dirty-tracking
131− */
132−struct vmw_buffer_object {
133− struct ttm_buffer_object base;
134− struct rb_root res_tree;
135− /* For KMS atomic helpers: ttm bo mapping count */
136− atomic_t base_mapped_count;
137−
138− atomic_t cpu_writers;
139− /* Not ref-counted. Protected by binding_mutex */
140− struct vmw_resource *dx_query_ctx;
141− /* Protected by reservation */
142− struct ttm_bo_kmap_obj map;
143− u32 res_prios[TTM_MAX_BO_PRIORITY];
144− struct vmw_bo_dirty *dirty;
145−};
146120
147121 /**
148122 * struct vmw_validate_buffer - Carries validation info about buffers.
@@ -168,21 +142,23 @@ struct vmw_res_func; · 19 unmodified lines
168142 * @kref: For refcounting.
169143 * @dev_priv: Pointer to the device private for this resource. Immutable.
170144 * @id: Device id. Protected by @dev_priv::resource_lock.
171− * @backup_size: Backup buffer size. Immutable.
172− * @res_dirty: Resource contains data not yet in the backup buffer. Protected
173− * by resource reserved.
174− * @backup_dirty: Backup buffer contains data not yet in the HW resource.
145+ * @guest_memory_size: Guest memory buffer size. Immutable.
146+ * @res_dirty: Resource contains data not yet in the guest memory buffer.
175147 * Protected by resource reserved.
148+ * @guest_memory_dirty: Guest memory buffer contains data not yet in the HW
149+ * resource. Protected by resource reserved.
176150 * @coherent: Emulate coherency by tracking vm accesses.
177− * @backup: The backup buffer if any. Protected by resource reserved.
178− * @backup_offset: Offset into the backup buffer if any. Protected by resource
179− * reserved. Note that only a few resource types can have a @backup_offset
180− * different from zero.
151+ * @guest_memory_bo: The guest memory buffer if any. Protected by resource
152+ * reserved.
153+ * @guest_memory_offset: Offset into the guest memory buffer if any. Protected
154+ * by resource reserved. Note that only a few resource types can have a
155+ * @guest_memory_offset different from zero.
181156 * @pin_count: The pin count for this resource. A pinned resource has a
182157 * pin-count greater than zero. It is not on the resource LRU lists and its
183− * backup buffer is pinned. Hence it can't be evicted.
158+ * guest memory buffer is pinned. Hence it can't be evicted.
184159 * @func: Method vtable for this resource. Immutable.
185− * @mob_node; Node for the MOB backup rbtree. Protected by @backup reserved.
160+ * @mob_node; Node for the MOB guest memory rbtree. Protected by
161+ * @guest_memory_bo reserved.
186162 * @lru_head: List head for the LRU list. Protected by @dev_priv::resource_lock.
187163 * @binding_head: List head for the context binding list. Protected by
188164 * the @dev_priv::binding_mutex
@@ -190,18 +166,20 @@ struct vmw_res_func; · 1 unmodified line
190166 * @hw_destroy: Callback to destroy the resource on the device, as part of
191167 * resource destruction.
192168 */
169+struct vmw_bo;
170+struct vmw_bo;
193171 struct vmw_resource_dirty;
194172 struct vmw_resource {
195173 struct kref kref;
196174 struct vmw_private *dev_priv;
197175 int id;
198176 u32 used_prio;
199− unsigned long backup_size;
177+ unsigned long guest_memory_size;
200178 u32 res_dirty : 1;
201− u32 backup_dirty : 1;
179+ u32 guest_memory_dirty : 1;
202180 u32 coherent : 1;
203− struct vmw_buffer_object *backup;
204− unsigned long backup_offset;
181+ struct vmw_bo *guest_memory_bo;
182+ unsigned long guest_memory_offset;
205183 unsigned long pin_count;
206184 const struct vmw_res_func *func;
207185 struct rb_node mob_node;
@@ -446,7 +424,7 @@ struct vmw_sw_context{ · 238 unmodified lines
446424 struct drm_file *filp;
447425 uint32_t *cmd_bounce;
448426 uint32_t cmd_bounce_size;
449− struct vmw_buffer_object *cur_query_bo;
427+ struct vmw_bo *cur_query_bo;
450428 struct list_head bo_relocations;
451429 struct list_head res_relocations;
452430 uint32_t *buf_start;
@@ -458,7 +436,7 @@ struct vmw_sw_context{ · 5 unmodified lines
458436 struct list_head staged_cmd_res;
459437 struct list_head ctx_list;
460438 struct vmw_ctx_validation_info *dx_ctx_node;
461− struct vmw_buffer_object *dx_query_mob;
439+ struct vmw_bo *dx_query_mob;
462440 struct vmw_resource *dx_query_ctx;
463441 struct vmw_cmdbuf_res_manager *man;
464442 struct vmw_validation_context *ctx;
@@ -492,7 +470,7 @@ struct vmw_otable_batch { · 27 unmodified lines
492470 unsigned num_otables;
493471 struct vmw_otable *otables;
494472 struct vmw_resource *context;
495− struct ttm_buffer_object *otable_bo;
473+ struct vmw_bo *otable_bo;
496474 };
497475
498476 enum {
@@ -632,8 +610,8 @@ struct vmw_private { · 133 unmodified lines
632610 * are protected by the cmdbuf mutex.
633611 */
634612
635− struct vmw_buffer_object *dummy_query_bo;
636− struct vmw_buffer_object *pinned_bo;
613+ struct vmw_bo *dummy_query_bo;
614+ struct vmw_bo *pinned_bo;
637615 uint32_t query_cid;
638616 uint32_t query_cid_valid;
639617 bool dummy_query_bo_pinned;
@@ -677,11 +655,6 @@ struct vmw_private { · 37 unmodified lines
677655 #endif
678656 };
679657
680−static inline struct vmw_buffer_object *gem_to_vmw_bo(struct drm_gem_object *gobj)
681−{
682− return container_of((gobj), struct vmw_buffer_object, base.base);
683−}
684−
685658 static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res)
686659 {
687660 return container_of(res, struct vmw_surface, res);
@@ -692,6 +665,11 @@ static inline struct vmw_private *vmw_priv(struct drm_device *dev) · 4 unmodified lines
692665 return (struct vmw_private *)dev->dev_private;
693666 }
694667
668+static inline struct vmw_private *vmw_priv_from_ttm(struct ttm_device *bdev)
669+{
670+ return container_of(bdev, struct vmw_private, bdev);
671+}
672+
695673 static inline struct vmw_fpriv *vmw_fpriv(struct drm_file *file_priv)
696674 {
697675 return (struct vmw_fpriv *)file_priv->driver_priv;
@@ -825,7 +803,7 @@ extern int vmw_user_lookup_handle(struct vmw_private *dev_priv, · 127 unmodified lines
825803 struct drm_file *filp,
826804 uint32_t handle,
827805 struct vmw_surface **out_surf,
828− struct vmw_buffer_object **out_buf);
806+ struct vmw_bo **out_buf);
829807 extern int vmw_user_resource_lookup_handle(
830808 struct vmw_private *dev_priv,
831809 struct ttm_object_file *tfile,
@@ -844,20 +822,20 @@ extern int vmw_user_stream_lookup(struct vmw_private *dev_priv, · 12 unmodified lines
844822 extern void vmw_resource_unreserve(struct vmw_resource *res,
845823 bool dirty_set,
846824 bool dirty,
847− bool switch_backup,
848− struct vmw_buffer_object *new_backup,
849− unsigned long new_backup_offset);
825+ bool switch_guest_memory,
826+ struct vmw_bo *new_guest_memory,
827+ unsigned long new_guest_memory_offset);
850828 extern void vmw_query_move_notify(struct ttm_buffer_object *bo,
851829 struct ttm_resource *old_mem,
852830 struct ttm_resource *new_mem);
853−extern int vmw_query_readback_all(struct vmw_buffer_object *dx_query_mob);
854−extern void vmw_resource_evict_all(struct vmw_private *dev_priv);
855−extern void vmw_resource_unbind_list(struct vmw_buffer_object *vbo);
831+int vmw_query_readback_all(struct vmw_bo *dx_query_mob);
832+void vmw_resource_evict_all(struct vmw_private *dev_priv);
833+void vmw_resource_unbind_list(struct vmw_bo *vbo);
856834 void vmw_resource_mob_attach(struct vmw_resource *res);
857835 void vmw_resource_mob_detach(struct vmw_resource *res);
858836 void vmw_resource_dirty_update(struct vmw_resource *res, pgoff_t start,
859837 pgoff_t end);
860−int vmw_resources_clean(struct vmw_buffer_object *vbo, pgoff_t start,
838+int vmw_resources_clean(struct vmw_bo *vbo, pgoff_t start,
861839 pgoff_t end, pgoff_t *num_prefault);
862840
863841 /**
@@ -871,107 +849,6 @@ static inline bool vmw_resource_mob_attached(const struct vmw_resource *res) · 7 unmodified lines
871849 return !RB_EMPTY_NODE(&res->mob_node);
872850 }
873851
874−/**
875− * Buffer object helper functions - vmwgfx_bo.c
876− */
877−extern int vmw_bo_pin_in_placement(struct vmw_private *vmw_priv,
878− struct vmw_buffer_object *bo,
879− struct ttm_placement *placement,
880− bool interruptible);
881−extern int vmw_bo_pin_in_vram(struct vmw_private *dev_priv,
882− struct vmw_buffer_object *buf,
883− bool interruptible);
884−extern int vmw_bo_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
885− struct vmw_buffer_object *buf,
886− bool interruptible);
887−extern int vmw_bo_pin_in_start_of_vram(struct vmw_private *vmw_priv,
888− struct vmw_buffer_object *bo,
889− bool interruptible);
890−extern int vmw_bo_unpin(struct vmw_private *vmw_priv,
891− struct vmw_buffer_object *bo,
892− bool interruptible);
893−extern void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *buf,
894− SVGAGuestPtr *ptr);
895−extern void vmw_bo_pin_reserved(struct vmw_buffer_object *bo, bool pin);
896−extern void vmw_bo_bo_free(struct ttm_buffer_object *bo);
897−extern int vmw_bo_create_kernel(struct vmw_private *dev_priv,
898− unsigned long size,
899− struct ttm_placement *placement,
900− struct ttm_buffer_object **p_bo);
901−extern int vmw_bo_create(struct vmw_private *dev_priv,
902− size_t size, struct ttm_placement *placement,
903− bool interruptible, bool pin,
904− void (*bo_free)(struct ttm_buffer_object *bo),
905− struct vmw_buffer_object **p_bo);
906−extern int vmw_bo_init(struct vmw_private *dev_priv,
907− struct vmw_buffer_object *vmw_bo,
908− size_t size, struct ttm_placement *placement,
909− bool interruptible, bool pin,
910− void (*bo_free)(struct ttm_buffer_object *bo));
911−extern int vmw_bo_unref_ioctl(struct drm_device *dev, void *data,
912− struct drm_file *file_priv);
913−extern int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data,
914− struct drm_file *file_priv);
915−extern int vmw_user_bo_lookup(struct drm_file *filp,
916− uint32_t handle,
917− struct vmw_buffer_object **out);
918−extern void vmw_bo_fence_single(struct ttm_buffer_object *bo,
919− struct vmw_fence_obj *fence);
920−extern void *vmw_bo_map_and_cache(struct vmw_buffer_object *vbo);
921−extern void vmw_bo_unmap(struct vmw_buffer_object *vbo);
922−extern void vmw_bo_move_notify(struct ttm_buffer_object *bo,
923− struct ttm_resource *mem);
924−extern void vmw_bo_swap_notify(struct ttm_buffer_object *bo);
925−
926−/**
927− * vmw_bo_adjust_prio - Adjust the buffer object eviction priority
928− * according to attached resources
929− * @vbo: The struct vmw_buffer_object
930− */
931−static inline void vmw_bo_prio_adjust(struct vmw_buffer_object *vbo)
932−{
933− int i = ARRAY_SIZE(vbo->res_prios);
934−
935− while (i--) {
936− if (vbo->res_prios[i]) {
937− vbo->base.priority = i;
938− return;
939− }
940− }
941−
942− vbo->base.priority = 3;
943−}
944−
945−/**
946− * vmw_bo_prio_add - Notify a buffer object of a newly attached resource
947− * eviction priority
948− * @vbo: The struct vmw_buffer_object
949− * @prio: The resource priority
950− *
951− * After being notified, the code assigns the highest resource eviction priority
952− * to the backing buffer object (mob).
953− */
954−static inline void vmw_bo_prio_add(struct vmw_buffer_object *vbo, int prio)
955−{
956− if (vbo->res_prios[prio]++ == 0)
957− vmw_bo_prio_adjust(vbo);
958−}
959−
960−/**
961− * vmw_bo_prio_del - Notify a buffer object of a resource with a certain
962− * priority being removed
963− * @vbo: The struct vmw_buffer_object
964− * @prio: The resource priority
965− *
966− * After being notified, the code assigns the highest resource eviction priority
967− * to the backing buffer object (mob).
968− */
969−static inline void vmw_bo_prio_del(struct vmw_buffer_object *vbo, int prio)
970−{
971− if (--vbo->res_prios[prio] == 0)
972− vmw_bo_prio_adjust(vbo);
973−}
974−
975852 /**
976853 * GEM related functionality - vmwgfx_gem.c
977854 */
@@ -979,10 +856,9 @@ extern int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv, · 1 unmodified line
979856 struct drm_file *filp,
980857 uint32_t size,
981858 uint32_t *handle,
982− struct vmw_buffer_object **p_vbo);
859+ struct vmw_bo **p_vbo);
983860 extern int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data,
984861 struct drm_file *filp);
985−extern void vmw_gem_destroy(struct ttm_buffer_object *bo);
986862 extern void vmw_debugfs_gem_init(struct vmw_private *vdev);
987863
988864 /**
@@ -1055,30 +931,21 @@ vmw_is_cursor_bypass3_enabled(const struct vmw_private *dev_priv) · 66 unmodified lines
1055931 return (vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_CURSOR_BYPASS_3) != 0;
1056932 }
1057933
1058−/**
1059− * TTM glue - vmwgfx_ttm_glue.c
1060− */
1061−
1062−extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma);
1063−
1064934 /**
1065935 * TTM buffer object driver - vmwgfx_ttm_buffer.c
1066936 */
1067937
1068938 extern const size_t vmw_tt_size;
1069939 extern struct ttm_placement vmw_vram_placement;
1070−extern struct ttm_placement vmw_vram_sys_placement;
1071940 extern struct ttm_placement vmw_vram_gmr_placement;
1072941 extern struct ttm_placement vmw_sys_placement;
1073−extern struct ttm_placement vmw_srf_placement;
1074−extern struct ttm_placement vmw_mob_placement;
1075−extern struct ttm_placement vmw_nonfixed_placement;
1076942 extern struct ttm_device_funcs vmw_bo_driver;
1077943 extern const struct vmw_sg_table *
1078944 vmw_bo_sg_table(struct ttm_buffer_object *bo);
1079−extern int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
1080− unsigned long bo_size,
1081− struct ttm_buffer_object **bo_p);
945+int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
946+ size_t bo_size,
947+ u32 domain,
948+ struct vmw_bo **bo_p);
1082949
1083950 extern void vmw_piter_start(struct vmw_piter *viter,
1084951 const struct vmw_sg_table *vsgt,
@@ -1297,8 +1164,8 @@ vmw_context_binding_state(struct vmw_resource *ctx); · 212 unmodified lines
12971164 extern void vmw_dx_context_scrub_cotables(struct vmw_resource *ctx,
12981165 bool readback);
12991166 extern int vmw_context_bind_dx_query(struct vmw_resource *ctx_res,
1300− struct vmw_buffer_object *mob);
1301−extern struct vmw_buffer_object *
1167+ struct vmw_bo *mob);
1168+extern struct vmw_bo *
13021169 vmw_context_get_dx_query_mob(struct vmw_resource *ctx_res);
13031170
13041171
@@ -1523,12 +1390,12 @@ int vmw_mksstat_remove_all(struct vmw_private *dev_priv); · 218 unmodified lines
15231390 DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__)
15241391
15251392 /* Resource dirtying - vmwgfx_page_dirty.c */
1526−void vmw_bo_dirty_scan(struct vmw_buffer_object *vbo);
1527−int vmw_bo_dirty_add(struct vmw_buffer_object *vbo);
1393+void vmw_bo_dirty_scan(struct vmw_bo *vbo);
1394+int vmw_bo_dirty_add(struct vmw_bo *vbo);
15281395 void vmw_bo_dirty_transfer_to_res(struct vmw_resource *res);
15291396 void vmw_bo_dirty_clear_res(struct vmw_resource *res);
1530−void vmw_bo_dirty_release(struct vmw_buffer_object *vbo);
1531−void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo,
1397+void vmw_bo_dirty_release(struct vmw_bo *vbo);
1398+void vmw_bo_dirty_unmap(struct vmw_bo *vbo,
15321399 pgoff_t start, pgoff_t end);
15331400 vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf);
15341401 vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf);
@@ -1561,22 +1428,6 @@ static inline struct vmw_surface *vmw_surface_reference(struct vmw_surface *srf) · 26 unmodified lines
15611428 return srf;
15621429 }
15631430
1564−static inline void vmw_bo_unreference(struct vmw_buffer_object **buf)
1565−{
1566− struct vmw_buffer_object *tmp_buf = *buf;
1567−
1568− *buf = NULL;
1569− if (tmp_buf != NULL)
1570− ttm_bo_put(&tmp_buf->base);
1571−}
1572−
1573−static inline struct vmw_buffer_object *
1574−vmw_bo_reference(struct vmw_buffer_object *buf)
1575−{
1576− ttm_bo_get(&buf->base);
1577− return buf;
1578−}
1579−
15801431 static inline void vmw_fifo_resource_inc(struct vmw_private *dev_priv)
15811432 {
15821433 atomic_inc(&dev_priv->num_fifo_resources);
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c+58−47
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009 - 2022 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009 - 2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -24,17 +24,17 @@ · 16 unmodified lines
2424 * USE OR OTHER DEALINGS IN THE SOFTWARE.
2525 *
2626 **************************************************************************/
27−#include <linux/sync_file.h>
28−#include <linux/hashtable.h>
29−
27+#include "vmwgfx_binding.h"
28+#include "vmwgfx_bo.h"
3029 #include "vmwgfx_drv.h"
31−#include "vmwgfx_reg.h"
30+#include "vmwgfx_mksstat.h"
31+#include "vmwgfx_so.h"
32+
3233 #include <drm/ttm/ttm_bo.h>
3334 #include <drm/ttm/ttm_placement.h>
34−#include "vmwgfx_so.h"
35−#include "vmwgfx_binding.h"
36−#include "vmwgfx_mksstat.h"
3735
36+#include <linux/sync_file.h>
37+#include <linux/hashtable.h>
3838
3939 /*
4040 * Helper macro to get dx_ctx_node if available otherwise print an error
@@ -65,7 +65,7 @@ · 24 unmodified lines
6565 */
6666 struct vmw_relocation {
6767 struct list_head head;
68− struct vmw_buffer_object *vbo;
68+ struct vmw_bo *vbo;
6969 union {
7070 SVGAMobId *mob_loc;
7171 SVGAGuestPtr *location;
@@ -149,7 +149,7 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, · 77 unmodified lines
149149 static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
150150 struct vmw_sw_context *sw_context,
151151 SVGAMobId *id,
152− struct vmw_buffer_object **vmw_bo_p);
152+ struct vmw_bo **vmw_bo_p);
153153 /**
154154 * vmw_ptr_diff - Compute the offset from a to b in bytes
155155 *
@@ -475,12 +475,16 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, · 319 unmodified lines
475475
476476 if (has_sm4_context(dev_priv) &&
477477 vmw_res_type(ctx) == vmw_res_dx_context) {
478− struct vmw_buffer_object *dx_query_mob;
478+ struct vmw_bo *dx_query_mob;
479479
480480 dx_query_mob = vmw_context_get_dx_query_mob(ctx);
481− if (dx_query_mob)
481+ if (dx_query_mob) {
482+ vmw_bo_placement_set(dx_query_mob,
483+ VMW_BO_DOMAIN_MOB,
484+ VMW_BO_DOMAIN_MOB);
482485 ret = vmw_validation_add_bo(sw_context->ctx,
483− dx_query_mob, true, false);
486+ dx_query_mob);
487+ }
484488 }
485489
486490 mutex_unlock(&dev_priv->binding_mutex);
@@ -596,7 +600,7 @@ static int vmw_resources_reserve(struct vmw_sw_context *sw_context) · 109 unmodified lines
596600 return ret;
597601
598602 if (sw_context->dx_query_mob) {
599− struct vmw_buffer_object *expected_dx_query_mob;
603+ struct vmw_bo *expected_dx_query_mob;
600604
601605 expected_dx_query_mob =
602606 vmw_context_get_dx_query_mob(sw_context->dx_query_ctx);
@@ -703,7 +707,7 @@ res_check_done: · 100 unmodified lines
703707 static int vmw_rebind_all_dx_query(struct vmw_resource *ctx_res)
704708 {
705709 struct vmw_private *dev_priv = ctx_res->dev_priv;
706− struct vmw_buffer_object *dx_query_mob;
710+ struct vmw_bo *dx_query_mob;
707711 VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindAllQuery);
708712
709713 dx_query_mob = vmw_context_get_dx_query_mob(ctx_res);
@@ -718,7 +722,7 @@ static int vmw_rebind_all_dx_query(struct vmw_resource *ctx_res) · 8 unmodified lines
718722 cmd->header.id = SVGA_3D_CMD_DX_BIND_ALL_QUERY;
719723 cmd->header.size = sizeof(cmd->body);
720724 cmd->body.cid = ctx_res->id;
721− cmd->body.mobid = dx_query_mob->base.resource->start;
725+ cmd->body.mobid = dx_query_mob->tbo.resource->start;
722726 vmw_cmd_commit(dev_priv, sizeof(*cmd));
723727
724728 vmw_context_bind_dx_query(ctx_res, dx_query_mob);
@@ -1017,7 +1021,7 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, · 292 unmodified lines
10171021 * after successful submission of the current command batch.
10181022 */
10191023 static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv,
1020− struct vmw_buffer_object *new_query_bo,
1024+ struct vmw_bo *new_query_bo,
10211025 struct vmw_sw_context *sw_context)
10221026 {
10231027 struct vmw_res_cache_entry *ctx_entry =
@@ -1029,24 +1033,24 @@ static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv, · 5 unmodified lines
10291033
10301034 if (unlikely(new_query_bo != sw_context->cur_query_bo)) {
10311035
1032− if (unlikely(PFN_UP(new_query_bo->base.resource->size) > 4)) {
1036+ if (unlikely(PFN_UP(new_query_bo->tbo.resource->size) > 4)) {
10331037 VMW_DEBUG_USER("Query buffer too large.\n");
10341038 return -EINVAL;
10351039 }
10361040
10371041 if (unlikely(sw_context->cur_query_bo != NULL)) {
10381042 sw_context->needs_post_query_barrier = true;
1043+ vmw_bo_placement_set_default_accelerated(sw_context->cur_query_bo);
10391044 ret = vmw_validation_add_bo(sw_context->ctx,
1040− sw_context->cur_query_bo,
1041− dev_priv->has_mob, false);
1045+ sw_context->cur_query_bo);
10421046 if (unlikely(ret != 0))
10431047 return ret;
10441048 }
10451049 sw_context->cur_query_bo = new_query_bo;
10461050
1051+ vmw_bo_placement_set_default_accelerated(dev_priv->dummy_query_bo);
10471052 ret = vmw_validation_add_bo(sw_context->ctx,
1048− dev_priv->dummy_query_bo,
1049− dev_priv->has_mob, false);
1053+ dev_priv->dummy_query_bo);
10501054 if (unlikely(ret != 0))
10511055 return ret;
10521056 }
@@ -1145,9 +1149,9 @@ static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv, · 92 unmodified lines
11451149 static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
11461150 struct vmw_sw_context *sw_context,
11471151 SVGAMobId *id,
1148− struct vmw_buffer_object **vmw_bo_p)
1152+ struct vmw_bo **vmw_bo_p)
11491153 {
1150− struct vmw_buffer_object *vmw_bo;
1154+ struct vmw_bo *vmw_bo;
11511155 uint32_t handle = *id;
11521156 struct vmw_relocation *reloc;
11531157 int ret;
@@ -1158,9 +1162,10 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, · 4 unmodified lines
11581162 drm_dbg(&dev_priv->drm, "Could not find or use MOB buffer.\n");
11591163 return PTR_ERR(vmw_bo);
11601164 }
1161− ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false);
1162− ttm_bo_put(&vmw_bo->base);
1163− drm_gem_object_put(&vmw_bo->base.base);
1165+ vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_MOB, VMW_BO_DOMAIN_MOB);
1166+ ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
1167+ ttm_bo_put(&vmw_bo->tbo);
1168+ drm_gem_object_put(&vmw_bo->tbo.base);
11641169 if (unlikely(ret != 0))
11651170 return ret;
11661171
@@ -1200,9 +1205,9 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, · 33 unmodified lines
12001205 static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
12011206 struct vmw_sw_context *sw_context,
12021207 SVGAGuestPtr *ptr,
1203− struct vmw_buffer_object **vmw_bo_p)
1208+ struct vmw_bo **vmw_bo_p)
12041209 {
1205− struct vmw_buffer_object *vmw_bo;
1210+ struct vmw_bo *vmw_bo;
12061211 uint32_t handle = ptr->gmrId;
12071212 struct vmw_relocation *reloc;
12081213 int ret;
@@ -1213,9 +1218,11 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, · 4 unmodified lines
12131218 drm_dbg(&dev_priv->drm, "Could not find or use GMR region.\n");
12141219 return PTR_ERR(vmw_bo);
12151220 }
1216− ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false);
1217− ttm_bo_put(&vmw_bo->base);
1218− drm_gem_object_put(&vmw_bo->base.base);
1221+ vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
1222+ VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
1223+ ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
1224+ ttm_bo_put(&vmw_bo->tbo);
1225+ drm_gem_object_put(&vmw_bo->tbo.base);
12191226 if (unlikely(ret != 0))
12201227 return ret;
12211228
@@ -1280,7 +1287,7 @@ static int vmw_cmd_dx_bind_query(struct vmw_private *dev_priv, · 58 unmodified lines
12801287 SVGA3dCmdHeader *header)
12811288 {
12821289 VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindQuery);
1283− struct vmw_buffer_object *vmw_bo;
1290+ struct vmw_bo *vmw_bo;
12841291 int ret;
12851292
12861293 cmd = container_of(header, typeof(*cmd), header);
@@ -1363,7 +1370,7 @@ static int vmw_cmd_end_gb_query(struct vmw_private *dev_priv, · 76 unmodified lines
13631370 struct vmw_sw_context *sw_context,
13641371 SVGA3dCmdHeader *header)
13651372 {
1366− struct vmw_buffer_object *vmw_bo;
1373+ struct vmw_bo *vmw_bo;
13671374 VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdEndGBQuery);
13681375 int ret;
13691376
@@ -1393,7 +1400,7 @@ static int vmw_cmd_end_query(struct vmw_private *dev_priv, · 23 unmodified lines
13931400 struct vmw_sw_context *sw_context,
13941401 SVGA3dCmdHeader *header)
13951402 {
1396− struct vmw_buffer_object *vmw_bo;
1403+ struct vmw_bo *vmw_bo;
13971404 VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdEndQuery);
13981405 int ret;
13991406
@@ -1439,7 +1446,7 @@ static int vmw_cmd_wait_gb_query(struct vmw_private *dev_priv, · 39 unmodified lines
14391446 struct vmw_sw_context *sw_context,
14401447 SVGA3dCmdHeader *header)
14411448 {
1442− struct vmw_buffer_object *vmw_bo;
1449+ struct vmw_bo *vmw_bo;
14431450 VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdWaitForGBQuery);
14441451 int ret;
14451452
@@ -1467,7 +1474,7 @@ static int vmw_cmd_wait_query(struct vmw_private *dev_priv, · 21 unmodified lines
14671474 struct vmw_sw_context *sw_context,
14681475 SVGA3dCmdHeader *header)
14691476 {
1470− struct vmw_buffer_object *vmw_bo;
1477+ struct vmw_bo *vmw_bo;
14711478 VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdWaitForQuery);
14721479 int ret;
14731480
@@ -1504,7 +1511,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, · 30 unmodified lines
15041511 struct vmw_sw_context *sw_context,
15051512 SVGA3dCmdHeader *header)
15061513 {
1507− struct vmw_buffer_object *vmw_bo = NULL;
1514+ struct vmw_bo *vmw_bo = NULL;
15081515 struct vmw_surface *srf = NULL;
15091516 VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSurfaceDMA);
15101517 int ret;
@@ -1528,7 +1535,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, · 17 unmodified lines
15281535 return ret;
15291536
15301537 /* Make sure DMA doesn't cross BO boundaries. */
1531− bo_size = vmw_bo->base.base.size;
1538+ bo_size = vmw_bo->tbo.base.size;
15321539 if (unlikely(cmd->body.guest.ptr.offset > bo_size)) {
15331540 VMW_DEBUG_USER("Invalid DMA offset.\n");
15341541 return -EINVAL;
@@ -1551,7 +1558,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, · 16 unmodified lines
15511558
15521559 srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res);
15531560
1554− vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->base, header);
1561+ vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->tbo, header);
15551562
15561563 return 0;
15571564 }
@@ -1670,7 +1677,7 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv, · 112 unmodified lines
16701677 struct vmw_sw_context *sw_context,
16711678 void *buf)
16721679 {
1673− struct vmw_buffer_object *vmw_bo;
1680+ struct vmw_bo *vmw_bo;
16741681
16751682 struct {
16761683 uint32_t header;
@@ -1701,7 +1708,7 @@ static int vmw_cmd_res_switch_backup(struct vmw_private *dev_priv, · 24 unmodified lines
17011708 struct vmw_resource *res, uint32_t *buf_id,
17021709 unsigned long backup_offset)
17031710 {
1704− struct vmw_buffer_object *vbo;
1711+ struct vmw_bo *vbo;
17051712 void *info;
17061713 int ret;
17071714
@@ -3754,7 +3761,7 @@ static void vmw_apply_relocations(struct vmw_sw_context *sw_context) · 2046 unmodified lines
37543761 struct ttm_buffer_object *bo;
37553762
37563763 list_for_each_entry(reloc, &sw_context->bo_relocations, head) {
3757− bo = &reloc->vbo->base;
3764+ bo = &reloc->vbo->tbo;
37583765 switch (bo->resource->mem_type) {
37593766 case TTM_PL_VRAM:
37603767 reloc->location->offset += bo->resource->start << PAGE_SHIFT;
@@ -4364,13 +4371,17 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, · 603 unmodified lines
43644371 if (dev_priv->pinned_bo == NULL)
43654372 goto out_unlock;
43664373
4367− ret = vmw_validation_add_bo(&val_ctx, dev_priv->pinned_bo, false,
4368− false);
4374+ vmw_bo_placement_set(dev_priv->pinned_bo,
4375+ VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
4376+ VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
4377+ ret = vmw_validation_add_bo(&val_ctx, dev_priv->pinned_bo);
43694378 if (ret)
43704379 goto out_no_reserve;
43714380
4372− ret = vmw_validation_add_bo(&val_ctx, dev_priv->dummy_query_bo, false,
4373− false);
4381+ vmw_bo_placement_set(dev_priv->dummy_query_bo,
4382+ VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
4383+ VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
4384+ ret = vmw_validation_add_bo(&val_ctx, dev_priv->dummy_query_bo);
43744385 if (ret)
43754386 goto out_no_reserve;
43764387
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c+1−1
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2011-2014 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2011-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
drivers/gpu/drm/vmwgfx/vmwgfx_gem.c+36−55
@@ -1,6 +1,6 @@
11 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
22 /*
3− * Copyright 2021 VMware, Inc.
3+ * Copyright 2021-2023 VMware, Inc.
44 *
55 * Permission is hereby granted, free of charge, to any person
66 * obtaining a copy of this software and associated documentation
@@ -24,31 +24,17 @@ · 17 unmodified lines
2424 *
2525 */
2626
27+#include "vmwgfx_bo.h"
2728 #include "vmwgfx_drv.h"
2829
2930 #include "drm/drm_prime.h"
3031 #include "drm/drm_gem_ttm_helper.h"
3132
32−/**
33− * vmw_buffer_object - Convert a struct ttm_buffer_object to a struct
34− * vmw_buffer_object.
35− *
36− * @bo: Pointer to the TTM buffer object.
37− * Return: Pointer to the struct vmw_buffer_object embedding the
38− * TTM buffer object.
39− */
40−static struct vmw_buffer_object *
41−vmw_buffer_object(struct ttm_buffer_object *bo)
42−{
43− return container_of(bo, struct vmw_buffer_object, base);
44−}
45−
4633 static void vmw_gem_object_free(struct drm_gem_object *gobj)
4734 {
4835 struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gobj);
49− if (bo) {
36+ if (bo)
5037 ttm_bo_put(bo);
51− }
5238 }
5339
5440 static int vmw_gem_object_open(struct drm_gem_object *obj,
@@ -65,7 +51,7 @@ static void vmw_gem_object_close(struct drm_gem_object *obj, · 10 unmodified lines
6551 static int vmw_gem_pin_private(struct drm_gem_object *obj, bool do_pin)
6652 {
6753 struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(obj);
68− struct vmw_buffer_object *vbo = vmw_buffer_object(bo);
54+ struct vmw_bo *vbo = to_vmw_bo(obj);
6955 int ret;
7056
7157 ret = ttm_bo_reserve(bo, false, false, NULL);
@@ -103,6 +89,13 @@ static struct sg_table *vmw_gem_object_get_sg_table(struct drm_gem_object *obj) · 31 unmodified lines
10389 return drm_prime_pages_to_sg(obj->dev, vmw_tt->dma_ttm.pages, vmw_tt->dma_ttm.num_pages);
10490 }
10591
92+static const struct vm_operations_struct vmw_vm_ops = {
93+ .pfn_mkwrite = vmw_bo_vm_mkwrite,
94+ .page_mkwrite = vmw_bo_vm_mkwrite,
95+ .fault = vmw_bo_vm_fault,
96+ .open = ttm_bo_vm_open,
97+ .close = ttm_bo_vm_close,
98+};
10699
107100 static const struct drm_gem_object_funcs vmw_gem_object_funcs = {
108101 .free = vmw_gem_object_free,
@@ -115,43 +108,31 @@ static const struct drm_gem_object_funcs vmw_gem_object_funcs = { · 6 unmodified lines
115108 .vmap = drm_gem_ttm_vmap,
116109 .vunmap = drm_gem_ttm_vunmap,
117110 .mmap = drm_gem_ttm_mmap,
111+ .vm_ops = &vmw_vm_ops,
118112 };
119113
120−/**
121− * vmw_gem_destroy - vmw buffer object destructor
122− *
123− * @bo: Pointer to the embedded struct ttm_buffer_object
124− */
125−void vmw_gem_destroy(struct ttm_buffer_object *bo)
126−{
127− struct vmw_buffer_object *vbo = vmw_buffer_object(bo);
128−
129− WARN_ON(vbo->dirty);
130− WARN_ON(!RB_EMPTY_ROOT(&vbo->res_tree));
131− vmw_bo_unmap(vbo);
132− drm_gem_object_release(&vbo->base.base);
133− kfree(vbo);
134−}
135−
136114 int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv,
137115 struct drm_file *filp,
138116 uint32_t size,
139117 uint32_t *handle,
140− struct vmw_buffer_object **p_vbo)
118+ struct vmw_bo **p_vbo)
141119 {
142120 int ret;
143−
144− ret = vmw_bo_create(dev_priv, size,
145− (dev_priv->has_mob) ?
146− &vmw_sys_placement :
147− &vmw_vram_sys_placement,
148− true, false, &vmw_gem_destroy, p_vbo);
121+ struct vmw_bo_params params = {
122+ .domain = (dev_priv->has_mob) ? VMW_BO_DOMAIN_SYS : VMW_BO_DOMAIN_VRAM,
123+ .busy_domain = VMW_BO_DOMAIN_SYS,
124+ .bo_type = ttm_bo_type_device,
125+ .size = size,
126+ .pin = false
127+ };
128+
129+ ret = vmw_bo_create(dev_priv, &params, p_vbo);
149130 if (ret != 0)
150131 goto out_no_bo;
151132
152− (*p_vbo)->base.base.funcs = &vmw_gem_object_funcs;
133+ (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs;
153134
154− ret = drm_gem_handle_create(filp, &(*p_vbo)->base.base, handle);
135+ ret = drm_gem_handle_create(filp, &(*p_vbo)->tbo.base, handle);
155136 out_no_bo:
156137 return ret;
157138 }
@@ -165,7 +146,7 @@ int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data, · 7 unmodified lines
165146 (union drm_vmw_alloc_dmabuf_arg *)data;
166147 struct drm_vmw_alloc_dmabuf_req *req = &arg->req;
167148 struct drm_vmw_dmabuf_rep *rep = &arg->rep;
168− struct vmw_buffer_object *vbo;
149+ struct vmw_bo *vbo;
169150 uint32_t handle;
170151 int ret;
171152
@@ -175,23 +156,23 @@ int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data, · 3 unmodified lines
175156 goto out_no_bo;
176157
177158 rep->handle = handle;
178− rep->map_handle = drm_vma_node_offset_addr(&vbo->base.base.vma_node);
159+ rep->map_handle = drm_vma_node_offset_addr(&vbo->tbo.base.vma_node);
179160 rep->cur_gmr_id = handle;
180161 rep->cur_gmr_offset = 0;
181162 /* drop reference from allocate - handle holds it now */
182− drm_gem_object_put(&vbo->base.base);
163+ drm_gem_object_put(&vbo->tbo.base);
183164 out_no_bo:
184165 return ret;
185166 }
186167
187168 #if defined(CONFIG_DEBUG_FS)
188169
189−static void vmw_bo_print_info(int id, struct vmw_buffer_object *bo, struct seq_file *m)
170+static void vmw_bo_print_info(int id, struct vmw_bo *bo, struct seq_file *m)
190171 {
191172 const char *placement;
192173 const char *type;
193174
194− switch (bo->base.resource->mem_type) {
175+ switch (bo->tbo.resource->mem_type) {
195176 case TTM_PL_SYSTEM:
196177 placement = " CPU";
197178 break;
@@ -212,7 +193,7 @@ static void vmw_bo_print_info(int id, struct vmw_buffer_object *bo, struct seq_f · 14 unmodified lines
212193 break;
213194 }
214195
215− switch (bo->base.type) {
196+ switch (bo->tbo.type) {
216197 case ttm_bo_type_device:
217198 type = "device";
218199 break;
@@ -228,12 +209,12 @@ static void vmw_bo_print_info(int id, struct vmw_buffer_object *bo, struct seq_f · 9 unmodified lines
228209 }
229210
230211 seq_printf(m, "\t\t0x%08x: %12zu bytes %s, type = %s",
231− id, bo->base.base.size, placement, type);
212+ id, bo->tbo.base.size, placement, type);
232213 seq_printf(m, ", priority = %u, pin_count = %u, GEM refs = %d, TTM refs = %d",
233− bo->base.priority,
234− bo->base.pin_count,
235− kref_read(&bo->base.base.refcount),
236− kref_read(&bo->base.kref));
214+ bo->tbo.priority,
215+ bo->tbo.pin_count,
216+ kref_read(&bo->tbo.base.refcount),
217+ kref_read(&bo->tbo.kref));
237218 seq_puts(m, "\n");
238219 }
239220
@@ -267,7 +248,7 @@ static int vmw_debugfs_gem_info_show(struct seq_file *m, void *unused) · 27 unmodified lines
267248
268249 spin_lock(&file->table_lock);
269250 idr_for_each_entry(&file->object_idr, gobj, id) {
270− struct vmw_buffer_object *bo = gem_to_vmw_bo(gobj);
251+ struct vmw_bo *bo = to_vmw_bo(gobj);
271252
272253 vmw_bo_print_info(id, bo, m);
273254 }
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c+77−155
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -24,8 +24,9 @@ · 16 unmodified lines
2424 * USE OR OTHER DEALINGS IN THE SOFTWARE.
2525 *
2626 **************************************************************************/
27−
2827 #include "vmwgfx_kms.h"
28+
29+#include "vmwgfx_bo.h"
2930 #include "vmw_surface_cache.h"
3031
3132 #include <drm/drm_atomic.h>
@@ -152,9 +153,8 @@ static void vmw_cursor_update_mob(struct vmw_private *dev_priv, · 120 unmodified lines
152153 SVGAGBCursorHeader *header;
153154 SVGAGBAlphaCursorHeader *alpha_header;
154155 const u32 image_size = width * height * sizeof(*image);
155− bool dummy;
156156
157− header = ttm_kmap_obj_virtual(&vps->cursor.map, &dummy);
157+ header = vmw_bo_map_and_cache(vps->cursor.bo);
158158 alpha_header = &header->header.alphaHeader;
159159
160160 memset(header, 0, sizeof(*header));
@@ -169,7 +169,7 @@ static void vmw_cursor_update_mob(struct vmw_private *dev_priv, · 8 unmodified lines
169169
170170 memcpy(header + 1, image, image_size);
171171 vmw_write(dev_priv, SVGA_REG_CURSOR_MOBID,
172− vps->cursor.bo->resource->start);
172+ vps->cursor.bo->tbo.resource->start);
173173 }
174174
175175
@@ -184,13 +184,13 @@ static u32 vmw_du_cursor_mob_size(u32 w, u32 h) · 8 unmodified lines
184184 */
185185 static u32 *vmw_du_cursor_plane_acquire_image(struct vmw_plane_state *vps)
186186 {
187− bool dummy;
187+ bool is_iomem;
188188 if (vps->surf) {
189189 if (vps->surf_mapped)
190− return vmw_bo_map_and_cache(vps->surf->res.backup);
190+ return vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo);
191191 return vps->surf->snooper.image;
192192 } else if (vps->bo)
193− return ttm_kmap_obj_virtual(&vps->bo->map, &dummy);
193+ return ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem);
194194 return NULL;
195195 }
196196
@@ -222,15 +222,13 @@ static bool vmw_du_cursor_plane_has_changed(struct vmw_plane_state *old_vps, · 25 unmodified lines
222222 return changed;
223223 }
224224
225−static void vmw_du_destroy_cursor_mob(struct ttm_buffer_object **bo)
225+static void vmw_du_destroy_cursor_mob(struct vmw_bo **vbo)
226226 {
227− if (!(*bo))
227+ if (!(*vbo))
228228 return;
229229
230− ttm_bo_unpin(*bo);
231− ttm_bo_put(*bo);
232− kfree(*bo);
233− *bo = NULL;
230+ ttm_bo_unpin(&(*vbo)->tbo);
231+ vmw_bo_unreference(vbo);
234232 }
235233
236234 static void vmw_du_put_cursor_mob(struct vmw_cursor_plane *vcp,
@@ -254,8 +252,8 @@ static void vmw_du_put_cursor_mob(struct vmw_cursor_plane *vcp, · 17 unmodified lines
254252
255253 /* Cache is full: See if this mob is bigger than an existing mob. */
256254 for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++) {
257− if (vcp->cursor_mobs[i]->base.size <
258− vps->cursor.bo->base.size) {
255+ if (vcp->cursor_mobs[i]->tbo.base.size <
256+ vps->cursor.bo->tbo.base.size) {
259257 vmw_du_destroy_cursor_mob(&vcp->cursor_mobs[i]);
260258 vcp->cursor_mobs[i] = vps->cursor.bo;
261259 vps->cursor.bo = NULL;
@@ -288,7 +286,7 @@ static int vmw_du_get_cursor_mob(struct vmw_cursor_plane *vcp, · 26 unmodified lines
288286 return -EINVAL;
289287
290288 if (vps->cursor.bo) {
291− if (vps->cursor.bo->base.size >= size)
289+ if (vps->cursor.bo->tbo.base.size >= size)
292290 return 0;
293291 vmw_du_put_cursor_mob(vcp, vps);
294292 }
@@ -296,26 +294,27 @@ static int vmw_du_get_cursor_mob(struct vmw_cursor_plane *vcp, · 1 unmodified line
296294 /* Look for an unused mob in the cache. */
297295 for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++) {
298296 if (vcp->cursor_mobs[i] &&
299− vcp->cursor_mobs[i]->base.size >= size) {
297+ vcp->cursor_mobs[i]->tbo.base.size >= size) {
300298 vps->cursor.bo = vcp->cursor_mobs[i];
301299 vcp->cursor_mobs[i] = NULL;
302300 return 0;
303301 }
304302 }
305303 /* Create a new mob if we can't find an existing one. */
306− ret = vmw_bo_create_kernel(dev_priv, size, &vmw_mob_placement,
307− &vps->cursor.bo);
304+ ret = vmw_bo_create_and_populate(dev_priv, size,
305+ VMW_BO_DOMAIN_MOB,
306+ &vps->cursor.bo);
308307
309308 if (ret != 0)
310309 return ret;
311310
312311 /* Fence the mob creation so we are guarateed to have the mob */
313− ret = ttm_bo_reserve(vps->cursor.bo, false, false, NULL);
312+ ret = ttm_bo_reserve(&vps->cursor.bo->tbo, false, false, NULL);
314313 if (ret != 0)
315314 goto teardown;
316315
317− vmw_bo_fence_single(vps->cursor.bo, NULL);
318− ttm_bo_unreserve(vps->cursor.bo);
316+ vmw_bo_fence_single(&vps->cursor.bo->tbo, NULL);
317+ ttm_bo_unreserve(&vps->cursor.bo->tbo);
319318 return 0;
320319
321320 teardown:
@@ -363,7 +362,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, · 41 unmodified lines
363362 SVGA3dCopyBox *box;
364363 unsigned box_count;
365364 void *virtual;
366− bool dummy;
365+ bool is_iomem;
367366 struct vmw_dma_cmd {
368367 SVGA3dCmdHeader header;
369368 SVGA3dCmdSurfaceDMA dma;
@@ -423,7 +422,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, · 53 unmodified lines
423422 if (unlikely(ret != 0))
424423 goto err_unreserve;
425424
426− virtual = ttm_kmap_obj_virtual(&map, &dummy);
425+ virtual = ttm_kmap_obj_virtual(&map, &is_iomem);
427426
428427 if (box->w == VMW_CURSOR_SNOOP_WIDTH && cmd->dma.guest.pitch == image_pitch) {
429428 memcpy(srf->snooper.image, virtual,
@@ -573,39 +572,30 @@ vmw_du_cursor_plane_map_cm(struct vmw_plane_state *vps) · 143 unmodified lines
573572 {
574573 int ret;
575574 u32 size = vmw_du_cursor_mob_size(vps->base.crtc_w, vps->base.crtc_h);
576− struct ttm_buffer_object *bo = vps->cursor.bo;
575+ struct ttm_buffer_object *bo;
577576
578− if (!bo)
577+ if (!vps->cursor.bo)
579578 return -EINVAL;
580579
580+ bo = &vps->cursor.bo->tbo;
581+
581582 if (bo->base.size < size)
582583 return -EINVAL;
583584
584− if (vps->cursor.mapped)
585+ if (vps->cursor.bo->map.virtual)
585586 return 0;
586587
587588 ret = ttm_bo_reserve(bo, false, false, NULL);
588−
589589 if (unlikely(ret != 0))
590590 return -ENOMEM;
591591
592− ret = ttm_bo_kmap(bo, 0, PFN_UP(size), &vps->cursor.map);
593−
594− /*
595− * We just want to try to get mob bind to finish
596− * so that the first write to SVGA_REG_CURSOR_MOBID
597− * is done with a buffer that the device has already
598− * seen
599− */
600− (void) ttm_bo_wait(bo, false, false);
592+ vmw_bo_map_and_cache(vps->cursor.bo);
601593
602594 ttm_bo_unreserve(bo);
603595
604596 if (unlikely(ret != 0))
605597 return -ENOMEM;
606598
607− vps->cursor.mapped = true;
608−
609599 return 0;
610600 }
611601
@@ -622,19 +612,15 @@ static int · 10 unmodified lines
622612 vmw_du_cursor_plane_unmap_cm(struct vmw_plane_state *vps)
623613 {
624614 int ret = 0;
625− struct ttm_buffer_object *bo = vps->cursor.bo;
626−
627− if (!vps->cursor.mapped)
628− return 0;
615+ struct vmw_bo *vbo = vps->cursor.bo;
629616
630− if (!bo)
617+ if (!vbo || !vbo->map.virtual)
631618 return 0;
632619
633− ret = ttm_bo_reserve(bo, true, false, NULL);
620+ ret = ttm_bo_reserve(&vbo->tbo, true, false, NULL);
634621 if (likely(ret == 0)) {
635− ttm_bo_kunmap(&vps->cursor.map);
636− ttm_bo_unreserve(bo);
637− vps->cursor.mapped = false;
622+ vmw_bo_unmap(vbo);
623+ ttm_bo_unreserve(&vbo->tbo);
638624 }
639625
640626 return ret;
@@ -657,20 +643,19 @@ vmw_du_cursor_plane_cleanup_fb(struct drm_plane *plane, · 16 unmodified lines
657643 {
658644 struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
659645 struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
660− bool dummy;
646+ bool is_iomem;
661647
662648 if (vps->surf_mapped) {
663− vmw_bo_unmap(vps->surf->res.backup);
649+ vmw_bo_unmap(vps->surf->res.guest_memory_bo);
664650 vps->surf_mapped = false;
665651 }
666652
667− if (vps->bo && ttm_kmap_obj_virtual(&vps->bo->map, &dummy)) {
668− const int ret = ttm_bo_reserve(&vps->bo->base, true, false, NULL);
653+ if (vps->bo && ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem)) {
654+ const int ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL);
669655
670656 if (likely(ret == 0)) {
671− if (atomic_read(&vps->bo->base_mapped_count) == 0)
672− ttm_bo_kunmap(&vps->bo->map);
673− ttm_bo_unreserve(&vps->bo->base);
657+ ttm_bo_kunmap(&vps->bo->map);
658+ ttm_bo_unreserve(&vps->bo->tbo);
674659 }
675660 }
676661
@@ -736,29 +721,26 @@ vmw_du_cursor_plane_prepare_fb(struct drm_plane *plane, · 59 unmodified lines
736721 * reserve the ttm_buffer_object first which
737722 * vmw_bo_map_and_cache() omits.
738723 */
739− ret = ttm_bo_reserve(&vps->bo->base, true, false, NULL);
724+ ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL);
740725
741726 if (unlikely(ret != 0))
742727 return -ENOMEM;
743728
744− ret = ttm_bo_kmap(&vps->bo->base, 0, PFN_UP(size), &vps->bo->map);
745−
746− if (likely(ret == 0))
747− atomic_inc(&vps->bo->base_mapped_count);
729+ ret = ttm_bo_kmap(&vps->bo->tbo, 0, PFN_UP(size), &vps->bo->map);
748730
749− ttm_bo_unreserve(&vps->bo->base);
731+ ttm_bo_unreserve(&vps->bo->tbo);
750732
751733 if (unlikely(ret != 0))
752734 return -ENOMEM;
753− } else if (vps->surf && !vps->bo && vps->surf->res.backup) {
735+ } else if (vps->surf && !vps->bo && vps->surf->res.guest_memory_bo) {
754736
755737 WARN_ON(vps->surf->snooper.image);
756− ret = ttm_bo_reserve(&vps->surf->res.backup->base, true, false,
738+ ret = ttm_bo_reserve(&vps->surf->res.guest_memory_bo->tbo, true, false,
757739 NULL);
758740 if (unlikely(ret != 0))
759741 return -ENOMEM;
760− vmw_bo_map_and_cache(vps->surf->res.backup);
761− ttm_bo_unreserve(&vps->surf->res.backup->base);
742+ vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo);
743+ ttm_bo_unreserve(&vps->surf->res.guest_memory_bo->tbo);
762744 vps->surf_mapped = true;
763745 }
764746
@@ -785,7 +767,6 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane, · 20 unmodified lines
785767 struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
786768 struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state);
787769 s32 hotspot_x, hotspot_y;
788− bool dummy;
789770
790771 hotspot_x = du->hotspot_x;
791772 hotspot_y = du->hotspot_y;
@@ -827,11 +808,6 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane, · 35 unmodified lines
827808 hotspot_x, hotspot_y);
828809 }
829810
830− if (vps->bo) {
831− if (ttm_kmap_obj_virtual(&vps->bo->map, &dummy))
832− atomic_dec(&vps->bo->base_mapped_count);
833− }
834−
835811 du->cursor_x = new_state->crtc_x + du->set_gui_x;
836812 du->cursor_y = new_state->crtc_y + du->set_gui_y;
837813
@@ -935,7 +911,7 @@ int vmw_du_cursor_plane_atomic_check(struct drm_plane *plane, · 97 unmodified lines
935911 WARN_ON(!surface);
936912
937913 if (!surface ||
938− (!surface->snooper.image && !surface->res.backup)) {
914+ (!surface->snooper.image && !surface->res.guest_memory_bo)) {
939915 DRM_ERROR("surface not suitable for cursor\n");
940916 return -EINVAL;
941917 }
@@ -1279,9 +1255,9 @@ int vmw_kms_readback(struct vmw_private *dev_priv, · 337 unmodified lines
12791255 user_fence_rep, vclips, num_clips,
12801256 NULL);
12811257 case vmw_du_screen_target:
1282− return vmw_kms_stdu_dma(dev_priv, file_priv, vfb,
1283− user_fence_rep, NULL, vclips, num_clips,
1284− 1, false, true, NULL);
1258+ return vmw_kms_stdu_readback(dev_priv, file_priv, vfb,
1259+ user_fence_rep, NULL, vclips, num_clips,
1260+ 1, NULL);
12851261 default:
12861262 WARN_ONCE(true,
12871263 "Readback called with invalid display system.\n");
@@ -1406,7 +1382,7 @@ static int vmw_framebuffer_bo_create_handle(struct drm_framebuffer *fb, · 118 unmodified lines
14061382 struct vmw_framebuffer_bo *vfbd =
14071383 vmw_framebuffer_to_vfbd(fb);
14081384
1409− return drm_gem_handle_create(file_priv, &vfbd->buffer->base.base, handle);
1385+ return drm_gem_handle_create(file_priv, &vfbd->buffer->tbo.base, handle);
14101386 }
14111387
14121388 static void vmw_framebuffer_bo_destroy(struct drm_framebuffer *framebuffer)
@@ -1486,69 +1462,6 @@ static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = { · 73 unmodified lines
14861462 .dirty = vmw_framebuffer_bo_dirty_ext,
14871463 };
14881464
1489−/*
1490− * Pin the bofer in a location suitable for access by the
1491− * display system.
1492− */
1493−static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
1494−{
1495− struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
1496− struct vmw_buffer_object *buf;
1497− struct ttm_placement *placement;
1498− int ret;
1499−
1500− buf = vfb->bo ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
1501− vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup;
1502−
1503− if (!buf)
1504− return 0;
1505−
1506− switch (dev_priv->active_display_unit) {
1507− case vmw_du_legacy:
1508− vmw_overlay_pause_all(dev_priv);
1509− ret = vmw_bo_pin_in_start_of_vram(dev_priv, buf, false);
1510− vmw_overlay_resume_all(dev_priv);
1511− break;
1512− case vmw_du_screen_object:
1513− case vmw_du_screen_target:
1514− if (vfb->bo) {
1515− if (dev_priv->capabilities & SVGA_CAP_3D) {
1516− /*
1517− * Use surface DMA to get content to
1518− * sreen target surface.
1519− */
1520− placement = &vmw_vram_gmr_placement;
1521− } else {
1522− /* Use CPU blit. */
1523− placement = &vmw_sys_placement;
1524− }
1525− } else {
1526− /* Use surface / image update */
1527− placement = &vmw_mob_placement;
1528− }
1529−
1530− return vmw_bo_pin_in_placement(dev_priv, buf, placement, false);
1531− default:
1532− return -EINVAL;
1533− }
1534−
1535− return ret;
1536−}
1537−
1538−static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb)
1539−{
1540− struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
1541− struct vmw_buffer_object *buf;
1542−
1543− buf = vfb->bo ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
1544− vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup;
1545−
1546− if (WARN_ON(!buf))
1547− return 0;
1548−
1549− return vmw_bo_unpin(dev_priv, buf, false);
1550−}
1551−
15521465 /**
15531466 * vmw_create_bo_proxy - create a proxy surface for the buffer object
15541467 *
@@ -1566,7 +1479,7 @@ static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb) · 11 unmodified lines
15661479 */
15671480 static int vmw_create_bo_proxy(struct drm_device *dev,
15681481 const struct drm_mode_fb_cmd2 *mode_cmd,
1569− struct vmw_buffer_object *bo_mob,
1482+ struct vmw_bo *bo_mob,
15701483 struct vmw_surface **srf_out)
15711484 {
15721485 struct vmw_surface_metadata metadata = {0};
@@ -1618,9 +1531,9 @@ static int vmw_create_bo_proxy(struct drm_device *dev, · 45 unmodified lines
16181531 /* Reserve and switch the backing mob. */
16191532 mutex_lock(&res->dev_priv->cmdbuf_mutex);
16201533 (void) vmw_resource_reserve(res, false, true);
1621− vmw_bo_unreference(&res->backup);
1622− res->backup = vmw_bo_reference(bo_mob);
1623− res->backup_offset = 0;
1534+ vmw_bo_unreference(&res->guest_memory_bo);
1535+ res->guest_memory_bo = vmw_bo_reference(bo_mob);
1536+ res->guest_memory_offset = 0;
16241537 vmw_resource_unreserve(res, false, false, false, NULL, 0);
16251538 mutex_unlock(&res->dev_priv->cmdbuf_mutex);
16261539
@@ -1630,7 +1543,7 @@ static int vmw_create_bo_proxy(struct drm_device *dev, · 3 unmodified lines
16301543
16311544
16321545 static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv,
1633− struct vmw_buffer_object *bo,
1546+ struct vmw_bo *bo,
16341547 struct vmw_framebuffer **out,
16351548 const struct drm_mode_fb_cmd2
16361549 *mode_cmd)
@@ -1642,7 +1555,7 @@ static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv, · 5 unmodified lines
16421555 int ret;
16431556
16441557 requested_size = mode_cmd->height * mode_cmd->pitches[0];
1645− if (unlikely(requested_size > bo->base.base.size)) {
1558+ if (unlikely(requested_size > bo->tbo.base.size)) {
16461559 DRM_ERROR("Screen buffer object size is too small "
16471560 "for requested mode.\n");
16481561 return -EINVAL;
@@ -1663,7 +1576,7 @@ static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv, · 14 unmodified lines
16631576 goto out_err1;
16641577 }
16651578
1666− vfbd->base.base.obj[0] = &bo->base.base;
1579+ vfbd->base.base.obj[0] = &bo->tbo.base;
16671580 drm_helper_mode_fill_fb_struct(dev, &vfbd->base.base, mode_cmd);
16681581 vfbd->base.bo = true;
16691582 vfbd->buffer = vmw_bo_reference(bo);
@@ -1718,7 +1631,7 @@ vmw_kms_srf_ok(struct vmw_private *dev_priv, uint32_t width, uint32_t height) · 48 unmodified lines
17181631 */
17191632 struct vmw_framebuffer *
17201633 vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
1721− struct vmw_buffer_object *bo,
1634+ struct vmw_bo *bo,
17221635 struct vmw_surface *surface,
17231636 bool only_2d,
17241637 const struct drm_mode_fb_cmd2 *mode_cmd)
@@ -1765,9 +1678,6 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv, · 40 unmodified lines
17651678 if (ret)
17661679 return ERR_PTR(ret);
17671680
1768− vfb->pin = vmw_framebuffer_pin;
1769− vfb->unpin = vmw_framebuffer_unpin;
1770−
17711681 return vfb;
17721682 }
17731683
@@ -1782,7 +1692,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, · 8 unmodified lines
17821692 struct vmw_private *dev_priv = vmw_priv(dev);
17831693 struct vmw_framebuffer *vfb = NULL;
17841694 struct vmw_surface *surface = NULL;
1785− struct vmw_buffer_object *bo = NULL;
1695+ struct vmw_bo *bo = NULL;
17861696 int ret;
17871697
17881698 /* returns either a bo or surface */
@@ -1817,7 +1727,7 @@ err_out: · 28 unmodified lines
18171727 /* vmw_user_lookup_handle takes one ref so does new_fb */
18181728 if (bo) {
18191729 vmw_bo_unreference(&bo);
1820− drm_gem_object_put(&bo->base.base);
1730+ drm_gem_object_put(&bo->tbo.base);
18211731 }
18221732 if (surface)
18231733 vmw_surface_unreference(&surface);
@@ -3076,8 +2986,20 @@ int vmw_du_helper_plane_update(struct vmw_du_update_plane *update) · 1252 unmodified lines
30762986 struct vmw_framebuffer_bo *vfbbo =
30772987 container_of(update->vfb, typeof(*vfbbo), base);
30782988
3079− ret = vmw_validation_add_bo(&val_ctx, vfbbo->buffer, false,
3080− update->cpu_blit);
2989+ /*
2990+ * For screen targets we want a mappable bo, for everything else we want
2991+ * accelerated i.e. host backed (vram or gmr) bo. If the display unit
2992+ * is not screen target then mob's shouldn't be available.
2993+ */
2994+ if (update->dev_priv->active_display_unit == vmw_du_screen_target) {
2995+ vmw_bo_placement_set(vfbbo->buffer,
2996+ VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_GMR,
2997+ VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_GMR);
2998+ } else {
2999+ WARN_ON(update->dev_priv->has_mob);
3000+ vmw_bo_placement_set_default_accelerated(vfbbo->buffer);
3001+ }
3002+ ret = vmw_validation_add_bo(&val_ctx, vfbbo->buffer);
30813003 } else {
30823004 struct vmw_framebuffer_surface *vfbs =
30833005 container_of(update->vfb, typeof(*vfbs), base);
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h+18−25
@@ -1,7 +1,7 @@
11 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
22 /**************************************************************************
33 *
4− * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -126,7 +126,6 @@ struct vmw_du_update_plane { · 118 unmodified lines
126126 struct vmw_framebuffer *vfb;
127127 struct vmw_fence_obj **out_fence;
128128 struct mutex *mutex;
129− bool cpu_blit;
130129 bool intr;
131130 };
132131
@@ -217,8 +216,6 @@ struct vmw_kms_dirty { · 84 unmodified lines
217216 */
218217 struct vmw_framebuffer {
219218 struct drm_framebuffer base;
220− int (*pin)(struct vmw_framebuffer *fb);
221− int (*unpin)(struct vmw_framebuffer *fb);
222219 bool bo;
223220 uint32_t user_handle;
224221 };
@@ -233,7 +230,7 @@ struct vmw_clip_rect { · 8 unmodified lines
233230 struct vmw_framebuffer_surface {
234231 struct vmw_framebuffer base;
235232 struct vmw_surface *surface;
236− struct vmw_buffer_object *buffer;
233+ struct vmw_bo *buffer;
237234 struct list_head head;
238235 bool is_bo_proxy; /* true if this is proxy surface for DMA buf */
239236 };
@@ -241,7 +238,7 @@ struct vmw_framebuffer_surface { · 1 unmodified line
241238
242239 struct vmw_framebuffer_bo {
243240 struct vmw_framebuffer base;
244− struct vmw_buffer_object *buffer;
241+ struct vmw_bo *buffer;
245242 };
246243
247244
@@ -273,9 +270,7 @@ struct vmw_crtc_state { · 25 unmodified lines
273270 };
274271
275272 struct vmw_cursor_plane_state {
276− struct ttm_buffer_object *bo;
277− struct ttm_bo_kmap_obj map;
278− bool mapped;
273+ struct vmw_bo *bo;
279274 s32 hotspot_x;
280275 s32 hotspot_y;
281276 };
@@ -293,7 +288,7 @@ struct vmw_cursor_plane_state { · 11 unmodified lines
293288 struct vmw_plane_state {
294289 struct drm_plane_state base;
295290 struct vmw_surface *surf;
296− struct vmw_buffer_object *bo;
291+ struct vmw_bo *bo;
297292
298293 int content_fb_type;
299294 unsigned long bo_size;
@@ -346,7 +341,7 @@ struct vmw_connector_state { · 46 unmodified lines
346341 struct vmw_cursor_plane {
347342 struct drm_plane base;
348343
349− struct ttm_buffer_object *cursor_mobs[3];
344+ struct vmw_bo *cursor_mobs[3];
350345 };
351346
352347 /**
@@ -364,7 +359,7 @@ struct vmw_display_unit { · 11 unmodified lines
364359 struct vmw_cursor_plane cursor;
365360
366361 struct vmw_surface *cursor_surface;
367− struct vmw_buffer_object *cursor_bo;
362+ struct vmw_bo *cursor_bo;
368363 size_t cursor_age;
369364
370365 int cursor_x;
@@ -397,7 +392,7 @@ struct vmw_display_unit { · 26 unmodified lines
397392
398393 struct vmw_validation_ctx {
399394 struct vmw_resource *res;
400− struct vmw_buffer_object *buf;
395+ struct vmw_bo *buf;
401396 };
402397
403398 #define vmw_crtc_to_du(x) \
@@ -458,7 +453,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv, · 54 unmodified lines
458453 uint32_t num_clips);
459454 struct vmw_framebuffer *
460455 vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
461− struct vmw_buffer_object *bo,
456+ struct vmw_bo *bo,
462457 struct vmw_surface *surface,
463458 bool only_2d,
464459 const struct drm_mode_fb_cmd2 *mode_cmd);
@@ -566,17 +561,15 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv, · 101 unmodified lines
566561 unsigned num_clips, int inc,
567562 struct vmw_fence_obj **out_fence,
568563 struct drm_crtc *crtc);
569−int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
570− struct drm_file *file_priv,
571− struct vmw_framebuffer *vfb,
572− struct drm_vmw_fence_rep __user *user_fence_rep,
573− struct drm_clip_rect *clips,
574− struct drm_vmw_rect *vclips,
575− uint32_t num_clips,
576− int increment,
577− bool to_surface,
578− bool interruptible,
579− struct drm_crtc *crtc);
564+int vmw_kms_stdu_readback(struct vmw_private *dev_priv,
565+ struct drm_file *file_priv,
566+ struct vmw_framebuffer *vfb,
567+ struct drm_vmw_fence_rep __user *user_fence_rep,
568+ struct drm_clip_rect *clips,
569+ struct drm_vmw_rect *vclips,
570+ uint32_t num_clips,
571+ int increment,
572+ struct drm_crtc *crtc);
580573
581574 int vmw_du_helper_plane_update(struct vmw_du_update_plane *update);
582575
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c+49−8
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -25,11 +25,13 @@ · 17 unmodified lines
2525 *
2626 **************************************************************************/
2727
28+#include "vmwgfx_bo.h"
29+#include "vmwgfx_kms.h"
30+
2831 #include <drm/drm_atomic.h>
2932 #include <drm/drm_atomic_helper.h>
3033 #include <drm/drm_fourcc.h>
3134
32−#include "vmwgfx_kms.h"
3335
3436 #define vmw_crtc_to_ldu(x) \
3537 container_of(x, struct vmw_legacy_display_unit, base.crtc)
@@ -134,6 +136,47 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) · 98 unmodified lines
134136 return 0;
135137 }
136138
139+/*
140+ * Pin the buffer in a location suitable for access by the
141+ * display system.
142+ */
143+static int vmw_ldu_fb_pin(struct vmw_framebuffer *vfb)
144+{
145+ struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
146+ struct vmw_bo *buf;
147+ int ret;
148+
149+ buf = vfb->bo ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
150+ vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.guest_memory_bo;
151+
152+ if (!buf)
153+ return 0;
154+ WARN_ON(dev_priv->active_display_unit != vmw_du_legacy);
155+
156+ if (dev_priv->active_display_unit == vmw_du_legacy) {
157+ vmw_overlay_pause_all(dev_priv);
158+ ret = vmw_bo_pin_in_start_of_vram(dev_priv, buf, false);
159+ vmw_overlay_resume_all(dev_priv);
160+ } else
161+ ret = -EINVAL;
162+
163+ return ret;
164+}
165+
166+static int vmw_ldu_fb_unpin(struct vmw_framebuffer *vfb)
167+{
168+ struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
169+ struct vmw_bo *buf;
170+
171+ buf = vfb->bo ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
172+ vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.guest_memory_bo;
173+
174+ if (WARN_ON(!buf))
175+ return 0;
176+
177+ return vmw_bo_unpin(dev_priv, buf, false);
178+}
179+
137180 static int vmw_ldu_del_active(struct vmw_private *vmw_priv,
138181 struct vmw_legacy_display_unit *ldu)
139182 {
@@ -145,8 +188,7 @@ static int vmw_ldu_del_active(struct vmw_private *vmw_priv, · 5 unmodified lines
145188 list_del_init(&ldu->active);
146189 if (--(ld->num_active) == 0) {
147190 BUG_ON(!ld->fb);
148− if (ld->fb->unpin)
149− ld->fb->unpin(ld->fb);
191+ WARN_ON(vmw_ldu_fb_unpin(ld->fb));
150192 ld->fb = NULL;
151193 }
152194
@@ -163,11 +205,10 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv, · 10 unmodified lines
163205
164206 BUG_ON(!ld->num_active && ld->fb);
165207 if (vfb != ld->fb) {
166− if (ld->fb && ld->fb->unpin)
167− ld->fb->unpin(ld->fb);
208+ if (ld->fb)
209+ WARN_ON(vmw_ldu_fb_unpin(ld->fb));
168210 vmw_svga_enable(vmw_priv);
169− if (vfb->pin)
170− vfb->pin(vfb);
211+ WARN_ON(vmw_ldu_fb_pin(vfb));
171212 ld->fb = vfb;
172213 }
173214
drivers/gpu/drm/vmwgfx/vmwgfx_mob.c+24−21
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2012-2021 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2012-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -25,10 +25,11 @@ · 17 unmodified lines
2525 *
2626 **************************************************************************/
2727
28−#include <linux/highmem.h>
29−
28+#include "vmwgfx_bo.h"
3029 #include "vmwgfx_drv.h"
3130
31+#include <linux/highmem.h>
32+
3233 #ifdef CONFIG_64BIT
3334 #define VMW_PPN_SIZE 8
3435 #define VMW_MOBFMT_PTDEPTH_0 SVGA3D_MOBFMT_PT64_0
@@ -50,7 +51,7 @@ · 15 unmodified lines
5051 * @pt_root_page DMA address of the level 0 page of the page table.
5152 */
5253 struct vmw_mob {
53− struct ttm_buffer_object *pt_bo;
54+ struct vmw_bo *pt_bo;
5455 unsigned long num_pages;
5556 unsigned pt_level;
5657 dma_addr_t pt_root_page;
@@ -203,7 +204,7 @@ static void vmw_takedown_otable_base(struct vmw_private *dev_priv, · 146 unmodified lines
203204 if (otable->page_table == NULL)
204205 return;
205206
206− bo = otable->page_table->pt_bo;
207+ bo = &otable->page_table->pt_bo->tbo;
207208 cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
208209 if (unlikely(cmd == NULL))
209210 return;
@@ -251,7 +252,9 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv, · 41 unmodified lines
251252 bo_size += otables[i].size;
252253 }
253254
254− ret = vmw_bo_create_and_populate(dev_priv, bo_size, &batch->otable_bo);
255+ ret = vmw_bo_create_and_populate(dev_priv, bo_size,
256+ VMW_BO_DOMAIN_WAITABLE_SYS,
257+ &batch->otable_bo);
255258 if (unlikely(ret != 0))
256259 return ret;
257260
@@ -260,7 +263,8 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv, · 2 unmodified lines
260263 if (!batch->otables[i].enabled)
261264 continue;
262265
263− ret = vmw_setup_otable_base(dev_priv, i, batch->otable_bo,
266+ ret = vmw_setup_otable_base(dev_priv, i,
267+ &batch->otable_bo->tbo,
264268 offset,
265269 &otables[i]);
266270 if (unlikely(ret != 0))
@@ -277,8 +281,8 @@ out_no_setup: · 10 unmodified lines
277281 &batch->otables[i]);
278282 }
279283
280− vmw_bo_unpin_unlocked(batch->otable_bo);
281− ttm_bo_put(batch->otable_bo);
284+ vmw_bo_unpin_unlocked(&batch->otable_bo->tbo);
285+ ttm_bo_put(&batch->otable_bo->tbo);
282286 batch->otable_bo = NULL;
283287 return ret;
284288 }
@@ -329,7 +333,7 @@ static void vmw_otable_batch_takedown(struct vmw_private *dev_priv, · 44 unmodified lines
329333 struct vmw_otable_batch *batch)
330334 {
331335 SVGAOTableType i;
332− struct ttm_buffer_object *bo = batch->otable_bo;
336+ struct ttm_buffer_object *bo = &batch->otable_bo->tbo;
333337 int ret;
334338
335339 for (i = 0; i < batch->num_otables; ++i)
@@ -344,8 +348,7 @@ static void vmw_otable_batch_takedown(struct vmw_private *dev_priv, · 8 unmodified lines
344348 ttm_bo_unpin(bo);
345349 ttm_bo_unreserve(bo);
346350
347− ttm_bo_put(batch->otable_bo);
348− batch->otable_bo = NULL;
351+ vmw_bo_unreference(&batch->otable_bo);
349352 }
350353
351354 /*
@@ -413,7 +416,9 @@ static int vmw_mob_pt_populate(struct vmw_private *dev_priv, · 61 unmodified lines
413416 {
414417 BUG_ON(mob->pt_bo != NULL);
415418
416− return vmw_bo_create_and_populate(dev_priv, mob->num_pages * PAGE_SIZE, &mob->pt_bo);
419+ return vmw_bo_create_and_populate(dev_priv, mob->num_pages * PAGE_SIZE,
420+ VMW_BO_DOMAIN_WAITABLE_SYS,
421+ &mob->pt_bo);
417422 }
418423
419424 /**
@@ -494,7 +499,7 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob, · 74 unmodified lines
494499 unsigned long num_data_pages)
495500 {
496501 unsigned long num_pt_pages = 0;
497− struct ttm_buffer_object *bo = mob->pt_bo;
502+ struct ttm_buffer_object *bo = &mob->pt_bo->tbo;
498503 struct vmw_piter save_pt_iter = {0};
499504 struct vmw_piter pt_iter;
500505 const struct vmw_sg_table *vsgt;
@@ -531,9 +536,8 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob, · 30 unmodified lines
531536 void vmw_mob_destroy(struct vmw_mob *mob)
532537 {
533538 if (mob->pt_bo) {
534− vmw_bo_unpin_unlocked(mob->pt_bo);
535− ttm_bo_put(mob->pt_bo);
536− mob->pt_bo = NULL;
539+ vmw_bo_unpin_unlocked(&mob->pt_bo->tbo);
540+ vmw_bo_unreference(&mob->pt_bo);
537541 }
538542 kfree(mob);
539543 }
@@ -552,7 +556,7 @@ void vmw_mob_unbind(struct vmw_private *dev_priv, · 12 unmodified lines
552556 SVGA3dCmdDestroyGBMob body;
553557 } *cmd;
554558 int ret;
555− struct ttm_buffer_object *bo = mob->pt_bo;
559+ struct ttm_buffer_object *bo = &mob->pt_bo->tbo;
556560
557561 if (bo) {
558562 ret = ttm_bo_reserve(bo, false, true, NULL);
@@ -644,9 +648,8 @@ int vmw_mob_bind(struct vmw_private *dev_priv, · 85 unmodified lines
644648 out_no_cmd_space:
645649 vmw_fifo_resource_dec(dev_priv);
646650 if (pt_set_up) {
647− vmw_bo_unpin_unlocked(mob->pt_bo);
648− ttm_bo_put(mob->pt_bo);
649− mob->pt_bo = NULL;
651+ vmw_bo_unpin_unlocked(&mob->pt_bo->tbo);
652+ vmw_bo_unreference(&mob->pt_bo);
650653 }
651654
652655 return -ENOMEM;
drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c+11−11
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2014 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -24,19 +24,19 @@ · 16 unmodified lines
2424 * USE OR OTHER DEALINGS IN THE SOFTWARE.
2525 *
2626 **************************************************************************/
27−
28−#include <drm/ttm/ttm_placement.h>
27+#include "vmwgfx_bo.h"
28+#include "vmwgfx_drv.h"
2929
3030 #include "device_include/svga_overlay.h"
3131 #include "device_include/svga_escape.h"
3232
33−#include "vmwgfx_drv.h"
33+#include <drm/ttm/ttm_placement.h>
3434
3535 #define VMW_MAX_NUM_STREAMS 1
3636 #define VMW_OVERLAY_CAP_MASK (SVGA_FIFO_CAP_VIDEO | SVGA_FIFO_CAP_ESCAPE)
3737
3838 struct vmw_stream {
39− struct vmw_buffer_object *buf;
39+ struct vmw_bo *buf;
4040 bool claimed;
4141 bool paused;
4242 struct drm_vmw_control_stream_arg saved;
@@ -92,7 +92,7 @@ static inline void fill_flush(struct vmw_escape_video_flush *cmd, · 49 unmodified lines
9292 * -ERESTARTSYS if interrupted by a signal.
9393 */
9494 static int vmw_overlay_send_put(struct vmw_private *dev_priv,
95− struct vmw_buffer_object *buf,
95+ struct vmw_bo *buf,
9696 struct drm_vmw_control_stream_arg *arg,
9797 bool interruptible)
9898 {
@@ -140,7 +140,7 @@ static int vmw_overlay_send_put(struct vmw_private *dev_priv, · 41 unmodified lines
140140 for (i = 0; i < num_items; i++)
141141 items[i].registerId = i;
142142
143− vmw_bo_get_guest_ptr(&buf->base, &ptr);
143+ vmw_bo_get_guest_ptr(&buf->tbo, &ptr);
144144 ptr.offset += arg->offset;
145145
146146 items[SVGA_VIDEO_ENABLED].value = true;
@@ -223,7 +223,7 @@ static int vmw_overlay_send_stop(struct vmw_private *dev_priv, · 76 unmodified lines
223223 * used with GMRs instead of being locked to vram.
224224 */
225225 static int vmw_overlay_move_buffer(struct vmw_private *dev_priv,
226− struct vmw_buffer_object *buf,
226+ struct vmw_bo *buf,
227227 bool pin, bool inter)
228228 {
229229 if (!pin)
@@ -295,7 +295,7 @@ static int vmw_overlay_stop(struct vmw_private *dev_priv, · 65 unmodified lines
295295 * -ERESTARTSYS if interrupted.
296296 */
297297 static int vmw_overlay_update_stream(struct vmw_private *dev_priv,
298− struct vmw_buffer_object *buf,
298+ struct vmw_bo *buf,
299299 struct drm_vmw_control_stream_arg *arg,
300300 bool interruptible)
301301 {
@@ -433,7 +433,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void *data, · 131 unmodified lines
433433 struct vmw_overlay *overlay = dev_priv->overlay_priv;
434434 struct drm_vmw_control_stream_arg *arg =
435435 (struct drm_vmw_control_stream_arg *)data;
436− struct vmw_buffer_object *buf;
436+ struct vmw_bo *buf;
437437 struct vmw_resource *res;
438438 int ret;
439439
@@ -458,7 +458,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void *data, · 18 unmodified lines
458458 ret = vmw_overlay_update_stream(dev_priv, buf, arg, true);
459459
460460 vmw_bo_unreference(&buf);
461− drm_gem_object_put(&buf->base.base);
461+ drm_gem_object_put(&buf->tbo.base);
462462
463463 out_unlock:
464464 mutex_unlock(&overlay->mutex);
drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c+33−35
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2019 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2019-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -24,6 +24,7 @@ · 16 unmodified lines
2424 * USE OR OTHER DEALINGS IN THE SOFTWARE.
2525 *
2626 **************************************************************************/
27+#include "vmwgfx_bo.h"
2728 #include "vmwgfx_drv.h"
2829
2930 /*
@@ -78,11 +79,11 @@ struct vmw_bo_dirty { · 48 unmodified lines
7879 * dirty structure with the results. This function may change the
7980 * dirty-tracking method.
8081 */
81−static void vmw_bo_dirty_scan_pagetable(struct vmw_buffer_object *vbo)
82+static void vmw_bo_dirty_scan_pagetable(struct vmw_bo *vbo)
8283 {
8384 struct vmw_bo_dirty *dirty = vbo->dirty;
84− pgoff_t offset = drm_vma_node_start(&vbo->base.base.vma_node);
85− struct address_space *mapping = vbo->base.bdev->dev_mapping;
85+ pgoff_t offset = drm_vma_node_start(&vbo->tbo.base.vma_node);
86+ struct address_space *mapping = vbo->tbo.bdev->dev_mapping;
8687 pgoff_t num_marked;
8788
8889 num_marked = clean_record_shared_mapping_range
@@ -116,26 +117,25 @@ static void vmw_bo_dirty_scan_pagetable(struct vmw_buffer_object *vbo) · 27 unmodified lines
116117 *
117118 * This function may change the dirty-tracking method.
118119 */
119−static void vmw_bo_dirty_scan_mkwrite(struct vmw_buffer_object *vbo)
120+static void vmw_bo_dirty_scan_mkwrite(struct vmw_bo *vbo)
120121 {
121122 struct vmw_bo_dirty *dirty = vbo->dirty;
122− unsigned long offset = drm_vma_node_start(&vbo->base.base.vma_node);
123− struct address_space *mapping = vbo->base.bdev->dev_mapping;
123+ unsigned long offset = drm_vma_node_start(&vbo->tbo.base.vma_node);
124+ struct address_space *mapping = vbo->tbo.bdev->dev_mapping;
124125 pgoff_t num_marked;
125126
126127 if (dirty->end <= dirty->start)
127128 return;
128129
129− num_marked = wp_shared_mapping_range(vbo->base.bdev->dev_mapping,
130− dirty->start + offset,
131− dirty->end - dirty->start);
130+ num_marked = wp_shared_mapping_range(vbo->tbo.bdev->dev_mapping,
131+ dirty->start + offset,
132+ dirty->end - dirty->start);
132133
133134 if (100UL * num_marked / dirty->bitmap_size >
134− VMW_DIRTY_PERCENTAGE) {
135+ VMW_DIRTY_PERCENTAGE)
135136 dirty->change_count++;
136− } else {
137+ else
137138 dirty->change_count = 0;
138− }
139139
140140 if (dirty->change_count > VMW_DIRTY_NUM_CHANGE_TRIGGERS) {
141141 pgoff_t start = 0;
@@ -160,7 +160,7 @@ static void vmw_bo_dirty_scan_mkwrite(struct vmw_buffer_object *vbo) · 18 unmodified lines
160160 *
161161 * This function may change the dirty tracking method.
162162 */
163−void vmw_bo_dirty_scan(struct vmw_buffer_object *vbo)
163+void vmw_bo_dirty_scan(struct vmw_bo *vbo)
164164 {
165165 struct vmw_bo_dirty *dirty = vbo->dirty;
166166
@@ -181,12 +181,12 @@ void vmw_bo_dirty_scan(struct vmw_buffer_object *vbo) · 14 unmodified lines
181181 * when calling unmap_mapping_range(). This function makes sure we pick
182182 * up all dirty pages.
183183 */
184−static void vmw_bo_dirty_pre_unmap(struct vmw_buffer_object *vbo,
184+static void vmw_bo_dirty_pre_unmap(struct vmw_bo *vbo,
185185 pgoff_t start, pgoff_t end)
186186 {
187187 struct vmw_bo_dirty *dirty = vbo->dirty;
188− unsigned long offset = drm_vma_node_start(&vbo->base.base.vma_node);
189− struct address_space *mapping = vbo->base.bdev->dev_mapping;
188+ unsigned long offset = drm_vma_node_start(&vbo->tbo.base.vma_node);
189+ struct address_space *mapping = vbo->tbo.bdev->dev_mapping;
190190
191191 if (dirty->method != VMW_BO_DIRTY_PAGETABLE || start >= end)
192192 return;
@@ -206,11 +206,11 @@ static void vmw_bo_dirty_pre_unmap(struct vmw_buffer_object *vbo, · 13 unmodified lines
206206 *
207207 * This is similar to ttm_bo_unmap_virtual() except it takes a subrange.
208208 */
209−void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo,
209+void vmw_bo_dirty_unmap(struct vmw_bo *vbo,
210210 pgoff_t start, pgoff_t end)
211211 {
212− unsigned long offset = drm_vma_node_start(&vbo->base.base.vma_node);
213− struct address_space *mapping = vbo->base.bdev->dev_mapping;
212+ unsigned long offset = drm_vma_node_start(&vbo->tbo.base.vma_node);
213+ struct address_space *mapping = vbo->tbo.bdev->dev_mapping;
214214
215215 vmw_bo_dirty_pre_unmap(vbo, start, end);
216216 unmap_shared_mapping_range(mapping, (offset + start) << PAGE_SHIFT,
@@ -227,10 +227,10 @@ void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo, · 10 unmodified lines
227227 *
228228 * Return: Zero on success, -ENOMEM on memory allocation failure.
229229 */
230−int vmw_bo_dirty_add(struct vmw_buffer_object *vbo)
230+int vmw_bo_dirty_add(struct vmw_bo *vbo)
231231 {
232232 struct vmw_bo_dirty *dirty = vbo->dirty;
233− pgoff_t num_pages = PFN_UP(vbo->base.resource->size);
233+ pgoff_t num_pages = PFN_UP(vbo->tbo.resource->size);
234234 size_t size;
235235 int ret;
236236
@@ -253,8 +253,8 @@ int vmw_bo_dirty_add(struct vmw_buffer_object *vbo) · 16 unmodified lines
253253 if (num_pages < PAGE_SIZE / sizeof(pte_t)) {
254254 dirty->method = VMW_BO_DIRTY_PAGETABLE;
255255 } else {
256− struct address_space *mapping = vbo->base.bdev->dev_mapping;
257− pgoff_t offset = drm_vma_node_start(&vbo->base.base.vma_node);
256+ struct address_space *mapping = vbo->tbo.bdev->dev_mapping;
257+ pgoff_t offset = drm_vma_node_start(&vbo->tbo.base.vma_node);
258258
259259 dirty->method = VMW_BO_DIRTY_MKWRITE;
260260
@@ -284,7 +284,7 @@ out_no_dirty: · 23 unmodified lines
284284 *
285285 * Return: Zero on success, -ENOMEM on memory allocation failure.
286286 */
287−void vmw_bo_dirty_release(struct vmw_buffer_object *vbo)
287+void vmw_bo_dirty_release(struct vmw_bo *vbo)
288288 {
289289 struct vmw_bo_dirty *dirty = vbo->dirty;
290290
@@ -306,11 +306,11 @@ void vmw_bo_dirty_release(struct vmw_buffer_object *vbo) · 15 unmodified lines
306306 */
307307 void vmw_bo_dirty_transfer_to_res(struct vmw_resource *res)
308308 {
309− struct vmw_buffer_object *vbo = res->backup;
309+ struct vmw_bo *vbo = res->guest_memory_bo;
310310 struct vmw_bo_dirty *dirty = vbo->dirty;
311311 pgoff_t start, cur, end;
312− unsigned long res_start = res->backup_offset;
313− unsigned long res_end = res->backup_offset + res->backup_size;
312+ unsigned long res_start = res->guest_memory_offset;
313+ unsigned long res_end = res->guest_memory_offset + res->guest_memory_size;
314314
315315 WARN_ON_ONCE(res_start & ~PAGE_MASK);
316316 res_start >>= PAGE_SHIFT;
@@ -351,9 +351,9 @@ void vmw_bo_dirty_transfer_to_res(struct vmw_resource *res) · 34 unmodified lines
351351 */
352352 void vmw_bo_dirty_clear_res(struct vmw_resource *res)
353353 {
354− unsigned long res_start = res->backup_offset;
355− unsigned long res_end = res->backup_offset + res->backup_size;
356− struct vmw_buffer_object *vbo = res->backup;
354+ unsigned long res_start = res->guest_memory_offset;
355+ unsigned long res_end = res->guest_memory_offset + res->guest_memory_size;
356+ struct vmw_bo *vbo = res->guest_memory_bo;
357357 struct vmw_bo_dirty *dirty = vbo->dirty;
358358
359359 res_start >>= PAGE_SHIFT;
@@ -380,8 +380,7 @@ vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf) · 20 unmodified lines
380380 vm_fault_t ret;
381381 unsigned long page_offset;
382382 unsigned int save_flags;
383− struct vmw_buffer_object *vbo =
384− container_of(bo, typeof(*vbo), base);
383+ struct vmw_bo *vbo = to_vmw_bo(&bo->base);
385384
386385 /*
387386 * mkwrite() doesn't handle the VM_FAULT_RETRY return value correctly.
@@ -419,8 +418,7 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf) · 31 unmodified lines
419418 struct vm_area_struct *vma = vmf->vma;
420419 struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
421420 vma->vm_private_data;
422− struct vmw_buffer_object *vbo =
423− container_of(bo, struct vmw_buffer_object, base);
421+ struct vmw_bo *vbo = to_vmw_bo(&bo->base);
424422 pgoff_t num_prefault;
425423 pgprot_t prot;
426424 vm_fault_t ret;
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c+128−118
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -27,9 +27,10 @@ · 19 unmodified lines
2727
2828 #include <drm/ttm/ttm_placement.h>
2929
30−#include "vmwgfx_resource_priv.h"
3130 #include "vmwgfx_binding.h"
31+#include "vmwgfx_bo.h"
3232 #include "vmwgfx_drv.h"
33+#include "vmwgfx_resource_priv.h"
3334
3435 #define VMW_RES_EVICT_ERR_COUNT 10
3536
@@ -39,10 +40,10 @@ · 3 unmodified lines
3940 */
4041 void vmw_resource_mob_attach(struct vmw_resource *res)
4142 {
42− struct vmw_buffer_object *backup = res->backup;
43− struct rb_node **new = &backup->res_tree.rb_node, *parent = NULL;
43+ struct vmw_bo *gbo = res->guest_memory_bo;
44+ struct rb_node **new = &gbo->res_tree.rb_node, *parent = NULL;
4445
45− dma_resv_assert_held(res->backup->base.base.resv);
46+ dma_resv_assert_held(gbo->tbo.base.resv);
4647 res->used_prio = (res->res_dirty) ? res->func->dirty_prio :
4748 res->func->prio;
4849
@@ -51,14 +52,14 @@ void vmw_resource_mob_attach(struct vmw_resource *res) · 2 unmodified lines
5152 container_of(*new, struct vmw_resource, mob_node);
5253
5354 parent = *new;
54− new = (res->backup_offset < this->backup_offset) ?
55+ new = (res->guest_memory_offset < this->guest_memory_offset) ?
5556 &((*new)->rb_left) : &((*new)->rb_right);
5657 }
5758
5859 rb_link_node(&res->mob_node, parent, new);
59− rb_insert_color(&res->mob_node, &backup->res_tree);
60+ rb_insert_color(&res->mob_node, &gbo->res_tree);
6061
61− vmw_bo_prio_add(backup, res->used_prio);
62+ vmw_bo_prio_add(gbo, res->used_prio);
6263 }
6364
6465 /**
@@ -67,13 +68,13 @@ void vmw_resource_mob_attach(struct vmw_resource *res) · 2 unmodified lines
6768 */
6869 void vmw_resource_mob_detach(struct vmw_resource *res)
6970 {
70− struct vmw_buffer_object *backup = res->backup;
71+ struct vmw_bo *gbo = res->guest_memory_bo;
7172
72− dma_resv_assert_held(backup->base.base.resv);
73+ dma_resv_assert_held(gbo->tbo.base.resv);
7374 if (vmw_resource_mob_attached(res)) {
74− rb_erase(&res->mob_node, &backup->res_tree);
75+ rb_erase(&res->mob_node, &gbo->res_tree);
7576 RB_CLEAR_NODE(&res->mob_node);
76− vmw_bo_prio_del(backup, res->used_prio);
77+ vmw_bo_prio_del(gbo, res->used_prio);
7778 }
7879 }
7980
@@ -120,8 +121,8 @@ static void vmw_resource_release(struct kref *kref) · 40 unmodified lines
120121 spin_lock(&dev_priv->resource_lock);
121122 list_del_init(&res->lru_head);
122123 spin_unlock(&dev_priv->resource_lock);
123− if (res->backup) {
124− struct ttm_buffer_object *bo = &res->backup->base;
124+ if (res->guest_memory_bo) {
125+ struct ttm_buffer_object *bo = &res->guest_memory_bo->tbo;
125126
126127 ret = ttm_bo_reserve(bo, false, false, NULL);
127128 BUG_ON(ret);
@@ -133,14 +134,14 @@ static void vmw_resource_release(struct kref *kref) · 5 unmodified lines
133134 val_buf.num_shared = 0;
134135 res->func->unbind(res, false, &val_buf);
135136 }
136− res->backup_dirty = false;
137+ res->guest_memory_size = false;
137138 vmw_resource_mob_detach(res);
138139 if (res->dirty)
139140 res->func->dirty_free(res);
140141 if (res->coherent)
141− vmw_bo_dirty_release(res->backup);
142+ vmw_bo_dirty_release(res->guest_memory_bo);
142143 ttm_bo_unreserve(bo);
143− vmw_bo_unreference(&res->backup);
144+ vmw_bo_unreference(&res->guest_memory_bo);
144145 }
145146
146147 if (likely(res->hw_destroy != NULL)) {
@@ -223,9 +224,9 @@ int vmw_resource_init(struct vmw_private *dev_priv, struct vmw_resource *res, · 76 unmodified lines
223224 INIT_LIST_HEAD(&res->lru_head);
224225 INIT_LIST_HEAD(&res->binding_head);
225226 res->id = -1;
226− res->backup = NULL;
227− res->backup_offset = 0;
228− res->backup_dirty = false;
227+ res->guest_memory_bo = NULL;
228+ res->guest_memory_offset = 0;
229+ res->guest_memory_dirty = false;
229230 res->res_dirty = false;
230231 res->coherent = false;
231232 res->used_prio = 3;
@@ -263,7 +264,7 @@ int vmw_user_resource_lookup_handle(struct vmw_private *dev_priv, · 31 unmodified lines
263264 int ret = -EINVAL;
264265
265266 base = ttm_base_object_lookup(tfile, handle);
266− if (unlikely(base == NULL))
267+ if (unlikely(!base))
267268 return -EINVAL;
268269
269270 if (unlikely(ttm_base_object_type(base) != converter->object_type))
@@ -290,7 +291,7 @@ int vmw_user_lookup_handle(struct vmw_private *dev_priv, · 20 unmodified lines
290291 struct drm_file *filp,
291292 uint32_t handle,
292293 struct vmw_surface **out_surf,
293− struct vmw_buffer_object **out_buf)
294+ struct vmw_bo **out_buf)
294295 {
295296 struct ttm_object_file *tfile = vmw_fpriv(filp)->tfile;
296297 struct vmw_resource *res;
@@ -312,32 +313,36 @@ int vmw_user_lookup_handle(struct vmw_private *dev_priv, · 15 unmodified lines
312313 }
313314
314315 /**
315− * vmw_resource_buf_alloc - Allocate a backup buffer for a resource.
316+ * vmw_resource_buf_alloc - Allocate a guest memory buffer for a resource.
316317 *
317− * @res: The resource for which to allocate a backup buffer.
318+ * @res: The resource for which to allocate a gbo buffer.
318319 * @interruptible: Whether any sleeps during allocation should be
319320 * performed while interruptible.
320321 */
321322 static int vmw_resource_buf_alloc(struct vmw_resource *res,
322323 bool interruptible)
323324 {
324− unsigned long size = PFN_ALIGN(res->backup_size);
325− struct vmw_buffer_object *backup;
325+ unsigned long size = PFN_ALIGN(res->guest_memory_size);
326+ struct vmw_bo *gbo;
327+ struct vmw_bo_params bo_params = {
328+ .domain = res->func->domain,
329+ .busy_domain = res->func->busy_domain,
330+ .bo_type = ttm_bo_type_device,
331+ .size = res->guest_memory_size,
332+ .pin = false
333+ };
326334 int ret;
327335
328− if (likely(res->backup)) {
329− BUG_ON(res->backup->base.base.size < size);
336+ if (likely(res->guest_memory_bo)) {
337+ BUG_ON(res->guest_memory_bo->tbo.base.size < size);
330338 return 0;
331339 }
332340
333− ret = vmw_bo_create(res->dev_priv, res->backup_size,
334− res->func->backup_placement,
335− interruptible, false,
336− &vmw_bo_bo_free, &backup);
341+ ret = vmw_bo_create(res->dev_priv, &bo_params, &gbo);
337342 if (unlikely(ret != 0))
338343 goto out_no_bo;
339344
340− res->backup = backup;
345+ res->guest_memory_bo = gbo;
341346
342347 out_no_bo:
343348 return ret;
@@ -369,13 +374,13 @@ static int vmw_resource_do_validate(struct vmw_resource *res, · 25 unmodified lines
369374 }
370375
371376 if (func->bind &&
372− ((func->needs_backup && !vmw_resource_mob_attached(res) &&
373− val_buf->bo != NULL) ||
374− (!func->needs_backup && val_buf->bo != NULL))) {
377+ ((func->needs_guest_memory && !vmw_resource_mob_attached(res) &&
378+ val_buf->bo) ||
379+ (!func->needs_guest_memory && val_buf->bo))) {
375380 ret = func->bind(res, val_buf);
376381 if (unlikely(ret != 0))
377382 goto out_bind_failed;
378− if (func->needs_backup)
383+ if (func->needs_guest_memory)
379384 vmw_resource_mob_attach(res);
380385 }
381386
@@ -385,11 +390,11 @@ static int vmw_resource_do_validate(struct vmw_resource *res, · 3 unmodified lines
385390 */
386391 if (func->dirty_alloc && vmw_resource_mob_attached(res) &&
387392 !res->coherent) {
388− if (res->backup->dirty && !res->dirty) {
393+ if (res->guest_memory_bo->dirty && !res->dirty) {
389394 ret = func->dirty_alloc(res);
390395 if (ret)
391396 return ret;
392− } else if (!res->backup->dirty && res->dirty) {
397+ } else if (!res->guest_memory_bo->dirty && res->dirty) {
393398 func->dirty_free(res);
394399 }
395400 }
@@ -400,12 +405,12 @@ static int vmw_resource_do_validate(struct vmw_resource *res, · 4 unmodified lines
400405 */
401406 if (res->dirty) {
402407 if (dirtying && !res->res_dirty) {
403− pgoff_t start = res->backup_offset >> PAGE_SHIFT;
408+ pgoff_t start = res->guest_memory_offset >> PAGE_SHIFT;
404409 pgoff_t end = __KERNEL_DIV_ROUND_UP
405− (res->backup_offset + res->backup_size,
410+ (res->guest_memory_offset + res->guest_memory_size,
406411 PAGE_SIZE);
407412
408− vmw_bo_dirty_unmap(res->backup, start, end);
413+ vmw_bo_dirty_unmap(res->guest_memory_bo, start, end);
409414 }
410415
411416 vmw_bo_dirty_transfer_to_res(res);
@@ -427,10 +432,10 @@ out_bind_failed: · 15 unmodified lines
427432 * @res: Pointer to the struct vmw_resource to unreserve.
428433 * @dirty_set: Change dirty status of the resource.
429434 * @dirty: When changing dirty status indicates the new status.
430− * @switch_backup: Backup buffer has been switched.
431− * @new_backup: Pointer to new backup buffer if command submission
435+ * @switch_guest_memory: Guest memory buffer has been switched.
436+ * @new_guest_memory_bo: Pointer to new guest memory buffer if command submission
432437 * switched. May be NULL.
433− * @new_backup_offset: New backup offset if @switch_backup is true.
438+ * @new_guest_memory_offset: New gbo offset if @switch_guest_memory is true.
434439 *
435440 * Currently unreserving a resource means putting it back on the device's
436441 * resource lru list, so that it can be evicted if necessary.
@@ -438,42 +443,42 @@ out_bind_failed: · 1 unmodified line
438443 void vmw_resource_unreserve(struct vmw_resource *res,
439444 bool dirty_set,
440445 bool dirty,
441− bool switch_backup,
442− struct vmw_buffer_object *new_backup,
443− unsigned long new_backup_offset)
446+ bool switch_guest_memory,
447+ struct vmw_bo *new_guest_memory_bo,
448+ unsigned long new_guest_memory_offset)
444449 {
445450 struct vmw_private *dev_priv = res->dev_priv;
446451
447452 if (!list_empty(&res->lru_head))
448453 return;
449454
450− if (switch_backup && new_backup != res->backup) {
451− if (res->backup) {
455+ if (switch_guest_memory && new_guest_memory_bo != res->guest_memory_bo) {
456+ if (res->guest_memory_bo) {
452457 vmw_resource_mob_detach(res);
453458 if (res->coherent)
454− vmw_bo_dirty_release(res->backup);
455− vmw_bo_unreference(&res->backup);
459+ vmw_bo_dirty_release(res->guest_memory_bo);
460+ vmw_bo_unreference(&res->guest_memory_bo);
456461 }
457462
458− if (new_backup) {
459− res->backup = vmw_bo_reference(new_backup);
463+ if (new_guest_memory_bo) {
464+ res->guest_memory_bo = vmw_bo_reference(new_guest_memory_bo);
460465
461466 /*
462467 * The validation code should already have added a
463468 * dirty tracker here.
464469 */
465− WARN_ON(res->coherent && !new_backup->dirty);
470+ WARN_ON(res->coherent && !new_guest_memory_bo->dirty);
466471
467472 vmw_resource_mob_attach(res);
468473 } else {
469− res->backup = NULL;
474+ res->guest_memory_bo = NULL;
470475 }
471− } else if (switch_backup && res->coherent) {
472− vmw_bo_dirty_release(res->backup);
476+ } else if (switch_guest_memory && res->coherent) {
477+ vmw_bo_dirty_release(res->guest_memory_bo);
473478 }
474479
475− if (switch_backup)
476− res->backup_offset = new_backup_offset;
480+ if (switch_guest_memory)
481+ res->guest_memory_offset = new_guest_memory_offset;
477482
478483 if (dirty_set)
479484 res->res_dirty = dirty;
@@ -507,30 +512,32 @@ vmw_resource_check_buffer(struct ww_acquire_ctx *ticket, · 27 unmodified lines
507512 {
508513 struct ttm_operation_ctx ctx = { true, false };
509514 struct list_head val_list;
510− bool backup_dirty = false;
515+ bool guest_memory_dirty = false;
511516 int ret;
512517
513− if (unlikely(res->backup == NULL)) {
518+ if (unlikely(!res->guest_memory_bo)) {
514519 ret = vmw_resource_buf_alloc(res, interruptible);
515520 if (unlikely(ret != 0))
516521 return ret;
517522 }
518523
519524 INIT_LIST_HEAD(&val_list);
520− ttm_bo_get(&res->backup->base);
521− val_buf->bo = &res->backup->base;
525+ ttm_bo_get(&res->guest_memory_bo->tbo);
526+ val_buf->bo = &res->guest_memory_bo->tbo;
522527 val_buf->num_shared = 0;
523528 list_add_tail(&val_buf->head, &val_list);
524529 ret = ttm_eu_reserve_buffers(ticket, &val_list, interruptible, NULL);
525530 if (unlikely(ret != 0))
526531 goto out_no_reserve;
527532
528− if (res->func->needs_backup && !vmw_resource_mob_attached(res))
533+ if (res->func->needs_guest_memory && !vmw_resource_mob_attached(res))
529534 return 0;
530535
531− backup_dirty = res->backup_dirty;
532− ret = ttm_bo_validate(&res->backup->base,
533− res->func->backup_placement,
536+ guest_memory_dirty = res->guest_memory_dirty;
537+ vmw_bo_placement_set(res->guest_memory_bo, res->func->domain,
538+ res->func->busy_domain);
539+ ret = ttm_bo_validate(&res->guest_memory_bo->tbo,
540+ &res->guest_memory_bo->placement,
534541 &ctx);
535542
536543 if (unlikely(ret != 0))
@@ -543,8 +550,8 @@ out_no_validate: · 6 unmodified lines
543550 out_no_reserve:
544551 ttm_bo_put(val_buf->bo);
545552 val_buf->bo = NULL;
546− if (backup_dirty)
547− vmw_bo_unreference(&res->backup);
553+ if (guest_memory_dirty)
554+ vmw_bo_unreference(&res->guest_memory_bo);
548555
549556 return ret;
550557 }
@@ -555,12 +562,13 @@ out_no_reserve: · 4 unmodified lines
555562 * @res: The resource to reserve.
556563 *
557564 * This function takes the resource off the LRU list and make sure
558− * a backup buffer is present for guest-backed resources. However,
559− * the buffer may not be bound to the resource at this point.
565+ * a guest memory buffer is present for guest-backed resources.
566+ * However, the buffer may not be bound to the resource at this
567+ * point.
560568 *
561569 */
562570 int vmw_resource_reserve(struct vmw_resource *res, bool interruptible,
563− bool no_backup)
571+ bool no_guest_memory)
564572 {
565573 struct vmw_private *dev_priv = res->dev_priv;
566574 int ret;
@@ -569,13 +577,13 @@ int vmw_resource_reserve(struct vmw_resource *res, bool interruptible, · 2 unmodified lines
569577 list_del_init(&res->lru_head);
570578 spin_unlock(&dev_priv->resource_lock);
571579
572− if (res->func->needs_backup && res->backup == NULL &&
573− !no_backup) {
580+ if (res->func->needs_guest_memory && !res->guest_memory_bo &&
581+ !no_guest_memory) {
574582 ret = vmw_resource_buf_alloc(res, interruptible);
575583 if (unlikely(ret != 0)) {
576− DRM_ERROR("Failed to allocate a backup buffer "
584+ DRM_ERROR("Failed to allocate a guest memory buffer "
577585 "of size %lu. bytes\n",
578− (unsigned long) res->backup_size);
586+ (unsigned long) res->guest_memory_size);
579587 return ret;
580588 }
581589 }
@@ -585,10 +593,10 @@ int vmw_resource_reserve(struct vmw_resource *res, bool interruptible, · 3 unmodified lines
585593
586594 /**
587595 * vmw_resource_backoff_reservation - Unreserve and unreference a
588− * backup buffer
596+ * guest memory buffer
589597 *.
590598 * @ticket: The ww acquire ctx used for reservation.
591− * @val_buf: Backup buffer information.
599+ * @val_buf: Guest memory buffer information.
592600 */
593601 static void
594602 vmw_resource_backoff_reservation(struct ww_acquire_ctx *ticket,
@@ -630,14 +638,14 @@ static int vmw_resource_do_evict(struct ww_acquire_ctx *ticket, · 35 unmodified lines
630638 return ret;
631639
632640 if (unlikely(func->unbind != NULL &&
633− (!func->needs_backup || vmw_resource_mob_attached(res)))) {
641+ (!func->needs_guest_memory || vmw_resource_mob_attached(res)))) {
634642 ret = func->unbind(res, res->res_dirty, &val_buf);
635643 if (unlikely(ret != 0))
636644 goto out_no_unbind;
637645 vmw_resource_mob_detach(res);
638646 }
639647 ret = func->destroy(res);
640− res->backup_dirty = true;
648+ res->guest_memory_dirty = true;
641649 res->res_dirty = false;
642650 out_no_unbind:
643651 vmw_resource_backoff_reservation(ticket, &val_buf);
@@ -676,8 +684,8 @@ int vmw_resource_validate(struct vmw_resource *res, bool intr, · 32 unmodified lines
676684
677685 val_buf.bo = NULL;
678686 val_buf.num_shared = 0;
679− if (res->backup)
680− val_buf.bo = &res->backup->base;
687+ if (res->guest_memory_bo)
688+ val_buf.bo = &res->guest_memory_bo->tbo;
681689 do {
682690 ret = vmw_resource_do_validate(res, &val_buf, dirtying);
683691 if (likely(ret != -EBUSY))
@@ -717,9 +725,9 @@ int vmw_resource_validate(struct vmw_resource *res, bool intr, · 33 unmodified lines
717725
718726 if (unlikely(ret != 0))
719727 goto out_no_validate;
720− else if (!res->func->needs_backup && res->backup) {
728+ else if (!res->func->needs_guest_memory && res->guest_memory_bo) {
721729 WARN_ON_ONCE(vmw_resource_mob_attached(res));
722− vmw_bo_unreference(&res->backup);
730+ vmw_bo_unreference(&res->guest_memory_bo);
723731 }
724732
725733 return 0;
@@ -740,14 +748,14 @@ out_no_validate: · 14 unmodified lines
740748 * validation code, since resource validation and eviction
741749 * both require the backup buffer to be reserved.
742750 */
743−void vmw_resource_unbind_list(struct vmw_buffer_object *vbo)
751+void vmw_resource_unbind_list(struct vmw_bo *vbo)
744752 {
745753 struct ttm_validate_buffer val_buf = {
746− .bo = &vbo->base,
754+ .bo = &vbo->tbo,
747755 .num_shared = 0
748756 };
749757
750− dma_resv_assert_held(vbo->base.base.resv);
758+ dma_resv_assert_held(vbo->tbo.base.resv);
751759 while (!RB_EMPTY_ROOT(&vbo->res_tree)) {
752760 struct rb_node *node = vbo->res_tree.rb_node;
753761 struct vmw_resource *res =
@@ -756,12 +764,12 @@ void vmw_resource_unbind_list(struct vmw_buffer_object *vbo) · 2 unmodified lines
756764 if (!WARN_ON_ONCE(!res->func->unbind))
757765 (void) res->func->unbind(res, res->res_dirty, &val_buf);
758766
759− res->backup_dirty = true;
767+ res->guest_memory_size = true;
760768 res->res_dirty = false;
761769 vmw_resource_mob_detach(res);
762770 }
763771
764− (void) ttm_bo_wait(&vbo->base, false, false);
772+ (void) ttm_bo_wait(&vbo->tbo, false, false);
765773 }
766774
767775
@@ -773,7 +781,7 @@ void vmw_resource_unbind_list(struct vmw_buffer_object *vbo) · 5 unmodified lines
773781 * Read back cached states from the device if they exist. This function
774782 * assumes binding_mutex is held.
775783 */
776−int vmw_query_readback_all(struct vmw_buffer_object *dx_query_mob)
784+int vmw_query_readback_all(struct vmw_bo *dx_query_mob)
777785 {
778786 struct vmw_resource *dx_query_ctx;
779787 struct vmw_private *dev_priv;
@@ -822,20 +830,19 @@ void vmw_query_move_notify(struct ttm_buffer_object *bo, · 42 unmodified lines
822830 struct ttm_resource *old_mem,
823831 struct ttm_resource *new_mem)
824832 {
825− struct vmw_buffer_object *dx_query_mob;
833+ struct vmw_bo *dx_query_mob;
826834 struct ttm_device *bdev = bo->bdev;
827− struct vmw_private *dev_priv;
828−
829− dev_priv = container_of(bdev, struct vmw_private, bdev);
835+ struct vmw_private *dev_priv = vmw_priv_from_ttm(bdev);
830836
831837 mutex_lock(&dev_priv->binding_mutex);
832838
833839 /* If BO is being moved from MOB to system memory */
834− if (new_mem->mem_type == TTM_PL_SYSTEM &&
840+ if (old_mem &&
841+ new_mem->mem_type == TTM_PL_SYSTEM &&
835842 old_mem->mem_type == VMW_PL_MOB) {
836843 struct vmw_fence_obj *fence;
837844
838− dx_query_mob = container_of(bo, struct vmw_buffer_object, base);
845+ dx_query_mob = to_vmw_bo(&bo->base);
839846 if (!dx_query_mob || !dx_query_mob->dx_query_ctx) {
840847 mutex_unlock(&dev_priv->binding_mutex);
841848 return;
@@ -863,7 +870,7 @@ void vmw_query_move_notify(struct ttm_buffer_object *bo, · 21 unmodified lines
863870 */
864871 bool vmw_resource_needs_backup(const struct vmw_resource *res)
865872 {
866− return res->func->needs_backup;
873+ return res->func->needs_guest_memory;
867874 }
868875
869876 /**
@@ -959,21 +966,24 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible) · 89 unmodified lines
959966 goto out_no_reserve;
960967
961968 if (res->pin_count == 0) {
962− struct vmw_buffer_object *vbo = NULL;
969+ struct vmw_bo *vbo = NULL;
963970
964− if (res->backup) {
965− vbo = res->backup;
971+ if (res->guest_memory_bo) {
972+ vbo = res->guest_memory_bo;
966973
967− ret = ttm_bo_reserve(&vbo->base, interruptible, false, NULL);
974+ ret = ttm_bo_reserve(&vbo->tbo, interruptible, false, NULL);
968975 if (ret)
969976 goto out_no_validate;
970− if (!vbo->base.pin_count) {
977+ if (!vbo->tbo.pin_count) {
978+ vmw_bo_placement_set(vbo,
979+ res->func->domain,
980+ res->func->busy_domain);
971981 ret = ttm_bo_validate
972− (&vbo->base,
973− res->func->backup_placement,
982+ (&vbo->tbo,
983+ &vbo->placement,
974984 &ctx);
975985 if (ret) {
976− ttm_bo_unreserve(&vbo->base);
986+ ttm_bo_unreserve(&vbo->tbo);
977987 goto out_no_validate;
978988 }
979989 }
@@ -983,7 +993,7 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible) · 3 unmodified lines
983993 }
984994 ret = vmw_resource_validate(res, interruptible, true);
985995 if (vbo)
986− ttm_bo_unreserve(&vbo->base);
996+ ttm_bo_unreserve(&vbo->tbo);
987997 if (ret)
988998 goto out_no_validate;
989999 }
@@ -1016,12 +1026,12 @@ void vmw_resource_unpin(struct vmw_resource *res) · 26 unmodified lines
10161026 WARN_ON(ret);
10171027
10181028 WARN_ON(res->pin_count == 0);
1019− if (--res->pin_count == 0 && res->backup) {
1020− struct vmw_buffer_object *vbo = res->backup;
1029+ if (--res->pin_count == 0 && res->guest_memory_bo) {
1030+ struct vmw_bo *vbo = res->guest_memory_bo;
10211031
1022− (void) ttm_bo_reserve(&vbo->base, false, false, NULL);
1032+ (void) ttm_bo_reserve(&vbo->tbo, false, false, NULL);
10231033 vmw_bo_pin_reserved(vbo, false);
1024− ttm_bo_unreserve(&vbo->base);
1034+ ttm_bo_unreserve(&vbo->tbo);
10251035 }
10261036
10271037 vmw_resource_unreserve(res, false, false, false, NULL, 0UL);
@@ -1062,7 +1072,7 @@ void vmw_resource_dirty_update(struct vmw_resource *res, pgoff_t start, · 34 unmodified lines
10621072 * @num_prefault: Returns how many pages including the first have been
10631073 * cleaned and are ok to prefault
10641074 */
1065−int vmw_resources_clean(struct vmw_buffer_object *vbo, pgoff_t start,
1075+int vmw_resources_clean(struct vmw_bo *vbo, pgoff_t start,
10661076 pgoff_t end, pgoff_t *num_prefault)
10671077 {
10681078 struct rb_node *cur = vbo->res_tree.rb_node;
@@ -1079,9 +1089,9 @@ int vmw_resources_clean(struct vmw_buffer_object *vbo, pgoff_t start, · 10 unmodified lines
10791089 struct vmw_resource *cur_res =
10801090 container_of(cur, struct vmw_resource, mob_node);
10811091
1082− if (cur_res->backup_offset >= res_end) {
1092+ if (cur_res->guest_memory_offset >= res_end) {
10831093 cur = cur->rb_left;
1084− } else if (cur_res->backup_offset + cur_res->backup_size <=
1094+ } else if (cur_res->guest_memory_offset + cur_res->guest_memory_size <=
10851095 res_start) {
10861096 cur = cur->rb_right;
10871097 } else {
@@ -1092,7 +1102,7 @@ int vmw_resources_clean(struct vmw_buffer_object *vbo, pgoff_t start, · 4 unmodified lines
10921102 }
10931103
10941104 /*
1095− * In order of increasing backup_offset, clean dirty resources
1105+ * In order of increasing guest_memory_offset, clean dirty resources
10961106 * intersecting the range.
10971107 */
10981108 while (found) {
@@ -1108,13 +1118,13 @@ int vmw_resources_clean(struct vmw_buffer_object *vbo, pgoff_t start, · 9 unmodified lines
11081118
11091119 found->res_dirty = false;
11101120 }
1111− last_cleaned = found->backup_offset + found->backup_size;
1121+ last_cleaned = found->guest_memory_offset + found->guest_memory_size;
11121122 cur = rb_next(&found->mob_node);
11131123 if (!cur)
11141124 break;
11151125
11161126 found = container_of(cur, struct vmw_resource, mob_node);
1117− if (found->backup_offset >= res_end)
1127+ if (found->guest_memory_offset >= res_end)
11181128 break;
11191129 }
11201130
@@ -1123,7 +1133,7 @@ int vmw_resources_clean(struct vmw_buffer_object *vbo, pgoff_t start, · 2 unmodified lines
11231133 */
11241134 *num_prefault = 1;
11251135 if (last_cleaned > res_start) {
1126− struct ttm_buffer_object *bo = &vbo->base;
1136+ struct ttm_buffer_object *bo = &vbo->tbo;
11271137
11281138 *num_prefault = __KERNEL_DIV_ROUND_UP(last_cleaned - res_start,
11291139 PAGE_SIZE);
drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h+6−4
@@ -58,10 +58,11 @@ struct vmw_user_resource_conv { · 57 unmodified lines
5858 * struct vmw_res_func - members and functions common for a resource type
5959 *
6060 * @res_type: Enum that identifies the lru list to use for eviction.
61− * @needs_backup: Whether the resource is guest-backed and needs
61+ * @needs_guest_memory:Whether the resource is guest-backed and needs
6262 * persistent buffer storage.
6363 * @type_name: String that identifies the resource type.
64− * @backup_placement: TTM placement for backup buffers.
64+ * @domain: TTM placement for guest memory buffers.
65+ * @busy_domain: TTM busy placement for guest memory buffers.
6566 * @may_evict Whether the resource may be evicted.
6667 * @create: Create a hardware resource.
6768 * @destroy: Destroy a hardware resource.
@@ -81,9 +82,10 @@ struct vmw_user_resource_conv { · 13 unmodified lines
8182 */
8283 struct vmw_res_func {
8384 enum vmw_res_type res_type;
84− bool needs_backup;
85+ bool needs_guest_memory;
8586 const char *type_name;
86− struct ttm_placement *backup_placement;
87+ u32 domain;
88+ u32 busy_domain;
8789 bool may_evict;
8890 u32 prio;
8991 u32 dirty_prio;
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c+28−25
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2011-2022 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2011-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -25,13 +25,14 @@ · 17 unmodified lines
2525 *
2626 **************************************************************************/
2727
28+#include "vmwgfx_bo.h"
29+#include "vmwgfx_kms.h"
30+
2831 #include <drm/drm_atomic.h>
2932 #include <drm/drm_atomic_helper.h>
3033 #include <drm/drm_damage_helper.h>
3134 #include <drm/drm_fourcc.h>
3235
33−#include "vmwgfx_kms.h"
34−
3536 #define vmw_crtc_to_sou(x) \
3637 container_of(x, struct vmw_screen_object_unit, base.crtc)
3738 #define vmw_encoder_to_sou(x) \
@@ -89,7 +90,7 @@ struct vmw_screen_object_unit { · 51 unmodified lines
8990 struct vmw_display_unit base;
9091
9192 unsigned long buffer_size; /**< Size of allocated buffer */
92− struct vmw_buffer_object *buffer; /**< Backing store buffer */
93+ struct vmw_bo *buffer; /**< Backing store buffer */
9394
9495 bool defined;
9596 };
@@ -148,7 +149,7 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv, · 52 unmodified lines
148149 sou->base.set_gui_y = cmd->obj.root.y;
149150
150151 /* Ok to assume that buffer is pinned in vram */
151− vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr);
152+ vmw_bo_get_guest_ptr(&sou->buffer->tbo, &cmd->obj.backingStore.ptr);
152153 cmd->obj.backingStore.pitch = mode->hdisplay * 4;
153154
154155 vmw_cmd_commit(dev_priv, fifo_size);
@@ -409,9 +410,13 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, · 254 unmodified lines
409410 struct drm_crtc *crtc = plane->state->crtc ?: new_state->crtc;
410411 struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
411412 struct vmw_private *dev_priv;
412− size_t size;
413413 int ret;
414−
414+ struct vmw_bo_params bo_params = {
415+ .domain = VMW_BO_DOMAIN_VRAM,
416+ .busy_domain = VMW_BO_DOMAIN_VRAM,
417+ .bo_type = ttm_bo_type_device,
418+ .pin = true
419+ };
415420
416421 if (!new_fb) {
417422 vmw_bo_unreference(&vps->bo);
@@ -420,11 +425,11 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, · 2 unmodified lines
420425 return 0;
421426 }
422427
423− size = new_state->crtc_w * new_state->crtc_h * 4;
428+ bo_params.size = new_state->crtc_w * new_state->crtc_h * 4;
424429 dev_priv = vmw_priv(crtc->dev);
425430
426431 if (vps->bo) {
427− if (vps->bo_size == size) {
432+ if (vps->bo_size == bo_params.size) {
428433 /*
429434 * Note that this might temporarily up the pin-count
430435 * to 2, until cleanup_fb() is called.
@@ -443,16 +448,12 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, · 12 unmodified lines
443448 * resume the overlays, this is preferred to failing to alloc.
444449 */
445450 vmw_overlay_pause_all(dev_priv);
446− ret = vmw_bo_create(dev_priv, size,
447− &vmw_vram_placement,
448− false, true, &vmw_bo_bo_free, &vps->bo);
451+ ret = vmw_bo_create(dev_priv, &bo_params, &vps->bo);
449452 vmw_overlay_resume_all(dev_priv);
450− if (ret) {
451− vps->bo = NULL; /* vmw_bo_init frees on error */
453+ if (ret)
452454 return ret;
453− }
454455
455− vps->bo_size = size;
456+ vps->bo_size = bo_params.size;
456457
457458 /*
458459 * TTM already thinks the buffer is pinned, but make sure the
@@ -489,7 +490,7 @@ static uint32_t vmw_sou_bo_define_gmrfb(struct vmw_du_update_plane *update, · 30 unmodified lines
489490 gmr->body.format.colorDepth = depth;
490491 gmr->body.format.reserved = 0;
491492 gmr->body.bytesPerLine = update->vfb->base.pitches[0];
492− vmw_bo_get_guest_ptr(&vfbbo->buffer->base, &gmr->body.ptr);
493+ vmw_bo_get_guest_ptr(&vfbbo->buffer->tbo, &gmr->body.ptr);
493494
494495 return sizeof(*gmr);
495496 }
@@ -546,7 +547,6 @@ static int vmw_sou_plane_update_bo(struct vmw_private *dev_priv, · 50 unmodified lines
546547 bo_update.base.vfb = vfb;
547548 bo_update.base.out_fence = out_fence;
548549 bo_update.base.mutex = NULL;
549− bo_update.base.cpu_blit = false;
550550 bo_update.base.intr = true;
551551
552552 bo_update.base.calc_fifo_size = vmw_sou_bo_fifo_size;
@@ -707,7 +707,6 @@ static int vmw_sou_plane_update_surface(struct vmw_private *dev_priv, · 154 unmodified lines
707707 srf_update.base.vfb = vfb;
708708 srf_update.base.out_fence = out_fence;
709709 srf_update.base.mutex = &dev_priv->cmdbuf_mutex;
710− srf_update.base.cpu_blit = false;
711710 srf_update.base.intr = true;
712711
713712 srf_update.base.calc_fifo_size = vmw_sou_surface_fifo_size;
@@ -947,7 +946,7 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv) · 233 unmodified lines
947946 static int do_bo_define_gmrfb(struct vmw_private *dev_priv,
948947 struct vmw_framebuffer *framebuffer)
949948 {
950− struct vmw_buffer_object *buf =
949+ struct vmw_bo *buf =
951950 container_of(framebuffer, struct vmw_framebuffer_bo,
952951 base)->buffer;
953952 int depth = framebuffer->base.format->depth;
@@ -973,7 +972,7 @@ static int do_bo_define_gmrfb(struct vmw_private *dev_priv, · 19 unmodified lines
973972 cmd->body.format.reserved = 0;
974973 cmd->body.bytesPerLine = framebuffer->base.pitches[0];
975974 /* Buffer is reserved in vram or GMR */
976− vmw_bo_get_guest_ptr(&buf->base, &cmd->body.ptr);
975+ vmw_bo_get_guest_ptr(&buf->tbo, &cmd->body.ptr);
977976 vmw_cmd_commit(dev_priv, sizeof(*cmd));
978977
979978 return 0;
@@ -1216,14 +1215,16 @@ int vmw_kms_sou_do_bo_dirty(struct vmw_private *dev_priv, · 236 unmodified lines
12161215 struct vmw_fence_obj **out_fence,
12171216 struct drm_crtc *crtc)
12181217 {
1219− struct vmw_buffer_object *buf =
1218+ struct vmw_bo *buf =
12201219 container_of(framebuffer, struct vmw_framebuffer_bo,
12211220 base)->buffer;
12221221 struct vmw_kms_dirty dirty;
12231222 DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
12241223 int ret;
12251224
1226− ret = vmw_validation_add_bo(&val_ctx, buf, false, false);
1225+ vmw_bo_placement_set(buf, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
1226+ VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
1227+ ret = vmw_validation_add_bo(&val_ctx, buf);
12271228 if (ret)
12281229 return ret;
12291230
@@ -1323,13 +1324,15 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv, · 93 unmodified lines
13231324 uint32_t num_clips,
13241325 struct drm_crtc *crtc)
13251326 {
1326− struct vmw_buffer_object *buf =
1327+ struct vmw_bo *buf =
13271328 container_of(vfb, struct vmw_framebuffer_bo, base)->buffer;
13281329 struct vmw_kms_dirty dirty;
13291330 DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
13301331 int ret;
13311332
1332− ret = vmw_validation_add_bo(&val_ctx, buf, false, false);
1333+ vmw_bo_placement_set(buf, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
1334+ VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
1335+ ret = vmw_validation_add_bo(&val_ctx, buf);
13331336 if (ret)
13341337 return ret;
13351338
drivers/gpu/drm/vmwgfx/vmwgfx_shader.c+38−29
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -27,9 +27,10 @@ · 19 unmodified lines
2727
2828 #include <drm/ttm/ttm_placement.h>
2929
30+#include "vmwgfx_binding.h"
31+#include "vmwgfx_bo.h"
3032 #include "vmwgfx_drv.h"
3133 #include "vmwgfx_resource_priv.h"
32−#include "vmwgfx_binding.h"
3334
3435 struct vmw_shader {
3536 struct vmw_resource res;
@@ -88,12 +89,13 @@ const struct vmw_user_resource_conv *user_shader_converter = · 52 unmodified lines
8889
8990 static const struct vmw_res_func vmw_gb_shader_func = {
9091 .res_type = vmw_res_shader,
91− .needs_backup = true,
92+ .needs_guest_memory = true,
9293 .may_evict = true,
9394 .prio = 3,
9495 .dirty_prio = 3,
9596 .type_name = "guest backed shaders",
96− .backup_placement = &vmw_mob_placement,
97+ .domain = VMW_BO_DOMAIN_MOB,
98+ .busy_domain = VMW_BO_DOMAIN_MOB,
9799 .create = vmw_gb_shader_create,
98100 .destroy = vmw_gb_shader_destroy,
99101 .bind = vmw_gb_shader_bind,
@@ -102,12 +104,13 @@ static const struct vmw_res_func vmw_gb_shader_func = { · 2 unmodified lines
102104
103105 static const struct vmw_res_func vmw_dx_shader_func = {
104106 .res_type = vmw_res_shader,
105− .needs_backup = true,
107+ .needs_guest_memory = true,
106108 .may_evict = true,
107109 .prio = 3,
108110 .dirty_prio = 3,
109111 .type_name = "dx shaders",
110− .backup_placement = &vmw_mob_placement,
112+ .domain = VMW_BO_DOMAIN_MOB,
113+ .busy_domain = VMW_BO_DOMAIN_MOB,
111114 .create = vmw_dx_shader_create,
112115 /*
113116 * The destroy callback is only called with a committed resource on
@@ -158,7 +161,7 @@ static int vmw_gb_shader_init(struct vmw_private *dev_priv, · 44 unmodified lines
158161 SVGA3dShaderType type,
159162 uint8_t num_input_sig,
160163 uint8_t num_output_sig,
161− struct vmw_buffer_object *byte_code,
164+ struct vmw_bo *byte_code,
162165 void (*res_free) (struct vmw_resource *res))
163166 {
164167 struct vmw_shader *shader = vmw_res_to_shader(res);
@@ -175,10 +178,10 @@ static int vmw_gb_shader_init(struct vmw_private *dev_priv, · 10 unmodified lines
175178 return ret;
176179 }
177180
178− res->backup_size = size;
181+ res->guest_memory_size = size;
179182 if (byte_code) {
180− res->backup = vmw_bo_reference(byte_code);
181− res->backup_offset = offset;
183+ res->guest_memory_bo = vmw_bo_reference(byte_code);
184+ res->guest_memory_offset = offset;
182185 }
183186 shader->size = size;
184187 shader->type = type;
@@ -259,8 +262,8 @@ static int vmw_gb_shader_bind(struct vmw_resource *res, · 74 unmodified lines
259262 cmd->header.size = sizeof(cmd->body);
260263 cmd->body.shid = res->id;
261264 cmd->body.mobid = bo->resource->start;
262− cmd->body.offsetInBytes = res->backup_offset;
263− res->backup_dirty = false;
265+ cmd->body.offsetInBytes = res->guest_memory_offset;
266+ res->guest_memory_dirty = false;
264267 vmw_cmd_commit(dev_priv, sizeof(*cmd));
265268
266269 return 0;
@@ -277,7 +280,7 @@ static int vmw_gb_shader_unbind(struct vmw_resource *res, · 10 unmodified lines
277280 } *cmd;
278281 struct vmw_fence_obj *fence;
279282
280− BUG_ON(res->backup->base.resource->mem_type != VMW_PL_MOB);
283+ BUG_ON(res->guest_memory_bo->tbo.resource->mem_type != VMW_PL_MOB);
281284
282285 cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
283286 if (unlikely(cmd == NULL))
@@ -397,8 +400,8 @@ static int vmw_dx_shader_unscrub(struct vmw_resource *res) · 113 unmodified lines
397400 cmd->header.size = sizeof(cmd->body);
398401 cmd->body.cid = shader->ctx->id;
399402 cmd->body.shid = shader->id;
400− cmd->body.mobid = res->backup->base.resource->start;
401− cmd->body.offsetInBytes = res->backup_offset;
403+ cmd->body.mobid = res->guest_memory_bo->tbo.resource->start;
404+ cmd->body.offsetInBytes = res->guest_memory_offset;
402405 vmw_cmd_commit(dev_priv, sizeof(*cmd));
403406
404407 vmw_cotable_add_resource(shader->cotable, &shader->cotable_head);
@@ -508,7 +511,7 @@ static int vmw_dx_shader_unbind(struct vmw_resource *res, · 103 unmodified lines
508511 struct vmw_fence_obj *fence;
509512 int ret;
510513
511− BUG_ON(res->backup->base.resource->mem_type != VMW_PL_MOB);
514+ BUG_ON(res->guest_memory_bo->tbo.resource->mem_type != VMW_PL_MOB);
512515
513516 mutex_lock(&dev_priv->binding_mutex);
514517 ret = vmw_dx_shader_scrub(res);
@@ -680,7 +683,7 @@ int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, · 165 unmodified lines
680683 }
681684
682685 static int vmw_user_shader_alloc(struct vmw_private *dev_priv,
683− struct vmw_buffer_object *buffer,
686+ struct vmw_bo *buffer,
684687 size_t shader_size,
685688 size_t offset,
686689 SVGA3dShaderType shader_type,
@@ -734,7 +737,7 @@ out: · 47 unmodified lines
734737
735738
736739 static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv,
737− struct vmw_buffer_object *buffer,
740+ struct vmw_bo *buffer,
738741 size_t shader_size,
739742 size_t offset,
740743 SVGA3dShaderType shader_type)
@@ -771,7 +774,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, · 30 unmodified lines
771774 {
772775 struct vmw_private *dev_priv = vmw_priv(dev);
773776 struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
774− struct vmw_buffer_object *buffer = NULL;
777+ struct vmw_bo *buffer = NULL;
775778 SVGA3dShaderType shader_type;
776779 int ret;
777780
@@ -782,7 +785,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, · 4 unmodified lines
782785 return ret;
783786 }
784787
785− if ((u64)buffer->base.base.size < (u64)size + (u64)offset) {
788+ if ((u64)buffer->tbo.base.size < (u64)size + (u64)offset) {
786789 VMW_DEBUG_USER("Illegal buffer- or shader size.\n");
787790 ret = -EINVAL;
788791 goto out_bad_arg;
@@ -807,7 +810,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, · 18 unmodified lines
807810 num_output_sig, tfile, shader_handle);
808811 out_bad_arg:
809812 vmw_bo_unreference(&buffer);
810− drm_gem_object_put(&buffer->base.base);
813+ drm_gem_object_put(&buffer->tbo.base);
811814 return ret;
812815 }
813816
@@ -884,28 +887,34 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, · 70 unmodified lines
884887 struct list_head *list)
885888 {
886889 struct ttm_operation_ctx ctx = { false, true };
887− struct vmw_buffer_object *buf;
890+ struct vmw_bo *buf;
888891 struct ttm_bo_kmap_obj map;
889892 bool is_iomem;
890893 int ret;
891894 struct vmw_resource *res;
895+ struct vmw_bo_params bo_params = {
896+ .domain = VMW_BO_DOMAIN_SYS,
897+ .busy_domain = VMW_BO_DOMAIN_SYS,
898+ .bo_type = ttm_bo_type_device,
899+ .size = size,
900+ .pin = true
901+ };
892902
893903 if (!vmw_shader_id_ok(user_key, shader_type))
894904 return -EINVAL;
895905
896− ret = vmw_bo_create(dev_priv, size, &vmw_sys_placement,
897− true, true, vmw_bo_bo_free, &buf);
906+ ret = vmw_bo_create(dev_priv, &bo_params, &buf);
898907 if (unlikely(ret != 0))
899908 goto out;
900909
901− ret = ttm_bo_reserve(&buf->base, false, true, NULL);
910+ ret = ttm_bo_reserve(&buf->tbo, false, true, NULL);
902911 if (unlikely(ret != 0))
903912 goto no_reserve;
904913
905914 /* Map and copy shader bytecode. */
906− ret = ttm_bo_kmap(&buf->base, 0, PFN_UP(size), &map);
915+ ret = ttm_bo_kmap(&buf->tbo, 0, PFN_UP(size), &map);
907916 if (unlikely(ret != 0)) {
908− ttm_bo_unreserve(&buf->base);
917+ ttm_bo_unreserve(&buf->tbo);
909918 goto no_reserve;
910919 }
911920
@@ -913,9 +922,9 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, · 1 unmodified line
913922 WARN_ON(is_iomem);
914923
915924 ttm_bo_kunmap(&map);
916− ret = ttm_bo_validate(&buf->base, &vmw_sys_placement, &ctx);
925+ ret = ttm_bo_validate(&buf->tbo, &buf->placement, &ctx);
917926 WARN_ON(ret != 0);
918− ttm_bo_unreserve(&buf->base);
927+ ttm_bo_unreserve(&buf->tbo);
919928
920929 res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type);
921930 if (unlikely(ret != 0))
drivers/gpu/drm/vmwgfx/vmwgfx_so.c+4−2
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 *
2525 **************************************************************************/
2626
27+#include "vmwgfx_bo.h"
2728 #include "vmwgfx_drv.h"
2829 #include "vmwgfx_resource_priv.h"
2930 #include "vmwgfx_so.h"
@@ -81,10 +82,11 @@ static void vmw_view_commit_notify(struct vmw_resource *res, · 51 unmodified lines
8182
8283 static const struct vmw_res_func vmw_view_func = {
8384 .res_type = vmw_res_view,
84− .needs_backup = false,
85+ .needs_guest_memory = false,
8586 .may_evict = false,
8687 .type_name = "DX view",
87− .backup_placement = NULL,
88+ .domain = VMW_BO_DOMAIN_SYS,
89+ .busy_domain = VMW_BO_DOMAIN_SYS,
8890 .create = vmw_view_create,
8991 .commit_notify = vmw_view_commit_notify,
9092 };
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c+45−278
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /******************************************************************************
33 *
4− * COPYRIGHT (C) 2014-2022 VMware, Inc., Palo Alto, CA., USA
4+ * COPYRIGHT (C) 2014-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -25,14 +25,15 @@ · 17 unmodified lines
2525 *
2626 ******************************************************************************/
2727
28+#include "vmwgfx_bo.h"
29+#include "vmwgfx_kms.h"
30+#include "vmw_surface_cache.h"
31+
2832 #include <drm/drm_atomic.h>
2933 #include <drm/drm_atomic_helper.h>
3034 #include <drm/drm_damage_helper.h>
3135 #include <drm/drm_fourcc.h>
3236
33−#include "vmwgfx_kms.h"
34−#include "vmw_surface_cache.h"
35−
3637 #define vmw_crtc_to_stdu(x) \
3738 container_of(x, struct vmw_screen_target_display_unit, base.crtc)
3839 #define vmw_encoder_to_stdu(x) \
@@ -65,12 +66,11 @@ enum stdu_content_type { · 26 unmodified lines
6566 */
6667 struct vmw_stdu_dirty {
6768 struct vmw_kms_dirty base;
68− SVGA3dTransferType transfer;
6969 s32 left, right, top, bottom;
7070 s32 fb_left, fb_top;
7171 u32 pitch;
7272 union {
73− struct vmw_buffer_object *buf;
73+ struct vmw_bo *buf;
7474 u32 sid;
7575 };
7676 };
@@ -136,12 +136,6 @@ static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu); · 59 unmodified lines
136136 * Screen Target Display Unit CRTC Functions
137137 *****************************************************************************/
138138
139−static bool vmw_stdu_use_cpu_blit(const struct vmw_private *vmw)
140−{
141− return !(vmw->capabilities & SVGA_CAP_3D) || vmw->vram_size < (32 * 1024 * 1024);
142−}
143−
144−
145139 /**
146140 * vmw_stdu_crtc_destroy - cleans up the STDU
147141 *
@@ -450,93 +444,6 @@ static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc, · 302 unmodified lines
450444 }
451445 }
452446
453−/**
454− * vmw_stdu_bo_clip - Callback to encode a suface DMA command cliprect
455− *
456− * @dirty: The closure structure.
457− *
458− * Encodes a surface DMA command cliprect and updates the bounding box
459− * for the DMA.
460− */
461−static void vmw_stdu_bo_clip(struct vmw_kms_dirty *dirty)
462−{
463− struct vmw_stdu_dirty *ddirty =
464− container_of(dirty, struct vmw_stdu_dirty, base);
465− struct vmw_stdu_dma *cmd = dirty->cmd;
466− struct SVGA3dCopyBox *blit = (struct SVGA3dCopyBox *) &cmd[1];
467−
468− blit += dirty->num_hits;
469− blit->srcx = dirty->fb_x;
470− blit->srcy = dirty->fb_y;
471− blit->x = dirty->unit_x1;
472− blit->y = dirty->unit_y1;
473− blit->d = 1;
474− blit->w = dirty->unit_x2 - dirty->unit_x1;
475− blit->h = dirty->unit_y2 - dirty->unit_y1;
476− dirty->num_hits++;
477−
478− if (ddirty->transfer != SVGA3D_WRITE_HOST_VRAM)
479− return;
480−
481− /* Destination bounding box */
482− ddirty->left = min_t(s32, ddirty->left, dirty->unit_x1);
483− ddirty->top = min_t(s32, ddirty->top, dirty->unit_y1);
484− ddirty->right = max_t(s32, ddirty->right, dirty->unit_x2);
485− ddirty->bottom = max_t(s32, ddirty->bottom, dirty->unit_y2);
486−}
487−
488−/**
489− * vmw_stdu_bo_fifo_commit - Callback to fill in and submit a DMA command.
490− *
491− * @dirty: The closure structure.
492− *
493− * Fills in the missing fields in a DMA command, and optionally encodes
494− * a screen target update command, depending on transfer direction.
495− */
496−static void vmw_stdu_bo_fifo_commit(struct vmw_kms_dirty *dirty)
497−{
498− struct vmw_stdu_dirty *ddirty =
499− container_of(dirty, struct vmw_stdu_dirty, base);
500− struct vmw_screen_target_display_unit *stdu =
501− container_of(dirty->unit, typeof(*stdu), base);
502− struct vmw_stdu_dma *cmd = dirty->cmd;
503− struct SVGA3dCopyBox *blit = (struct SVGA3dCopyBox *) &cmd[1];
504− SVGA3dCmdSurfaceDMASuffix *suffix =
505− (SVGA3dCmdSurfaceDMASuffix *) &blit[dirty->num_hits];
506− size_t blit_size = sizeof(*blit) * dirty->num_hits + sizeof(*suffix);
507−
508− if (!dirty->num_hits) {
509− vmw_cmd_commit(dirty->dev_priv, 0);
510− return;
511− }
512−
513− cmd->header.id = SVGA_3D_CMD_SURFACE_DMA;
514− cmd->header.size = sizeof(cmd->body) + blit_size;
515− vmw_bo_get_guest_ptr(&ddirty->buf->base, &cmd->body.guest.ptr);
516− cmd->body.guest.pitch = ddirty->pitch;
517− cmd->body.host.sid = stdu->display_srf->res.id;
518− cmd->body.host.face = 0;
519− cmd->body.host.mipmap = 0;
520− cmd->body.transfer = ddirty->transfer;
521− suffix->suffixSize = sizeof(*suffix);
522− suffix->maximumOffset = ddirty->buf->base.base.size;
523−
524− if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM) {
525− blit_size += sizeof(struct vmw_stdu_update);
526−
527− vmw_stdu_populate_update(&suffix[1], stdu->base.unit,
528− ddirty->left, ddirty->right,
529− ddirty->top, ddirty->bottom);
530− }
531−
532− vmw_cmd_commit(dirty->dev_priv, sizeof(*cmd) + blit_size);
533−
534− stdu->display_srf->res.res_dirty = true;
535− ddirty->left = ddirty->top = S32_MAX;
536− ddirty->right = ddirty->bottom = S32_MIN;
537−}
538−
539−
540447 /**
541448 * vmw_stdu_bo_cpu_clip - Callback to encode a CPU blit
542449 *
@@ -597,62 +504,21 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty) · 54 unmodified lines
597504 return;
598505
599506 /* Assume we are blitting from Guest (bo) to Host (display_srf) */
600− dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp;
601− dst_bo = &stdu->display_srf->res.backup->base;
602− dst_offset = ddirty->top * dst_pitch + ddirty->left * stdu->cpp;
603−
604− src_pitch = ddirty->pitch;
605− src_bo = &ddirty->buf->base;
606− src_offset = ddirty->fb_top * src_pitch + ddirty->fb_left * stdu->cpp;
607−
608− /* Swap src and dst if the assumption was wrong. */
609− if (ddirty->transfer != SVGA3D_WRITE_HOST_VRAM) {
610− swap(dst_pitch, src_pitch);
611− swap(dst_bo, src_bo);
612− swap(src_offset, dst_offset);
613− }
507+ src_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp;
508+ src_bo = &stdu->display_srf->res.guest_memory_bo->tbo;
509+ src_offset = ddirty->top * dst_pitch + ddirty->left * stdu->cpp;
510+
511+ dst_pitch = ddirty->pitch;
512+ dst_bo = &ddirty->buf->tbo;
513+ dst_offset = ddirty->fb_top * src_pitch + ddirty->fb_left * stdu->cpp;
614514
615515 (void) vmw_bo_cpu_blit(dst_bo, dst_offset, dst_pitch,
616516 src_bo, src_offset, src_pitch,
617517 width * stdu->cpp, height, &diff);
618−
619− if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM &&
620− drm_rect_visible(&diff.rect)) {
621− struct vmw_private *dev_priv;
622− struct vmw_stdu_update *cmd;
623− struct drm_clip_rect region;
624− int ret;
625−
626− /* We are updating the actual surface, not a proxy */
627− region.x1 = diff.rect.x1;
628− region.x2 = diff.rect.x2;
629− region.y1 = diff.rect.y1;
630− region.y2 = diff.rect.y2;
631− ret = vmw_kms_update_proxy(&stdu->display_srf->res, &region,
632− 1, 1);
633− if (ret)
634− goto out_cleanup;
635−
636−
637− dev_priv = vmw_priv(stdu->base.crtc.dev);
638− cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
639− if (!cmd)
640− goto out_cleanup;
641−
642− vmw_stdu_populate_update(cmd, stdu->base.unit,
643− region.x1, region.x2,
644− region.y1, region.y2);
645−
646− vmw_cmd_commit(dev_priv, sizeof(*cmd));
647− }
648−
649−out_cleanup:
650− ddirty->left = ddirty->top = ddirty->fb_left = ddirty->fb_top = S32_MAX;
651− ddirty->right = ddirty->bottom = S32_MIN;
652518 }
653519
654520 /**
655− * vmw_kms_stdu_dma - Perform a DMA transfer between a buffer-object backed
521+ * vmw_kms_stdu_readback - Perform a readback from a buffer-object backed
656522 * framebuffer and the screen target system.
657523 *
658524 * @dev_priv: Pointer to the device private structure.
@@ -665,9 +531,6 @@ out_cleanup: · 6 unmodified lines
665531 * be NULL.
666532 * @num_clips: Number of clip rects in @clips or @vclips.
667533 * @increment: Increment to use when looping over @clips or @vclips.
668− * @to_surface: Whether to DMA to the screen target system as opposed to
669− * from the screen target system.
670− * @interruptible: Whether to perform waits interruptible if possible.
671534 * @crtc: If crtc is passed, perform stdu dma on that crtc only.
672535 *
673536 * If DMA-ing till the screen target system, the function will also notify
@@ -676,59 +539,49 @@ out_cleanup: · 2 unmodified lines
676539 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
677540 * interrupted.
678541 */
679−int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
680− struct drm_file *file_priv,
681− struct vmw_framebuffer *vfb,
682− struct drm_vmw_fence_rep __user *user_fence_rep,
683− struct drm_clip_rect *clips,
684− struct drm_vmw_rect *vclips,
685− uint32_t num_clips,
686− int increment,
687− bool to_surface,
688− bool interruptible,
689− struct drm_crtc *crtc)
542+int vmw_kms_stdu_readback(struct vmw_private *dev_priv,
543+ struct drm_file *file_priv,
544+ struct vmw_framebuffer *vfb,
545+ struct drm_vmw_fence_rep __user *user_fence_rep,
546+ struct drm_clip_rect *clips,
547+ struct drm_vmw_rect *vclips,
548+ uint32_t num_clips,
549+ int increment,
550+ struct drm_crtc *crtc)
690551 {
691− struct vmw_buffer_object *buf =
552+ struct vmw_bo *buf =
692553 container_of(vfb, struct vmw_framebuffer_bo, base)->buffer;
693554 struct vmw_stdu_dirty ddirty;
694555 int ret;
695− bool cpu_blit = vmw_stdu_use_cpu_blit(dev_priv);
696556 DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
697557
698558 /*
699− * VMs without 3D support don't have the surface DMA command and
700− * we'll be using a CPU blit, and the framebuffer should be moved out
701− * of VRAM.
559+ * The GMR domain might seem confusing because it might seem like it should
560+ * never happen with screen targets but e.g. the xorg vmware driver issues
561+ * CMD_SURFACE_DMA for various pixmap updates which might transition our bo to
562+ * a GMR. Instead of forcing another transition we can optimize the readback
563+ * by reading directly from the GMR.
702564 */
703− ret = vmw_validation_add_bo(&val_ctx, buf, false, cpu_blit);
565+ vmw_bo_placement_set(buf,
566+ VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_GMR,
567+ VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_GMR);
568+ ret = vmw_validation_add_bo(&val_ctx, buf);
704569 if (ret)
705570 return ret;
706571
707− ret = vmw_validation_prepare(&val_ctx, NULL, interruptible);
572+ ret = vmw_validation_prepare(&val_ctx, NULL, true);
708573 if (ret)
709574 goto out_unref;
710575
711− ddirty.transfer = (to_surface) ? SVGA3D_WRITE_HOST_VRAM :
712− SVGA3D_READ_HOST_VRAM;
713576 ddirty.left = ddirty.top = S32_MAX;
714577 ddirty.right = ddirty.bottom = S32_MIN;
715578 ddirty.fb_left = ddirty.fb_top = S32_MAX;
716579 ddirty.pitch = vfb->base.pitches[0];
717580 ddirty.buf = buf;
718− ddirty.base.fifo_commit = vmw_stdu_bo_fifo_commit;
719− ddirty.base.clip = vmw_stdu_bo_clip;
720− ddirty.base.fifo_reserve_size = sizeof(struct vmw_stdu_dma) +
721− num_clips * sizeof(SVGA3dCopyBox) +
722− sizeof(SVGA3dCmdSurfaceDMASuffix);
723− if (to_surface)
724− ddirty.base.fifo_reserve_size += sizeof(struct vmw_stdu_update);
725−
726−
727− if (cpu_blit) {
728− ddirty.base.fifo_commit = vmw_stdu_bo_cpu_commit;
729− ddirty.base.clip = vmw_stdu_bo_cpu_clip;
730− ddirty.base.fifo_reserve_size = 0;
731− }
581+
582+ ddirty.base.fifo_commit = vmw_stdu_bo_cpu_commit;
583+ ddirty.base.clip = vmw_stdu_bo_cpu_clip;
584+ ddirty.base.fifo_reserve_size = 0;
732585
733586 ddirty.base.crtc = crtc;
734587
@@ -1160,11 +1013,8 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, · 425 unmodified lines
11601013 /*
11611014 * This should only happen if the buffer object is too large to create a
11621015 * proxy surface for.
1163− * If we are a 2D VM with a buffer object then we have to use CPU blit
1164− * so cache these mappings
11651016 */
1166− if (vps->content_fb_type == SEPARATE_BO &&
1167− vmw_stdu_use_cpu_blit(dev_priv))
1017+ if (vps->content_fb_type == SEPARATE_BO)
11681018 vps->cpp = new_fb->pitches[0] / new_fb->width;
11691019
11701020 return 0;
@@ -1174,14 +1024,6 @@ out_srf_unref: · 3 unmodified lines
11741024 return ret;
11751025 }
11761026
1177−static uint32_t vmw_stdu_bo_fifo_size(struct vmw_du_update_plane *update,
1178− uint32_t num_hits)
1179−{
1180− return sizeof(struct vmw_stdu_dma) + sizeof(SVGA3dCopyBox) * num_hits +
1181− sizeof(SVGA3dCmdSurfaceDMASuffix) +
1182− sizeof(struct vmw_stdu_update);
1183−}
1184−
11851027 static uint32_t vmw_stdu_bo_fifo_size_cpu(struct vmw_du_update_plane *update,
11861028 uint32_t num_hits)
11871029 {
@@ -1189,68 +1031,6 @@ static uint32_t vmw_stdu_bo_fifo_size_cpu(struct vmw_du_update_plane *update, · 1 unmodified line
11891031 sizeof(struct vmw_stdu_update);
11901032 }
11911033
1192−static uint32_t vmw_stdu_bo_populate_dma(struct vmw_du_update_plane *update,
1193− void *cmd, uint32_t num_hits)
1194−{
1195− struct vmw_screen_target_display_unit *stdu;
1196− struct vmw_framebuffer_bo *vfbbo;
1197− struct vmw_stdu_dma *cmd_dma = cmd;
1198−
1199− stdu = container_of(update->du, typeof(*stdu), base);
1200− vfbbo = container_of(update->vfb, typeof(*vfbbo), base);
1201−
1202− cmd_dma->header.id = SVGA_3D_CMD_SURFACE_DMA;
1203− cmd_dma->header.size = sizeof(cmd_dma->body) +
1204− sizeof(struct SVGA3dCopyBox) * num_hits +
1205− sizeof(SVGA3dCmdSurfaceDMASuffix);
1206− vmw_bo_get_guest_ptr(&vfbbo->buffer->base, &cmd_dma->body.guest.ptr);
1207− cmd_dma->body.guest.pitch = update->vfb->base.pitches[0];
1208− cmd_dma->body.host.sid = stdu->display_srf->res.id;
1209− cmd_dma->body.host.face = 0;
1210− cmd_dma->body.host.mipmap = 0;
1211− cmd_dma->body.transfer = SVGA3D_WRITE_HOST_VRAM;
1212−
1213− return sizeof(*cmd_dma);
1214−}
1215−
1216−static uint32_t vmw_stdu_bo_populate_clip(struct vmw_du_update_plane *update,
1217− void *cmd, struct drm_rect *clip,
1218− uint32_t fb_x, uint32_t fb_y)
1219−{
1220− struct SVGA3dCopyBox *box = cmd;
1221−
1222− box->srcx = fb_x;
1223− box->srcy = fb_y;
1224− box->srcz = 0;
1225− box->x = clip->x1;
1226− box->y = clip->y1;
1227− box->z = 0;
1228− box->w = drm_rect_width(clip);
1229− box->h = drm_rect_height(clip);
1230− box->d = 1;
1231−
1232− return sizeof(*box);
1233−}
1234−
1235−static uint32_t vmw_stdu_bo_populate_update(struct vmw_du_update_plane *update,
1236− void *cmd, struct drm_rect *bb)
1237−{
1238− struct vmw_screen_target_display_unit *stdu;
1239− struct vmw_framebuffer_bo *vfbbo;
1240− SVGA3dCmdSurfaceDMASuffix *suffix = cmd;
1241−
1242− stdu = container_of(update->du, typeof(*stdu), base);
1243− vfbbo = container_of(update->vfb, typeof(*vfbbo), base);
1244−
1245− suffix->suffixSize = sizeof(*suffix);
1246− suffix->maximumOffset = vfbbo->buffer->base.base.size;
1247−
1248− vmw_stdu_populate_update(&suffix[1], stdu->base.unit, bb->x1, bb->x2,
1249− bb->y1, bb->y2);
1250−
1251− return sizeof(*suffix) + sizeof(struct vmw_stdu_update);
1252−}
1253−
12541034 static uint32_t vmw_stdu_bo_pre_clip_cpu(struct vmw_du_update_plane *update,
12551035 void *cmd, uint32_t num_hits)
12561036 {
@@ -1300,11 +1080,11 @@ vmw_stdu_bo_populate_update_cpu(struct vmw_du_update_plane *update, void *cmd, · 43 unmodified lines
13001080
13011081 diff.cpp = stdu->cpp;
13021082
1303− dst_bo = &stdu->display_srf->res.backup->base;
1083+ dst_bo = &stdu->display_srf->res.guest_memory_bo->tbo;
13041084 dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp;
13051085 dst_offset = bb->y1 * dst_pitch + bb->x1 * stdu->cpp;
13061086
1307− src_bo = &vfbbo->buffer->base;
1087+ src_bo = &vfbbo->buffer->tbo;
13081088 src_pitch = update->vfb->base.pitches[0];
13091089 src_offset = bo_update->fb_top * src_pitch + bo_update->fb_left *
13101090 stdu->cpp;
@@ -1368,24 +1148,12 @@ static int vmw_stdu_plane_update_bo(struct vmw_private *dev_priv, · 57 unmodified lines
13681148 bo_update.base.vfb = vfb;
13691149 bo_update.base.out_fence = out_fence;
13701150 bo_update.base.mutex = NULL;
1371− bo_update.base.cpu_blit = vmw_stdu_use_cpu_blit(dev_priv);
13721151 bo_update.base.intr = false;
13731152
1374− /*
1375− * VM without 3D support don't have surface DMA command and framebuffer
1376− * should be moved out of VRAM.
1377− */
1378− if (bo_update.base.cpu_blit) {
1379− bo_update.base.calc_fifo_size = vmw_stdu_bo_fifo_size_cpu;
1380− bo_update.base.pre_clip = vmw_stdu_bo_pre_clip_cpu;
1381− bo_update.base.clip = vmw_stdu_bo_clip_cpu;
1382− bo_update.base.post_clip = vmw_stdu_bo_populate_update_cpu;
1383− } else {
1384− bo_update.base.calc_fifo_size = vmw_stdu_bo_fifo_size;
1385− bo_update.base.pre_clip = vmw_stdu_bo_populate_dma;
1386− bo_update.base.clip = vmw_stdu_bo_populate_clip;
1387− bo_update.base.post_clip = vmw_stdu_bo_populate_update;
1388− }
1153+ bo_update.base.calc_fifo_size = vmw_stdu_bo_fifo_size_cpu;
1154+ bo_update.base.pre_clip = vmw_stdu_bo_pre_clip_cpu;
1155+ bo_update.base.clip = vmw_stdu_bo_clip_cpu;
1156+ bo_update.base.post_clip = vmw_stdu_bo_populate_update_cpu;
13891157
13901158 return vmw_du_helper_plane_update(&bo_update.base);
13911159 }
@@ -1548,7 +1316,6 @@ static int vmw_stdu_plane_update_surface(struct vmw_private *dev_priv, · 156 unmodified lines
15481316 srf_update.vfb = vfb;
15491317 srf_update.out_fence = out_fence;
15501318 srf_update.mutex = &dev_priv->cmdbuf_mutex;
1551− srf_update.cpu_blit = false;
15521319 srf_update.intr = true;
15531320
15541321 if (vfbs->is_bo_proxy)
drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c+11−9
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright © 2018-2019 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright © 2018-2023 VMware, Inc., Palo Alto, CA., USA
55 * All Rights Reserved.
66 *
77 * Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,11 +26,12 @@ · 18 unmodified lines
2626 *
2727 **************************************************************************/
2828
29−#include <drm/ttm/ttm_placement.h>
30−
29+#include "vmwgfx_binding.h"
30+#include "vmwgfx_bo.h"
3131 #include "vmwgfx_drv.h"
3232 #include "vmwgfx_resource_priv.h"
33−#include "vmwgfx_binding.h"
33+
34+#include <drm/ttm/ttm_placement.h>
3435
3536 /**
3637 * struct vmw_dx_streamoutput - Streamoutput resource metadata.
@@ -62,10 +63,11 @@ static void vmw_dx_streamoutput_commit_notify(struct vmw_resource *res, · 25 unmodified lines
6263
6364 static const struct vmw_res_func vmw_dx_streamoutput_func = {
6465 .res_type = vmw_res_streamoutput,
65− .needs_backup = true,
66+ .needs_guest_memory = true,
6667 .may_evict = false,
6768 .type_name = "DX streamoutput",
68− .backup_placement = &vmw_mob_placement,
69+ .domain = VMW_BO_DOMAIN_MOB,
70+ .busy_domain = VMW_BO_DOMAIN_MOB,
6971 .create = vmw_dx_streamoutput_create,
7072 .destroy = NULL, /* Command buffer managed resource. */
7173 .bind = vmw_dx_streamoutput_bind,
@@ -104,8 +106,8 @@ static int vmw_dx_streamoutput_unscrub(struct vmw_resource *res) · 32 unmodified lines
104106 cmd->header.id = SVGA_3D_CMD_DX_BIND_STREAMOUTPUT;
105107 cmd->header.size = sizeof(cmd->body);
106108 cmd->body.soid = so->id;
107− cmd->body.mobid = res->backup->base.resource->start;
108− cmd->body.offsetInBytes = res->backup_offset;
109+ cmd->body.mobid = res->guest_memory_bo->tbo.resource->start;
110+ cmd->body.offsetInBytes = res->guest_memory_offset;
109111 cmd->body.sizeInBytes = so->size;
110112 vmw_cmd_commit(dev_priv, sizeof(*cmd));
111113
@@ -195,7 +197,7 @@ static int vmw_dx_streamoutput_unbind(struct vmw_resource *res, bool readback, · 83 unmodified lines
195197 struct vmw_fence_obj *fence;
196198 int ret;
197199
198− if (WARN_ON(res->backup->base.resource->mem_type != VMW_PL_MOB))
200+ if (WARN_ON(res->guest_memory_bo->tbo.resource->mem_type != VMW_PL_MOB))
199201 return -EINVAL;
200202
201203 mutex_lock(&dev_priv->binding_mutex);
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c+55−52
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -25,8 +25,7 @@ · 17 unmodified lines
2525 *
2626 **************************************************************************/
2727
28−#include <drm/ttm/ttm_placement.h>
29−
28+#include "vmwgfx_bo.h"
3029 #include "vmwgfx_drv.h"
3130 #include "vmwgfx_resource_priv.h"
3231 #include "vmwgfx_so.h"
@@ -34,6 +33,8 @@ · 1 unmodified line
3433 #include "vmw_surface_cache.h"
3534 #include "device_include/svga3d_surfacedefs.h"
3635
36+#include <drm/ttm/ttm_placement.h>
37+
3738 #define SVGA3D_FLAGS_64(upper32, lower32) (((uint64_t)upper32 << 32) | lower32)
3839 #define SVGA3D_FLAGS_UPPER_32(svga3d_flags) (svga3d_flags >> 32)
3940 #define SVGA3D_FLAGS_LOWER_32(svga3d_flags) \
@@ -125,12 +126,13 @@ const struct vmw_user_resource_conv *user_surface_converter = · 85 unmodified lines
125126
126127 static const struct vmw_res_func vmw_legacy_surface_func = {
127128 .res_type = vmw_res_surface,
128− .needs_backup = false,
129+ .needs_guest_memory = false,
129130 .may_evict = true,
130131 .prio = 1,
131132 .dirty_prio = 1,
132133 .type_name = "legacy surfaces",
133− .backup_placement = &vmw_srf_placement,
134+ .domain = VMW_BO_DOMAIN_GMR,
135+ .busy_domain = VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
134136 .create = &vmw_legacy_srf_create,
135137 .destroy = &vmw_legacy_srf_destroy,
136138 .bind = &vmw_legacy_srf_bind,
@@ -139,12 +141,13 @@ static const struct vmw_res_func vmw_legacy_surface_func = { · 2 unmodified lines
139141
140142 static const struct vmw_res_func vmw_gb_surface_func = {
141143 .res_type = vmw_res_surface,
142− .needs_backup = true,
144+ .needs_guest_memory = true,
143145 .may_evict = true,
144146 .prio = 1,
145147 .dirty_prio = 2,
146148 .type_name = "guest backed surfaces",
147− .backup_placement = &vmw_mob_placement,
149+ .domain = VMW_BO_DOMAIN_MOB,
150+ .busy_domain = VMW_BO_DOMAIN_MOB,
148151 .create = vmw_gb_surface_create,
149152 .destroy = vmw_gb_surface_destroy,
150153 .bind = vmw_gb_surface_bind,
@@ -379,7 +382,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) · 228 unmodified lines
379382 */
380383
381384 mutex_lock(&dev_priv->cmdbuf_mutex);
382− dev_priv->used_memory_size -= res->backup_size;
385+ dev_priv->used_memory_size -= res->guest_memory_size;
383386 mutex_unlock(&dev_priv->cmdbuf_mutex);
384387 }
385388 }
@@ -409,7 +412,7 @@ static int vmw_legacy_srf_create(struct vmw_resource *res) · 23 unmodified lines
409412 return 0;
410413
411414 srf = vmw_res_to_srf(res);
412− if (unlikely(dev_priv->used_memory_size + res->backup_size >=
415+ if (unlikely(dev_priv->used_memory_size + res->guest_memory_size >=
413416 dev_priv->memory_size))
414417 return -EBUSY;
415418
@@ -447,7 +450,7 @@ static int vmw_legacy_srf_create(struct vmw_resource *res) · 31 unmodified lines
447450 * Surface memory usage accounting.
448451 */
449452
450− dev_priv->used_memory_size += res->backup_size;
453+ dev_priv->used_memory_size += res->guest_memory_size;
451454 return 0;
452455
453456 out_no_fifo:
@@ -524,7 +527,7 @@ static int vmw_legacy_srf_dma(struct vmw_resource *res, · 70 unmodified lines
524527 static int vmw_legacy_srf_bind(struct vmw_resource *res,
525528 struct ttm_validate_buffer *val_buf)
526529 {
527− if (!res->backup_dirty)
530+ if (!res->guest_memory_dirty)
528531 return 0;
529532
530533 return vmw_legacy_srf_dma(res, val_buf, true);
@@ -583,7 +586,7 @@ static int vmw_legacy_srf_destroy(struct vmw_resource *res) · 52 unmodified lines
583586 * Surface memory usage accounting.
584587 */
585588
586− dev_priv->used_memory_size -= res->backup_size;
589+ dev_priv->used_memory_size -= res->guest_memory_size;
587590
588591 /*
589592 * Release the surface ID.
@@ -683,8 +686,8 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base) · 93 unmodified lines
683686 container_of(base, struct vmw_user_surface, prime.base);
684687 struct vmw_resource *res = &user_srf->srf.res;
685688
686− if (res && res->backup)
687− drm_gem_object_put(&res->backup->base.base);
689+ if (res->guest_memory_bo)
690+ drm_gem_object_put(&res->guest_memory_bo->tbo.base);
688691
689692 *p_base = NULL;
690693 vmw_resource_unreference(&res);
@@ -812,7 +815,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, · 121 unmodified lines
812815 ++cur_size;
813816 }
814817 }
815− res->backup_size = cur_bo_offset;
818+ res->guest_memory_size = cur_bo_offset;
816819 if (metadata->scanout &&
817820 metadata->num_sizes == 1 &&
818821 metadata->sizes[0].width == VMW_CURSOR_SNOOP_WIDTH &&
@@ -856,14 +859,14 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, · 37 unmodified lines
856859
857860 ret = vmw_gem_object_create_with_handle(dev_priv,
858861 file_priv,
859− res->backup_size,
862+ res->guest_memory_size,
860863 &backup_handle,
861− &res->backup);
864+ &res->guest_memory_bo);
862865 if (unlikely(ret != 0)) {
863866 vmw_resource_unreference(&res);
864867 goto out_unlock;
865868 }
866− vmw_bo_reference(res->backup);
869+ vmw_bo_reference(res->guest_memory_bo);
867870 /*
868871 * We don't expose the handle to the userspace and surface
869872 * already holds a gem reference
@@ -872,7 +875,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, · 2 unmodified lines
872875 }
873876
874877 tmp = vmw_resource_reference(&srf->res);
875− ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
878+ ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime,
876879 req->shareable, VMW_RES_SURFACE,
877880 &vmw_user_surface_base_release);
878881
@@ -1186,7 +1189,7 @@ static int vmw_gb_surface_bind(struct vmw_resource *res, · 307 unmodified lines
11861189
11871190 BUG_ON(bo->resource->mem_type != VMW_PL_MOB);
11881191
1189− submit_size = sizeof(*cmd1) + (res->backup_dirty ? sizeof(*cmd2) : 0);
1192+ submit_size = sizeof(*cmd1) + (res->guest_memory_dirty ? sizeof(*cmd2) : 0);
11901193
11911194 cmd1 = VMW_CMD_RESERVE(dev_priv, submit_size);
11921195 if (unlikely(!cmd1))
@@ -1196,7 +1199,7 @@ static int vmw_gb_surface_bind(struct vmw_resource *res, · 3 unmodified lines
11961199 cmd1->header.size = sizeof(cmd1->body);
11971200 cmd1->body.sid = res->id;
11981201 cmd1->body.mobid = bo->resource->start;
1199− if (res->backup_dirty) {
1202+ if (res->guest_memory_dirty) {
12001203 cmd2 = (void *) &cmd1[1];
12011204 cmd2->header.id = SVGA_3D_CMD_UPDATE_GB_SURFACE;
12021205 cmd2->header.size = sizeof(cmd2->body);
@@ -1204,12 +1207,12 @@ static int vmw_gb_surface_bind(struct vmw_resource *res, · 1 unmodified line
12041207 }
12051208 vmw_cmd_commit(dev_priv, submit_size);
12061209
1207− if (res->backup->dirty && res->backup_dirty) {
1210+ if (res->guest_memory_bo->dirty && res->guest_memory_dirty) {
12081211 /* We've just made a full upload. Cear dirty regions. */
12091212 vmw_bo_dirty_clear_res(res);
12101213 }
12111214
1212− res->backup_dirty = false;
1215+ res->guest_memory_dirty = false;
12131216
12141217 return 0;
12151218 }
@@ -1505,11 +1508,11 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 289 unmodified lines
15051508
15061509 if (req->base.buffer_handle != SVGA3D_INVALID_ID) {
15071510 ret = vmw_user_bo_lookup(file_priv, req->base.buffer_handle,
1508− &res->backup);
1511+ &res->guest_memory_bo);
15091512 if (ret == 0) {
1510− if (res->backup->base.base.size < res->backup_size) {
1513+ if (res->guest_memory_bo->tbo.base.size < res->guest_memory_size) {
15111514 VMW_DEBUG_USER("Surface backup buffer too small.\n");
1512− vmw_bo_unreference(&res->backup);
1515+ vmw_bo_unreference(&res->guest_memory_bo);
15131516 ret = -EINVAL;
15141517 goto out_unlock;
15151518 } else {
@@ -1520,11 +1523,11 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 4 unmodified lines
15201523 (drm_vmw_surface_flag_create_buffer |
15211524 drm_vmw_surface_flag_coherent)) {
15221525 ret = vmw_gem_object_create_with_handle(dev_priv, file_priv,
1523− res->backup_size,
1526+ res->guest_memory_size,
15241527 &backup_handle,
1525− &res->backup);
1528+ &res->guest_memory_bo);
15261529 if (ret == 0)
1527− vmw_bo_reference(res->backup);
1530+ vmw_bo_reference(res->guest_memory_bo);
15281531 }
15291532
15301533 if (unlikely(ret != 0)) {
@@ -1533,9 +1536,9 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 2 unmodified lines
15331536 }
15341537
15351538 if (req->base.drm_surface_flags & drm_vmw_surface_flag_coherent) {
1536− struct vmw_buffer_object *backup = res->backup;
1539+ struct vmw_bo *backup = res->guest_memory_bo;
15371540
1538− ttm_bo_reserve(&backup->base, false, false, NULL);
1541+ ttm_bo_reserve(&backup->tbo, false, false, NULL);
15391542 if (!res->func->dirty_alloc)
15401543 ret = -EINVAL;
15411544 if (!ret)
@@ -1544,7 +1547,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 2 unmodified lines
15441547 res->coherent = true;
15451548 ret = res->func->dirty_alloc(res);
15461549 }
1547− ttm_bo_unreserve(&backup->base);
1550+ ttm_bo_unreserve(&backup->tbo);
15481551 if (ret) {
15491552 vmw_resource_unreference(&res);
15501553 goto out_unlock;
@@ -1553,7 +1556,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 2 unmodified lines
15531556 }
15541557
15551558 tmp = vmw_resource_reference(res);
1556− ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
1559+ ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime,
15571560 req->base.drm_surface_flags &
15581561 drm_vmw_surface_flag_shareable,
15591562 VMW_RES_SURFACE,
@@ -1566,11 +1569,11 @@ vmw_gb_surface_define_internal(struct drm_device *dev, · 6 unmodified lines
15661569 }
15671570
15681571 rep->handle = user_srf->prime.base.handle;
1569− rep->backup_size = res->backup_size;
1570− if (res->backup) {
1572+ rep->backup_size = res->guest_memory_size;
1573+ if (res->guest_memory_bo) {
15711574 rep->buffer_map_handle =
1572− drm_vma_node_offset_addr(&res->backup->base.base.vma_node);
1573− rep->buffer_size = res->backup->base.base.size;
1575+ drm_vma_node_offset_addr(&res->guest_memory_bo->tbo.base.vma_node);
1576+ rep->buffer_size = res->guest_memory_bo->tbo.base.size;
15741577 rep->buffer_handle = backup_handle;
15751578 } else {
15761579 rep->buffer_map_handle = 0;
@@ -1613,14 +1616,14 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, · 36 unmodified lines
16131616
16141617 user_srf = container_of(base, struct vmw_user_surface, prime.base);
16151618 srf = &user_srf->srf;
1616− if (!srf->res.backup) {
1619+ if (!srf->res.guest_memory_bo) {
16171620 DRM_ERROR("Shared GB surface is missing a backup buffer.\n");
16181621 goto out_bad_resource;
16191622 }
16201623 metadata = &srf->metadata;
16211624
16221625 mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */
1623− ret = drm_gem_handle_create(file_priv, &srf->res.backup->base.base,
1626+ ret = drm_gem_handle_create(file_priv, &srf->res.guest_memory_bo->tbo.base,
16241627 &backup_handle);
16251628 mutex_unlock(&dev_priv->cmdbuf_mutex);
16261629 if (ret != 0) {
@@ -1639,11 +1642,11 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, · 12 unmodified lines
16391642 rep->creq.base.buffer_handle = backup_handle;
16401643 rep->creq.base.base_size = metadata->base_size;
16411644 rep->crep.handle = user_srf->prime.base.handle;
1642− rep->crep.backup_size = srf->res.backup_size;
1645+ rep->crep.backup_size = srf->res.guest_memory_size;
16431646 rep->crep.buffer_handle = backup_handle;
16441647 rep->crep.buffer_map_handle =
1645− drm_vma_node_offset_addr(&srf->res.backup->base.base.vma_node);
1646− rep->crep.buffer_size = srf->res.backup->base.base.size;
1648+ drm_vma_node_offset_addr(&srf->res.guest_memory_bo->tbo.base.vma_node);
1649+ rep->crep.buffer_size = srf->res.guest_memory_bo->tbo.base.size;
16471650
16481651 rep->creq.version = drm_vmw_gb_surface_v1;
16491652 rep->creq.svga3d_flags_upper_32_bits =
@@ -1742,12 +1745,12 @@ static void vmw_surface_tex_dirty_range_add(struct vmw_resource *res, · 92 unmodified lines
17421745 {
17431746 struct vmw_surface_dirty *dirty =
17441747 (struct vmw_surface_dirty *) res->dirty;
1745− size_t backup_end = res->backup_offset + res->backup_size;
1748+ size_t backup_end = res->guest_memory_offset + res->guest_memory_size;
17461749 struct vmw_surface_loc loc1, loc2;
17471750 const struct vmw_surface_cache *cache;
17481751
1749− start = max_t(size_t, start, res->backup_offset) - res->backup_offset;
1750− end = min(end, backup_end) - res->backup_offset;
1752+ start = max_t(size_t, start, res->guest_memory_offset) - res->guest_memory_offset;
1753+ end = min(end, backup_end) - res->guest_memory_offset;
17511754 cache = &dirty->cache;
17521755 vmw_surface_get_loc(cache, &loc1, start);
17531756 vmw_surface_get_loc(cache, &loc2, end - 1);
@@ -1794,13 +1797,13 @@ static void vmw_surface_buf_dirty_range_add(struct vmw_resource *res, · 40 unmodified lines
17941797 struct vmw_surface_dirty *dirty =
17951798 (struct vmw_surface_dirty *) res->dirty;
17961799 const struct vmw_surface_cache *cache = &dirty->cache;
1797− size_t backup_end = res->backup_offset + cache->mip_chain_bytes;
1800+ size_t backup_end = res->guest_memory_offset + cache->mip_chain_bytes;
17981801 SVGA3dBox *box = &dirty->boxes[0];
17991802 u32 box_c2;
18001803
18011804 box->h = box->d = 1;
1802− start = max_t(size_t, start, res->backup_offset) - res->backup_offset;
1803− end = min(end, backup_end) - res->backup_offset;
1805+ start = max_t(size_t, start, res->guest_memory_offset) - res->guest_memory_offset;
1806+ end = min(end, backup_end) - res->guest_memory_offset;
18041807 box_c2 = box->x + box->w;
18051808 if (box->w == 0 || box->x > start)
18061809 box->x = start;
@@ -1816,8 +1819,8 @@ static void vmw_surface_dirty_range_add(struct vmw_resource *res, size_t start, · 9 unmodified lines
18161819 {
18171820 struct vmw_surface *srf = vmw_res_to_srf(res);
18181821
1819− if (WARN_ON(end <= res->backup_offset ||
1820− start >= res->backup_offset + res->backup_size))
1822+ if (WARN_ON(end <= res->guest_memory_offset ||
1823+ start >= res->guest_memory_offset + res->guest_memory_size))
18211824 return;
18221825
18231826 if (srf->metadata.format == SVGA3D_BUFFER)
@@ -2074,7 +2077,7 @@ int vmw_gb_surface_define(struct vmw_private *dev_priv, · 250 unmodified lines
20742077 if (metadata->flags & SVGA3D_SURFACE_MULTISAMPLE)
20752078 sample_count = metadata->multisample_count;
20762079
2077− srf->res.backup_size =
2080+ srf->res.guest_memory_size =
20782081 vmw_surface_get_serialized_size_extended(
20792082 metadata->format,
20802083 metadata->base_size,
@@ -2083,7 +2086,7 @@ int vmw_gb_surface_define(struct vmw_private *dev_priv, · 2 unmodified lines
20832086 sample_count);
20842087
20852088 if (metadata->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT)
2086− srf->res.backup_size += sizeof(SVGA3dDXSOState);
2089+ srf->res.guest_memory_size += sizeof(SVGA3dDXSOState);
20872090
20882091 /*
20892092 * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c+34−100
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
55 *
66 * Permission is hereby granted, free of charge, to any person obtaining a
77 * copy of this software and associated documentation files (the
@@ -25,6 +25,7 @@ · 17 unmodified lines
2525 *
2626 **************************************************************************/
2727
28+#include "vmwgfx_bo.h"
2829 #include "vmwgfx_drv.h"
2930 #include <drm/ttm/ttm_placement.h>
3031
@@ -49,13 +50,6 @@ static const struct ttm_place gmr_placement_flags = { · 18 unmodified lines
4950 .flags = 0
5051 };
5152
52−static const struct ttm_place mob_placement_flags = {
53− .fpfn = 0,
54− .lpfn = 0,
55− .mem_type = VMW_PL_MOB,
56− .flags = 0
57−};
58−
5953 struct ttm_placement vmw_vram_placement = {
6054 .num_placement = 1,
6155 .placement = &vram_placement_flags,
@@ -77,27 +71,6 @@ static const struct ttm_place vram_gmr_placement_flags[] = { · 15 unmodified lines
7771 }
7872 };
7973
80−static const struct ttm_place gmr_vram_placement_flags[] = {
81− {
82− .fpfn = 0,
83− .lpfn = 0,
84− .mem_type = VMW_PL_GMR,
85− .flags = 0
86− }, {
87− .fpfn = 0,
88− .lpfn = 0,
89− .mem_type = TTM_PL_VRAM,
90− .flags = 0
91− }
92−};
93−
94−static const struct ttm_place vmw_sys_placement_flags = {
95− .fpfn = 0,
96− .lpfn = 0,
97− .mem_type = VMW_PL_SYSTEM,
98− .flags = 0
99−};
100−
10174 struct ttm_placement vmw_vram_gmr_placement = {
10275 .num_placement = 2,
10376 .placement = vram_gmr_placement_flags,
@@ -105,13 +78,6 @@ struct ttm_placement vmw_vram_gmr_placement = { · 1 unmodified line
10578 .busy_placement = &gmr_placement_flags
10679 };
10780
108−struct ttm_placement vmw_vram_sys_placement = {
109− .num_placement = 1,
110− .placement = &vram_placement_flags,
111− .num_busy_placement = 1,
112− .busy_placement = &sys_placement_flags
113−};
114−
11581 struct ttm_placement vmw_sys_placement = {
11682 .num_placement = 1,
11783 .placement = &sys_placement_flags,
@@ -119,53 +85,6 @@ struct ttm_placement vmw_sys_placement = { · 1 unmodified line
11985 .busy_placement = &sys_placement_flags
12086 };
12187
122−struct ttm_placement vmw_pt_sys_placement = {
123− .num_placement = 1,
124− .placement = &vmw_sys_placement_flags,
125− .num_busy_placement = 1,
126− .busy_placement = &vmw_sys_placement_flags
127−};
128−
129−static const struct ttm_place nonfixed_placement_flags[] = {
130− {
131− .fpfn = 0,
132− .lpfn = 0,
133− .mem_type = TTM_PL_SYSTEM,
134− .flags = 0
135− }, {
136− .fpfn = 0,
137− .lpfn = 0,
138− .mem_type = VMW_PL_GMR,
139− .flags = 0
140− }, {
141− .fpfn = 0,
142− .lpfn = 0,
143− .mem_type = VMW_PL_MOB,
144− .flags = 0
145− }
146−};
147−
148−struct ttm_placement vmw_srf_placement = {
149− .num_placement = 1,
150− .num_busy_placement = 2,
151− .placement = &gmr_placement_flags,
152− .busy_placement = gmr_vram_placement_flags
153−};
154−
155−struct ttm_placement vmw_mob_placement = {
156− .num_placement = 1,
157− .num_busy_placement = 1,
158− .placement = &mob_placement_flags,
159− .busy_placement = &mob_placement_flags
160−};
161−
162−struct ttm_placement vmw_nonfixed_placement = {
163− .num_placement = 3,
164− .placement = nonfixed_placement_flags,
165− .num_busy_placement = 1,
166− .busy_placement = &sys_placement_flags
167−};
168−
16988 const size_t vmw_tt_size = sizeof(struct vmw_ttm_tt);
17089
17190 /**
@@ -508,7 +427,7 @@ static struct ttm_tt *vmw_ttm_tt_create(struct ttm_buffer_object *bo, · 336 unmodified lines
508427 if (!vmw_be)
509428 return NULL;
510429
511− vmw_be->dev_priv = container_of(bo->bdev, struct vmw_private, bdev);
430+ vmw_be->dev_priv = vmw_priv_from_ttm(bo->bdev);
512431 vmw_be->mob = NULL;
513432
514433 if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent)
@@ -534,7 +453,7 @@ static void vmw_evict_flags(struct ttm_buffer_object *bo, · 19 unmodified lines
534453
535454 static int vmw_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource *mem)
536455 {
537− struct vmw_private *dev_priv = container_of(bdev, struct vmw_private, bdev);
456+ struct vmw_private *dev_priv = vmw_priv_from_ttm(bdev);
538457
539458 switch (mem->mem_type) {
540459 case TTM_PL_SYSTEM:
@@ -596,9 +515,13 @@ static int vmw_move(struct ttm_buffer_object *bo, · 55 unmodified lines
596515 struct ttm_resource *new_mem,
597516 struct ttm_place *hop)
598517 {
599− struct ttm_resource_manager *old_man = ttm_manager_type(bo->bdev, bo->resource->mem_type);
600− struct ttm_resource_manager *new_man = ttm_manager_type(bo->bdev, new_mem->mem_type);
601− int ret;
518+ struct ttm_resource_manager *new_man;
519+ struct ttm_resource_manager *old_man = NULL;
520+ int ret = 0;
521+
522+ new_man = ttm_manager_type(bo->bdev, new_mem->mem_type);
523+ if (bo->resource)
524+ old_man = ttm_manager_type(bo->bdev, bo->resource->mem_type);
602525
603526 if (new_man->use_tt && !vmw_memtype_is_system(new_mem->mem_type)) {
604527 ret = vmw_ttm_bind(bo->bdev, bo->ttm, new_mem);
@@ -606,9 +529,15 @@ static int vmw_move(struct ttm_buffer_object *bo, · 1 unmodified line
606529 return ret;
607530 }
608531
532+ if (!bo->resource || (bo->resource->mem_type == TTM_PL_SYSTEM &&
533+ bo->ttm == NULL)) {
534+ ttm_bo_move_null(bo, new_mem);
535+ return 0;
536+ }
537+
609538 vmw_move_notify(bo, bo->resource, new_mem);
610539
611− if (old_man->use_tt && new_man->use_tt) {
540+ if (old_man && old_man->use_tt && new_man->use_tt) {
612541 if (vmw_memtype_is_system(bo->resource->mem_type)) {
613542 ttm_bo_move_null(bo, new_mem);
614543 return 0;
@@ -645,34 +574,39 @@ struct ttm_device_funcs vmw_bo_driver = { · 30 unmodified lines
645574 };
646575
647576 int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
648− unsigned long bo_size,
649− struct ttm_buffer_object **bo_p)
577+ size_t bo_size, u32 domain,
578+ struct vmw_bo **bo_p)
650579 {
651580 struct ttm_operation_ctx ctx = {
652581 .interruptible = false,
653582 .no_wait_gpu = false
654583 };
655− struct ttm_buffer_object *bo;
584+ struct vmw_bo *vbo;
656585 int ret;
586+ struct vmw_bo_params bo_params = {
587+ .domain = domain,
588+ .busy_domain = domain,
589+ .bo_type = ttm_bo_type_kernel,
590+ .size = bo_size,
591+ .pin = true
592+ };
657593
658− ret = vmw_bo_create_kernel(dev_priv, bo_size,
659− &vmw_pt_sys_placement,
660− &bo);
594+ ret = vmw_bo_create(dev_priv, &bo_params, &vbo);
661595 if (unlikely(ret != 0))
662596 return ret;
663597
664− ret = ttm_bo_reserve(bo, false, true, NULL);
598+ ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
665599 BUG_ON(ret != 0);
666− ret = vmw_ttm_populate(bo->bdev, bo->ttm, &ctx);
600+ ret = vmw_ttm_populate(vbo->tbo.bdev, vbo->tbo.ttm, &ctx);
667601 if (likely(ret == 0)) {
668602 struct vmw_ttm_tt *vmw_tt =
669− container_of(bo->ttm, struct vmw_ttm_tt, dma_ttm);
603+ container_of(vbo->tbo.ttm, struct vmw_ttm_tt, dma_ttm);
670604 ret = vmw_ttm_map_dma(vmw_tt);
671605 }
672606
673− ttm_bo_unreserve(bo);
607+ ttm_bo_unreserve(&vbo->tbo);
674608
675609 if (likely(ret == 0))
676− *bo_p = bo;
610+ *bo_p = vbo;
677611 return ret;
678612 }
drivers/gpu/drm/vmwgfx/vmwgfx_va.c+4−2
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 *
2626 **************************************************************************/
2727
28+#include "vmwgfx_bo.h"
2829 #include "vmwgfx_drv.h"
2930 #include "vmwgfx_resource_priv.h"
3031
@@ -80,10 +81,11 @@ static void vmw_stream_set_arg_handle(void *data, u32 handle) · 49 unmodified lines
8081 static const struct vmw_simple_resource_func va_stream_func = {
8182 .res_func = {
8283 .res_type = vmw_res_stream,
83− .needs_backup = false,
84+ .needs_guest_memory = false,
8485 .may_evict = false,
8586 .type_name = "overlay stream",
86− .backup_placement = NULL,
87+ .domain = VMW_BO_DOMAIN_SYS,
88+ .busy_domain = VMW_BO_DOMAIN_SYS,
8789 .create = NULL,
8890 .destroy = NULL,
8991 .bind = NULL,
drivers/gpu/drm/vmwgfx/vmwgfx_validation.c+56−94
@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 OR MIT
22 /**************************************************************************
33 *
4− * Copyright © 2018 - 2022 VMware, Inc., Palo Alto, CA., USA
4+ * Copyright © 2018 - 2023 VMware, Inc., Palo Alto, CA., USA
55 * All Rights Reserved.
66 *
77 * Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,9 +25,12 @@ · 17 unmodified lines
2525 * USE OR OTHER DEALINGS IN THE SOFTWARE.
2626 *
2727 **************************************************************************/
28−#include <linux/slab.h>
29−#include "vmwgfx_validation.h"
28+#include "vmwgfx_bo.h"
3029 #include "vmwgfx_drv.h"
30+#include "vmwgfx_resource_priv.h"
31+#include "vmwgfx_validation.h"
32+
33+#include <linux/slab.h>
3134
3235
3336 #define VMWGFX_VALIDATION_MEM_GRAN (16*PAGE_SIZE)
@@ -38,8 +41,6 @@ · 4 unmodified lines
3841 * @hash: A hash entry used for the duplicate detection hash table.
3942 * @coherent_count: If switching backup buffers, number of new coherent
4043 * resources that will have this buffer as a backup buffer.
41− * @as_mob: Validate as mob.
42− * @cpu_blit: Validate for cpu blit access.
4344 *
4445 * Bit fields are used since these structures are allocated and freed in
4546 * large numbers and space conservation is desired.
@@ -48,21 +49,19 @@ struct vmw_validation_bo_node { · 2 unmodified lines
4849 struct ttm_validate_buffer base;
4950 struct vmwgfx_hash_item hash;
5051 unsigned int coherent_count;
51− u32 as_mob : 1;
52− u32 cpu_blit : 1;
5352 };
5453 /**
5554 * struct vmw_validation_res_node - Resource validation metadata.
5655 * @head: List head for the resource validation list.
5756 * @hash: A hash entry used for the duplicate detection hash table.
5857 * @res: Reference counted resource pointer.
59− * @new_backup: Non ref-counted pointer to new backup buffer to be assigned
60− * to a resource.
61− * @new_backup_offset: Offset into the new backup mob for resources that can
62− * share MOBs.
58+ * @new_guest_memory_bo: Non ref-counted pointer to new guest memory buffer
59+ * to be assigned to a resource.
60+ * @new_guest_memory_offset: Offset into the new backup mob for resources
61+ * that can share MOBs.
6362 * @no_buffer_needed: Kernel does not need to allocate a MOB during validation,
6463 * the command stream provides a mob bind operation.
65− * @switching_backup: The validation process is switching backup MOB.
64+ * @switching_guest_memory_bo: The validation process is switching backup MOB.
6665 * @first_usage: True iff the resource has been seen only once in the current
6766 * validation batch.
6867 * @reserved: Whether the resource is currently reserved by this process.
@@ -77,10 +76,10 @@ struct vmw_validation_res_node { · 8 unmodified lines
7776 struct list_head head;
7877 struct vmwgfx_hash_item hash;
7978 struct vmw_resource *res;
80− struct vmw_buffer_object *new_backup;
81− unsigned long new_backup_offset;
79+ struct vmw_bo *new_guest_memory_bo;
80+ unsigned long new_guest_memory_offset;
8281 u32 no_buffer_needed : 1;
83− u32 switching_backup : 1;
82+ u32 switching_guest_memory_bo : 1;
8483 u32 first_usage : 1;
8584 u32 reserved : 1;
8685 u32 dirty : 1;
@@ -173,7 +172,7 @@ static void vmw_validation_mem_free(struct vmw_validation_context *ctx) · 86 unmodified lines
173172 */
174173 static struct vmw_validation_bo_node *
175174 vmw_validation_find_bo_dup(struct vmw_validation_context *ctx,
176− struct vmw_buffer_object *vbo)
175+ struct vmw_bo *vbo)
177176 {
178177 struct vmw_validation_bo_node *bo_node = NULL;
179178
@@ -194,7 +193,7 @@ vmw_validation_find_bo_dup(struct vmw_validation_context *ctx, · 14 unmodified lines
194193 struct vmw_validation_bo_node *entry;
195194
196195 list_for_each_entry(entry, &ctx->bo_list, base.head) {
197− if (entry->base.bo == &vbo->base) {
196+ if (entry->base.bo == &vbo->tbo) {
198197 bo_node = entry;
199198 break;
200199 }
@@ -258,26 +257,16 @@ out: · 57 unmodified lines
258257 * vmw_validation_add_bo - Add a buffer object to the validation context.
259258 * @ctx: The validation context.
260259 * @vbo: The buffer object.
261− * @as_mob: Validate as mob, otherwise suitable for GMR operations.
262− * @cpu_blit: Validate in a page-mappable location.
263260 *
264261 * Return: Zero on success, negative error code otherwise.
265262 */
266263 int vmw_validation_add_bo(struct vmw_validation_context *ctx,
267− struct vmw_buffer_object *vbo,
268− bool as_mob,
269− bool cpu_blit)
264+ struct vmw_bo *vbo)
270265 {
271266 struct vmw_validation_bo_node *bo_node;
272267
273268 bo_node = vmw_validation_find_bo_dup(ctx, vbo);
274− if (bo_node) {
275− if (bo_node->as_mob != as_mob ||
276− bo_node->cpu_blit != cpu_blit) {
277− DRM_ERROR("Inconsistent buffer usage.\n");
278− return -EINVAL;
279− }
280− } else {
269+ if (!bo_node) {
281270 struct ttm_validate_buffer *val_buf;
282271
283272 bo_node = vmw_validation_mem_alloc(ctx, sizeof(*bo_node));
@@ -290,13 +279,11 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx, · 6 unmodified lines
290279 bo_node->hash.key);
291280 }
292281 val_buf = &bo_node->base;
293− val_buf->bo = ttm_bo_get_unless_zero(&vbo->base);
282+ val_buf->bo = ttm_bo_get_unless_zero(&vbo->tbo);
294283 if (!val_buf->bo)
295284 return -ESRCH;
296285 val_buf->num_shared = 0;
297286 list_add_tail(&val_buf->head, &ctx->bo_list);
298− bo_node->as_mob = as_mob;
299− bo_node->cpu_blit = cpu_blit;
300287 }
301288
302289 return 0;
@@ -406,23 +393,23 @@ void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx, · 103 unmodified lines
406393 * the resource.
407394 * @vbo: The new backup buffer object MOB. This buffer object needs to have
408395 * already been registered with the validation context.
409− * @backup_offset: Offset into the new backup MOB.
396+ * @guest_memory_offset: Offset into the new backup MOB.
410397 */
411398 void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx,
412399 void *val_private,
413− struct vmw_buffer_object *vbo,
414− unsigned long backup_offset)
400+ struct vmw_bo *vbo,
401+ unsigned long guest_memory_offset)
415402 {
416403 struct vmw_validation_res_node *val;
417404
418405 val = container_of(val_private, typeof(*val), private);
419406
420− val->switching_backup = 1;
407+ val->switching_guest_memory_bo = 1;
421408 if (val->first_usage)
422409 val->no_buffer_needed = 1;
423410
424− val->new_backup = vbo;
425− val->new_backup_offset = backup_offset;
411+ val->new_guest_memory_bo = vbo;
412+ val->new_guest_memory_offset = guest_memory_offset;
426413 }
427414
428415 /**
@@ -450,21 +437,22 @@ int vmw_validation_res_reserve(struct vmw_validation_context *ctx, · 21 unmodified lines
450437 goto out_unreserve;
451438
452439 val->reserved = 1;
453− if (res->backup) {
454− struct vmw_buffer_object *vbo = res->backup;
440+ if (res->guest_memory_bo) {
441+ struct vmw_bo *vbo = res->guest_memory_bo;
455442
456− ret = vmw_validation_add_bo
457− (ctx, vbo, vmw_resource_needs_backup(res),
458− false);
443+ vmw_bo_placement_set(vbo,
444+ res->func->domain,
445+ res->func->busy_domain);
446+ ret = vmw_validation_add_bo(ctx, vbo);
459447 if (ret)
460448 goto out_unreserve;
461449 }
462450
463− if (val->switching_backup && val->new_backup &&
451+ if (val->switching_guest_memory_bo && val->new_guest_memory_bo &&
464452 res->coherent) {
465453 struct vmw_validation_bo_node *bo_node =
466454 vmw_validation_find_bo_dup(ctx,
467− val->new_backup);
455+ val->new_guest_memory_bo);
468456
469457 if (WARN_ON(!bo_node)) {
470458 ret = -EINVAL;
@@ -507,9 +495,9 @@ void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, · 36 unmodified lines
507495 vmw_resource_unreserve(val->res,
508496 val->dirty_set,
509497 val->dirty,
510− val->switching_backup,
511− val->new_backup,
512− val->new_backup_offset);
498+ val->switching_guest_memory_bo,
499+ val->new_guest_memory_bo,
500+ val->new_guest_memory_offset);
513501 }
514502 }
515503
@@ -517,17 +505,14 @@ void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, · 1 unmodified line
517505 * vmw_validation_bo_validate_single - Validate a single buffer object.
518506 * @bo: The TTM buffer object base.
519507 * @interruptible: Whether to perform waits interruptible if possible.
520− * @validate_as_mob: Whether to validate in MOB memory.
521508 *
522509 * Return: Zero on success, -ERESTARTSYS if interrupted. Negative error
523510 * code on failure.
524511 */
525−int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo,
526− bool interruptible,
527− bool validate_as_mob)
512+static int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo,
513+ bool interruptible)
528514 {
529− struct vmw_buffer_object *vbo =
530− container_of(bo, struct vmw_buffer_object, base);
515+ struct vmw_bo *vbo = to_vmw_bo(&bo->base);
531516 struct ttm_operation_ctx ctx = {
532517 .interruptible = interruptible,
533518 .no_wait_gpu = false
@@ -537,30 +522,20 @@ int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo, · 3 unmodified lines
537522 if (atomic_read(&vbo->cpu_writers))
538523 return -EBUSY;
539524
540− if (vbo->base.pin_count > 0)
525+ if (vbo->tbo.pin_count > 0)
541526 return 0;
542527
543− if (validate_as_mob)
544− return ttm_bo_validate(bo, &vmw_mob_placement, &ctx);
545−
546− /**
547− * Put BO in VRAM if there is space, otherwise as a GMR.
548− * If there is no space in VRAM and GMR ids are all used up,
549− * start evicting GMRs to make room. If the DMA buffer can't be
550− * used as a GMR, this will return -ENOMEM.
551− */
552−
553− ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, &ctx);
528+ ret = ttm_bo_validate(bo, &vbo->placement, &ctx);
554529 if (ret == 0 || ret == -ERESTARTSYS)
555530 return ret;
556531
557− /**
558− * If that failed, try VRAM again, this time evicting
532+ /*
533+ * If that failed, try again, this time evicting
559534 * previous contents.
560535 */
536+ ctx.allow_res_evict = true;
561537
562− ret = ttm_bo_validate(bo, &vmw_vram_placement, &ctx);
563− return ret;
538+ return ttm_bo_validate(bo, &vbo->placement, &ctx);
564539 }
565540
566541 /**
@@ -578,21 +553,10 @@ int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr) · 11 unmodified lines
578553 int ret;
579554
580555 list_for_each_entry(entry, &ctx->bo_list, base.head) {
581− struct vmw_buffer_object *vbo =
582− container_of(entry->base.bo, typeof(*vbo), base);
583−
584− if (entry->cpu_blit) {
585− struct ttm_operation_ctx ttm_ctx = {
586− .interruptible = intr,
587− .no_wait_gpu = false
588− };
589−
590− ret = ttm_bo_validate(entry->base.bo,
591− &vmw_nonfixed_placement, &ttm_ctx);
592− } else {
593− ret = vmw_validation_bo_validate_single
594− (entry->base.bo, intr, entry->as_mob);
595− }
556+ struct vmw_bo *vbo = to_vmw_bo(&entry->base.bo->base);
557+
558+ ret = vmw_validation_bo_validate_single(entry->base.bo, intr);
559+
596560 if (ret)
597561 return ret;
598562
@@ -639,7 +603,7 @@ int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr) · 40 unmodified lines
639603
640604 list_for_each_entry(val, &ctx->resource_list, head) {
641605 struct vmw_resource *res = val->res;
642− struct vmw_buffer_object *backup = res->backup;
606+ struct vmw_bo *backup = res->guest_memory_bo;
643607
644608 ret = vmw_resource_validate(res, intr, val->dirty_set &&
645609 val->dirty);
@@ -650,12 +614,12 @@ int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr) · 4 unmodified lines
650614 }
651615
652616 /* Check if the resource switched backup buffer */
653− if (backup && res->backup && (backup != res->backup)) {
654− struct vmw_buffer_object *vbo = res->backup;
617+ if (backup && res->guest_memory_bo && backup != res->guest_memory_bo) {
618+ struct vmw_bo *vbo = res->guest_memory_bo;
655619
656− ret = vmw_validation_add_bo
657− (ctx, vbo, vmw_resource_needs_backup(res),
658− false);
620+ vmw_bo_placement_set(vbo, res->func->domain,
621+ res->func->busy_domain);
622+ ret = vmw_validation_add_bo(ctx, vbo);
659623 if (ret)
660624 return ret;
661625 }
@@ -889,9 +853,7 @@ void vmw_validation_bo_backoff(struct vmw_validation_context *ctx) · 227 unmodified lines
889853 list_for_each_entry(entry, &ctx->bo_list, base.head) {
890854 if (entry->coherent_count) {
891855 unsigned int coherent_count = entry->coherent_count;
892− struct vmw_buffer_object *vbo =
893− container_of(entry->base.bo, typeof(*vbo),
894− base);
856+ struct vmw_bo *vbo = to_vmw_bo(&entry->base.bo->base);
895857
896858 while (coherent_count--)
897859 vmw_bo_dirty_release(vbo);
drivers/gpu/drm/vmwgfx/vmwgfx_validation.h+3−7
@@ -73,7 +73,7 @@ struct vmw_validation_context { · 72 unmodified lines
7373 size_t total_mem;
7474 };
7575
76−struct vmw_buffer_object;
76+struct vmw_bo;
7777 struct vmw_resource;
7878 struct vmw_fence_obj;
7979
@@ -159,11 +159,7 @@ static inline unsigned int vmw_validation_align(unsigned int val) · 79 unmodified lines
159159 }
160160
161161 int vmw_validation_add_bo(struct vmw_validation_context *ctx,
162− struct vmw_buffer_object *vbo,
163− bool as_mob, bool cpu_blit);
164−int vmw_validation_bo_validate_single(struct ttm_buffer_object *bo,
165− bool interruptible,
166− bool validate_as_mob);
162+ struct vmw_bo *vbo);
167163 int vmw_validation_bo_validate(struct vmw_validation_context *ctx, bool intr);
168164 void vmw_validation_unref_lists(struct vmw_validation_context *ctx);
169165 int vmw_validation_add_resource(struct vmw_validation_context *ctx,
@@ -179,7 +175,7 @@ void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, · 9 unmodified lines
179175 bool backoff);
180176 void vmw_validation_res_switch_backup(struct vmw_validation_context *ctx,
181177 void *val_private,
182− struct vmw_buffer_object *vbo,
178+ struct vmw_bo *vbo,
183179 unsigned long backup_offset);
184180 int vmw_validation_res_validate(struct vmw_validation_context *ctx, bool intr);
185181
drivers/ps3/ps3av.c+5−4
@@ -11,13 +11,14 @@ · 10 unmodified lines
1111 #include <linux/delay.h>
1212 #include <linux/notifier.h>
1313 #include <linux/ioctl.h>
14−#include <linux/fb.h>
1514 #include <linux/slab.h>
1615
1716 #include <asm/firmware.h>
1817 #include <asm/ps3av.h>
1918 #include <asm/ps3.h>
2019
20+#include <video/cmdline.h>
21+
2122 #include "vuart.h"
2223
2324 #define BUFSIZE 4096 /* vuart buf size */
@@ -921,6 +922,7 @@ EXPORT_SYMBOL_GPL(ps3av_audio_mute); · 897 unmodified lines
921922
922923 static int ps3av_probe(struct ps3_system_bus_device *dev)
923924 {
925+ const char *mode_option;
924926 int res;
925927 int id;
926928
@@ -968,10 +970,9 @@ static int ps3av_probe(struct ps3_system_bus_device *dev) · 41 unmodified lines
968970
969971 ps3av_get_hw_conf(ps3av);
970972
971−#ifdef CONFIG_FB
972− if (fb_mode_option && !strcmp(fb_mode_option, "safe"))
973+ mode_option = video_get_options(NULL);
974+ if (mode_option && !strcmp(mode_option, "safe"))
973975 safe_mode = 1;
974−#endif /* CONFIG_FB */
975976 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
976977 if (id < 0) {
977978 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
drivers/video/Kconfig+3−0
@@ -11,6 +11,9 @@ config APERTURE_HELPERS · 10 unmodified lines
1111 Support tracking and hand-over of aperture ownership. Required
1212 by graphics drivers for firmware-provided framebuffers.
1313
14+config VIDEO_CMDLINE
15+ bool
16+
1417 config VIDEO_NOMODESET
1518 bool
1619 default n
drivers/video/Makefile+1−0
@@ -2,6 +2,7 @@ · 1 unmodified line
22
33 obj-$(CONFIG_APERTURE_HELPERS) += aperture.o
44 obj-$(CONFIG_VGASTATE) += vgastate.o
5+obj-$(CONFIG_VIDEO_CMDLINE) += cmdline.o
56 obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o
67 obj-$(CONFIG_HDMI) += hdmi.o
78
drivers/video/cmdline.c+133−0
@@ -0,0 +1,133 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Based on the fbdev code in drivers/video/fbdev/core/fb_cmdline:
4+ *
5+ * Copyright (C) 2014 Intel Corp
6+ * Copyright (C) 1994 Martin Schaller
7+ *
8+ * 2001 - Documented with DocBook
9+ * - Brad Douglas <brad@neruo.com>
10+ *
11+ * This file is subject to the terms and conditions of the GNU General Public
12+ * License. See the file COPYING in the main directory of this archive
13+ * for more details.
14+ *
15+ * Authors:
16+ * Daniel Vetter <daniel.vetter@ffwll.ch>
17+ */
18+
19+#include <linux/fb.h> /* for FB_MAX */
20+#include <linux/init.h>
21+
22+#include <video/cmdline.h>
23+
24+/*
25+ * FB_MAX is the maximum number of framebuffer devices and also
26+ * the maximum number of video= parameters. Although not directly
27+ * related to each other, it makes sense to keep it that way.
28+ */
29+static const char *video_options[FB_MAX] __read_mostly;
30+static const char *video_option __read_mostly;
31+static int video_of_only __read_mostly;
32+
33+static const char *__video_get_option_string(const char *name)
34+{
35+ const char *options = NULL;
36+ size_t name_len = 0;
37+
38+ if (name)
39+ name_len = strlen(name);
40+
41+ if (name_len) {
42+ unsigned int i;
43+ const char *opt;
44+
45+ for (i = 0; i < ARRAY_SIZE(video_options); ++i) {
46+ if (!video_options[i])
47+ continue;
48+ if (video_options[i][0] == '\0')
49+ continue;
50+ opt = video_options[i];
51+ if (!strncmp(opt, name, name_len) && opt[name_len] == ':')
52+ options = opt + name_len + 1;
53+ }
54+ }
55+
56+ /* No match, return global options */
57+ if (!options)
58+ options = video_option;
59+
60+ return options;
61+}
62+
63+/**
64+ * video_get_options - get kernel boot parameters
65+ * @name: name of the output as it would appear in the boot parameter
66+ * line (video=<name>:<options>)
67+ *
68+ * Looks up the video= options for the given name. Names are connector
69+ * names with DRM, or driver names with fbdev. If no video option for
70+ * the name has been specified, the function returns the global video=
71+ * setting. A @name of NULL always returns the global video setting.
72+ *
73+ * Returns:
74+ * The string of video options for the given name, or NULL if no video
75+ * option has been specified.
76+ */
77+const char *video_get_options(const char *name)
78+{
79+ return __video_get_option_string(name);
80+}
81+EXPORT_SYMBOL(video_get_options);
82+
83+bool __video_get_options(const char *name, const char **options, bool is_of)
84+{
85+ bool enabled = true;
86+ const char *opt = NULL;
87+
88+ if (video_of_only && !is_of)
89+ enabled = false;
90+
91+ opt = __video_get_option_string(name);
92+
93+ if (options)
94+ *options = opt;
95+
96+ return enabled;
97+}
98+EXPORT_SYMBOL(__video_get_options);
99+
100+/*
101+ * Process command line options for video adapters. This function is
102+ * a __setup and __init function. It only stores the options. Drivers
103+ * have to call video_get_options() as necessary.
104+ */
105+static int __init video_setup(char *options)
106+{
107+ if (!options || !*options)
108+ goto out;
109+
110+ if (!strncmp(options, "ofonly", 6)) {
111+ video_of_only = true;
112+ goto out;
113+ }
114+
115+ if (strchr(options, ':')) {
116+ /* named */
117+ size_t i;
118+
119+ for (i = 0; i < ARRAY_SIZE(video_options); i++) {
120+ if (!video_options[i]) {
121+ video_options[i] = options;
122+ break;
123+ }
124+ }
125+ } else {
126+ /* global */
127+ video_option = options;
128+ }
129+
130+out:
131+ return 1;
132+}
133+__setup("video=", video_setup);
drivers/video/fbdev/Kconfig+1−4
@@ -3,16 +3,13 @@ · 2 unmodified lines
33 # fbdev configuration
44 #
55
6−config FB_CMDLINE
7− bool
8−
96 config FB_NOTIFY
107 bool
118
129 menuconfig FB
1310 tristate "Support for frame buffer devices"
14− select FB_CMDLINE
1511 select FB_NOTIFY
12+ select VIDEO_CMDLINE
1613 help
1714 The frame buffer device provides an abstraction for the graphics
1815 hardware. It represents the frame buffer of some video hardware and
drivers/video/fbdev/core/Makefile+1−2
@@ -1,9 +1,8 @@
11 # SPDX-License-Identifier: GPL-2.0
2−obj-$(CONFIG_FB_CMDLINE) += fb_cmdline.o
32 obj-$(CONFIG_FB_NOTIFY) += fb_notify.o
43 obj-$(CONFIG_FB) += fb.o
54 fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
6− modedb.o fbcvt.o
5+ modedb.o fbcvt.o fb_cmdline.o
76 fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
87
98 ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE),y)
drivers/video/fbdev/core/fb_cmdline.c+24−70
@@ -12,16 +12,14 @@ · 11 unmodified lines
1212 * for more details.
1313 *
1414 * Authors:
15− * Vetter <danie.vetter@ffwll.ch>
15+ * Daniel Vetter <daniel.vetter@ffwll.ch>
1616 */
17−#include <linux/init.h>
18−#include <linux/fb.h>
1917
20−static char *video_options[FB_MAX] __read_mostly;
21−static int ofonly __read_mostly;
18+#include <linux/export.h>
19+#include <linux/fb.h>
20+#include <linux/string.h>
2221
23−const char *fb_mode_option;
24−EXPORT_SYMBOL_GPL(fb_mode_option);
22+#include <video/cmdline.h>
2523
2624 /**
2725 * fb_get_options - get kernel boot parameters
@@ -30,78 +28,34 @@ EXPORT_SYMBOL_GPL(fb_mode_option); · 2 unmodified lines
3028 * (video=<name>:<options>)
3129 * @option: the option will be stored here
3230 *
31+ * The caller owns the string returned in @option and is
32+ * responsible for releasing the memory.
33+ *
3334 * NOTE: Needed to maintain backwards compatibility
3435 */
3536 int fb_get_options(const char *name, char **option)
3637 {
37− char *opt, *options = NULL;
38− int retval = 0;
39− int name_len = strlen(name), i;
40−
41− if (name_len && ofonly && strncmp(name, "offb", 4))
42− retval = 1;
38+ const char *options = NULL;
39+ bool is_of = false;
40+ bool enabled;
4341
44− if (name_len && !retval) {
45− for (i = 0; i < FB_MAX; i++) {
46− if (video_options[i] == NULL)
47− continue;
48− if (!video_options[i][0])
49− continue;
50− opt = video_options[i];
51− if (!strncmp(name, opt, name_len) &&
52− opt[name_len] == ':')
53− options = opt + name_len + 1;
54− }
55− }
56− /* No match, pass global option */
57− if (!options && option && fb_mode_option)
58− options = kstrdup(fb_mode_option, GFP_KERNEL);
59− if (options && !strncmp(options, "off", 3))
60− retval = 1;
61−
62− if (option)
63− *option = options;
64−
65− return retval;
66−}
67−EXPORT_SYMBOL(fb_get_options);
42+ if (name)
43+ is_of = strncmp(name, "offb", 4);
6844
69−/**
70− * video_setup - process command line options
71− * @options: string of options
72− *
73− * Process command line options for frame buffer subsystem.
74− *
75− * NOTE: This function is a __setup and __init function.
76− * It only stores the options. Drivers have to call
77− * fb_get_options() as necessary.
78− */
79−static int __init video_setup(char *options)
80−{
81− if (!options || !*options)
82− goto out;
45+ enabled = __video_get_options(name, &options, is_of);
8346
84− if (!strncmp(options, "ofonly", 6)) {
85− ofonly = 1;
86− goto out;
47+ if (options) {
48+ if (!strncmp(options, "off", 3))
49+ enabled = false;
8750 }
8851
89− if (strchr(options, ':')) {
90− /* named */
91− int i;
92−
93− for (i = 0; i < FB_MAX; i++) {
94− if (video_options[i] == NULL) {
95− video_options[i] = options;
96− break;
97− }
98− }
99− } else {
100− /* global */
101− fb_mode_option = options;
52+ if (option) {
53+ if (options)
54+ *option = kstrdup(options, GFP_KERNEL);
55+ else
56+ *option = NULL;
10257 }
10358
104−out:
105− return 1;
59+ return enabled ? 0 : 1; // 0 on success, 1 otherwise
10660 }
107−__setup("video=", video_setup);
61+EXPORT_SYMBOL(fb_get_options);
drivers/video/fbdev/core/modedb.c+6−2
@@ -620,6 +620,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, · 619 unmodified lines
620620 const struct fb_videomode *default_mode,
621621 unsigned int default_bpp)
622622 {
623+ char *mode_option_buf = NULL;
623624 int i;
624625
625626 /* Set up defaults */
@@ -635,8 +636,10 @@ int fb_find_mode(struct fb_var_screeninfo *var, · 9 unmodified lines
635636 default_bpp = 8;
636637
637638 /* Did the user specify a video mode? */
638− if (!mode_option)
639− mode_option = fb_mode_option;
639+ if (!mode_option) {
640+ fb_get_options(NULL, &mode_option_buf);
641+ mode_option = mode_option_buf;
642+ }
640643 if (mode_option) {
641644 const char *name = mode_option;
642645 unsigned int namelen = strlen(name);
@@ -715,6 +718,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, · 72 unmodified lines
715718 res_specified = 1;
716719 }
717720 done:
721+ kfree(mode_option_buf);
718722 if (cvt) {
719723 struct fb_videomode cvt_mode;
720724 int ret;
include/drm/drm_atomic_helper.h+26−0
@@ -209,6 +209,32 @@ int drm_atomic_helper_page_flip_target( · 208 unmodified lines
209209 __drm_atomic_get_current_plane_state((crtc_state)->state, \
210210 plane)))
211211
212+/**
213+ * drm_atomic_plane_enabling - check whether a plane is being enabled
214+ * @old_plane_state: old atomic plane state
215+ * @new_plane_state: new atomic plane state
216+ *
217+ * Checks the atomic state of a plane to determine whether it's being enabled
218+ * or not. This also WARNs if it detects an invalid state (both CRTC and FB
219+ * need to either both be NULL or both be non-NULL).
220+ *
221+ * RETURNS:
222+ * True if the plane is being enabled, false otherwise.
223+ */
224+static inline bool drm_atomic_plane_enabling(struct drm_plane_state *old_plane_state,
225+ struct drm_plane_state *new_plane_state)
226+{
227+ /*
228+ * When enabling a plane, CRTC and FB should always be set together.
229+ * Anything else should be considered a bug in the atomic core, so we
230+ * gently warn about it.
231+ */
232+ WARN_ON((!new_plane_state->crtc && new_plane_state->fb) ||
233+ (new_plane_state->crtc && !new_plane_state->fb));
234+
235+ return !old_plane_state->crtc && new_plane_state->crtc;
236+}
237+
212238 /**
213239 * drm_atomic_plane_disabling - check whether a plane is being disabled
214240 * @old_plane_state: old atomic plane state
include/drm/drm_displayid.h+11−1
@@ -139,7 +139,11 @@ struct displayid_vesa_vendor_specific_block { · 138 unmodified lines
139139 u8 mso;
140140 } __packed;
141141
142−/* DisplayID iteration */
142+/*
143+ * DisplayID iteration.
144+ *
145+ * Do not access directly, this is private.
146+ */
143147 struct displayid_iter {
144148 const struct drm_edid *drm_edid;
145149
@@ -147,6 +151,9 @@ struct displayid_iter { · 1 unmodified line
147151 int length;
148152 int idx;
149153 int ext_index;
154+
155+ u8 version;
156+ u8 primary_use;
150157 };
151158
152159 void displayid_iter_edid_begin(const struct drm_edid *drm_edid,
@@ -157,4 +164,7 @@ __displayid_iter_next(struct displayid_iter *iter); · 4 unmodified lines
157164 while (((__block) = __displayid_iter_next(__iter)))
158165 void displayid_iter_end(struct displayid_iter *iter);
159166
167+u8 displayid_version(const struct displayid_iter *iter);
168+u8 displayid_primary_use(const struct displayid_iter *iter);
169+
160170 #endif
include/drm/drm_drv.h+0−19
@@ -400,25 +400,6 @@ struct drm_driver { · 399 unmodified lines
400400 int (*dumb_map_offset)(struct drm_file *file_priv,
401401 struct drm_device *dev, uint32_t handle,
402402 uint64_t *offset);
403− /**
404− * @dumb_destroy:
405− *
406− * This destroys the userspace handle for the given dumb backing storage buffer.
407− * Since buffer objects must be reference counted in the kernel a buffer object
408− * won't be immediately freed if a framebuffer modeset object still uses it.
409− *
410− * Called by the user via ioctl.
411− *
412− * The default implementation is drm_gem_dumb_destroy(). GEM based drivers
413− * must not overwrite this.
414− *
415− * Returns:
416− *
417− * Zero on success, negative errno on failure.
418− */
419− int (*dumb_destroy)(struct drm_file *file_priv,
420− struct drm_device *dev,
421− uint32_t handle);
422403
423404 /** @major: driver major number */
424405 int major;
include/drm/drm_edid.h+9−3
@@ -61,9 +61,15 @@ struct std_timing { · 60 unmodified lines
6161 u8 vfreq_aspect;
6262 } __attribute__((packed));
6363
64−#define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1)
65−#define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2)
66−#define DRM_EDID_PT_SEPARATE_SYNC (3 << 3)
64+#define DRM_EDID_PT_SYNC_MASK (3 << 3)
65+# define DRM_EDID_PT_ANALOG_CSYNC (0 << 3)
66+# define DRM_EDID_PT_BIPOLAR_ANALOG_CSYNC (1 << 3)
67+# define DRM_EDID_PT_DIGITAL_CSYNC (2 << 3)
68+# define DRM_EDID_PT_CSYNC_ON_RGB (1 << 1) /* analog csync only */
69+# define DRM_EDID_PT_CSYNC_SERRATE (1 << 2)
70+# define DRM_EDID_PT_DIGITAL_SEPARATE_SYNC (3 << 3)
71+# define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1) /* also digital csync */
72+# define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2)
6773 #define DRM_EDID_PT_STEREO (1 << 5)
6874 #define DRM_EDID_PT_INTERLACED (1 << 7)
6975
include/drm/drm_gem.h+12−0
@@ -164,6 +164,16 @@ struct drm_gem_object_funcs { · 163 unmodified lines
164164 */
165165 int (*mmap)(struct drm_gem_object *obj, struct vm_area_struct *vma);
166166
167+ /**
168+ * @evict:
169+ *
170+ * Evicts gem object out from memory. Used by the drm_gem_object_evict()
171+ * helper. Returns 0 on success, -errno otherwise.
172+ *
173+ * This callback is optional.
174+ */
175+ int (*evict)(struct drm_gem_object *obj);
176+
167177 /**
168178 * @vm_ops:
169179 *
@@ -479,4 +489,6 @@ void drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj); · 309 unmodified lines
479489 unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
480490 bool (*shrink)(struct drm_gem_object *obj));
481491
492+int drm_gem_evict(struct drm_gem_object *obj);
493+
482494 #endif /* __DRM_GEM_H__ */
include/drm/drm_gem_shmem_helper.h+15−15
@@ -60,20 +60,6 @@ struct drm_gem_shmem_object { · 59 unmodified lines
6060 */
6161 struct list_head madv_list;
6262
63− /**
64− * @pages_mark_dirty_on_put:
65− *
66− * Mark pages as dirty when they are put.
67− */
68− unsigned int pages_mark_dirty_on_put : 1;
69−
70− /**
71− * @pages_mark_accessed_on_put:
72− *
73− * Mark pages as accessed when they are put.
74− */
75− unsigned int pages_mark_accessed_on_put : 1;
76−
7763 /**
7864 * @sgt: Scatter/gather table for imported PRIME buffers
7965 */
@@ -97,10 +83,24 @@ struct drm_gem_shmem_object { · 17 unmodified lines
9783 */
9884 unsigned int vmap_use_count;
9985
86+ /**
87+ * @pages_mark_dirty_on_put:
88+ *
89+ * Mark pages as dirty when they are put.
90+ */
91+ bool pages_mark_dirty_on_put : 1;
92+
93+ /**
94+ * @pages_mark_accessed_on_put:
95+ *
96+ * Mark pages as accessed when they are put.
97+ */
98+ bool pages_mark_accessed_on_put : 1;
99+
100100 /**
101101 * @map_wc: map object write-combined (instead of using shmem defaults).
102102 */
103− bool map_wc;
103+ bool map_wc : 1;
104104 };
105105
106106 #define to_drm_gem_shmem_obj(obj) \
include/drm/drm_modeset_helper_vtables.h+28−1
@@ -1331,6 +1331,32 @@ struct drm_plane_helper_funcs { · 1330 unmodified lines
13311331 */
13321332 void (*atomic_update)(struct drm_plane *plane,
13331333 struct drm_atomic_state *state);
1334+
1335+ /**
1336+ * @atomic_enable:
1337+ *
1338+ * Drivers should use this function to unconditionally enable a plane.
1339+ * This hook is called in-between the &drm_crtc_helper_funcs.atomic_begin
1340+ * and drm_crtc_helper_funcs.atomic_flush callbacks. It is called after
1341+ * @atomic_update, which will be called for all enabled planes. Drivers
1342+ * that use @atomic_enable should set up a plane in @atomic_update and
1343+ * afterwards enable the plane in @atomic_enable. If a plane needs to be
1344+ * enabled before installing the scanout buffer, drivers can still do
1345+ * so in @atomic_update.
1346+ *
1347+ * Note that the power state of the display pipe when this function is
1348+ * called depends upon the exact helpers and calling sequence the driver
1349+ * has picked. See drm_atomic_helper_commit_planes() for a discussion of
1350+ * the tradeoffs and variants of plane commit helpers.
1351+ *
1352+ * This callback is used by the atomic modeset helpers, but it is
1353+ * optional. If implemented, @atomic_enable should be the inverse of
1354+ * @atomic_disable. Drivers that don't want to use either can still
1355+ * implement the complete plane update in @atomic_update.
1356+ */
1357+ void (*atomic_enable)(struct drm_plane *plane,
1358+ struct drm_atomic_state *state);
1359+
13341360 /**
13351361 * @atomic_disable:
13361362 *
@@ -1351,7 +1377,8 @@ struct drm_plane_helper_funcs { · 14 unmodified lines
13511377 * the tradeoffs and variants of plane commit helpers.
13521378 *
13531379 * This callback is used by the atomic modeset helpers and by the
1354− * transitional plane helpers, but it is optional.
1380+ * transitional plane helpers, but it is optional. It's intended to
1381+ * reverse the effects of @atomic_enable.
13551382 */
13561383 void (*atomic_disable)(struct drm_plane *plane,
13571384 struct drm_atomic_state *state);
include/drm/drm_of.h+12−0
@@ -15,6 +15,8 @@ struct drm_encoder; · 14 unmodified lines
1515 struct drm_panel;
1616 struct drm_bridge;
1717 struct device_node;
18+struct mipi_dsi_device_info;
19+struct mipi_dsi_host;
1820
1921 /**
2022 * enum drm_lvds_dual_link_pixels - Pixel order of an LVDS dual-link connection
@@ -129,6 +131,16 @@ drm_of_get_data_lanes_count_ep(const struct device_node *port, · 108 unmodified lines
129131 }
130132 #endif
131133
134+#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_MIPI_DSI)
135+struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev);
136+#else
137+static inline struct
138+mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev)
139+{
140+ return ERR_PTR(-EINVAL);
141+}
142+#endif /* CONFIG_OF && CONFIG_DRM_MIPI_DSI */
143+
132144 /*
133145 * drm_of_panel_bridge_remove - remove panel bridge
134146 * @np: device tree node containing panel bridge output ports
include/drm/drm_suballoc.h+108−0
@@ -0,0 +1,108 @@
1+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
2+/*
3+ * Copyright 2011 Red Hat Inc.
4+ * Copyright © 2022 Intel Corporation
5+ */
6+#ifndef _DRM_SUBALLOC_H_
7+#define _DRM_SUBALLOC_H_
8+
9+#include <drm/drm_mm.h>
10+
11+#include <linux/dma-fence.h>
12+#include <linux/types.h>
13+
14+#define DRM_SUBALLOC_MAX_QUEUES 32
15+/**
16+ * struct drm_suballoc_manager - fenced range allocations
17+ * @wq: Wait queue for sleeping allocations on contention.
18+ * @hole: Pointer to first hole node.
19+ * @olist: List of allocated ranges.
20+ * @flist: Array[fence context hash] of queues of fenced allocated ranges.
21+ * @size: Size of the managed range.
22+ * @align: Default alignment for the managed range.
23+ */
24+struct drm_suballoc_manager {
25+ wait_queue_head_t wq;
26+ struct list_head *hole;
27+ struct list_head olist;
28+ struct list_head flist[DRM_SUBALLOC_MAX_QUEUES];
29+ size_t size;
30+ size_t align;
31+};
32+
33+/**
34+ * struct drm_suballoc - Sub-allocated range
35+ * @olist: List link for list of allocated ranges.
36+ * @flist: List linkk for the manager fenced allocated ranges queues.
37+ * @manager: The drm_suballoc_manager.
38+ * @soffset: Start offset.
39+ * @eoffset: End offset + 1 so that @eoffset - @soffset = size.
40+ * @dma_fence: The fence protecting the allocation.
41+ */
42+struct drm_suballoc {
43+ struct list_head olist;
44+ struct list_head flist;
45+ struct drm_suballoc_manager *manager;
46+ size_t soffset;
47+ size_t eoffset;
48+ struct dma_fence *fence;
49+};
50+
51+void drm_suballoc_manager_init(struct drm_suballoc_manager *sa_manager,
52+ size_t size, size_t align);
53+
54+void drm_suballoc_manager_fini(struct drm_suballoc_manager *sa_manager);
55+
56+struct drm_suballoc *
57+drm_suballoc_new(struct drm_suballoc_manager *sa_manager, size_t size,
58+ gfp_t gfp, bool intr, size_t align);
59+
60+void drm_suballoc_free(struct drm_suballoc *sa, struct dma_fence *fence);
61+
62+/**
63+ * drm_suballoc_soffset - Range start.
64+ * @sa: The struct drm_suballoc.
65+ *
66+ * Return: The start of the allocated range.
67+ */
68+static inline size_t drm_suballoc_soffset(struct drm_suballoc *sa)
69+{
70+ return sa->soffset;
71+}
72+
73+/**
74+ * drm_suballoc_eoffset - Range end.
75+ * @sa: The struct drm_suballoc.
76+ *
77+ * Return: The end of the allocated range + 1.
78+ */
79+static inline size_t drm_suballoc_eoffset(struct drm_suballoc *sa)
80+{
81+ return sa->eoffset;
82+}
83+
84+/**
85+ * drm_suballoc_size - Range size.
86+ * @sa: The struct drm_suballoc.
87+ *
88+ * Return: The size of the allocated range.
89+ */
90+static inline size_t drm_suballoc_size(struct drm_suballoc *sa)
91+{
92+ return sa->eoffset - sa->soffset;
93+}
94+
95+#ifdef CONFIG_DEBUG_FS
96+void drm_suballoc_dump_debug_info(struct drm_suballoc_manager *sa_manager,
97+ struct drm_printer *p,
98+ unsigned long long suballoc_base);
99+#else
100+static inline void
101+drm_suballoc_dump_debug_info(struct drm_suballoc_manager *sa_manager,
102+ struct drm_printer *p,
103+ unsigned long long suballoc_base)
104+{ }
105+
106+#endif
107+
108+#endif /* _DRM_SUBALLOC_H_ */
include/drm/gpu_scheduler.h+6−0
@@ -48,6 +48,8 @@ struct drm_gem_object; · 47 unmodified lines
4848 struct drm_gpu_scheduler;
4949 struct drm_sched_rq;
5050
51+struct drm_file;
52+
5153 /* These are often used as an (initial) index
5254 * to an array, and as such should start at 0.
5355 */
@@ -522,6 +524,10 @@ int drm_sched_job_init(struct drm_sched_job *job, · 468 unmodified lines
522524 void drm_sched_job_arm(struct drm_sched_job *job);
523525 int drm_sched_job_add_dependency(struct drm_sched_job *job,
524526 struct dma_fence *fence);
527+int drm_sched_job_add_syncobj_dependency(struct drm_sched_job *job,
528+ struct drm_file *file,
529+ u32 handle,
530+ u32 point);
525531 int drm_sched_job_add_resv_dependencies(struct drm_sched_job *job,
526532 struct dma_resv *resv,
527533 enum dma_resv_usage usage);
include/drm/ttm/ttm_device.h+1−1
@@ -141,7 +141,7 @@ struct ttm_device_funcs { · 140 unmodified lines
141141 * the graphics address space
142142 * @ctx: context for this move with parameters
143143 * @new_mem: the new memory region receiving the buffer
144− @ @hop: placement for driver directed intermediate hop
144+ * @hop: placement for driver directed intermediate hop
145145 *
146146 * Move a buffer between two memory regions.
147147 * Returns errno -EMULTIHOP if driver requests a hop
include/linux/fb.h+0−1
@@ -765,7 +765,6 @@ struct dmt_videomode { · 764 unmodified lines
765765 const struct fb_videomode *mode;
766766 };
767767
768−extern const char *fb_mode_option;
769768 extern const struct fb_videomode vesa_modes[];
770769 extern const struct dmt_videomode dmt_modes[];
771770
include/uapi/drm/drm.h+55−2
@@ -972,6 +972,19 @@ extern "C" { · 971 unmodified lines
972972 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
973973 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
974974 #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
975+/**
976+ * DRM_IOCTL_GEM_CLOSE - Close a GEM handle.
977+ *
978+ * GEM handles are not reference-counted by the kernel. User-space is
979+ * responsible for managing their lifetime. For example, if user-space imports
980+ * the same memory object twice on the same DRM file description, the same GEM
981+ * handle is returned by both imports, and user-space needs to ensure
982+ * &DRM_IOCTL_GEM_CLOSE is performed once only. The same situation can happen
983+ * when a memory object is allocated, then exported and imported again on the
984+ * same DRM file description. The &DRM_IOCTL_MODE_GETFB2 IOCTL is an exception
985+ * and always returns fresh new GEM handles even if an existing GEM handle
986+ * already refers to the same memory object before the IOCTL is performed.
987+ */
975988 #define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
976989 #define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
977990 #define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
@@ -1012,7 +1025,37 @@ extern "C" { · 34 unmodified lines
10121025 #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock)
10131026 #define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock)
10141027
1028+/**
1029+ * DRM_IOCTL_PRIME_HANDLE_TO_FD - Convert a GEM handle to a DMA-BUF FD.
1030+ *
1031+ * User-space sets &drm_prime_handle.handle with the GEM handle to export and
1032+ * &drm_prime_handle.flags, and gets back a DMA-BUF file descriptor in
1033+ * &drm_prime_handle.fd.
1034+ *
1035+ * The export can fail for any driver-specific reason, e.g. because export is
1036+ * not supported for this specific GEM handle (but might be for others).
1037+ *
1038+ * Support for exporting DMA-BUFs is advertised via &DRM_PRIME_CAP_EXPORT.
1039+ */
10151040 #define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle)
1041+/**
1042+ * DRM_IOCTL_PRIME_FD_TO_HANDLE - Convert a DMA-BUF FD to a GEM handle.
1043+ *
1044+ * User-space sets &drm_prime_handle.fd with a DMA-BUF file descriptor to
1045+ * import, and gets back a GEM handle in &drm_prime_handle.handle.
1046+ * &drm_prime_handle.flags is unused.
1047+ *
1048+ * If an existing GEM handle refers to the memory object backing the DMA-BUF,
1049+ * that GEM handle is returned. Therefore user-space which needs to handle
1050+ * arbitrary DMA-BUFs must have a user-space lookup data structure to manually
1051+ * reference-count duplicated GEM handles. For more information see
1052+ * &DRM_IOCTL_GEM_CLOSE.
1053+ *
1054+ * The import can fail for any driver-specific reason, e.g. because import is
1055+ * only supported for DMA-BUFs allocated on this DRM device.
1056+ *
1057+ * Support for importing DMA-BUFs is advertised via &DRM_PRIME_CAP_IMPORT.
1058+ */
10161059 #define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle)
10171060
10181061 #define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
@@ -1104,8 +1147,13 @@ extern "C" { · 85 unmodified lines
11041147 * struct as the output.
11051148 *
11061149 * If the client is DRM master or has &CAP_SYS_ADMIN, &drm_mode_fb_cmd2.handles
1107− * will be filled with GEM buffer handles. Planes are valid until one has a
1108− * zero handle -- this can be used to compute the number of planes.
1150+ * will be filled with GEM buffer handles. Fresh new GEM handles are always
1151+ * returned, even if another GEM handle referring to the same memory object
1152+ * already exists on the DRM file description. The caller is responsible for
1153+ * removing the new handles, e.g. via the &DRM_IOCTL_GEM_CLOSE IOCTL. The same
1154+ * new handle will be returned for multiple planes in case they use the same
1155+ * memory object. Planes are valid until one has a zero handle -- this can be
1156+ * used to compute the number of planes.
11091157 *
11101158 * Otherwise, &drm_mode_fb_cmd2.handles will be zeroed and planes are valid
11111159 * until one has a zero &drm_mode_fb_cmd2.pitches.
@@ -1113,6 +1161,11 @@ extern "C" { · 1 unmodified line
11131161 * If the framebuffer has a format modifier, &DRM_MODE_FB_MODIFIERS will be set
11141162 * in &drm_mode_fb_cmd2.flags and &drm_mode_fb_cmd2.modifier will contain the
11151163 * modifier. Otherwise, user-space must ignore &drm_mode_fb_cmd2.modifier.
1164+ *
1165+ * To obtain DMA-BUF FDs for each plane without leaking GEM handles, user-space
1166+ * can export each handle via &DRM_IOCTL_PRIME_HANDLE_TO_FD, then immediately
1167+ * close each unique handle via &DRM_IOCTL_GEM_CLOSE, making sure to not
1168+ * double-close handles which are specified multiple times in the array.
11161169 */
11171170 #define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
11181171
include/video/cmdline.h+20−0
@@ -0,0 +1,20 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+
3+#ifndef VIDEO_CMDLINE_H
4+#define VIDEO_CMDLINE_H
5+
6+#include <linux/types.h>
7+
8+#if defined(CONFIG_VIDEO_CMDLINE)
9+const char *video_get_options(const char *name);
10+
11+/* exported for compatibility with fbdev; don't use in new code */
12+bool __video_get_options(const char *name, const char **option, bool is_of);
13+#else
14+static inline const char *video_get_options(const char *name)
15+{
16+ return NULL;
17+}
18+#endif
19+
20+#endif