drm pull for 6.1-rc1

core:
 - convert selftests to kunit
 - managed init for more objects
 - move to idr_init_base
 - rename fb and gem cma helpers to dma
 - hide unregistered connectors from getconnector ioctl
 - DSC passthrough aux support
 - backlight handling improvements
 - add dma_resv_assert_held to vmap/vunmap
 
 edid:
 - move luminance calculation to core
 
 fbdev:
 - fix aperture helper usage
 
 fourcc:
 - add more format helpers
 - add DRM_FORMAT_Cxx, DRM_FORMAT_Rxx, DRM_FORMAT_Dxx
 - add packed AYUV8888, XYUV8888
 - add some kunit tests
 
 ttm:
 - allow bos without backing store
 - rewrite placement to use intersect/compatible functions
 
 dma-buf:
 - docs update
 - improve signalling when debugging
 
 udmabuf:
 - fix failure path GPF
 
 dp:
 - drop dp/mst legacy code
 - atomic mst state support
 - audio infoframe packing
 
 panel:
 - Samsung LTL101AL01
 - B120XAN01.0
 - R140NWF5 RH
 - DMT028VGHMCMI-1A T
 - AUO B133UAN02.1
 - IVO M133NW4J-R3
 - Innolux N120ACA-EA1
 
 amdgpu:
 - Gang submit support
 - Mode2 reset for RDNA2
 - New IP support:
   DCN 3.1.4, 3.2
   SMU 13.x
   NBIO 7.7
   GC 11.x
   PSP 13.x
   SDMA 6.x
   GMC 11.x
 - DSC passthrough support
 - PSP fixes for TA support
 - vangogh GFXOFF stats
 - clang fixes
 - gang submit CS cleanup prep work
 - fix VRAM eviction issues
 
 amdkfd:
 - GC 10.3 IP ISA fixes
 - fix CRIU regression
 - CPU fault on COW mapping fixes
 
 i915:
 - align fw versioning with kernel practices
 - add display substruct to i915 private
 - add initial runtime info to driver info
 - split out HDCP and backlight registers
 - MEI XeHP SDV GSC support
 - add per-gt sysfs defaults
 - TLB invalidation improvements
 - Disable PCI BAR resize on 32-bit
 - GuC firmware updates and compat changes
 - GuC log timestamp translation
 - DG2 preemption workaround changes
 - DG2 improved HDMI pixel clocks support
 - PCI BAR sanity checks
 - Enable DC5 on DG2
 - DG2 DMC fw bumped
 - ADL-S PCI ID added
 - Meteorlake enablement
 - Rename ggtt_view to gtt_view
 - host RPS fixes
 - release mmaps on rpm suspend on discrete
 - clocking and dpll refactoring
 - VBT definitions and parsing updates
 - SKL watermark code extracted to separate file
 - allow seamless M/N changes on eDP panels
 - BUG_ON removal and cleanups
 
 msm:
 - DPU: simplified VBIF configuration
 -      cleanup CTL interfaces
 - DSI: removed unused msm_display_dsc_config struct
 -      switch regulator calls to new API
 -      switched to PANEL_BRIDGE for direct attached panels
 - DSI_PHY: convert drivers to parent_hws
 - DP: cleanup pixel_rate handling
 - HDMI: turned hdmi-phy-8996 into OF clk provider
 - misc dt-bindings fixes
 - choose eDP as primary display if it's available
 - support getting interconnects from either the mdss or the mdp5/dpu
   device nodes
 - gem: Shrinker + LRU re-work:
 - adds a shared GEM LRU+shrinker helper and moves msm over to that
 - reduces lock contention between retire and submit by avoiding the
   need to acquire obj lock in retire path (and instead using resv
   seeing obj's busyness in the shrinker
 - fix reclaim vs submit issues
 - GEM fault injection for triggering userspace error paths
 - Map/unmap optimization
 - Improved robustness for a6xx GPU recovery
 
 virtio:
 - Improve error and edge conditions handling
 - Convert to use managed helpers
 - stop exposing LINEAR modifier
 
 mgag200:
 - split modeset handling per model
 
 udl:
 - suspend/disconnect handling improvements
 
 vc4:
 - rework HDMI power up
 - depend on PM
 - better unplugging support
 
 ast:
 - resolution handling improvements
 
 ingenic:
 - Add JZ4760(B) support
 - avoid a modeset when sharpness property is unchanged
 - use the new PM ops
 
 it6505:
 - power seq and clock updates
 
 ssd130x:
 - regmap bulk write
 - use atomic helpers instead of simple helpers
 
 via:
 - rename via_drv to via_dri1, consolidate all code.
 
 radeon:
 - drop DP MST experimental support
 - delayed work flush fix
 - use time_after
 
 ti-sn65dsi86:
 - DP support
 
 mediatek:
 - MT8195 DP support
 - drop of_gpio header
 - remove unneeded result
 - small DP code improvements
 
 vkms:
 - RGB565, XRGB64 and ARGB64 support
 
 sun4i:
 - tv: convert to atomic
 
 rcar-du:
 - Synopsys DW HDMI bridge DT bindings update
 
 exynos:
 - use drm_display_info.is_hdmi
 - correct return of mixer_mode_valid and hdmi_mode_valid
 
 omap:
 - refcounting fix
 
 rockchip:
 - RK3568 support
 - RK3399 gamma support
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmM894sACgkQDHTzWXnE
 hr7EYw//WdVe69TNauCAQiOYdmPp1twmr2o5gDOFLoo4IZw5v+qK0HL/nTrDkBq6
 xIu1GLTScOh0AItW1rhFmrtKhO/u/QPQ15P6cO7x8AzlUIhVOYqM79+OA0X6zIV8
 IZjpc6EEWPSKJTCRud9HdzsV06DIa+QlwShLCaOFxRiGSuUqsxzacIHUqnFekRnV
 PBG7RzcmdWwe6Gy/7T2wegsFjw1mh4S4FypEGs53emru3PGvcau5dwXcE5Jro7Br
 k4BFFknuXahVJ2ynVfIFn3QUQRMLgAKRWflqxo7McLeKVQEt4gfB6+PaMwGpSiRQ
 iC9QPy69TWEx6X015q2DvvlQDewnCbPOlzyoj9O991QDGLPIim8srPblr8DPeeOz
 Y7IW1PRVnPdKReMJvTyrIVED/XT9fUoR7N+F9sfPnEee5HsvjXNGumEHbOE8avFf
 rB6CFdby+Ecd9cSeINXowFy4ss0d5zCHMiKEVyQWTZOJysp29vLyKezNqU5m37FK
 LAQHtsRdn1+V3o22H5y1PJyqssbOMImMV1ffqW/urRLLefPVHIKCKI8Ycgh0qxqc
 B+gebHMgF8j6RR0DHAcQby+PIVi/Pn36TAMI3lPsVjFWGS5s5EQwpKlMNj46H0Cr
 yE2Vr4w29+Nsv0b4Uz16AZ0mHcauqx4bvWMyT0frJfNcE86x8MI=
 =u/MJ
 -----END PGP SIGNATURE-----

Merge tag 'drm-next-2022-10-05' of git://anongit.freedesktop.org/drm/drm

Pull drm updates from Dave Airlie:
 "Lots of stuff all over, some new AMD IP support and gang submit
  support. i915 has further DG2 and Meteorlake pieces, and a bunch of
  i915 display refactoring. msm has a shrinker rework. There are also a
  bunch of conversions to use kunit.

  This has two external pieces, some MEI changes needed for future Intel
  discrete GPUs. These should be acked by Greg. There is also a cross
  maintainer shared tree with some backlight rework from Hans in here.

  Core:
   - convert selftests to kunit
   - managed init for more objects
   - move to idr_init_base
   - rename fb and gem cma helpers to dma
   - hide unregistered connectors from getconnector ioctl
   - DSC passthrough aux support
   - backlight handling improvements
   - add dma_resv_assert_held to vmap/vunmap

  edid:
   - move luminance calculation to core

  fbdev:
   - fix aperture helper usage

  fourcc:
   - add more format helpers
   - add DRM_FORMAT_Cxx, DRM_FORMAT_Rxx, DRM_FORMAT_Dxx
   - add packed AYUV8888, XYUV8888
   - add some kunit tests

  ttm:
   - allow bos without backing store
   - rewrite placement to use intersect/compatible functions

  dma-buf:
   - docs update
   - improve signalling when debugging

  udmabuf:
   - fix failure path GPF

  dp:
   - drop dp/mst legacy code
   - atomic mst state support
   - audio infoframe packing

  panel:
   - Samsung LTL101AL01
   - B120XAN01.0
   - R140NWF5 RH
   - DMT028VGHMCMI-1A T
   - AUO B133UAN02.1
   - IVO M133NW4J-R3
   - Innolux N120ACA-EA1

  amdgpu:
   - Gang submit support
   - Mode2 reset for RDNA2
   - New IP support:
        DCN 3.1.4, 3.2
        SMU 13.x
        NBIO 7.7
        GC 11.x
        PSP 13.x
        SDMA 6.x
        GMC 11.x
   - DSC passthrough support
   - PSP fixes for TA support
   - vangogh GFXOFF stats
   - clang fixes
   - gang submit CS cleanup prep work
   - fix VRAM eviction issues

  amdkfd:
   - GC 10.3 IP ISA fixes
   - fix CRIU regression
   - CPU fault on COW mapping fixes

  i915:
   - align fw versioning with kernel practices
   - add display substruct to i915 private
   - add initial runtime info to driver info
   - split out HDCP and backlight registers
   - MEI XeHP SDV GSC support
   - add per-gt sysfs defaults
   - TLB invalidation improvements
   - Disable PCI BAR resize on 32-bit
   - GuC firmware updates and compat changes
   - GuC log timestamp translation
   - DG2 preemption workaround changes
   - DG2 improved HDMI pixel clocks support
   - PCI BAR sanity checks
   - Enable DC5 on DG2
   - DG2 DMC fw bumped
   - ADL-S PCI ID added
   - Meteorlake enablement
   - Rename ggtt_view to gtt_view
   - host RPS fixes
   - release mmaps on rpm suspend on discrete
   - clocking and dpll refactoring
   - VBT definitions and parsing updates
   - SKL watermark code extracted to separate file
   - allow seamless M/N changes on eDP panels
   - BUG_ON removal and cleanups

  msm:
   - DPU:
       simplified VBIF configuration
       cleanup CTL interfaces
   - DSI:
       removed unused msm_display_dsc_config struct
       switch regulator calls to new API
       switched to PANEL_BRIDGE for direct attached panels
   - DSI_PHY: convert drivers to parent_hws
   - DP: cleanup pixel_rate handling
   - HDMI: turned hdmi-phy-8996 into OF clk provider
   - misc dt-bindings fixes
   - choose eDP as primary display if it's available
   - support getting interconnects from either the mdss or the mdp5/dpu
     device nodes
   - gem: Shrinker + LRU re-work:
   - adds a shared GEM LRU+shrinker helper and moves msm over to that
   - reduce lock contention between retire and submit by avoiding the
     need to acquire obj lock in retire path (and instead using resv
     seeing obj's busyness in the shrinker
   - fix reclaim vs submit issues
   - GEM fault injection for triggering userspace error paths
   - Map/unmap optimization
   - Improved robustness for a6xx GPU recovery

  virtio:
   - improve error and edge conditions handling
   - convert to use managed helpers
   - stop exposing LINEAR modifier

  mgag200:
   - split modeset handling per model

  udl:
   - suspend/disconnect handling improvements

  vc4:
   - rework HDMI power up
   - depend on PM
   - better unplugging support

  ast:
   - resolution handling improvements

  ingenic:
   - add JZ4760(B) support
   - avoid a modeset when sharpness property is unchanged
   - use the new PM ops

  it6505:
   - power seq and clock updates

  ssd130x:
   - regmap bulk write
   - use atomic helpers instead of simple helpers

  via:
   - rename via_drv to via_dri1, consolidate all code.

  radeon:
   - drop DP MST experimental support
   - delayed work flush fix
   - use time_after

  ti-sn65dsi86:
   - DP support

  mediatek:
   - MT8195 DP support
   - drop of_gpio header
   - remove unneeded result
   - small DP code improvements

  vkms:
   - RGB565, XRGB64 and ARGB64 support

  sun4i:
   - tv: convert to atomic

  rcar-du:
   - Synopsys DW HDMI bridge DT bindings update

  exynos:
   - use drm_display_info.is_hdmi
   - correct return of mixer_mode_valid and hdmi_mode_valid

  omap:
   - refcounting fix

  rockchip:
   - RK3568 support
   - RK3399 gamma support"

* tag 'drm-next-2022-10-05' of git://anongit.freedesktop.org/drm/drm: (1374 commits)
  drm/amdkfd: Fix UBSAN shift-out-of-bounds warning
  drm/amdkfd: Track unified memory when switching xnack mode
  drm/amdgpu: Enable sram on vcn_4_0_2
  drm/amdgpu: Enable VCN DPG for GC11_0_1
  drm/msm: Fix build break with recent mm tree
  drm/panel: simple: Use dev_err_probe() to simplify code
  drm/panel: panel-edp: Use dev_err_probe() to simplify code
  drm/panel: simple: Add Multi-Inno Technology MI0800FT-9
  dt-bindings: display: simple: Add Multi-Inno Technology MI0800FT-9 panel
  drm/amdgpu: correct the memcpy size for ip discovery firmware
  drm/amdgpu: Skip put_reset_domain if it doesn't exist
  drm/amdgpu: remove switch from amdgpu_gmc_noretry_set
  drm/amdgpu: Fix mc_umc_status used uninitialized warning
  drm/amd/display: Prevent OTG shutdown during PSR SU
  drm/amdgpu: add page retirement handling for CPU RAS
  drm/amdgpu: use RAS error address convert api in mca notifier
  drm/amdgpu: support to convert dedicated umc mca address
  drm/amdgpu: export umc error address convert interface
  drm/amdgpu: fix sdma v4 init microcode error
  drm/amd/display: fix array-bounds error in dc_stream_remove_writeback()
  ...
This commit is contained in:
Linus Torvalds 2022-10-05 11:24:12 -07:00
commit 7e6739b933
1162 changed files with 112868 additions and 35664 deletions

View File

@ -24,6 +24,15 @@ properties:
maxItems: 1 maxItems: 1
description: virtual channel number of a DSI peripheral description: virtual channel number of a DSI peripheral
clock-names:
const: refclk
clocks:
maxItems: 1
description: |
Optional external clock connected to REF_CLK input.
The clock rate must be in 10..154 MHz range.
enable-gpios: enable-gpios:
description: Bridge EN pin, chip is reset when EN is low. description: Bridge EN pin, chip is reset when EN is low.

View File

@ -38,6 +38,9 @@ properties:
clock-names: clock-names:
maxItems: 2 maxItems: 2
resets:
maxItems: 1
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports
@ -67,6 +70,7 @@ required:
- reg - reg
- clocks - clocks
- clock-names - clock-names
- resets
- interrupts - interrupts
- ports - ports
@ -85,6 +89,7 @@ examples:
clocks = <&cpg CPG_CORE R8A7795_CLK_S0D4>, <&cpg CPG_MOD 729>; clocks = <&cpg CPG_CORE R8A7795_CLK_S0D4>, <&cpg CPG_MOD 729>;
clock-names = "iahb", "isfr"; clock-names = "iahb", "isfr";
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
resets = <&cpg 729>;
ports { ports {
#address-cells = <1>; #address-cells = <1>;

View File

@ -17,6 +17,8 @@ properties:
enum: enum:
- ingenic,jz4740-lcd - ingenic,jz4740-lcd
- ingenic,jz4725b-lcd - ingenic,jz4725b-lcd
- ingenic,jz4760-lcd
- ingenic,jz4760b-lcd
- ingenic,jz4770-lcd - ingenic,jz4770-lcd
- ingenic,jz4780-lcd - ingenic,jz4780-lcd

View File

@ -0,0 +1,116 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/mediatek/mediatek,dp.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek Display Port Controller
maintainers:
- Chun-Kuang Hu <chunkuang.hu@kernel.org>
- Jitao shi <jitao.shi@mediatek.com>
description: |
MediaTek DP and eDP are different hardwares and there are some features
which are not supported for eDP. For example, audio is not supported for
eDP. Therefore, we need to use two different compatibles to describe them.
In addition, We just need to enable the power domain of DP, so the clock
of DP is generated by itself and we are not using other PLL to generate
clocks.
properties:
compatible:
enum:
- mediatek,mt8195-dp-tx
- mediatek,mt8195-edp-tx
reg:
maxItems: 1
nvmem-cells:
maxItems: 1
description: efuse data for display port calibration
nvmem-cell-names:
const: dp_calibration_data
power-domains:
maxItems: 1
interrupts:
maxItems: 1
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
description: Input endpoint of the controller, usually dp_intf
port@1:
$ref: /schemas/graph.yaml#/$defs/port-base
unevaluatedProperties: false
description: Output endpoint of the controller
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
data-lanes:
description: |
number of lanes supported by the hardware.
The possible values:
0 - For 1 lane enabled in IP.
0 1 - For 2 lanes enabled in IP.
0 1 2 3 - For 4 lanes enabled in IP.
minItems: 1
maxItems: 4
required:
- data-lanes
required:
- port@0
- port@1
max-linkrate-mhz:
enum: [ 1620, 2700, 5400, 8100 ]
description: maximum link rate supported by the hardware.
required:
- compatible
- reg
- interrupts
- ports
- max-linkrate-mhz
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/mt8195-power.h>
dptx@1c600000 {
compatible = "mediatek,mt8195-dp-tx";
reg = <0x1c600000 0x8000>;
power-domains = <&spm MT8195_POWER_DOMAIN_DP_TX>;
interrupts = <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH 0>;
max-linkrate-mhz = <8100>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dptx_in: endpoint {
remote-endpoint = <&dp_intf0_out>;
};
};
port@1 {
reg = <1>;
dptx_out: endpoint {
data-lanes = <0 1 2 3>;
};
};
};
};

View File

@ -24,6 +24,7 @@ properties:
- qcom,sm8350-dp - qcom,sm8350-dp
reg: reg:
minItems: 4
items: items:
- description: ahb register block - description: ahb register block
- description: aux register block - description: aux register block
@ -70,14 +71,28 @@ properties:
operating-points-v2: operating-points-v2:
maxItems: 1 maxItems: 1
opp-table: true
power-domains: power-domains:
maxItems: 1 maxItems: 1
aux-bus:
$ref: /schemas/display/dp-aux-bus.yaml#
data-lanes:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 4
items:
maximum: 3
"#sound-dai-cells": "#sound-dai-cells":
const: 0 const: 0
vdda-0p9-supply: true vdda-0p9-supply:
vdda-1p2-supply: true deprecated: true
vdda-1p2-supply:
deprecated: true
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports
@ -98,10 +113,33 @@ required:
- clock-names - clock-names
- phys - phys
- phy-names - phy-names
- "#sound-dai-cells"
- power-domains - power-domains
- ports - ports
allOf:
# AUX BUS does not exist on DP controllers
# Audio output also is present only on DP output
# p1 regions is present on DP, but not on eDP
- if:
properties:
compatible:
contains:
enum:
- qcom,sc7280-edp
- qcom,sc8180x-edp
then:
properties:
"#sound-dai-cells": false
reg:
maxItems: 4
else:
properties:
aux-bus: false
reg:
minItems: 5
required:
- "#sound-dai-cells"
additionalProperties: false additionalProperties: false
examples: examples:
@ -140,9 +178,6 @@ examples:
power-domains = <&rpmhpd SC7180_CX>; power-domains = <&rpmhpd SC7180_CX>;
vdda-0p9-supply = <&vdda_usb_ss_dp_core>;
vdda-1p2-supply = <&vdda_usb_ss_dp_1p2>;
ports { ports {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;

View File

@ -62,6 +62,7 @@ patternProperties:
"^display-controller@[0-9a-f]+$": "^display-controller@[0-9a-f]+$":
type: object type: object
description: Node containing the properties of DPU. description: Node containing the properties of DPU.
additionalProperties: false
properties: properties:
compatible: compatible:
@ -105,6 +106,9 @@ patternProperties:
maxItems: 1 maxItems: 1
operating-points-v2: true operating-points-v2: true
opp-table:
type: object
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports
description: | description: |

View File

@ -74,6 +74,7 @@ patternProperties:
"^display-controller@[0-9a-f]+$": "^display-controller@[0-9a-f]+$":
type: object type: object
description: Node containing the properties of DPU. description: Node containing the properties of DPU.
additionalProperties: false
properties: properties:
compatible: compatible:
@ -113,6 +114,8 @@ patternProperties:
maxItems: 1 maxItems: 1
operating-points-v2: true operating-points-v2: true
opp-table:
type: object
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports

View File

@ -73,6 +73,7 @@ patternProperties:
"^display-controller@[0-9a-f]+$": "^display-controller@[0-9a-f]+$":
type: object type: object
description: Node containing the properties of DPU. description: Node containing the properties of DPU.
additionalProperties: false
properties: properties:
compatible: compatible:
@ -114,6 +115,8 @@ patternProperties:
maxItems: 1 maxItems: 1
operating-points-v2: true operating-points-v2: true
opp-table:
type: object
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports

View File

@ -72,6 +72,7 @@ patternProperties:
"^display-controller@[0-9a-f]+$": "^display-controller@[0-9a-f]+$":
type: object type: object
description: Node containing the properties of DPU. description: Node containing the properties of DPU.
additionalProperties: false
properties: properties:
compatible: compatible:
@ -112,6 +113,8 @@ patternProperties:
maxItems: 1 maxItems: 1
operating-points-v2: true operating-points-v2: true
opp-table:
type: object
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports

View File

@ -65,6 +65,7 @@ patternProperties:
"^display-controller@[0-9a-f]+$": "^display-controller@[0-9a-f]+$":
type: object type: object
description: Node containing the properties of DPU. description: Node containing the properties of DPU.
additionalProperties: false
properties: properties:
compatible: compatible:
@ -102,6 +103,9 @@ patternProperties:
maxItems: 1 maxItems: 1
operating-points-v2: true operating-points-v2: true
opp-table:
type: object
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports
description: | description: |

View File

@ -20,35 +20,24 @@ description: |
properties: properties:
compatible: compatible:
items: items:
- enum: - pattern: '^qcom,adreno-gmu-6[0-9][0-9]\.[0-9]$'
- qcom,adreno-gmu-630.2
- const: qcom,adreno-gmu - const: qcom,adreno-gmu
reg: reg:
items: minItems: 3
- description: Core GMU registers maxItems: 4
- description: GMU PDC registers
- description: GMU PDC sequence registers
reg-names: reg-names:
items: minItems: 3
- const: gmu maxItems: 4
- const: gmu_pdc
- const: gmu_pdc_seq
clocks: clocks:
items: minItems: 4
- description: GMU clock maxItems: 7
- description: GPU CX clock
- description: GPU AXI clock
- description: GPU MEMNOC clock
clock-names: clock-names:
items: minItems: 4
- const: gmu maxItems: 7
- const: cxo
- const: axi
- const: memnoc
interrupts: interrupts:
items: items:
@ -76,6 +65,9 @@ properties:
operating-points-v2: true operating-points-v2: true
opp-table:
type: object
required: required:
- compatible - compatible
- reg - reg
@ -91,6 +83,140 @@ required:
additionalProperties: false additionalProperties: false
allOf:
- if:
properties:
compatible:
contains:
enum:
- qcom,adreno-gmu-618.0
- qcom,adreno-gmu-630.2
then:
properties:
reg:
items:
- description: Core GMU registers
- description: GMU PDC registers
- description: GMU PDC sequence registers
reg-names:
items:
- const: gmu
- const: gmu_pdc
- const: gmu_pdc_seq
clocks:
items:
- description: GMU clock
- description: GPU CX clock
- description: GPU AXI clock
- description: GPU MEMNOC clock
clock-names:
items:
- const: gmu
- const: cxo
- const: axi
- const: memnoc
- if:
properties:
compatible:
contains:
enum:
- qcom,adreno-gmu-635.0
then:
properties:
reg:
items:
- description: Core GMU registers
- description: Resource controller registers
- description: GMU PDC registers
reg-names:
items:
- const: gmu
- const: rscc
- const: gmu_pdc
clocks:
items:
- description: GMU clock
- description: GPU CX clock
- description: GPU AXI clock
- description: GPU MEMNOC clock
- description: GPU AHB clock
- description: GPU HUB CX clock
- description: GPU SMMU vote clock
clock-names:
items:
- const: gmu
- const: cxo
- const: axi
- const: memnoc
- const: ahb
- const: hub
- const: smmu_vote
- if:
properties:
compatible:
contains:
enum:
- qcom,adreno-gmu-640.1
then:
properties:
reg:
items:
- description: Core GMU registers
- description: GMU PDC registers
- description: GMU PDC sequence registers
reg-names:
items:
- const: gmu
- const: gmu_pdc
- const: gmu_pdc_seq
- if:
properties:
compatible:
contains:
enum:
- qcom,adreno-gmu-650.2
then:
properties:
reg:
items:
- description: Core GMU registers
- description: Resource controller registers
- description: GMU PDC registers
- description: GMU PDC sequence registers
reg-names:
items:
- const: gmu
- const: rscc
- const: gmu_pdc
- const: gmu_pdc_seq
- if:
properties:
compatible:
contains:
enum:
- qcom,adreno-gmu-640.1
- qcom,adreno-gmu-650.2
then:
properties:
clocks:
items:
- description: GPU AHB clock
- description: GMU clock
- description: GPU CX clock
- description: GPU AXI clock
- description: GPU MEMNOC clock
clock-names:
items:
- const: ahb
- const: gmu
- const: cxo
- const: axi
- const: memnoc
examples: examples:
- | - |
#include <dt-bindings/clock/qcom,gpucc-sdm845.h> #include <dt-bindings/clock/qcom,gpucc-sdm845.h>

View File

@ -58,7 +58,8 @@ properties:
- const: ocmem - const: ocmem
iommus: iommus:
maxItems: 1 minItems: 1
maxItems: 64
sram: sram:
$ref: /schemas/types.yaml#/definitions/phandle-array $ref: /schemas/types.yaml#/definitions/phandle-array

View File

@ -36,7 +36,7 @@ properties:
maxItems: 1 maxItems: 1
iommus: iommus:
maxItems: 1 maxItems: 4
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports

View File

@ -234,6 +234,8 @@ properties:
- mitsubishi,aa070mc01-ca1 - mitsubishi,aa070mc01-ca1
# Multi-Inno Technology Co.,Ltd MI0700S4T-6 7" 800x480 TFT Resistive Touch Module # Multi-Inno Technology Co.,Ltd MI0700S4T-6 7" 800x480 TFT Resistive Touch Module
- multi-inno,mi0700s4t-6 - multi-inno,mi0700s4t-6
# Multi-Inno Technology Co.,Ltd MI0800FT-9 8" 800x600 TFT Resistive Touch Module
- multi-inno,mi0800ft-9
# Multi-Inno Technology Co.,Ltd MI1010AIT-1CP 10.1" 1280x800 LVDS IPS Cap Touch Mod. # Multi-Inno Technology Co.,Ltd MI1010AIT-1CP 10.1" 1280x800 LVDS IPS Cap Touch Mod.
- multi-inno,mi1010ait-1cp - multi-inno,mi1010ait-1cp
# NEC LCD Technologies, Ltd. 12.1" WXGA (1280x800) LVDS TFT LCD panel # NEC LCD Technologies, Ltd. 12.1" WXGA (1280x800) LVDS TFT LCD panel
@ -280,6 +282,8 @@ properties:
- samsung,atna33xc20 - samsung,atna33xc20
# Samsung 12.2" (2560x1600 pixels) TFT LCD panel # Samsung 12.2" (2560x1600 pixels) TFT LCD panel
- samsung,lsn122dl01-c01 - samsung,lsn122dl01-c01
# Samsung Electronics 10.1" WXGA (1280x800) TFT LCD panel
- samsung,ltl101al01
# Samsung Electronics 10.1" WSVGA TFT LCD panel # Samsung Electronics 10.1" WSVGA TFT LCD panel
- samsung,ltn101nt05 - samsung,ltn101nt05
# Samsung Electronics 14" WXGA (1366x768) TFT LCD panel # Samsung Electronics 14" WXGA (1366x768) TFT LCD panel

View File

@ -17,6 +17,9 @@ description: |
Techstar TS8550B is 480x854, 2-lane MIPI DSI LCD panel which has Techstar TS8550B is 480x854, 2-lane MIPI DSI LCD panel which has
inbuilt ST7701 chip. inbuilt ST7701 chip.
Densitron DMT028VGHMCMI-1A is 480x640, 2-lane MIPI DSI LCD panel
which has built-in ST7701 chip.
allOf: allOf:
- $ref: panel-common.yaml# - $ref: panel-common.yaml#
@ -24,6 +27,7 @@ properties:
compatible: compatible:
items: items:
- enum: - enum:
- densitron,dmt028vghmcmi-1a
- techstar,ts8550b - techstar,ts8550b
- const: sitronix,st7701 - const: sitronix,st7701

View File

@ -8,6 +8,7 @@ Required properties:
"rockchip,px30-mipi-dsi", "snps,dw-mipi-dsi" "rockchip,px30-mipi-dsi", "snps,dw-mipi-dsi"
"rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi" "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"
"rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi" "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi"
"rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi"
- reg: Represent the physical address range of the controller. - reg: Represent the physical address range of the controller.
- interrupts: Represent the controller's interrupt to the CPU(s). - interrupts: Represent the controller's interrupt to the CPU(s).
- clocks, clock-names: Phandles to the controller's pll reference - clocks, clock-names: Phandles to the controller's pll reference

View File

@ -28,12 +28,15 @@ properties:
- const: hdmi_phy - const: hdmi_phy
clocks: clocks:
maxItems: 2 minItems: 2
maxItems: 3
clock-names: clock-names:
minItems: 2
items: items:
- const: iface - const: iface
- const: ref - const: ref
- const: xo
power-domains: power-domains:
maxItems: 1 maxItems: 1
@ -44,6 +47,9 @@ properties:
vddio-supply: vddio-supply:
description: phandle to VDD I/O supply regulator description: phandle to VDD I/O supply regulator
'#clock-cells':
const: 0
'#phy-cells': '#phy-cells':
const: 0 const: 0
@ -75,9 +81,12 @@ examples:
"hdmi_phy"; "hdmi_phy";
clocks = <&mmcc 116>, clocks = <&mmcc 116>,
<&gcc 214>; <&gcc 214>,
<&xo_board>;
clock-names = "iface", clock-names = "iface",
"ref"; "ref",
"xo";
#clock-cells = <0>;
#phy-cells = <0>; #phy-cells = <0>;
vddio-supply = <&vreg_l12a_1p8>; vddio-supply = <&vreg_l12a_1p8>;

View File

@ -0,0 +1,8 @@
Product Name, Code Reference, DCN/DCE version, GC version, VCE/UVD/VCN version, SDMA version
Radeon R* Graphics, CARRIZO/STONEY, DCE 11, 8, VCE 3 / UVD 6, 3
Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN/PICASSO, DCN 1.0, 9.1.0, VCN 1.0, 4.1.0
Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2
Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1
SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1
Ryzen 5000 series, GREEN SARDINE, DCN 2.1, 9.3, VCN 2.2, 4.1.1
Ryzen 6000 Zen, YELLOW CARP, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3
1 Product Name Code Reference DCN/DCE version GC version VCE/UVD/VCN version SDMA version
2 Radeon R* Graphics CARRIZO/STONEY DCE 11 8 VCE 3 / UVD 6 3
3 Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx RAVEN/PICASSO DCN 1.0 9.1.0 VCN 1.0 4.1.0
4 Ryzen 4000 series RENOIR DCN 2.1 9.3 VCN 2.2 4.1.2
5 Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx RAVEN2 DCN 1.0 9.2.2 VCN 1.0.1 4.1.1
6 SteamDeck VANGOGH DCN 3.0.1 10.3.1 VCN 3.1.0 5.2.1
7 Ryzen 5000 series GREEN SARDINE DCN 2.1 9.3 VCN 2.2 4.1.1
8 Ryzen 6000 Zen YELLOW CARP 3.1.2 10.3.3 VCN 3.1.1 5.2.3

View File

@ -0,0 +1,24 @@
Product Name, Code Reference, DCN/DCE version, GC version, VCN version, SDMA version
AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series, HAINAN, --, 6, --, --
AMD Radeon HD 7800 /7900 /FireGL Series, TAHITI, DCE 6, 6, VCE 1 / UVD 3, --
AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M, OLAND, DCE 6, 6, VCE 1 / UVD 3, --
AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series, PITCAIRN, DCE 6, 6, VCE 1 / UVD 3, --
AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series, VERDE, DCE 6, 6, VCE 1 / UVD 3, --
AMD Radeon HD M280X /M380 /7700 /8950 /W5100, BONAIRE, DCE 8, 7, VCE 2 / UVD 4.2, 1
AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series, HAWAII, DCE 8, 7, VCE 2 / UVD 4.2, 1
AMD Radeon (TM) R(5|7) M315 /M340 /M360, TOPAZ, *, 8, --, 2
AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series, TONGA, DCE 10, 8, VCE 3 / UVD 5, 3
AMD Radeon (FirePro) (TM) R9 Fury Series, FIJI, DCE 10, 8, VCE 3 / UVD 6, 3
Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH, POLARIS10, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series, POLARIS11, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series, POLARIS12, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3
Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU, VEGA10, DCE 12, 9.0.1, VCE 4.0.0 / UVD 7.0.0, 4.0.0
AMD Radeon (Pro) VII /MI50 /MI60, VEGA20, DCE 12, 9.4.0, VCE 4.1.0 / UVD 7.2.0, 4.2.0
MI100, ARCTURUS, *, 9.4.1, VCN 2.5.0, 4.2.2
MI200, ALDEBARAN, *, 9.4.2, VCN 2.6.0, 4.4.0
AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700, NAVI10, DCN 2.0.0, 10.1.10, VCN 2.0.0, 5.0.0
AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500, NAVI14, DCN 2.0.0, 10.1.1, VCN 2.0.2, 5.0.2
AMD Radeon RX 6800(XT) /6900(XT) /W6800, SIENNA_CICHLID, DCN 3.0.0, 10.3.0, VCN 3.0.0, 5.2.0
AMD Radeon RX 6700 XT / 6800M / 6700M, NAVY_FLOUNDER, DCN 3.0.0, 10.3.2, VCN 3.0.0, 5.2.2
AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M, DIMGREY_CAVEFISH, DCN 3.0.2, 10.3.4, VCN 3.0.16, 5.2.4
AMD Radeon RX 6500M /6300M /W6500M /W6300M, BEIGE_GOBY, DCN 3.0.3, 10.3.5, VCN 3.0.33, 5.2.5
1 Product Name Code Reference DCN/DCE version GC version VCN version SDMA version
2 AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series HAINAN -- 6 -- --
3 AMD Radeon HD 7800 /7900 /FireGL Series TAHITI DCE 6 6 VCE 1 / UVD 3 --
4 AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M OLAND DCE 6 6 VCE 1 / UVD 3 --
5 AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series PITCAIRN DCE 6 6 VCE 1 / UVD 3 --
6 AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series VERDE DCE 6 6 VCE 1 / UVD 3 --
7 AMD Radeon HD M280X /M380 /7700 /8950 /W5100 BONAIRE DCE 8 7 VCE 2 / UVD 4.2 1
8 AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series HAWAII DCE 8 7 VCE 2 / UVD 4.2 1
9 AMD Radeon (TM) R(5|7) M315 /M340 /M360 TOPAZ * 8 -- 2
10 AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series TONGA DCE 10 8 VCE 3 / UVD 5 3
11 AMD Radeon (FirePro) (TM) R9 Fury Series FIJI DCE 10 8 VCE 3 / UVD 6 3
12 Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH POLARIS10 DCE 11.2 8 VCE 3.4 / UVD 6.3 3
13 Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series POLARIS11 DCE 11.2 8 VCE 3.4 / UVD 6.3 3
14 Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series POLARIS12 DCE 11.2 8 VCE 3.4 / UVD 6.3 3
15 Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU VEGA10 DCE 12 9.0.1 VCE 4.0.0 / UVD 7.0.0 4.0.0
16 AMD Radeon (Pro) VII /MI50 /MI60 VEGA20 DCE 12 9.4.0 VCE 4.1.0 / UVD 7.2.0 4.2.0
17 MI100 ARCTURUS * 9.4.1 VCN 2.5.0 4.2.2
18 MI200 ALDEBARAN * 9.4.2 VCN 2.6.0 4.4.0
19 AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700 NAVI10 DCN 2.0.0 10.1.10 VCN 2.0.0 5.0.0
20 AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500 NAVI14 DCN 2.0.0 10.1.1 VCN 2.0.2 5.0.2
21 AMD Radeon RX 6800(XT) /6900(XT) /W6800 SIENNA_CICHLID DCN 3.0.0 10.3.0 VCN 3.0.0 5.2.0
22 AMD Radeon RX 6700 XT / 6800M / 6700M NAVY_FLOUNDER DCN 3.0.0 10.3.2 VCN 3.0.0 5.2.2
23 AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M DIMGREY_CAVEFISH DCN 3.0.2 10.3.4 VCN 3.0.16 5.2.4
24 AMD Radeon RX 6500M /6300M /W6500M /W6300M BEIGE_GOBY DCN 3.0.3 10.3.5 VCN 3.0.33 5.2.5

View File

@ -170,7 +170,7 @@ consider asking in the amdgfx and update this page.
MC MC
Memory Controller Memory Controller
MPC MPC/MPCC
Multiple pipes and plane combine Multiple pipes and plane combine
MPO MPO

View File

@ -124,6 +124,65 @@ depth format), bit-depth reduction/dithering would kick in. In OPP, we would
also apply a regamma function to introduce the gamma removed earlier back. also apply a regamma function to introduce the gamma removed earlier back.
Eventually, we output data in integer format at DIO. Eventually, we output data in integer format at DIO.
AMD Hardware Pipeline
---------------------
When discussing graphics on Linux, the **pipeline** term can sometimes be
overloaded with multiple meanings, so it is important to define what we mean
when we say **pipeline**. In the DCN driver, we use the term **hardware
pipeline** or **pipeline** or just **pipe** as an abstraction to indicate a
sequence of DCN blocks instantiated to address some specific configuration. DC
core treats DCN blocks as individual resources, meaning we can build a pipeline
by taking resources for all individual hardware blocks to compose one pipeline.
In actuality, we can't connect an arbitrary block from one pipe to a block from
another pipe; they are routed linearly, except for DSC, which can be
arbitrarily assigned as needed. We have this pipeline concept for trying to
optimize bandwidth utilization.
.. kernel-figure:: pipeline_4k_no_split.svg
Additionally, let's take a look at parts of the DTN log (see
'Documentation/gpu/amdgpu/display/dc-debug.rst' for more information) since
this log can help us to see part of this pipeline behavior in real-time::
HUBP: format addr_hi width height ...
[ 0]: 8h 81h 3840 2160
[ 1]: 0h 0h 0 0
[ 2]: 0h 0h 0 0
[ 3]: 0h 0h 0 0
[ 4]: 0h 0h 0 0
...
MPCC: OPP DPP ...
[ 0]: 0h 0h ...
The first thing to notice from the diagram and DTN log it is the fact that we
have different clock domains for each part of the DCN blocks. In this example,
we have just a single **pipeline** where the data flows from DCHUB to DIO, as
we intuitively expect. Nonetheless, DCN is flexible, as mentioned before, and
we can split this single pipe differently, as described in the below diagram:
.. kernel-figure:: pipeline_4k_split.svg
Now, if we inspect the DTN log again we can see some interesting changes::
HUBP: format addr_hi width height ...
[ 0]: 8h 81h 1920 2160 ...
...
[ 4]: 0h 0h 0 0 ...
[ 5]: 8h 81h 1920 2160 ...
...
MPCC: OPP DPP ...
[ 0]: 0h 0h ...
[ 5]: 0h 5h ...
From the above example, we now split the display pipeline into two vertical
parts of 1920x2160 (i.e., 3440x2160), and as a result, we could reduce the
clock frequency in the DPP part. This is not only useful for saving power but
also to better handle the required throughput. The idea to keep in mind here is
that the pipe configuration can vary a lot according to the display
configuration, and it is the DML's responsibility to set up all required
configuration parameters for multiple scenarios supported by our hardware.
Global Sync Global Sync
----------- -----------

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 56 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -40,3 +40,144 @@ Atomic Implementation
.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c .. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
:functions: amdgpu_dm_atomic_check amdgpu_dm_atomic_commit_tail :functions: amdgpu_dm_atomic_check amdgpu_dm_atomic_commit_tail
Color Management Properties
===========================
.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
:doc: overview
.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
:internal:
DC Color Capabilities between DCN generations
---------------------------------------------
DRM/KMS framework defines three CRTC color correction properties: degamma,
color transformation matrix (CTM) and gamma, and two properties for degamma and
gamma LUT sizes. AMD DC programs some of the color correction features
pre-blending but DRM/KMS has not per-plane color correction properties.
In general, the DRM CRTC color properties are programmed to DC, as follows:
CRTC gamma after blending, and CRTC degamma pre-blending. Although CTM is
programmed after blending, it is mapped to DPP hw blocks (pre-blending). Other
color caps available in the hw is not currently exposed by DRM interface and
are bypassed.
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/dc.h
:doc: color-management-caps
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/dc.h
:internal:
The color pipeline has undergone major changes between DCN hardware
generations. What's possible to do before and after blending depends on
hardware capabilities, as illustrated below by the DCN 2.0 and DCN 3.0 families
schemas.
**DCN 2.0 family color caps and mapping**
.. kernel-figure:: dcn2_cm_drm_current.svg
**DCN 3.0 family color caps and mapping**
.. kernel-figure:: dcn3_cm_drm_current.svg
Blend Mode Properties
=====================
Pixel blend mode is a DRM plane composition property of :c:type:`drm_plane` used to
describes how pixels from a foreground plane (fg) are composited with the
background plane (bg). Here, we present main concepts of DRM blend mode to help
to understand how this property is mapped to AMD DC interface. See more about
this DRM property and the alpha blending equations in :ref:`DRM Plane
Composition Properties <plane_composition_properties>`.
Basically, a blend mode sets the alpha blending equation for plane
composition that fits the mode in which the alpha channel affects the state of
pixel color values and, therefore, the resulted pixel color. For
example, consider the following elements of the alpha blending equation:
- *fg.rgb*: Each of the RGB component values from the foreground's pixel.
- *fg.alpha*: Alpha component value from the foreground's pixel.
- *bg.rgb*: Each of the RGB component values from the background.
- *plane_alpha*: Plane alpha value set by the **plane "alpha" property**, see
more in :ref:`DRM Plane Composition Properties <plane_composition_properties>`.
in the basic alpha blending equation::
out.rgb = alpha * fg.rgb + (1 - alpha) * bg.rgb
the alpha channel value of each pixel in a plane is ignored and only the plane
alpha affects the resulted pixel color values.
DRM has three blend mode to define the blend formula in the plane composition:
* **None**: Blend formula that ignores the pixel alpha.
* **Pre-multiplied**: Blend formula that assumes the pixel color values in a
plane was already pre-multiplied by its own alpha channel before storage.
* **Coverage**: Blend formula that assumes the pixel color values were not
pre-multiplied with the alpha channel values.
and pre-multiplied is the default pixel blend mode, that means, when no blend
mode property is created or defined, DRM considers the plane's pixels has
pre-multiplied color values. On IGT GPU tools, the kms_plane_alpha_blend test
provides a set of subtests to verify plane alpha and blend mode properties.
The DRM blend mode and its elements are then mapped by AMDGPU display manager
(DM) to program the blending configuration of the Multiple Pipe/Plane Combined
(MPC), as follows:
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
:doc: mpc-overview
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
:functions: mpcc_blnd_cfg
Therefore, the blending configuration for a single MPCC instance on the MPC
tree is defined by :c:type:`mpcc_blnd_cfg`, where
:c:type:`pre_multiplied_alpha` is the alpha pre-multiplied mode flag used to
set :c:type:`MPCC_ALPHA_MULTIPLIED_MODE`. It controls whether alpha is
multiplied (true/false), being only true for DRM pre-multiplied blend mode.
:c:type:`mpcc_alpha_blend_mode` defines the alpha blend mode regarding pixel
alpha and plane alpha values. It sets one of the three modes for
:c:type:`MPCC_ALPHA_BLND_MODE`, as described below.
.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
:functions: mpcc_alpha_blend_mode
DM then maps the elements of `enum mpcc_alpha_blend_mode` to those in the DRM
blend formula, as follows:
* *MPC pixel alpha* matches *DRM fg.alpha* as the alpha component value
from the plane's pixel
* *MPC global alpha* matches *DRM plane_alpha* when the pixel alpha should
be ignored and, therefore, pixel values are not pre-multiplied
* *MPC global gain* assumes *MPC global alpha* value when both *DRM
fg.alpha* and *DRM plane_alpha* participate in the blend equation
In short, *fg.alpha* is ignored by selecting
:c:type:`MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA`. On the other hand, (plane_alpha *
fg.alpha) component becomes available by selecting
:c:type:`MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN`. And the
:c:type:`MPCC_ALPHA_MULTIPLIED_MODE` defines if the pixel color values are
pre-multiplied by alpha or not.
Blend configuration flow
------------------------
The alpha blending equation is configured from DRM to DC interface by the
following path:
1. When updating a :c:type:`drm_plane_state <drm_plane_state>`, DM calls
:c:type:`fill_blending_from_plane_state()` that maps
:c:type:`drm_plane_state <drm_plane_state>` attributes to
:c:type:`dc_plane_info <dc_plane_info>` struct to be handled in the
OS-agnostic component (DC).
2. On DC interface, :c:type:`struct mpcc_blnd_cfg <mpcc_blnd_cfg>` programs the
MPCC blend configuration considering the :c:type:`dc_plane_info
<dc_plane_info>` input from DPP.

View File

@ -28,4 +28,5 @@ table of content:
display-manager.rst display-manager.rst
dc-debug.rst dc-debug.rst
dcn-overview.rst dcn-overview.rst
mpo-overview.rst
dc-glossary.rst dc-glossary.rst

View File

@ -0,0 +1,435 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="160.5318mm"
height="65.443306mm"
viewBox="0 0 160.5318 65.443308"
version="1.1"
id="svg843"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="mpo-cursor.svg">
<defs
id="defs837">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1568"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1562"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker1837"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1835"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1580"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-5"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-7-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-5-2"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-9"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-7"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-9-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-7-1"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-9-6-9"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1568-7-1-3"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="895.68984"
inkscape:cy="-284.87808"
inkscape:document-units="mm"
inkscape:current-layer="g1433-6"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata840">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(70.035531,-11.72001)">
<g
id="g1438"
transform="matrix(0.33108827,0,0,0.33108827,-46.847588,7.8396545)">
<rect
y="51.228218"
x="-69.09626"
height="34.773811"
width="66.523811"
id="rect1388"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392"
y="73.238098"
x="-59.718166"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="73.238098"
x="-59.718166"
id="tspan1390"
sodipodi:role="line">Cursor</tspan></text>
</g>
<g
id="g1433"
transform="matrix(0.33108827,0,0,0.33108827,-49.701591,6.5552955)">
<rect
y="116.32738"
x="-60.476192"
height="34.773811"
width="66.523811"
id="rect1388-3"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-6"
y="138.44888"
x="-53.932037"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="138.44888"
x="-53.932037"
id="tspan1390-7"
sodipodi:role="line">Plane 1</tspan></text>
</g>
<g
id="g1428"
transform="matrix(0.33108827,0,0,0.33108827,-46.847588,7.8396518)">
<rect
y="173.66814"
x="-69.09626"
height="34.773811"
width="66.523811"
id="rect1388-5"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-3"
y="195.78964"
x="-62.437382"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="195.78964"
x="-62.437382"
id="tspan1390-5"
sodipodi:role="line">Plane 2</tspan></text>
</g>
<g
id="g1433-6"
transform="translate(116.41667,-9.0714256)">
<g
id="g1467"
transform="matrix(0.33108827,0,0,0.33108827,-132.72925,15.626721)">
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1388-3-2"
width="66.523811"
height="34.773811"
x="-60.476192"
y="116.32738" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-45.380619"
y="138.33725"
id="text1392-6-9"><tspan
sodipodi:role="line"
id="tspan1390-7-1"
x="-45.380619"
y="138.33725"
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332">CRTC</tspan></text>
</g>
<g
id="g1438-2"
transform="matrix(0.33108827,0,0,0.33108827,-92.282164,27.16881)">
<rect
y="51.228218"
x="-69.09626"
height="34.773811"
width="66.523811"
id="rect1388-7"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-0"
y="73.238098"
x="-59.718166"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="73.238098"
x="-59.718166"
id="tspan1390-9"
sodipodi:role="line">Cursor</tspan></text>
</g>
<g
id="g1433-3"
transform="matrix(0.33108827,0,0,0.33108827,-61.59731,5.6152398)">
<rect
y="116.32738"
x="-60.476192"
height="34.773811"
width="66.523811"
id="rect1388-3-6"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-6-0"
y="138.44888"
x="-53.932037"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="138.44888"
x="-53.932037"
id="tspan1390-7-6"
sodipodi:role="line">Plane 1</tspan></text>
</g>
<g
id="g1428-2"
transform="matrix(0.33108827,0,0,0.33108827,-58.743296,6.7994816)">
<rect
y="173.66814"
x="-69.09626"
height="34.773811"
width="66.523811"
id="rect1388-5-6"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<text
id="text1392-3-1"
y="195.78964"
x="-62.437382"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332"
y="195.78964"
x="-62.437382"
id="tspan1390-5-8"
sodipodi:role="line">Plane 2</tspan></text>
</g>
<g
id="g1467-7"
transform="matrix(0.33108827,0,0,0.33108827,-28.233674,5.6152398)">
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.87854159;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1388-3-2-9"
width="66.523811"
height="34.773811"
x="-60.476192"
y="116.32738" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-45.380619"
y="138.33725"
id="text1392-6-9-2"><tspan
sodipodi:role="line"
id="tspan1390-7-1-0"
x="-45.380619"
y="138.33725"
style="font-weight:bold;font-size:12.69999981px;stroke-width:0.26458332">CRTC</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:1.05120528px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.08760043"
x="-164.26541"
y="24.302296"
id="text1531"><tspan
sodipodi:role="line"
id="tspan1529"
x="-164.26541"
y="24.302296"
style="font-weight:bold;font-size:4.6720233px;stroke-width:0.08760043">DRM</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:1.05120528px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.08760043"
x="-89.233742"
y="24.341078"
id="text1531-2"><tspan
sodipodi:role="line"
id="tspan1529-3"
x="-89.233742"
y="24.341078"
style="font-weight:bold;font-size:4.6720233px;stroke-width:0.08760043">AMD Hardware</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send)"
d="m -164.26541,39.407343 h 20.27325 v 11.262913"
id="path1551"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-7)"
d="m -164.11597,80.385815 h 20.27325 v -11.26291"
id="path1551-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-7-2)"
d="m -59.24211,70.452123 h 20.273243 V 59.18921"
id="path1551-9-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9)"
d="m -163.61178,59.821549 h 9.26062"
id="path1551-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9-6)"
d="m -93.426241,50.16968 h 9.260617"
id="path1551-3-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.53318286;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-9-6-9)"
d="m -59.637503,50.169684 h 9.260618"
id="path1551-3-2-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,242 @@
========================
Multiplane Overlay (MPO)
========================
.. note:: You will get more from this page if you have already read the
'Documentation/gpu/amdgpu/display/dcn-overview.rst'.
Multiplane Overlay (MPO) allows for multiple framebuffers to be composited via
fixed-function hardware in the display controller rather than using graphics or
compute shaders for composition. This can yield some power savings if it means
the graphics/compute pipelines can be put into low-power states. In summary,
MPO can bring the following benefits:
* Decreased GPU and CPU workload - no composition shaders needed, no extra
buffer copy needed, GPU can remain idle.
* Plane independent page flips - No need to be tied to global compositor
page-flip present rate, reduced latency, independent timing.
.. note:: Keep in mind that MPO is all about power-saving; if you want to learn
more about power-save in the display context, check the link:
`Power <https://gitlab.freedesktop.org/pq/color-and-hdr/-/blob/main/doc/power.rst>`__.
Multiplane Overlay is only available using the DRM atomic model. The atomic
model only uses a single userspace IOCTL for configuring the display hardware
(modesetting, page-flipping, etc) - drmModeAtomicCommit. To query hardware
resources and limitations userspace also calls into drmModeGetResources which
reports back the number of planes, CRTCs, and connectors. There are three types
of DRM planes that the driver can register and work with:
* ``DRM_PLANE_TYPE_PRIMARY``: Primary planes represent a "main" plane for a
CRTC, primary planes are the planes operated upon by CRTC modesetting and
flipping operations.
* ``DRM_PLANE_TYPE_CURSOR``: Cursor planes represent a "cursor" plane for a
CRTC. Cursor planes are the planes operated upon by the cursor IOCTLs
* ``DRM_PLANE_TYPE_OVERLAY``: Overlay planes represent all non-primary,
non-cursor planes. Some drivers refer to these types of planes as "sprites"
internally.
To illustrate how it works, let's take a look at a device that exposes the
following planes to userspace:
* 4 Primary planes (1 per CRTC).
* 4 Cursor planes (1 per CRTC).
* 1 Overlay plane (shared among CRTCs).
.. note:: Keep in mind that different ASICs might expose other numbers of
planes.
For this hardware example, we have 4 pipes (if you don't know what AMD pipe
means, look at 'Documentation/gpu/amdgpu/display/dcn-overview.rst', section
"AMD Hardware Pipeline"). Typically most AMD devices operate in a pipe-split
configuration for optimal single display output (e.g., 2 pipes per plane).
A typical MPO configuration from userspace - 1 primary + 1 overlay on a single
display - will see 4 pipes in use, 2 per plane.
At least 1 pipe must be used per plane (primary and overlay), so for this
hypothetical hardware that we are using as an example, we have an absolute
limit of 4 planes across all CRTCs. Atomic commits will be rejected for display
configurations using more than 4 planes. Again, it is important to stress that
every DCN has different restrictions; here, we are just trying to provide the
concept idea.
Plane Restrictions
==================
AMDGPU imposes restrictions on the use of DRM planes in the driver.
Atomic commits will be rejected for commits which do not follow these
restrictions:
* Overlay planes must be in ARGB8888 or XRGB8888 format
* Planes cannot be placed outside of the CRTC destination rectangle
* Planes cannot be downscaled more than 1/4x of their original size
* Planes cannot be upscaled more than 16x of their original size
Not every property is available on every plane:
* Only primary planes have color-space and non-RGB format support
* Only overlay planes have alpha blending support
Cursor Restrictions
===================
Before we start to describe some restrictions around cursor and MPO, see the
below image:
.. kernel-figure:: mpo-cursor.svg
The image on the left side represents how DRM expects the cursor and planes to
be blended. However, AMD hardware handles cursors differently, as you can see
on the right side; basically, our cursor cannot be drawn outside its associated
plane as it is being treated as part of the plane. Another consequence of that
is that cursors inherit the color and scale from the plane.
As a result of the above behavior, do not use legacy API to set up the cursor
plane when working with MPO; otherwise, you might encounter unexpected
behavior.
In short, AMD HW has no dedicated cursor planes. A cursor is attached to
another plane and therefore inherits any scaling or color processing from its
parent plane.
Use Cases
=========
Picture-in-Picture (PIP) playback - Underlay strategy
-----------------------------------------------------
Video playback should be done using the "primary plane as underlay" MPO
strategy. This is a 2 planes configuration:
* 1 YUV DRM Primary Plane (e.g. NV12 Video)
* 1 RGBA DRM Overlay Plane (e.g. ARGB8888 desktop). The compositor should
prepare the framebuffers for the planes as follows:
- The overlay plane contains general desktop UI, video player controls, and video subtitles
- Primary plane contains one or more videos
.. note:: Keep in mind that we could extend this configuration to more planes,
but that is currently not supported by our driver yet (maybe if we have a
userspace request in the future, we can change that).
See below a single-video example:
.. kernel-figure:: single-display-mpo.svg
.. note:: We could extend this behavior to more planes, but that is currently
not supported by our driver.
The video buffer should be used directly for the primary plane. The video can
be scaled and positioned for the desktop using the properties: CRTC_X, CRTC_Y,
CRTC_W, and CRTC_H. The primary plane should also have the color encoding and
color range properties set based on the source content:
* ``COLOR_RANGE``, ``COLOR_ENCODING``
The overlay plane should be the native size of the CRTC. The compositor must
draw a transparent cutout for where the video should be placed on the desktop
(i.e., set the alpha to zero). The primary plane video will be visible through
the underlay. The overlay plane's buffer may remain static while the primary
plane's framebuffer is used for standard double-buffered playback.
The compositor should create a YUV buffer matching the native size of the CRTC.
Each video buffer should be composited onto this YUV buffer for direct YUV
scanout. The primary plane should have the color encoding and color range
properties set based on the source content: ``COLOR_RANGE``,
``COLOR_ENCODING``. However, be mindful that the source color space and
encoding match for each video since it affect the entire plane.
The overlay plane should be the native size of the CRTC. The compositor must
draw a transparent cutout for where each video should be placed on the desktop
(i.e., set the alpha to zero). The primary plane videos will be visible through
the underlay. The overlay plane's buffer may remain static while compositing
operations for video playback will be done on the video buffer.
This kernel interface is validated using IGT GPU Tools. The following tests can
be run to validate positioning, blending, scaling under a variety of sequences
and interactions with operations such as DPMS and S3:
- ``kms_plane@plane-panning-bottom-right-pipe-*-planes``
- ``kms_plane@plane-panning-bottom-right-suspend-pipe-*-``
- ``kms_plane@plane-panning-top-left-pipe-*-``
- ``kms_plane@plane-position-covered-pipe-*-``
- ``kms_plane@plane-position-hole-dpms-pipe-*-``
- ``kms_plane@plane-position-hole-pipe-*-``
- ``kms_plane_multiple@atomic-pipe-*-tiling-``
- ``kms_plane_scaling@pipe-*-plane-scaling``
- ``kms_plane_alpha_blend@pipe-*-alpha-basic``
- ``kms_plane_alpha_blend@pipe-*-alpha-transparant-fb``
- ``kms_plane_alpha_blend@pipe-*-alpha-opaque-fb``
- ``kms_plane_alpha_blend@pipe-*-constant-alpha-min``
- ``kms_plane_alpha_blend@pipe-*-constant-alpha-mid``
- ``kms_plane_alpha_blend@pipe-*-constant-alpha-max``
Multiple Display MPO
--------------------
AMDGPU supports display MPO when using multiple displays; however, this feature
behavior heavily relies on the compositor implementation. Keep in mind that
usespace can define different policies. For example, some OSes can use MPO to
protect the plane that handles the video playback; notice that we don't have
many limitations for a single display. Nonetheless, this manipulation can have
many more restrictions for a multi-display scenario. The below example shows a
video playback in the middle of two displays, and it is up to the compositor to
define a policy on how to handle it:
.. kernel-figure:: multi-display-hdcp-mpo.svg
Let's discuss some of the hardware limitations we have when dealing with
multi-display with MPO.
Limitations
~~~~~~~~~~~
For simplicity's sake, for discussing the hardware limitation, this
documentation supposes an example where we have two displays and video playback
that will be moved around different displays.
* **Hardware limitations**
From the DCN overview page, each display requires at least one pipe and each
MPO plane needs another pipe. As a result, when the video is in the middle of
the two displays, we need to use 2 pipes. See the example below where we avoid
pipe split:
- 1 display (1 pipe) + MPO (1 pipe), we will use two pipes
- 2 displays (2 pipes) + MPO (1-2 pipes); we will use 4 pipes. MPO in the
middle of both displays needs 2 pipes.
- 3 Displays (3 pipes) + MPO (1-2 pipes), we need 5 pipes.
If we use MPO with multiple displays, the userspace has to decide to enable
multiple MPO by the price of limiting the number of external displays supported
or disable it in favor of multiple displays; it is a policy decision. For
example:
* When ASIC has 3 pipes, AMD hardware can NOT support 2 displays with MPO
* When ASIC has 4 pipes, AMD hardware can NOT support 3 displays with MPO
Let's briefly explore how userspace can handle these two display configurations
on an ASIC that only supports three pipes. We can have:
.. kernel-figure:: multi-display-hdcp-mpo-less-pipe-ex.svg
- Total pipes are 3
- User lights up 2 displays (2 out of 3 pipes are used)
- User launches video (1 pipe used for MPO)
- Now, if the user moves the video in the middle of 2 displays, one part of the
video won't be MPO since we have used 3/3 pipes.
* **Scaling limitation**
MPO cannot handle scaling less than 0.25 and more than x16. For example:
If 4k video (3840x2160) is playing in windowed mode, the physical size of the
window cannot be smaller than (960x540).
.. note:: These scaling limitations might vary from ASIC to ASIC.
* **Size Limitation**
The minimum MPO size is 12px.

View File

@ -0,0 +1,220 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="103.08798mm"
height="30.335283mm"
viewBox="0 0 103.08798 30.335284"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="multi-display-hdcp-mpo-less-pipe-ex.svg">
<defs
id="defs2">
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1133"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1133-0"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="205.69673"
inkscape:cy="33.960031"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1288"
inkscape:window-height="1376"
inkscape:window-x="1272"
inkscape:window-y="27"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(112.75816,51.721433)">
<rect
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836"
width="48.988979"
height="29.48851"
x="-112.44358"
y="-51.189243"
ry="0" />
<rect
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.38327959;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834"
width="14.422765"
height="15.872559"
x="-78.227928"
y="-44.469936" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-71.189278"
y="-48.114422"
id="text844"><tspan
sodipodi:role="line"
x="-71.189278"
y="-48.114422"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846">Protected</tspan><tspan
sodipodi:role="line"
x="-71.189278"
y="-45.584015"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2288">MPO plane</tspan></text>
<rect
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-3"
width="48.988979"
height="29.48851"
x="-58.973743"
y="-51.406849"
ry="0" />
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.2500253;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834-6"
width="6.1374092"
height="15.872559"
x="-58.632965"
y="-44.469936" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-107.96788"
y="-47.033775"
id="text844-7"><tspan
sodipodi:role="line"
x="-107.96788"
y="-47.033775"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-3">#1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-15.20074"
y="-46.715996"
id="text844-7-2"><tspan
sodipodi:role="line"
x="-15.20074"
y="-46.715996"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-3-9">#2</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-88.926605"
y="-23.173674"
id="text844-1"><tspan
sodipodi:role="line"
x="-88.926605"
y="-23.173674"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7">Desktop</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-33.770744"
y="-23.819901"
id="text844-1-0"><tspan
sodipodi:role="line"
x="-33.770744"
y="-23.819901"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7-9">Desktop</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-75.17498"
y="-41.219398"
id="text844-7-2-3"><tspan
sodipodi:role="line"
x="-75.17498"
y="-41.219398"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:0.06901112"
id="tspan846-3-9-6">#3</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-47.142235"
y="-48.056866"
id="text844-0"><tspan
sodipodi:role="line"
x="-47.142235"
y="-48.056866"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2288-2">Software</tspan><tspan
sodipodi:role="line"
x="-47.142235"
y="-45.526459"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2313">Composited Video</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-36.23288"
y="-34.592064"
id="text844-1-6"><tspan
sodipodi:role="line"
x="-36.23288"
y="-34.592064"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7-1">Video will not be displayed</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="103.08798mm"
height="30.335283mm"
viewBox="0 0 103.08798 30.335284"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="multi-display-hdcp-mpo.svg">
<defs
id="defs2">
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1133"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1133-0"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="196.85789"
inkscape:cy="33.960027"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1288"
inkscape:window-height="1376"
inkscape:window-x="1272"
inkscape:window-y="27"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(112.75816,51.721433)">
<rect
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836"
width="48.988979"
height="29.48851"
x="-112.44358"
y="-51.189243"
ry="0" />
<rect
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.38327959;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834"
width="14.422765"
height="15.872559"
x="-78.227928"
y="-44.469936" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-71.189278"
y="-48.114422"
id="text844"><tspan
sodipodi:role="line"
x="-71.189278"
y="-48.114422"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846">Protected</tspan><tspan
sodipodi:role="line"
x="-71.189278"
y="-45.584015"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2288">MPO plane</tspan></text>
<rect
style="fill:#ffe680;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-3"
width="48.988979"
height="29.48851"
x="-58.973743"
y="-51.406849"
ry="0" />
<rect
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.2500253;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834-6"
width="6.1374092"
height="15.872559"
x="-58.632965"
y="-44.469936" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-88.926605"
y="-23.173674"
id="text844-1"><tspan
sodipodi:role="line"
x="-88.926605"
y="-23.173674"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7">Desktop</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-33.770744"
y="-23.819901"
id="text844-1-0"><tspan
sodipodi:role="line"
x="-33.770744"
y="-23.819901"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7-9">Desktop</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-70.364128"
y="-35.740372"
id="text844-7-2-3"><tspan
sodipodi:role="line"
x="-70.364128"
y="-35.740372"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;fill:#ffffff;stroke-width:0.06901112"
id="tspan846-3-9-6">Video</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -0,0 +1,958 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1055.4928"
height="404.60379"
viewBox="0 0 279.26579 107.05142"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="pipeline_4k_no_split.svg">
<defs
id="defs2">
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker8858"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8616"
style="fill:#aa00d4;fill-opacity:1;fill-rule:evenodd;stroke:#aa00d4;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Send"
orient="auto"
refY="0"
refX="0"
id="Arrow2Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8622"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-0.3,0,0,-0.3,0.69,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8592"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8610"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-8"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-4"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-5"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-1"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-1"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0-7"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3-4"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-6-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-1-0"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-2-8"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-9-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker8858-3"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8616-5"
style="fill:#00ffcc;fill-opacity:1;fill-rule:evenodd;stroke:#00ffcc;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-3-3"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-6-56"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-8-0-2"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1200-9-3-9"
style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-9"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-3"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-7"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-4"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0-1"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7-4"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0-2"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0-2-4"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7-6-9"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-8"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-7"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend-94-6-0-2-7"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1200-7-9-7-6-6"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="213.41584"
inkscape:cy="301.17934"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
showguides="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:snap-global="false" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(349.34521,-0.81564989)">
<rect
style="fill:none;stroke:#000000;stroke-width:1.00353587;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none"
id="rect834"
width="30.251244"
height="88.477814"
x="-317.81958"
y="14.782127"
ry="2.5590618e-06" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-314.73792"
y="21.83947"
id="text838"><tspan
sodipodi:role="line"
id="tspan836"
x="-314.73792"
y="21.83947"
style="stroke-width:0.16370411">DCHUB</tspan></text>
<g
id="g2025"
transform="translate(-2.4916954,-1.2533369)">
<text
id="text838-5"
y="31.969406"
x="-254.53119"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="31.969406"
x="-254.53119"
id="tspan836-3"
sodipodi:role="line">DPP</tspan><tspan
id="tspan936"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="40.15461"
x="-254.53119"
sodipodi:role="line">(0)</tspan></text>
<rect
ry="7.8154301e-07"
y="20.596174"
x="-269.66983"
height="27.021315"
width="30.696135"
id="rect834-5"
style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.1637041"
x="-297.75696"
y="109.44505"
id="text1063"><tspan
sodipodi:role="line"
id="tspan1061"
x="-297.75696"
y="115.23865"
style="stroke-width:0.1637041" /></text>
<g
id="g1878"
transform="translate(-0.62971878)">
<text
id="text846"
y="30.716068"
x="-302.27368"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="30.716068"
x="-302.27368"
id="tspan844"
sodipodi:role="line">HUBP</tspan><tspan
id="tspan863"
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="38.901276"
x="-302.27368"
sodipodi:role="line">(0)</tspan></text>
<g
id="g1853">
<rect
style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1850"
width="24.708241"
height="17.224693"
x="-314.41837"
y="24.241148" />
</g>
</g>
<g
transform="translate(-0.62971878,18.810271)"
id="g1878-1">
<text
id="text846-2"
y="30.716068"
x="-302.27368"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="30.716068"
x="-302.27368"
id="tspan844-7"
sodipodi:role="line">HUBP</tspan><tspan
id="tspan863-0"
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="38.901276"
x="-302.27368"
sodipodi:role="line">(1)</tspan></text>
<g
id="g1853-9">
<rect
style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1850-3"
width="24.708241"
height="17.224693"
x="-314.41837"
y="24.241148" />
</g>
</g>
<g
transform="translate(-0.62971878,57.029814)"
id="g1878-8">
<text
id="text846-7"
y="30.716068"
x="-302.27368"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#44aa00;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="30.716068"
x="-302.27368"
id="tspan844-9"
sodipodi:role="line">HUBP</tspan><tspan
id="tspan863-20"
style="text-align:center;text-anchor:middle;fill:#44aa00;stroke-width:0.16370411"
y="38.901276"
x="-302.27368"
sodipodi:role="line">(5)</tspan></text>
<g
id="g1853-2">
<rect
style="fill:none;fill-opacity:1;stroke:#55d400;stroke-width:0.94157624;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect1850-37"
width="24.708241"
height="17.224693"
x="-314.41837"
y="24.241148" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-310.7348"
y="72.106789"
id="text8862-5"><tspan
sodipodi:role="line"
id="tspan8860-9"
x="-310.7348"
y="72.106789"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#44aa00;stroke-width:0.26458332">...</tspan></text>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.96187615;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94)"
d="m -288.90777,32.862737 h 14.20296"
id="path1171"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-264.85431"
y="62.072891"
id="text8862-5-8"><tspan
sodipodi:role="line"
id="tspan8860-9-4"
x="-264.85431"
y="62.072891"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
<g
id="g2025-5"
transform="translate(40.522337,-1.1484419)" />
<g
id="g7343"
transform="translate(40.522337,-1.2533369)">
<text
id="text838-5-6"
y="31.969406"
x="-254.53119"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="31.969406"
x="-254.53119"
id="tspan836-3-3"
sodipodi:role="line">MPC</tspan><tspan
id="tspan936-2"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="40.15461"
x="-254.53119"
sodipodi:role="line">(0)</tspan></text>
<rect
ry="7.8154301e-07"
y="20.596174"
x="-269.66983"
height="27.021315"
width="30.696135"
id="rect834-5-0"
style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<g
id="g7343-2"
transform="translate(84.178583,-1.2533369)">
<text
id="text838-5-6-54"
y="31.969406"
x="-254.53119"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="31.969406"
x="-254.53119"
id="tspan836-3-3-7"
sodipodi:role="line">OPP</tspan><tspan
id="tspan936-2-44"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="40.15461"
x="-254.53119"
sodipodi:role="line">(0)</tspan></text>
<rect
ry="7.8154301e-07"
y="20.596174"
x="-269.66983"
height="27.021315"
width="30.696135"
id="rect834-5-0-3"
style="fill:none;stroke:#000000;stroke-width:0.55864918;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-221.84029"
y="62.072891"
id="text8862-5-8-6"><tspan
sodipodi:role="line"
id="tspan8860-9-4-5"
x="-221.84029"
y="62.072891"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6)"
d="m -240.90479,32.86192 h 10.61353"
id="path1171-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0)"
d="m -198.19009,32.86192 h 10.61353"
id="path1171-3-8"
inkscape:connector-curvature="0" />
<g
id="g7343-2-2"
transform="translate(127.15447,-1.1484419)">
<text
id="text838-5-6-54-0"
y="65.122154"
x="-254.32814"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
id="tspan936-2-44-8"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="65.122154"
x="-254.32814"
sodipodi:role="line">OPTC</tspan></text>
<rect
ry="2.4256708e-06"
y="20.805576"
x="-269.46042"
height="83.865906"
width="30.277332"
id="rect834-5-0-3-9"
style="fill:none;stroke:#000000;stroke-width:0.97745234;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0-2)"
d="m -154.34485,32.86192 h 10.61353"
id="path1171-3-8-6"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:3.17499995px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-178.18404"
y="62.072891"
id="text8862-5-8-6-0"><tspan
sodipodi:role="line"
id="tspan8860-9-4-5-4"
x="-178.18404"
y="62.072891"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:14.11111069px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.26458332">...</tspan></text>
<path
style="fill:#000000;stroke:#000000;stroke-width:0.96187615;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-8)"
d="m -335.20986,59.030276 h 14.20296"
id="path1171-17"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-349.77686"
y="61.404655"
id="text838-2"><tspan
sodipodi:role="line"
id="tspan836-7"
x="-349.77686"
y="61.404655"
style="stroke-width:0.16370411">SDP</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291667, 1.32291667;stroke-dashoffset:0;stroke-opacity:1"
d="M -279.04164,107.86706 V 0.89985833"
id="path11907"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.3229167, 1.3229167;stroke-dashoffset:0;stroke-opacity:1"
d="M -235.57438,107.86707 V 0.89985663"
id="path11907-6-1"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291671, 1.32291671;stroke-dashoffset:0;stroke-opacity:1"
d="M -149.96277,107.86707 V 0.89985223"
id="path11907-6-1-0"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-257.38275"
y="5.003336"
id="text838-6"><tspan
sodipodi:role="line"
id="tspan836-1"
x="-257.38275"
y="5.003336"
style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411">DPPCLK</tspan><tspan
sodipodi:role="line"
x="-257.38275"
y="13.188541"
style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411"
id="tspan12658">535.916Mhz</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-192.85298"
y="5.003336"
id="text838-6-5"><tspan
sodipodi:role="line"
id="tspan836-1-9"
x="-192.85298"
y="5.003336"
style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411">DISPCLK</tspan><tspan
sodipodi:role="line"
x="-192.85298"
y="13.188541"
style="font-size:4.93888903px;text-align:center;text-anchor:middle;stroke-width:0.16370411"
id="tspan12662">541.275 Mhz</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-302.03766"
y="5.003336"
id="text838-6-5-4"><tspan
sodipodi:role="line"
id="tspan836-1-9-9"
x="-312.23135"
y="5.003336"
style="font-size:4.93888903px;stroke-width:0.16370411;text-anchor:middle;text-align:center">DCFCLK</tspan><tspan
sodipodi:role="line"
x="-312.23135"
y="13.188541"
style="font-size:4.93888903px;stroke-width:0.16370411;text-anchor:middle;text-align:center"
id="tspan12660">506 Mhz</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-96.075348"
y="4.568048"
id="text838-6-5-0"><tspan
sodipodi:role="line"
id="tspan836-1-9-91"
x="-96.075348"
y="4.568048"
style="font-size:4.93888903px;stroke-width:0.16370411">SymCLK</tspan></text>
<g
id="g7343-2-2-7"
transform="translate(168.61494,-1.1484419)">
<text
id="text838-5-6-54-0-7"
y="65.122154"
x="-254.32814"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
xml:space="preserve"><tspan
id="tspan936-2-44-8-1"
style="text-align:center;text-anchor:middle;stroke-width:0.16370411"
y="65.122154"
x="-254.32814"
sodipodi:role="line">DIO</tspan></text>
<rect
ry="2.4256708e-06"
y="20.805576"
x="-269.46042"
height="83.865906"
width="30.277332"
id="rect834-5-0-3-9-1"
style="fill:none;stroke:#000000;stroke-width:0.97745234;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1.32291663;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.32291672, 1.32291672;stroke-dashoffset:0;stroke-opacity:1"
d="M -108.38539,107.86707 V 0.89985092"
id="path11907-6-1-0-5"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.54816437px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16370411"
x="-143.52292"
y="5.0467439"
id="text838-6-5-0-9"><tspan
sodipodi:role="line"
id="tspan836-1-9-91-7"
x="-143.52292"
y="5.0467439"
style="font-size:4.93888903px;stroke-width:0.16370411">VirtualPCLK</tspan></text>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.83149505;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-94-6-0-2-7)"
d="m -112.24183,60.747629 h 10.61353"
id="path1171-3-8-6-7"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 40 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,339 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="112.16296mm"
height="93.314507mm"
viewBox="0 0 112.16296 93.314508"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="single-display-mpo-multi-video.svg">
<defs
id="defs2">
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1133"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1006"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1133-0"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="255.95284"
inkscape:cy="222.25473"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1514"
inkscape:window-height="1376"
inkscape:window-x="1046"
inkscape:window-y="27"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(26.189925,5.2546503)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-2.2053311"
y="32.839729"
id="text844"><tspan
sodipodi:role="line"
x="-2.2053313"
y="32.839729"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846">Video Buffer (YUV)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="30.867918"
y="87.638779"
id="text844-2"><tspan
sodipodi:role="line"
x="30.867918"
y="87.638779"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-0">CRTC Output</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.53249496;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.59748484, 0.53249495;stroke-dashoffset:0"
id="rect969"
width="111.63046"
height="44.238331"
x="-25.923677"
y="-4.9884028" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="48.037342"
y="45.781586"
id="text844-2-9"><tspan
sodipodi:role="line"
x="48.037342"
y="45.781586"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2868">Hardware Composition</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL)"
d="m 32.66992,40.326865 v 9.760144"
id="path989"
inkscape:connector-curvature="0" />
<g
id="g4447"
style="stroke:#000000">
<rect
ry="0"
y="0.23764905"
x="-23.784248"
height="29.48851"
width="48.988979"
id="rect836"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="3.8184125"
x="-20.589451"
height="6.9794898"
width="11.594959"
id="rect836-2-6"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="3.8184123"
x="-5.6613555"
height="6.9794903"
width="11.594959"
id="rect836-2-6-1"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="3.8184121"
x="10.374816"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-8"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="18.386644"
x="-20.341679"
height="6.9794903"
width="11.594959"
id="rect836-2-6-7"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="18.386644"
x="-5.4135842"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-9"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="18.386644"
x="10.622585"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-8-2"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
</g>
<rect
style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2"
width="48.988979"
height="29.48851"
x="31.367332"
y="0.45039755"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-3"
width="11.594959"
height="6.9794898"
x="34.56213"
y="4.0311608"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-1-7"
width="11.594959"
height="6.9794903"
x="49.490223"
y="4.0311608"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-1-8-5"
width="11.594959"
height="6.9794908"
x="65.526398"
y="4.0311604"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-7-9"
width="11.594959"
height="6.9794903"
x="34.809902"
y="18.599392"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-1-9-2"
width="11.594959"
height="6.9794908"
x="49.737995"
y="18.599392"
ry="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836-2-6-1-8-2-2"
width="11.594959"
height="6.9794908"
x="65.774162"
y="18.599392"
ry="0" />
<g
id="g4562"
transform="translate(0,11.22532)">
<rect
ry="0"
y="43.21352"
x="5.9767256"
height="29.48851"
width="48.988979"
id="rect836-97"
style="fill:#808080;fill-opacity:1;stroke:#808080;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="46.794285"
x="9.1715231"
height="6.9794898"
width="11.594959"
id="rect836-2-6-36"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891468;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="46.794285"
x="24.099619"
height="6.9794903"
width="11.594959"
id="rect836-2-6-1-1"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="46.794285"
x="40.135792"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-8-29"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="61.362514"
x="9.4192953"
height="6.9794903"
width="11.594959"
id="rect836-2-6-7-3"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="61.362514"
x="24.347389"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-9-1"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
ry="0"
y="61.362514"
x="40.38356"
height="6.9794908"
width="11.594959"
id="rect836-2-6-1-8-2-9"
style="fill:#008000;fill-opacity:1;stroke:#000000;stroke-width:0.14891469;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813358px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="57.012939"
y="33.603645"
id="text844-4"><tspan
sodipodi:role="line"
x="57.012939"
y="33.603645"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-7">Desktop Buffer (ARGB)</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,266 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="148.71147mm"
height="38.356358mm"
viewBox="0 0 148.71148 38.356358"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="single-display-mpo.svg">
<defs
id="defs2">
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1133"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path1006"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL-6"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path1133-0"
d="M 5.77,0 -2.88,5 V -5 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
transform="scale(0.8)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="266.07058"
inkscape:cy="81.254796"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1514"
inkscape:window-height="1376"
inkscape:window-x="1046"
inkscape:window-y="27"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(26.323559,-14.790568)">
<rect
style="fill:#999999;fill-opacity:1;stroke:#999999;stroke-width:0.62916809;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect836"
width="48.988979"
height="29.48851"
x="4.9472256"
y="17.075632"
ry="0" />
<g
id="g905"
transform="matrix(0.26082945,0,0,0.26082945,-26.950235,-0.99631462)">
<rect
y="67.568451"
x="12.473214"
height="60.854164"
width="102.43154"
id="rect834"
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<path
inkscape:transform-center-y="-3.581986e-06"
inkscape:transform-center-x="-3.3106064"
d="m 73.620805,97.995537 -9.931819,5.734143 -9.931819,5.73413 0,-11.468274 0,-11.468276 9.931819,5.734139 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.0471976"
sodipodi:arg1="0"
sodipodi:r2="6.6212125"
sodipodi:r1="13.242425"
sodipodi:cy="97.995537"
sodipodi:cx="60.37838"
sodipodi:sides="3"
id="path840"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.22854495;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="star" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="-10.357052"
y="34.176075"
id="text844"><tspan
sodipodi:role="line"
id="tspan842"
x="-10.357052"
y="34.176075"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112">Video Buffer (YUV)</tspan><tspan
sodipodi:role="line"
x="-10.357052"
y="36.706482"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846">DRM PRIMARY PLANE</tspan></text>
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.5216589;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834-3"
width="26.717165"
height="15.872559"
x="16.083126"
y="23.883608" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="28.437061"
y="49.158085"
id="text844-6"><tspan
sodipodi:role="line"
x="28.437061"
y="49.158085"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-5">Desktop Buffer (ARGB)</tspan><tspan
sodipodi:role="line"
x="28.437061"
y="51.688492"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan886">DRM OVERLAY PLANE</tspan></text>
<g
id="g2874"
transform="matrix(1.0858687,0,0,1.0858687,-4.5597909,-2.06277)">
<rect
ry="0"
y="17.624969"
x="71.504173"
height="27.156607"
width="45.115009"
id="rect836-9"
style="fill:#999999;fill-opacity:1;stroke:#999999;stroke-width:0.57941455;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" />
<g
id="g905-5"
transform="matrix(0.24020349,0,0,0.24020349,78.763353,7.664402)">
<rect
style="fill:#008000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="rect834-6"
width="102.43154"
height="60.854164"
x="12.473214"
y="67.568451" />
<path
sodipodi:type="star"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.22854495;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
id="path840-2"
sodipodi:sides="3"
sodipodi:cx="60.37838"
sodipodi:cy="97.995537"
sodipodi:r1="13.242425"
sodipodi:r2="6.6212125"
sodipodi:arg1="0"
sodipodi:arg2="1.0471976"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 73.620805,97.995537 -9.931819,5.734143 -9.931819,5.73413 0,-11.468274 0,-11.468276 9.931819,5.734139 z"
inkscape:transform-center-x="-3.3106064"
inkscape:transform-center-y="-3.581986e-06" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="97.551666"
y="50.221046"
id="text844-2"><tspan
sodipodi:role="line"
x="97.551666"
y="50.221046"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-0">CRTC Output</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.42211887;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:1.26635657, 0.42211886;stroke-dashoffset:0"
id="rect969"
width="81.806648"
height="37.934238"
x="-26.112499"
y="15.001627" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:0.82813352px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06901112"
x="64.474419"
y="31.883568"
id="text844-2-9"><tspan
sodipodi:role="line"
x="64.474419"
y="31.883568"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan846-0-3">Hardware</tspan><tspan
sodipodi:role="line"
x="64.474419"
y="34.413975"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.02432632px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;text-anchor:middle;stroke-width:0.06901112"
id="tspan2868">Composition</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL)"
d="m 57.401149,24.81643 h 9.760144"
id="path989"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.48997903;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#TriangleOutL-6)"
d="m 57.401149,41.794278 h 9.760144"
id="path989-6"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -32,6 +32,23 @@ unique_id
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c .. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
:doc: unique_id :doc: unique_id
Accelerated Processing Units (APU) Info
---------------------------------------
.. csv-table::
:header-rows: 1
:widths: 3, 2, 2, 1, 1, 1
:file: ./apu-asic-info-table.csv
Discrete GPU Info
-----------------
.. csv-table::
:header-rows: 1
:widths: 3, 2, 2, 1, 1, 1
:file: ./dgpu-asic-info-table.csv
GPU Memory Usage Information GPU Memory Usage Information
============================ ============================

View File

@ -72,7 +72,8 @@ card's RLC (RunList Controller) firmware powers off the gfx engine
dynamically when there is no workload on gfx or compute pipes. GFXOFF is on by dynamically when there is no workload on gfx or compute pipes. GFXOFF is on by
default on supported GPUs. default on supported GPUs.
Userspace can interact with GFXOFF through a debugfs interface: Userspace can interact with GFXOFF through a debugfs interface (all values in
`uint32_t`, unless otherwise noted):
``amdgpu_gfxoff`` ``amdgpu_gfxoff``
----------------- -----------------
@ -104,3 +105,18 @@ Read it to check current GFXOFF's status of a GPU::
If GFXOFF is enabled, the value will be transitioning around [0, 3], always If GFXOFF is enabled, the value will be transitioning around [0, 3], always
getting into 0 when possible. When it's disabled, it's always at 2. Returns getting into 0 when possible. When it's disabled, it's always at 2. Returns
``-EINVAL`` if it's not supported. ``-EINVAL`` if it's not supported.
``amdgpu_gfxoff_count``
-----------------------
Read it to get the total GFXOFF entry count at the time of query since system
power-up. The value is an `uint64_t` type, however, due to firmware limitations,
it can currently overflow as an `uint32_t`. *Only supported in vangogh*
``amdgpu_gfxoff_residency``
---------------------------
Write 1 to amdgpu_gfxoff_residency to start logging, and 0 to stop. Read it to
get average GFXOFF residency % multiplied by 100 during the last logging
interval. E.g. a value of 7854 means 78.54% of the time in the last logging
interval the GPU was in GFXOFF mode. *Only supported in vangogh*

View File

@ -122,13 +122,13 @@ format Helper Functions Reference
.. kernel-doc:: drivers/gpu/drm/drm_format_helper.c .. kernel-doc:: drivers/gpu/drm/drm_format_helper.c
:export: :export:
Framebuffer CMA Helper Functions Reference Framebuffer DMA Helper Functions Reference
========================================== ==========================================
.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c .. kernel-doc:: drivers/gpu/drm/drm_fb_dma_helper.c
:doc: framebuffer cma helper functions :doc: framebuffer dma helper functions
.. kernel-doc:: drivers/gpu/drm/drm_fb_cma_helper.c .. kernel-doc:: drivers/gpu/drm/drm_fb_dma_helper.c
:export: :export:
Framebuffer GEM Helper Reference Framebuffer GEM Helper Reference

View File

@ -532,6 +532,8 @@ Standard Plane Properties
.. kernel-doc:: drivers/gpu/drm/drm_plane.c .. kernel-doc:: drivers/gpu/drm/drm_plane.c
:doc: standard plane properties :doc: standard plane properties
.. _plane_composition_properties:
Plane Composition Properties Plane Composition Properties
---------------------------- ----------------------------

View File

@ -300,12 +300,12 @@ Drivers that want to map the GEM object upfront instead of handling page
faults can implement their own mmap file operation handler. faults can implement their own mmap file operation handler.
For platforms without MMU the GEM core provides a helper method For platforms without MMU the GEM core provides a helper method
drm_gem_cma_get_unmapped_area(). The mmap() routines will call this to get a drm_gem_dma_get_unmapped_area(). The mmap() routines will call this to get a
proposed address for the mapping. proposed address for the mapping.
To use drm_gem_cma_get_unmapped_area(), drivers must fill the struct To use drm_gem_dma_get_unmapped_area(), drivers must fill the struct
:c:type:`struct file_operations <file_operations>` get_unmapped_area field with :c:type:`struct file_operations <file_operations>` get_unmapped_area field with
a pointer on drm_gem_cma_get_unmapped_area(). a pointer on drm_gem_dma_get_unmapped_area().
More detailed information about get_unmapped_area can be found in More detailed information about get_unmapped_area can be found in
Documentation/admin-guide/mm/nommu-mmap.rst Documentation/admin-guide/mm/nommu-mmap.rst
@ -355,16 +355,16 @@ GEM Function Reference
.. kernel-doc:: drivers/gpu/drm/drm_gem.c .. kernel-doc:: drivers/gpu/drm/drm_gem.c
:export: :export:
GEM CMA Helper Functions Reference GEM DMA Helper Functions Reference
---------------------------------- ----------------------------------
.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c .. kernel-doc:: drivers/gpu/drm/drm_gem_dma_helper.c
:doc: cma helpers :doc: dma helpers
.. kernel-doc:: include/drm/drm_gem_cma_helper.h .. kernel-doc:: include/drm/drm_gem_dma_helper.h
:internal: :internal:
.. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c .. kernel-doc:: drivers/gpu/drm/drm_gem_dma_helper.c
:export: :export:
GEM SHMEM Helper Function Reference GEM SHMEM Helper Function Reference

View File

@ -322,18 +322,6 @@ Contact: Daniel Vetter, Noralf Tronnes
Level: Advanced Level: Advanced
idr_init_base()
---------------
DRM core&drivers uses a lot of idr (integer lookup directories) for mapping
userspace IDs to internal objects, and in most places ID=0 means NULL and hence
is never used. Switching to idr_init_base() for these would make the idr more
efficient.
Contact: Daniel Vetter
Level: Starter
struct drm_gem_object_funcs struct drm_gem_object_funcs
--------------------------- ---------------------------
@ -343,19 +331,6 @@ converted, except for struct drm_driver.gem_prime_mmap.
Level: Intermediate Level: Intermediate
Rename CMA helpers to DMA helpers
---------------------------------
CMA (standing for contiguous memory allocator) is really a bit an accident of
what these were used for first, a much better name would be DMA helpers. In the
text these should even be called coherent DMA memory helpers (so maybe CDM, but
no one knows what that means) since underneath they just use dma_alloc_coherent.
Contact: Laurent Pinchart, Daniel Vetter
Level: Intermediate (mostly because it is a huge tasks without good partial
milestones, not technically itself that challenging)
connector register/unregister fixes connector register/unregister fixes
----------------------------------- -----------------------------------
@ -617,17 +592,6 @@ Contact: Javier Martinez Canillas <javierm@redhat.com>
Level: Intermediate Level: Intermediate
Convert Kernel Selftests (kselftest) to KUnit tests when appropriate
--------------------------------------------------------------------
Many of the `Kselftest <https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html>`_
tests in DRM could be converted to Kunit tests instead, since that framework
is more suitable for unit testing.
Contact: Javier Martinez Canillas <javierm@redhat.com>
Level: Starter
Enable trinity for DRM Enable trinity for DRM
---------------------- ----------------------

View File

@ -118,15 +118,10 @@ Add Plane Features
There's lots of plane features we could add support for: There's lots of plane features we could add support for:
- Clearing primary plane: clear primary plane before plane composition (at the
start) for correctness of pixel blend ops. It also guarantees alpha channel
is cleared in the target buffer for stable crc. [Good to get started]
- ARGB format on primary plane: blend the primary plane into background with - ARGB format on primary plane: blend the primary plane into background with
translucent alpha. translucent alpha.
- Support when the primary plane isn't exactly matching the output size: blend - Add background color KMS property[Good to get started].
the primary plane into the black background.
- Full alpha blending on all planes. - Full alpha blending on all planes.

View File

@ -6431,6 +6431,11 @@ S: Maintained
F: Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.yaml F: Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.yaml
F: drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c F: drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
DRM DRIVER FOR GENERIC EDP PANELS
R: Douglas Anderson <dianders@chromium.org>
F: Documentation/devicetree/bindings/display/panel/panel-edp.yaml
F: drivers/gpu/drm/panel/panel-edp.c
DRM DRIVER FOR GENERIC USB DISPLAY DRM DRIVER FOR GENERIC USB DISPLAY
M: Noralf Trønnes <noralf@tronnes.org> M: Noralf Trønnes <noralf@tronnes.org>
S: Maintained S: Maintained

View File

@ -136,6 +136,10 @@ struct dma_fence *dma_fence_get_stub(void)
&dma_fence_stub_ops, &dma_fence_stub_ops,
&dma_fence_stub_lock, &dma_fence_stub_lock,
0, 0); 0, 0);
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
&dma_fence_stub.flags);
dma_fence_signal_locked(&dma_fence_stub); dma_fence_signal_locked(&dma_fence_stub);
} }
spin_unlock(&dma_fence_stub_lock); spin_unlock(&dma_fence_stub_lock);
@ -161,6 +165,10 @@ struct dma_fence *dma_fence_allocate_private_stub(void)
&dma_fence_stub_ops, &dma_fence_stub_ops,
&dma_fence_stub_lock, &dma_fence_stub_lock,
0, 0); 0, 0);
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
&dma_fence_stub.flags);
dma_fence_signal(fence); dma_fence_signal(fence);
return fence; return fence;
@ -500,6 +508,8 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
__dma_fence_might_wait(); __dma_fence_might_wait();
dma_fence_enable_sw_signaling(fence);
trace_dma_fence_wait_start(fence); trace_dma_fence_wait_start(fence);
if (fence->ops->wait) if (fence->ops->wait)
ret = fence->ops->wait(fence, intr, timeout); ret = fence->ops->wait(fence, intr, timeout);
@ -601,9 +611,6 @@ void dma_fence_enable_sw_signaling(struct dma_fence *fence)
{ {
unsigned long flags; unsigned long flags;
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return;
spin_lock_irqsave(fence->lock, flags); spin_lock_irqsave(fence->lock, flags);
__dma_fence_enable_signaling(fence); __dma_fence_enable_signaling(fence);
spin_unlock_irqrestore(fence->lock, flags); spin_unlock_irqrestore(fence->lock, flags);
@ -756,19 +763,16 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
unsigned long flags; unsigned long flags;
signed long ret = timeout ? timeout : 1; signed long ret = timeout ? timeout : 1;
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return ret;
spin_lock_irqsave(fence->lock, flags); spin_lock_irqsave(fence->lock, flags);
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
goto out;
if (intr && signal_pending(current)) { if (intr && signal_pending(current)) {
ret = -ERESTARTSYS; ret = -ERESTARTSYS;
goto out; goto out;
} }
if (!__dma_fence_enable_signaling(fence))
goto out;
if (!timeout) { if (!timeout) {
ret = 0; ret = 0;
goto out; goto out;

View File

@ -87,6 +87,8 @@ static int sanitycheck(void *arg)
if (!chain) if (!chain)
err = -ENOMEM; err = -ENOMEM;
dma_fence_enable_sw_signaling(chain);
dma_fence_signal(f); dma_fence_signal(f);
dma_fence_put(f); dma_fence_put(f);
@ -143,6 +145,8 @@ static int fence_chains_init(struct fence_chains *fc, unsigned int count,
} }
fc->tail = fc->chains[i]; fc->tail = fc->chains[i];
dma_fence_enable_sw_signaling(fc->chains[i]);
} }
fc->chain_length = i; fc->chain_length = i;

View File

@ -102,6 +102,8 @@ static int sanitycheck(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
array = mock_array(1, f); array = mock_array(1, f);
if (!array) if (!array)
return -ENOMEM; return -ENOMEM;
@ -124,12 +126,16 @@ static int unwrap_array(void *arg)
if (!f1) if (!f1)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); f2 = mock_fence();
if (!f2) { if (!f2) {
dma_fence_put(f1); dma_fence_put(f1);
return -ENOMEM; return -ENOMEM;
} }
dma_fence_enable_sw_signaling(f2);
array = mock_array(2, f1, f2); array = mock_array(2, f1, f2);
if (!array) if (!array)
return -ENOMEM; return -ENOMEM;
@ -164,12 +170,16 @@ static int unwrap_chain(void *arg)
if (!f1) if (!f1)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); f2 = mock_fence();
if (!f2) { if (!f2) {
dma_fence_put(f1); dma_fence_put(f1);
return -ENOMEM; return -ENOMEM;
} }
dma_fence_enable_sw_signaling(f2);
chain = mock_chain(f1, f2); chain = mock_chain(f1, f2);
if (!chain) if (!chain)
return -ENOMEM; return -ENOMEM;
@ -204,12 +214,16 @@ static int unwrap_chain_array(void *arg)
if (!f1) if (!f1)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); f2 = mock_fence();
if (!f2) { if (!f2) {
dma_fence_put(f1); dma_fence_put(f1);
return -ENOMEM; return -ENOMEM;
} }
dma_fence_enable_sw_signaling(f2);
array = mock_array(2, f1, f2); array = mock_array(2, f1, f2);
if (!array) if (!array)
return -ENOMEM; return -ENOMEM;
@ -248,12 +262,16 @@ static int unwrap_merge(void *arg)
if (!f1) if (!f1)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); f2 = mock_fence();
if (!f2) { if (!f2) {
err = -ENOMEM; err = -ENOMEM;
goto error_put_f1; goto error_put_f1;
} }
dma_fence_enable_sw_signaling(f2);
f3 = dma_fence_unwrap_merge(f1, f2); f3 = dma_fence_unwrap_merge(f1, f2);
if (!f3) { if (!f3) {
err = -ENOMEM; err = -ENOMEM;
@ -296,10 +314,14 @@ static int unwrap_merge_complex(void *arg)
if (!f1) if (!f1)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); f2 = mock_fence();
if (!f2) if (!f2)
goto error_put_f1; goto error_put_f1;
dma_fence_enable_sw_signaling(f2);
f3 = dma_fence_unwrap_merge(f1, f2); f3 = dma_fence_unwrap_merge(f1, f2);
if (!f3) if (!f3)
goto error_put_f2; goto error_put_f2;

View File

@ -102,6 +102,8 @@ static int sanitycheck(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
dma_fence_signal(f); dma_fence_signal(f);
dma_fence_put(f); dma_fence_put(f);
@ -117,6 +119,8 @@ static int test_signaling(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
if (dma_fence_is_signaled(f)) { if (dma_fence_is_signaled(f)) {
pr_err("Fence unexpectedly signaled on creation\n"); pr_err("Fence unexpectedly signaled on creation\n");
goto err_free; goto err_free;
@ -190,6 +194,8 @@ static int test_late_add_callback(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
dma_fence_signal(f); dma_fence_signal(f);
if (!dma_fence_add_callback(f, &cb.cb, simple_callback)) { if (!dma_fence_add_callback(f, &cb.cb, simple_callback)) {
@ -282,6 +288,8 @@ static int test_status(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
if (dma_fence_get_status(f)) { if (dma_fence_get_status(f)) {
pr_err("Fence unexpectedly has signaled status on creation\n"); pr_err("Fence unexpectedly has signaled status on creation\n");
goto err_free; goto err_free;
@ -308,6 +316,8 @@ static int test_error(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
dma_fence_set_error(f, -EIO); dma_fence_set_error(f, -EIO);
if (dma_fence_get_status(f)) { if (dma_fence_get_status(f)) {
@ -337,6 +347,8 @@ static int test_wait(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
if (dma_fence_wait_timeout(f, false, 0) != -ETIME) { if (dma_fence_wait_timeout(f, false, 0) != -ETIME) {
pr_err("Wait reported complete before being signaled\n"); pr_err("Wait reported complete before being signaled\n");
goto err_free; goto err_free;
@ -379,6 +391,8 @@ static int test_wait_timeout(void *arg)
if (!wt.f) if (!wt.f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(wt.f);
if (dma_fence_wait_timeout(wt.f, false, 1) != -ETIME) { if (dma_fence_wait_timeout(wt.f, false, 1) != -ETIME) {
pr_err("Wait reported complete before being signaled\n"); pr_err("Wait reported complete before being signaled\n");
goto err_free; goto err_free;
@ -458,6 +472,8 @@ static int thread_signal_callback(void *arg)
break; break;
} }
dma_fence_enable_sw_signaling(f1);
rcu_assign_pointer(t->fences[t->id], f1); rcu_assign_pointer(t->fences[t->id], f1);
smp_wmb(); smp_wmb();

View File

@ -45,6 +45,8 @@ static int sanitycheck(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
dma_fence_signal(f); dma_fence_signal(f);
dma_fence_put(f); dma_fence_put(f);
@ -69,6 +71,8 @@ static int test_signaling(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
dma_resv_init(&resv); dma_resv_init(&resv);
r = dma_resv_lock(&resv, NULL); r = dma_resv_lock(&resv, NULL);
if (r) { if (r) {
@ -114,6 +118,8 @@ static int test_for_each(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
dma_resv_init(&resv); dma_resv_init(&resv);
r = dma_resv_lock(&resv, NULL); r = dma_resv_lock(&resv, NULL);
if (r) { if (r) {
@ -173,6 +179,8 @@ static int test_for_each_unlocked(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
dma_resv_init(&resv); dma_resv_init(&resv);
r = dma_resv_lock(&resv, NULL); r = dma_resv_lock(&resv, NULL);
if (r) { if (r) {
@ -244,6 +252,8 @@ static int test_get_fences(void *arg)
if (!f) if (!f)
return -ENOMEM; return -ENOMEM;
dma_fence_enable_sw_signaling(f);
dma_resv_init(&resv); dma_resv_init(&resv);
r = dma_resv_lock(&resv, NULL); r = dma_resv_lock(&resv, NULL);
if (r) { if (r) {

View File

@ -132,7 +132,7 @@ EXPORT_SYMBOL(sync_file_get_fence);
char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len) char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len)
{ {
if (sync_file->user_name[0]) { if (sync_file->user_name[0]) {
strlcpy(buf, sync_file->user_name, len); strscpy(buf, sync_file->user_name, len);
} else { } else {
struct dma_fence *fence = sync_file->fence; struct dma_fence *fence = sync_file->fence;
@ -172,7 +172,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
return NULL; return NULL;
} }
sync_file->fence = fence; sync_file->fence = fence;
strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name)); strscpy(sync_file->user_name, name, sizeof(sync_file->user_name));
return sync_file; return sync_file;
} }
@ -262,9 +262,9 @@ err_put_fd:
static int sync_fill_fence_info(struct dma_fence *fence, static int sync_fill_fence_info(struct dma_fence *fence,
struct sync_fence_info *info) struct sync_fence_info *info)
{ {
strlcpy(info->obj_name, fence->ops->get_timeline_name(fence), strscpy(info->obj_name, fence->ops->get_timeline_name(fence),
sizeof(info->obj_name)); sizeof(info->obj_name));
strlcpy(info->driver_name, fence->ops->get_driver_name(fence), strscpy(info->driver_name, fence->ops->get_driver_name(fence),
sizeof(info->driver_name)); sizeof(info->driver_name));
info->status = dma_fence_get_status(fence); info->status = dma_fence_get_status(fence);

View File

@ -124,17 +124,20 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
{ {
struct udmabuf *ubuf = buf->priv; struct udmabuf *ubuf = buf->priv;
struct device *dev = ubuf->device->this_device; struct device *dev = ubuf->device->this_device;
int ret = 0;
if (!ubuf->sg) { if (!ubuf->sg) {
ubuf->sg = get_sg_table(dev, buf, direction); ubuf->sg = get_sg_table(dev, buf, direction);
if (IS_ERR(ubuf->sg)) if (IS_ERR(ubuf->sg)) {
return PTR_ERR(ubuf->sg); ret = PTR_ERR(ubuf->sg);
ubuf->sg = NULL;
}
} else { } else {
dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents, dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents,
direction); direction);
} }
return 0; return ret;
} }
static int end_cpu_udmabuf(struct dma_buf *buf, static int end_cpu_udmabuf(struct dma_buf *buf,

View File

@ -94,6 +94,10 @@ static __init int sysfb_init(void)
name = "efi-framebuffer"; name = "efi-framebuffer";
else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB) else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
name = "vesa-framebuffer"; name = "vesa-framebuffer";
else if (si->orig_video_isVGA == VIDEO_TYPE_VGAC)
name = "vga-framebuffer";
else if (si->orig_video_isVGA == VIDEO_TYPE_EGAC)
name = "ega-framebuffer";
else else
name = "platform-framebuffer"; name = "platform-framebuffer";

View File

@ -31,6 +31,7 @@ menuconfig DRM
config DRM_MIPI_DBI config DRM_MIPI_DBI
tristate tristate
depends on DRM depends on DRM
select DRM_KMS_HELPER
config DRM_MIPI_DSI config DRM_MIPI_DSI
bool bool
@ -50,10 +51,9 @@ config DRM_DEBUG_MM
If in doubt, say "N". If in doubt, say "N".
config DRM_DEBUG_SELFTEST config DRM_KUNIT_TEST
tristate "kselftests for DRM" tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
depends on DRM depends on DRM && KUNIT
depends on DEBUG_KERNEL
select PRIME_NUMBERS select PRIME_NUMBERS
select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HELPER select DRM_DISPLAY_HELPER
@ -61,19 +61,6 @@ config DRM_DEBUG_SELFTEST
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_BUDDY select DRM_BUDDY
select DRM_EXPORT_FOR_TESTS if m select DRM_EXPORT_FOR_TESTS if m
default n
help
This option provides kernel modules that can be used to run
various selftests on parts of the DRM api. This option is not
useful for distributions or general kernels, but only for kernel
developers working on DRM and associated drivers.
If in doubt, say "N".
config DRM_KUNIT_TEST
tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
depends on DRM && KUNIT=y
select DRM_KMS_HELPER
default KUNIT_ALL_TESTS default KUNIT_ALL_TESTS
help help
This builds unit tests for DRM. This option is not useful for This builds unit tests for DRM. This option is not useful for
@ -214,11 +201,11 @@ config DRM_TTM_HELPER
help help
Helpers for ttm-based gem objects Helpers for ttm-based gem objects
config DRM_GEM_CMA_HELPER config DRM_GEM_DMA_HELPER
tristate tristate
depends on DRM depends on DRM
help help
Choose this if you need the GEM CMA helper functions Choose this if you need the GEM DMA helper functions
config DRM_GEM_SHMEM_HELPER config DRM_GEM_SHMEM_HELPER
tristate tristate

View File

@ -40,9 +40,9 @@ obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o
drm_cma_helper-y := drm_gem_cma_helper.o drm_dma_helper-y := drm_gem_dma_helper.o
drm_cma_helper-$(CONFIG_DRM_KMS_HELPER) += drm_fb_cma_helper.o drm_dma_helper-$(CONFIG_DRM_KMS_HELPER) += drm_fb_dma_helper.o
obj-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_cma_helper.o obj-$(CONFIG_DRM_GEM_DMA_HELPER) += drm_dma_helper.o
drm_shmem_helper-y := drm_gem_shmem_helper.o drm_shmem_helper-y := drm_gem_shmem_helper.o
obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o
@ -75,7 +75,6 @@ obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
# Drivers and the rest # Drivers and the rest
# #
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
obj-$(CONFIG_DRM_KUNIT_TEST) += tests/ obj-$(CONFIG_DRM_KUNIT_TEST) += tests/
obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o

View File

@ -75,7 +75,7 @@ amdgpu-y += \
vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \ vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \ vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \ nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o \
nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o sienna_cichlid.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o
# add DF block # add DF block
amdgpu-y += \ amdgpu-y += \
@ -89,7 +89,7 @@ amdgpu-y += \
gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \ gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \
gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o \ gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o \
mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o \ mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o \
mmhub_v3_0_1.o mmhub_v3_0_1.o gfxhub_v3_0_3.o
# add UMC block # add UMC block
amdgpu-y += \ amdgpu-y += \
@ -134,7 +134,8 @@ amdgpu-y += \
gfx_v9_4_2.o \ gfx_v9_4_2.o \
gfx_v10_0.o \ gfx_v10_0.o \
imu_v11_0.o \ imu_v11_0.o \
gfx_v11_0.o gfx_v11_0.o \
imu_v11_0_3.o
# add async DMA block # add async DMA block
amdgpu-y += \ amdgpu-y += \

View File

@ -274,6 +274,9 @@ extern int amdgpu_vcnfw_log;
#define AMDGPU_RESET_VCE (1 << 13) #define AMDGPU_RESET_VCE (1 << 13)
#define AMDGPU_RESET_VCE1 (1 << 14) #define AMDGPU_RESET_VCE1 (1 << 14)
#define AMDGPU_RESET_LEVEL_SOFT_RECOVERY (1 << 0)
#define AMDGPU_RESET_LEVEL_MODE2 (1 << 1)
/* max cursor sizes (in pixels) */ /* max cursor sizes (in pixels) */
#define CIK_CURSOR_WIDTH 128 #define CIK_CURSOR_WIDTH 128
#define CIK_CURSOR_HEIGHT 128 #define CIK_CURSOR_HEIGHT 128
@ -882,6 +885,7 @@ struct amdgpu_device {
u64 fence_context; u64 fence_context;
unsigned num_rings; unsigned num_rings;
struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; struct amdgpu_ring *rings[AMDGPU_MAX_RINGS];
struct dma_fence __rcu *gang_submit;
bool ib_pool_ready; bool ib_pool_ready;
struct amdgpu_sa_manager ib_pools[AMDGPU_IB_POOL_MAX]; struct amdgpu_sa_manager ib_pools[AMDGPU_IB_POOL_MAX];
struct amdgpu_sched gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX]; struct amdgpu_sched gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX];
@ -1060,6 +1064,9 @@ struct amdgpu_device {
uint32_t scpm_status; uint32_t scpm_status;
struct work_struct reset_work; struct work_struct reset_work;
uint32_t amdgpu_reset_level_mask;
bool job_hang;
}; };
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev) static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
@ -1288,6 +1295,8 @@ u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
u32 reg); u32 reg);
void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev, void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
u32 reg, u32 v); u32 reg, u32 v);
struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
struct dma_fence *gang);
/* atpx handler */ /* atpx handler */
#if defined(CONFIG_VGA_SWITCHEROO) #if defined(CONFIG_VGA_SWITCHEROO)

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: MIT
/* /*
* Copyright 2012 Advanced Micro Devices, Inc. * Copyright 2012 Advanced Micro Devices, Inc.
* *
@ -849,6 +850,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
if (amdgpu_device_has_dc_support(adev)) { if (amdgpu_device_has_dc_support(adev)) {
#if defined(CONFIG_DRM_AMD_DC) #if defined(CONFIG_DRM_AMD_DC)
struct amdgpu_display_manager *dm = &adev->dm; struct amdgpu_display_manager *dm = &adev->dm;
if (dm->backlight_dev[0]) if (dm->backlight_dev[0])
atif->bd = dm->backlight_dev[0]; atif->bd = dm->backlight_dev[0];
#endif #endif
@ -863,6 +865,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) && if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) &&
enc->enc_priv) { enc->enc_priv) {
struct amdgpu_encoder_atom_dig *dig = enc->enc_priv; struct amdgpu_encoder_atom_dig *dig = enc->enc_priv;
if (dig->bl_dev) { if (dig->bl_dev) {
atif->bd = dig->bl_dev; atif->bd = dig->bl_dev;
break; break;
@ -919,9 +922,9 @@ static bool amdgpu_atif_pci_probe_handle(struct pci_dev *pdev)
return false; return false;
status = acpi_get_handle(dhandle, "ATIF", &atif_handle); status = acpi_get_handle(dhandle, "ATIF", &atif_handle);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status))
return false; return false;
}
amdgpu_acpi_priv.atif.handle = atif_handle; amdgpu_acpi_priv.atif.handle = atif_handle;
acpi_get_name(amdgpu_acpi_priv.atif.handle, ACPI_FULL_PATHNAME, &buffer); acpi_get_name(amdgpu_acpi_priv.atif.handle, ACPI_FULL_PATHNAME, &buffer);
DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name); DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name);
@ -954,9 +957,9 @@ static bool amdgpu_atcs_pci_probe_handle(struct pci_dev *pdev)
return false; return false;
status = acpi_get_handle(dhandle, "ATCS", &atcs_handle); status = acpi_get_handle(dhandle, "ATCS", &atcs_handle);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status))
return false; return false;
}
amdgpu_acpi_priv.atcs.handle = atcs_handle; amdgpu_acpi_priv.atcs.handle = atcs_handle;
acpi_get_name(amdgpu_acpi_priv.atcs.handle, ACPI_FULL_PATHNAME, &buffer); acpi_get_name(amdgpu_acpi_priv.atcs.handle, ACPI_FULL_PATHNAME, &buffer);
DRM_DEBUG_DRIVER("Found ATCS handle %s\n", acpi_method_name); DRM_DEBUG_DRIVER("Found ATCS handle %s\n", acpi_method_name);
@ -1070,6 +1073,12 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
(pm_suspend_target_state != PM_SUSPEND_TO_IDLE)) (pm_suspend_target_state != PM_SUSPEND_TO_IDLE))
return false; return false;
/*
* If ACPI_FADT_LOW_POWER_S0 is not set in the FADT, it is generally
* risky to do any special firmware-related preparations for entering
* S0ix even though the system is suspending to idle, so return false
* in that case.
*/
if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) { if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
dev_warn_once(adev->dev, dev_warn_once(adev->dev,
"Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n" "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: MIT
/* /*
* Copyright 2014 Advanced Micro Devices, Inc. * Copyright 2014 Advanced Micro Devices, Inc.
* *
@ -130,11 +131,13 @@ static void amdgpu_amdkfd_reset_work(struct work_struct *work)
kfd.reset_work); kfd.reset_work);
struct amdgpu_reset_context reset_context; struct amdgpu_reset_context reset_context;
memset(&reset_context, 0, sizeof(reset_context)); memset(&reset_context, 0, sizeof(reset_context));
reset_context.method = AMD_RESET_METHOD_NONE; reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev; reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
amdgpu_device_gpu_recover(adev, NULL, &reset_context); amdgpu_device_gpu_recover(adev, NULL, &reset_context);
} }
@ -683,6 +686,7 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
ib->length_dw = ib_len; ib->length_dw = ib_len;
/* This works for NO_HWS. TODO: need to handle without knowing VMID */ /* This works for NO_HWS. TODO: need to handle without knowing VMID */
job->vmid = vmid; job->vmid = vmid;
job->num_ibs = 1;
ret = amdgpu_ib_schedule(ring, 1, ib, job, &f); ret = amdgpu_ib_schedule(ring, 1, ib, job, &f);
@ -752,11 +756,7 @@ void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev, bo
{ {
struct ras_err_data err_data = {0, 0, 0, NULL}; struct ras_err_data err_data = {0, 0, 0, NULL};
/* CPU MCA will handle page retirement if connected_to_cpu is 1 */ amdgpu_umc_poison_handler(adev, &err_data, reset);
if (!adev->gmc.xgmi.connected_to_cpu)
amdgpu_umc_poison_handler(adev, &err_data, reset);
else if (reset)
amdgpu_amdkfd_gpu_reset(adev);
} }
bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev) bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev)

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: MIT
/* /*
* Copyright 2014-2018 Advanced Micro Devices, Inc. * Copyright 2014-2018 Advanced Micro Devices, Inc.
* *
@ -297,7 +298,7 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo,
*/ */
replacement = dma_fence_get_stub(); replacement = dma_fence_get_stub();
dma_resv_replace_fences(bo->tbo.base.resv, ef->base.context, dma_resv_replace_fences(bo->tbo.base.resv, ef->base.context,
replacement, DMA_RESV_USAGE_READ); replacement, DMA_RESV_USAGE_BOOKKEEP);
dma_fence_put(replacement); dma_fence_put(replacement);
return 0; return 0;
} }
@ -1390,8 +1391,9 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
ret = dma_resv_reserve_fences(vm->root.bo->tbo.base.resv, 1); ret = dma_resv_reserve_fences(vm->root.bo->tbo.base.resv, 1);
if (ret) if (ret)
goto reserve_shared_fail; goto reserve_shared_fail;
amdgpu_bo_fence(vm->root.bo, dma_resv_add_fence(vm->root.bo->tbo.base.resv,
&vm->process_info->eviction_fence->base, true); &vm->process_info->eviction_fence->base,
DMA_RESV_USAGE_BOOKKEEP);
amdgpu_bo_unreserve(vm->root.bo); amdgpu_bo_unreserve(vm->root.bo);
/* Update process info */ /* Update process info */
@ -1612,6 +1614,7 @@ size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev)
uint64_t reserved_for_pt = uint64_t reserved_for_pt =
ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size); ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
size_t available; size_t available;
spin_lock(&kfd_mem_limit.mem_limit_lock); spin_lock(&kfd_mem_limit.mem_limit_lock);
available = adev->gmc.real_vram_size available = adev->gmc.real_vram_size
- adev->kfd.vram_used_aligned - adev->kfd.vram_used_aligned
@ -1987,9 +1990,9 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
} }
if (!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) && !bo->tbo.pin_count) if (!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) && !bo->tbo.pin_count)
amdgpu_bo_fence(bo, dma_resv_add_fence(bo->tbo.base.resv,
&avm->process_info->eviction_fence->base, &avm->process_info->eviction_fence->base,
true); DMA_RESV_USAGE_BOOKKEEP);
ret = unreserve_bo_and_vms(&ctx, false, false); ret = unreserve_bo_and_vms(&ctx, false, false);
goto out; goto out;
@ -2216,7 +2219,7 @@ int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev,
{ {
if (atomic_read(&adev->gmc.vm_fault_info_updated) == 1) { if (atomic_read(&adev->gmc.vm_fault_info_updated) == 1) {
*mem = *adev->gmc.vm_fault_info; *mem = *adev->gmc.vm_fault_info;
mb(); mb(); /* make sure read happened */
atomic_set(&adev->gmc.vm_fault_info_updated, 0); atomic_set(&adev->gmc.vm_fault_info_updated, 0);
} }
return 0; return 0;
@ -2758,15 +2761,18 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
if (mem->bo->tbo.pin_count) if (mem->bo->tbo.pin_count)
continue; continue;
amdgpu_bo_fence(mem->bo, dma_resv_add_fence(mem->bo->tbo.base.resv,
&process_info->eviction_fence->base, true); &process_info->eviction_fence->base,
DMA_RESV_USAGE_BOOKKEEP);
} }
/* Attach eviction fence to PD / PT BOs */ /* Attach eviction fence to PD / PT BOs */
list_for_each_entry(peer_vm, &process_info->vm_list_head, list_for_each_entry(peer_vm, &process_info->vm_list_head,
vm_list_node) { vm_list_node) {
struct amdgpu_bo *bo = peer_vm->root.bo; struct amdgpu_bo *bo = peer_vm->root.bo;
amdgpu_bo_fence(bo, &process_info->eviction_fence->base, true); dma_resv_add_fence(bo->tbo.base.resv,
&process_info->eviction_fence->base,
DMA_RESV_USAGE_BOOKKEEP);
} }
validate_map_fail: validate_map_fail:
@ -2820,7 +2826,9 @@ int amdgpu_amdkfd_add_gws_to_process(void *info, void *gws, struct kgd_mem **mem
ret = dma_resv_reserve_fences(gws_bo->tbo.base.resv, 1); ret = dma_resv_reserve_fences(gws_bo->tbo.base.resv, 1);
if (ret) if (ret)
goto reserve_shared_fail; goto reserve_shared_fail;
amdgpu_bo_fence(gws_bo, &process_info->eviction_fence->base, true); dma_resv_add_fence(gws_bo->tbo.base.resv,
&process_info->eviction_fence->base,
DMA_RESV_USAGE_BOOKKEEP);
amdgpu_bo_unreserve(gws_bo); amdgpu_bo_unreserve(gws_bo);
mutex_unlock(&(*mem)->process_info->lock); mutex_unlock(&(*mem)->process_info->lock);

View File

@ -1674,10 +1674,12 @@ amdgpu_connector_add(struct amdgpu_device *adev,
adev->mode_info.dither_property, adev->mode_info.dither_property,
AMDGPU_FMT_DITHER_DISABLE); AMDGPU_FMT_DITHER_DISABLE);
if (amdgpu_audio != 0) if (amdgpu_audio != 0) {
drm_object_attach_property(&amdgpu_connector->base.base, drm_object_attach_property(&amdgpu_connector->base.base,
adev->mode_info.audio_property, adev->mode_info.audio_property,
AMDGPU_AUDIO_AUTO); AMDGPU_AUDIO_AUTO);
amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
}
subpixel_order = SubPixelHorizontalRGB; subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true; connector->interlace_allowed = true;
@ -1799,6 +1801,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
drm_object_attach_property(&amdgpu_connector->base.base, drm_object_attach_property(&amdgpu_connector->base.base,
adev->mode_info.audio_property, adev->mode_info.audio_property,
AMDGPU_AUDIO_AUTO); AMDGPU_AUDIO_AUTO);
amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
} }
drm_object_attach_property(&amdgpu_connector->base.base, drm_object_attach_property(&amdgpu_connector->base.base,
adev->mode_info.dither_property, adev->mode_info.dither_property,
@ -1852,6 +1855,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
drm_object_attach_property(&amdgpu_connector->base.base, drm_object_attach_property(&amdgpu_connector->base.base,
adev->mode_info.audio_property, adev->mode_info.audio_property,
AMDGPU_AUDIO_AUTO); AMDGPU_AUDIO_AUTO);
amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
} }
drm_object_attach_property(&amdgpu_connector->base.base, drm_object_attach_property(&amdgpu_connector->base.base,
adev->mode_info.dither_property, adev->mode_info.dither_property,
@ -1902,6 +1906,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
drm_object_attach_property(&amdgpu_connector->base.base, drm_object_attach_property(&amdgpu_connector->base.base,
adev->mode_info.audio_property, adev->mode_info.audio_property,
AMDGPU_AUDIO_AUTO); AMDGPU_AUDIO_AUTO);
amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
} }
drm_object_attach_property(&amdgpu_connector->base.base, drm_object_attach_property(&amdgpu_connector->base.base,
adev->mode_info.dither_property, adev->mode_info.dither_property,

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,8 @@
#include "amdgpu_bo_list.h" #include "amdgpu_bo_list.h"
#include "amdgpu_ring.h" #include "amdgpu_ring.h"
#define AMDGPU_CS_GANG_SIZE 4
struct amdgpu_bo_va_mapping; struct amdgpu_bo_va_mapping;
struct amdgpu_cs_chunk { struct amdgpu_cs_chunk {
@ -50,9 +52,11 @@ struct amdgpu_cs_parser {
unsigned nchunks; unsigned nchunks;
struct amdgpu_cs_chunk *chunks; struct amdgpu_cs_chunk *chunks;
/* scheduler job object */ /* scheduler job objects */
struct amdgpu_job *job; unsigned int gang_size;
struct drm_sched_entity *entity; struct drm_sched_entity *entities[AMDGPU_CS_GANG_SIZE];
struct amdgpu_job *jobs[AMDGPU_CS_GANG_SIZE];
struct amdgpu_job *gang_leader;
/* buffer objects */ /* buffer objects */
struct ww_acquire_ctx ticket; struct ww_acquire_ctx ticket;

View File

@ -315,7 +315,6 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
kref_init(&ctx->refcount); kref_init(&ctx->refcount);
ctx->mgr = mgr; ctx->mgr = mgr;
spin_lock_init(&ctx->ring_lock); spin_lock_init(&ctx->ring_lock);
mutex_init(&ctx->lock);
ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter); ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
ctx->reset_counter_query = ctx->reset_counter; ctx->reset_counter_query = ctx->reset_counter;
@ -402,12 +401,11 @@ static void amdgpu_ctx_fini(struct kref *ref)
} }
} }
if (drm_dev_enter(&adev->ddev, &idx)) { if (drm_dev_enter(adev_to_drm(adev), &idx)) {
amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate); amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
drm_dev_exit(idx); drm_dev_exit(idx);
} }
mutex_destroy(&ctx->lock);
kfree(ctx); kfree(ctx);
} }
@ -848,7 +846,7 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr,
mgr->adev = adev; mgr->adev = adev;
mutex_init(&mgr->lock); mutex_init(&mgr->lock);
idr_init(&mgr->ctx_handles); idr_init_base(&mgr->ctx_handles, 1);
for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) for (i = 0; i < AMDGPU_HW_IP_NUM; ++i)
atomic64_set(&mgr->time_spend[i], 0); atomic64_set(&mgr->time_spend[i], 0);

View File

@ -53,7 +53,6 @@ struct amdgpu_ctx {
bool preamble_presented; bool preamble_presented;
int32_t init_priority; int32_t init_priority;
int32_t override_priority; int32_t override_priority;
struct mutex lock;
atomic_t guilty; atomic_t guilty;
unsigned long ras_counter_ce; unsigned long ras_counter_ce;
unsigned long ras_counter_ue; unsigned long ras_counter_ue;

View File

@ -1042,6 +1042,157 @@ err:
return r; return r;
} }
/**
* amdgpu_debugfs_gfxoff_residency_read - Read GFXOFF residency
*
* @f: open file handle
* @buf: User buffer to store read data in
* @size: Number of bytes to read
* @pos: Offset to seek to
*
* Read the last residency value logged. It doesn't auto update, one needs to
* stop logging before getting the current value.
*/
static ssize_t amdgpu_debugfs_gfxoff_residency_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_device *adev = file_inode(f)->i_private;
ssize_t result = 0;
int r;
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
while (size) {
uint32_t value;
r = amdgpu_get_gfx_off_residency(adev, &value);
if (r)
goto out;
r = put_user(value, (uint32_t *)buf);
if (r)
goto out;
result += 4;
buf += 4;
*pos += 4;
size -= 4;
}
r = result;
out:
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/**
* amdgpu_debugfs_gfxoff_residency_write - Log GFXOFF Residency
*
* @f: open file handle
* @buf: User buffer to write data from
* @size: Number of bytes to write
* @pos: Offset to seek to
*
* Write a 32-bit non-zero to start logging; write a 32-bit zero to stop
*/
static ssize_t amdgpu_debugfs_gfxoff_residency_write(struct file *f, const char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_device *adev = file_inode(f)->i_private;
ssize_t result = 0;
int r;
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
while (size) {
u32 value;
r = get_user(value, (uint32_t *)buf);
if (r)
goto out;
amdgpu_set_gfx_off_residency(adev, value ? true : false);
result += 4;
buf += 4;
*pos += 4;
size -= 4;
}
r = result;
out:
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/**
* amdgpu_debugfs_gfxoff_count_read - Read GFXOFF entry count
*
* @f: open file handle
* @buf: User buffer to store read data in
* @size: Number of bytes to read
* @pos: Offset to seek to
*/
static ssize_t amdgpu_debugfs_gfxoff_count_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_device *adev = file_inode(f)->i_private;
ssize_t result = 0;
int r;
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
while (size) {
u64 value = 0;
r = amdgpu_get_gfx_off_entrycount(adev, &value);
if (r)
goto out;
r = put_user(value, (u64 *)buf);
if (r)
goto out;
result += 4;
buf += 4;
*pos += 4;
size -= 4;
}
r = result;
out:
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
return r;
}
/** /**
* amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF * amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF
* *
@ -1249,6 +1400,19 @@ static const struct file_operations amdgpu_debugfs_gfxoff_status_fops = {
.llseek = default_llseek .llseek = default_llseek
}; };
static const struct file_operations amdgpu_debugfs_gfxoff_count_fops = {
.owner = THIS_MODULE,
.read = amdgpu_debugfs_gfxoff_count_read,
.llseek = default_llseek
};
static const struct file_operations amdgpu_debugfs_gfxoff_residency_fops = {
.owner = THIS_MODULE,
.read = amdgpu_debugfs_gfxoff_residency_read,
.write = amdgpu_debugfs_gfxoff_residency_write,
.llseek = default_llseek
};
static const struct file_operations *debugfs_regs[] = { static const struct file_operations *debugfs_regs[] = {
&amdgpu_debugfs_regs_fops, &amdgpu_debugfs_regs_fops,
&amdgpu_debugfs_regs2_fops, &amdgpu_debugfs_regs2_fops,
@ -1261,6 +1425,8 @@ static const struct file_operations *debugfs_regs[] = {
&amdgpu_debugfs_gpr_fops, &amdgpu_debugfs_gpr_fops,
&amdgpu_debugfs_gfxoff_fops, &amdgpu_debugfs_gfxoff_fops,
&amdgpu_debugfs_gfxoff_status_fops, &amdgpu_debugfs_gfxoff_status_fops,
&amdgpu_debugfs_gfxoff_count_fops,
&amdgpu_debugfs_gfxoff_residency_fops,
}; };
static const char *debugfs_regs_names[] = { static const char *debugfs_regs_names[] = {
@ -1275,6 +1441,8 @@ static const char *debugfs_regs_names[] = {
"amdgpu_gpr", "amdgpu_gpr",
"amdgpu_gfxoff", "amdgpu_gfxoff",
"amdgpu_gfxoff_status", "amdgpu_gfxoff_status",
"amdgpu_gfxoff_count",
"amdgpu_gfxoff_residency",
}; };
/** /**
@ -1786,6 +1954,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
return PTR_ERR(ent); return PTR_ERR(ent);
} }
debugfs_create_u32("amdgpu_reset_level", 0600, root, &adev->amdgpu_reset_level_mask);
/* Register debugfs entries for amdgpu_ttm */ /* Register debugfs entries for amdgpu_ttm */
amdgpu_ttm_debugfs_init(adev); amdgpu_ttm_debugfs_init(adev);
amdgpu_debugfs_pm_init(adev); amdgpu_debugfs_pm_init(adev);

View File

@ -2459,19 +2459,21 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
*/ */
if (adev->gmc.xgmi.num_physical_nodes > 1) { if (adev->gmc.xgmi.num_physical_nodes > 1) {
if (amdgpu_xgmi_add_device(adev) == 0) { if (amdgpu_xgmi_add_device(adev) == 0) {
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev); if (!amdgpu_sriov_vf(adev)) {
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
if (!hive->reset_domain || if (!hive->reset_domain ||
!amdgpu_reset_get_reset_domain(hive->reset_domain)) { !amdgpu_reset_get_reset_domain(hive->reset_domain)) {
r = -ENOENT; r = -ENOENT;
amdgpu_put_xgmi_hive(hive);
goto init_failed;
}
/* Drop the early temporary reset domain we created for device */
amdgpu_reset_put_reset_domain(adev->reset_domain);
adev->reset_domain = hive->reset_domain;
amdgpu_put_xgmi_hive(hive); amdgpu_put_xgmi_hive(hive);
goto init_failed;
} }
/* Drop the early temporary reset domain we created for device */
amdgpu_reset_put_reset_domain(adev->reset_domain);
adev->reset_domain = hive->reset_domain;
amdgpu_put_xgmi_hive(hive);
} }
} }
@ -3510,6 +3512,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->gmc.gart_size = 512 * 1024 * 1024; adev->gmc.gart_size = 512 * 1024 * 1024;
adev->accel_working = false; adev->accel_working = false;
adev->num_rings = 0; adev->num_rings = 0;
RCU_INIT_POINTER(adev->gang_submit, dma_fence_get_stub());
adev->mman.buffer_funcs = NULL; adev->mman.buffer_funcs = NULL;
adev->mman.buffer_funcs_ring = NULL; adev->mman.buffer_funcs_ring = NULL;
adev->vm_manager.vm_pte_funcs = NULL; adev->vm_manager.vm_pte_funcs = NULL;
@ -3588,6 +3591,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
INIT_WORK(&adev->xgmi_reset_work, amdgpu_device_xgmi_reset_func); INIT_WORK(&adev->xgmi_reset_work, amdgpu_device_xgmi_reset_func);
adev->gfx.gfx_off_req_count = 1; adev->gfx.gfx_off_req_count = 1;
adev->gfx.gfx_off_residency = 0;
adev->gfx.gfx_off_entrycount = 0;
adev->pm.ac_power = power_supply_is_system_supplied() > 0; adev->pm.ac_power = power_supply_is_system_supplied() > 0;
atomic_set(&adev->throttling_logging_enabled, 1); atomic_set(&adev->throttling_logging_enabled, 1);
@ -3976,8 +3981,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
amdgpu_gart_dummy_page_fini(adev); amdgpu_gart_dummy_page_fini(adev);
if (drm_dev_is_unplugged(adev_to_drm(adev))) amdgpu_device_unmap_mmio(adev);
amdgpu_device_unmap_mmio(adev);
} }
@ -3990,6 +3994,7 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
release_firmware(adev->firmware.gpu_info_fw); release_firmware(adev->firmware.gpu_info_fw);
adev->firmware.gpu_info_fw = NULL; adev->firmware.gpu_info_fw = NULL;
adev->accel_working = false; adev->accel_working = false;
dma_fence_put(rcu_dereference_protected(adev->gang_submit, true));
amdgpu_reset_fini(adev); amdgpu_reset_fini(adev);
@ -4542,14 +4547,15 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev)
*/ */
bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev) bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
{ {
if (!amdgpu_device_ip_check_soft_reset(adev)) {
dev_info(adev->dev, "Timeout, but no hardware hang detected.\n");
return false;
}
if (amdgpu_gpu_recovery == 0) if (amdgpu_gpu_recovery == 0)
goto disabled; goto disabled;
if (!amdgpu_device_ip_check_soft_reset(adev)) {
dev_info(adev->dev,"Timeout, but no hardware hang detected.\n");
return false;
}
if (amdgpu_sriov_vf(adev)) if (amdgpu_sriov_vf(adev))
return true; return true;
@ -4674,7 +4680,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
if (!need_full_reset) if (!need_full_reset)
need_full_reset = amdgpu_device_ip_need_full_reset(adev); need_full_reset = amdgpu_device_ip_need_full_reset(adev);
if (!need_full_reset) { if (!need_full_reset && amdgpu_gpu_recovery) {
amdgpu_device_ip_pre_soft_reset(adev); amdgpu_device_ip_pre_soft_reset(adev);
r = amdgpu_device_ip_soft_reset(adev); r = amdgpu_device_ip_soft_reset(adev);
amdgpu_device_ip_post_soft_reset(adev); amdgpu_device_ip_post_soft_reset(adev);
@ -4770,6 +4776,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
struct amdgpu_device *tmp_adev = NULL; struct amdgpu_device *tmp_adev = NULL;
bool need_full_reset, skip_hw_reset, vram_lost = false; bool need_full_reset, skip_hw_reset, vram_lost = false;
int r = 0; int r = 0;
bool gpu_reset_for_dev_remove = 0;
/* Try reset handler method first */ /* Try reset handler method first */
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device, tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
@ -4789,6 +4796,10 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags); test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags); skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags);
gpu_reset_for_dev_remove =
test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
/* /*
* ASIC reset has to be done on all XGMI hive nodes ASAP * ASIC reset has to be done on all XGMI hive nodes ASAP
* to allow proper links negotiation in FW (within 1 sec) * to allow proper links negotiation in FW (within 1 sec)
@ -4833,6 +4844,18 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
amdgpu_ras_intr_cleared(); amdgpu_ras_intr_cleared();
} }
/* Since the mode1 reset affects base ip blocks, the
* phase1 ip blocks need to be resumed. Otherwise there
* will be a BIOS signature error and the psp bootloader
* can't load kdb on the next amdgpu install.
*/
if (gpu_reset_for_dev_remove) {
list_for_each_entry(tmp_adev, device_list_handle, reset_list)
amdgpu_device_ip_resume_phase1(tmp_adev);
goto end;
}
list_for_each_entry(tmp_adev, device_list_handle, reset_list) { list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
if (need_full_reset) { if (need_full_reset) {
/* post card */ /* post card */
@ -5072,6 +5095,7 @@ static void amdgpu_device_recheck_guilty_jobs(
/* set guilty */ /* set guilty */
drm_sched_increase_karma(s_job); drm_sched_increase_karma(s_job);
amdgpu_reset_prepare_hwcontext(adev, reset_context);
retry: retry:
/* do hw reset */ /* do hw reset */
if (amdgpu_sriov_vf(adev)) { if (amdgpu_sriov_vf(adev)) {
@ -5154,6 +5178,11 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
bool need_emergency_restart = false; bool need_emergency_restart = false;
bool audio_suspended = false; bool audio_suspended = false;
int tmp_vram_lost_counter; int tmp_vram_lost_counter;
bool gpu_reset_for_dev_remove = false;
gpu_reset_for_dev_remove =
test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
/* /*
* Special case: RAS triggered and full reset isn't supported * Special case: RAS triggered and full reset isn't supported
@ -5181,6 +5210,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
reset_context->job = job; reset_context->job = job;
reset_context->hive = hive; reset_context->hive = hive;
/* /*
* Build list of devices to reset. * Build list of devices to reset.
* In case we are in XGMI hive mode, resort the device list * In case we are in XGMI hive mode, resort the device list
@ -5188,8 +5218,11 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
*/ */
INIT_LIST_HEAD(&device_list); INIT_LIST_HEAD(&device_list);
if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) { if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) {
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
list_add_tail(&tmp_adev->reset_list, &device_list); list_add_tail(&tmp_adev->reset_list, &device_list);
if (gpu_reset_for_dev_remove && adev->shutdown)
tmp_adev->shutdown = true;
}
if (!list_is_first(&adev->reset_list, &device_list)) if (!list_is_first(&adev->reset_list, &device_list))
list_rotate_to_front(&adev->reset_list, &device_list); list_rotate_to_front(&adev->reset_list, &device_list);
device_list_handle = &device_list; device_list_handle = &device_list;
@ -5272,6 +5305,10 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
retry: /* Rest of adevs pre asic reset from XGMI hive. */ retry: /* Rest of adevs pre asic reset from XGMI hive. */
list_for_each_entry(tmp_adev, device_list_handle, reset_list) { list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
if (gpu_reset_for_dev_remove) {
/* Workaroud for ASICs need to disable SMC first */
amdgpu_device_smu_fini_early(tmp_adev);
}
r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context); r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context);
/*TODO Should we stop ?*/ /*TODO Should we stop ?*/
if (r) { if (r) {
@ -5300,8 +5337,14 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
amdgpu_ras_resume(adev); amdgpu_ras_resume(adev);
} else { } else {
r = amdgpu_do_asic_reset(device_list_handle, reset_context); r = amdgpu_do_asic_reset(device_list_handle, reset_context);
if (r && r == -EAGAIN) if (r && r == -EAGAIN) {
set_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags);
adev->asic_reset_res = 0;
goto retry; goto retry;
}
if (!r && gpu_reset_for_dev_remove)
goto recover_end;
} }
skip_hw_reset: skip_hw_reset:
@ -5375,6 +5418,7 @@ skip_sched_resume:
amdgpu_device_unset_mp1_state(tmp_adev); amdgpu_device_unset_mp1_state(tmp_adev);
} }
recover_end:
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device, tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
reset_list); reset_list);
amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain); amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain);
@ -5557,9 +5601,9 @@ bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1); ~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1);
resource_size_t aper_limit = resource_size_t aper_limit =
adev->gmc.aper_base + adev->gmc.aper_size - 1; adev->gmc.aper_base + adev->gmc.aper_size - 1;
bool p2p_access = !adev->gmc.xgmi.connected_to_cpu && bool p2p_access =
!(pci_p2pdma_distance_many(adev->pdev, !adev->gmc.xgmi.connected_to_cpu &&
&peer_adev->dev, 1, true) < 0); !(pci_p2pdma_distance(adev->pdev, peer_adev->dev, false) < 0);
return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size && return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size &&
adev->gmc.real_vram_size == adev->gmc.visible_vram_size && adev->gmc.real_vram_size == adev->gmc.visible_vram_size &&
@ -5733,6 +5777,7 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
reset_context.reset_req_dev = adev; reset_context.reset_req_dev = adev;
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags); set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
set_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
adev->no_hw_access = true; adev->no_hw_access = true;
r = amdgpu_device_pre_asic_reset(adev, &reset_context); r = amdgpu_device_pre_asic_reset(adev, &reset_context);
@ -5942,3 +5987,36 @@ void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
(void)RREG32(data); (void)RREG32(data);
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
} }
/**
* amdgpu_device_switch_gang - switch to a new gang
* @adev: amdgpu_device pointer
* @gang: the gang to switch to
*
* Try to switch to a new gang.
* Returns: NULL if we switched to the new gang or a reference to the current
* gang leader.
*/
struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
struct dma_fence *gang)
{
struct dma_fence *old = NULL;
do {
dma_fence_put(old);
rcu_read_lock();
old = dma_fence_get_rcu_safe(&adev->gang_submit);
rcu_read_unlock();
if (old == gang)
break;
if (!dma_fence_is_signaled(old))
return old;
} while (cmpxchg((struct dma_fence __force **)&adev->gang_submit,
old, gang) != old);
dma_fence_put(old);
return NULL;
}

View File

@ -229,7 +229,7 @@ static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev, ui
return r; return r;
} }
memcpy((u8 *)binary, (u8 *)fw->data, adev->mman.discovery_tmr_size); memcpy((u8 *)binary, (u8 *)fw->data, fw->size);
release_firmware(fw); release_firmware(fw);
return 0; return 0;
@ -1506,6 +1506,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
amdgpu_device_ip_block_add(adev, &soc21_common_ip_block); amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
break; break;
default: default:
@ -1549,6 +1550,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block); amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
break; break;
default: default:
@ -1633,6 +1635,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 5): case IP_VERSION(13, 0, 5):
case IP_VERSION(13, 0, 7): case IP_VERSION(13, 0, 7):
case IP_VERSION(13, 0, 8): case IP_VERSION(13, 0, 8):
case IP_VERSION(13, 0, 10):
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
break; break;
case IP_VERSION(13, 0, 4): case IP_VERSION(13, 0, 4):
@ -1682,6 +1685,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 5): case IP_VERSION(13, 0, 5):
case IP_VERSION(13, 0, 7): case IP_VERSION(13, 0, 7):
case IP_VERSION(13, 0, 8): case IP_VERSION(13, 0, 8):
case IP_VERSION(13, 0, 10):
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block); amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
break; break;
default: default:
@ -1780,6 +1784,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block); amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
break; break;
default: default:
@ -1823,6 +1828,7 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(6, 0, 0): case IP_VERSION(6, 0, 0):
case IP_VERSION(6, 0, 1): case IP_VERSION(6, 0, 1):
case IP_VERSION(6, 0, 2): case IP_VERSION(6, 0, 2):
case IP_VERSION(6, 0, 3):
amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block); amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);
break; break;
default: default:
@ -1903,7 +1909,8 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(4, 0, 2): case IP_VERSION(4, 0, 2):
case IP_VERSION(4, 0, 4): case IP_VERSION(4, 0, 4):
amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block); amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block);
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block); if (!amdgpu_sriov_vf(adev))
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
break; break;
default: default:
dev_err(adev->dev, dev_err(adev->dev,
@ -1940,6 +1947,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 1):
case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block); amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
adev->enable_mes = true; adev->enable_mes = true;
adev->enable_mes_kiq = true; adev->enable_mes_kiq = true;
@ -2165,6 +2173,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
break; break;
case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 0):
case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
adev->family = AMDGPU_FAMILY_GC_11_0_0; adev->family = AMDGPU_FAMILY_GC_11_0_0;
break; break;
case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 1):
@ -2234,7 +2243,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
break; break;
case IP_VERSION(4, 3, 0): case IP_VERSION(4, 3, 0):
case IP_VERSION(4, 3, 1): case IP_VERSION(4, 3, 1):
adev->nbio.funcs = &nbio_v4_3_funcs; if (amdgpu_sriov_vf(adev))
adev->nbio.funcs = &nbio_v4_3_sriov_funcs;
else
adev->nbio.funcs = &nbio_v4_3_funcs;
adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg; adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg;
break; break;
case IP_VERSION(7, 7, 0): case IP_VERSION(7, 7, 0):
@ -2332,6 +2344,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(6, 0, 0): case IP_VERSION(6, 0, 0):
case IP_VERSION(6, 0, 1): case IP_VERSION(6, 0, 1):
case IP_VERSION(6, 0, 2): case IP_VERSION(6, 0, 2):
case IP_VERSION(6, 0, 3):
adev->lsdma.funcs = &lsdma_v6_0_funcs; adev->lsdma.funcs = &lsdma_v6_0_funcs;
break; break;
default: default:

View File

@ -58,7 +58,7 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
int r; int r;
if (pci_p2pdma_distance_many(adev->pdev, &attach->dev, 1, true) < 0) if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
attach->peer2peer = false; attach->peer2peer = false;
r = pm_runtime_get_sync(adev_to_drm(adev)->dev); r = pm_runtime_get_sync(adev_to_drm(adev)->dev);

View File

@ -102,9 +102,10 @@
* - 3.46.0 - To enable hot plug amdgpu tests in libdrm * - 3.46.0 - To enable hot plug amdgpu tests in libdrm
* - 3.47.0 - Add AMDGPU_GEM_CREATE_DISCARDABLE and AMDGPU_VM_NOALLOC flags * - 3.47.0 - Add AMDGPU_GEM_CREATE_DISCARDABLE and AMDGPU_VM_NOALLOC flags
* - 3.48.0 - Add IP discovery version info to HW INFO * - 3.48.0 - Add IP discovery version info to HW INFO
* 3.49.0 - Add gang submit into CS IOCTL
*/ */
#define KMS_DRIVER_MAJOR 3 #define KMS_DRIVER_MAJOR 3
#define KMS_DRIVER_MINOR 48 #define KMS_DRIVER_MINOR 49
#define KMS_DRIVER_PATCHLEVEL 0 #define KMS_DRIVER_PATCHLEVEL 0
int amdgpu_vram_limit; int amdgpu_vram_limit;
@ -2181,15 +2182,46 @@ amdgpu_pci_remove(struct pci_dev *pdev)
struct drm_device *dev = pci_get_drvdata(pdev); struct drm_device *dev = pci_get_drvdata(pdev);
struct amdgpu_device *adev = drm_to_adev(dev); struct amdgpu_device *adev = drm_to_adev(dev);
drm_dev_unplug(dev);
if (adev->pm.rpm_mode != AMDGPU_RUNPM_NONE) { if (adev->pm.rpm_mode != AMDGPU_RUNPM_NONE) {
pm_runtime_get_sync(dev->dev); pm_runtime_get_sync(dev->dev);
pm_runtime_forbid(dev->dev); pm_runtime_forbid(dev->dev);
} }
if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) {
bool need_to_reset_gpu = false;
if (adev->gmc.xgmi.num_physical_nodes > 1) {
struct amdgpu_hive_info *hive;
hive = amdgpu_get_xgmi_hive(adev);
if (hive->device_remove_count == 0)
need_to_reset_gpu = true;
hive->device_remove_count++;
amdgpu_put_xgmi_hive(hive);
} else {
need_to_reset_gpu = true;
}
/* Workaround for ASICs need to reset SMU.
* Called only when the first device is removed.
*/
if (need_to_reset_gpu) {
struct amdgpu_reset_context reset_context;
adev->shutdown = true;
memset(&reset_context, 0, sizeof(reset_context));
reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev;
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
set_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context.flags);
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
}
}
amdgpu_driver_unload_kms(dev); amdgpu_driver_unload_kms(dev);
drm_dev_unplug(dev);
/* /*
* Flush any in flight DMA operations from device. * Flush any in flight DMA operations from device.
* Clear the Bus Master Enable bit and then wait on the PCIe Device * Clear the Bus Master Enable bit and then wait on the PCIe Device
@ -2563,8 +2595,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
amdgpu_device_baco_exit(drm_dev); amdgpu_device_baco_exit(drm_dev);
} }
ret = amdgpu_device_resume(drm_dev, false); ret = amdgpu_device_resume(drm_dev, false);
if (ret) if (ret) {
if (amdgpu_device_supports_px(drm_dev))
pci_disable_device(pdev);
return ret; return ret;
}
if (amdgpu_device_supports_px(drm_dev)) if (amdgpu_device_supports_px(drm_dev))
drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;

View File

@ -23,6 +23,7 @@
* *
*/ */
#include <linux/firmware.h>
#include "amdgpu.h" #include "amdgpu.h"
#include "amdgpu_gfx.h" #include "amdgpu_gfx.h"
#include "amdgpu_rlc.h" #include "amdgpu_rlc.h"
@ -477,7 +478,7 @@ int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev)
kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.compute_ring[i], kiq->pmf->kiq_unmap_queues(kiq_ring, &adev->gfx.compute_ring[i],
RESET_QUEUES, 0, 0); RESET_QUEUES, 0, 0);
if (adev->gfx.kiq.ring.sched.ready) if (adev->gfx.kiq.ring.sched.ready && !adev->job_hang)
r = amdgpu_ring_test_helper(kiq_ring); r = amdgpu_ring_test_helper(kiq_ring);
spin_unlock(&adev->gfx.kiq.ring_lock); spin_unlock(&adev->gfx.kiq.ring_lock);
@ -610,6 +611,45 @@ unlock:
mutex_unlock(&adev->gfx.gfx_off_mutex); mutex_unlock(&adev->gfx.gfx_off_mutex);
} }
int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value)
{
int r = 0;
mutex_lock(&adev->gfx.gfx_off_mutex);
r = amdgpu_dpm_set_residency_gfxoff(adev, value);
mutex_unlock(&adev->gfx.gfx_off_mutex);
return r;
}
int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *value)
{
int r = 0;
mutex_lock(&adev->gfx.gfx_off_mutex);
r = amdgpu_dpm_get_residency_gfxoff(adev, value);
mutex_unlock(&adev->gfx.gfx_off_mutex);
return r;
}
int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value)
{
int r = 0;
mutex_lock(&adev->gfx.gfx_off_mutex);
r = amdgpu_dpm_get_entrycount_gfxoff(adev, value);
mutex_unlock(&adev->gfx.gfx_off_mutex);
return r;
}
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value) int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value)
{ {
@ -826,3 +866,142 @@ int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev)
} }
return amdgpu_num_kcq; return amdgpu_num_kcq;
} }
void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev,
uint32_t ucode_id)
{
const struct gfx_firmware_header_v1_0 *cp_hdr;
const struct gfx_firmware_header_v2_0 *cp_hdr_v2_0;
struct amdgpu_firmware_info *info = NULL;
const struct firmware *ucode_fw;
unsigned int fw_size;
switch (ucode_id) {
case AMDGPU_UCODE_ID_CP_PFP:
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
adev->gfx.pfp_fw->data;
adev->gfx.pfp_fw_version =
le32_to_cpu(cp_hdr->header.ucode_version);
adev->gfx.pfp_feature_version =
le32_to_cpu(cp_hdr->ucode_feature_version);
ucode_fw = adev->gfx.pfp_fw;
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
break;
case AMDGPU_UCODE_ID_CP_RS64_PFP:
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
adev->gfx.pfp_fw->data;
adev->gfx.pfp_fw_version =
le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
adev->gfx.pfp_feature_version =
le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
ucode_fw = adev->gfx.pfp_fw;
fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
break;
case AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK:
case AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK:
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
adev->gfx.pfp_fw->data;
ucode_fw = adev->gfx.pfp_fw;
fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
break;
case AMDGPU_UCODE_ID_CP_ME:
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
adev->gfx.me_fw->data;
adev->gfx.me_fw_version =
le32_to_cpu(cp_hdr->header.ucode_version);
adev->gfx.me_feature_version =
le32_to_cpu(cp_hdr->ucode_feature_version);
ucode_fw = adev->gfx.me_fw;
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
break;
case AMDGPU_UCODE_ID_CP_RS64_ME:
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
adev->gfx.me_fw->data;
adev->gfx.me_fw_version =
le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
adev->gfx.me_feature_version =
le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
ucode_fw = adev->gfx.me_fw;
fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
break;
case AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK:
case AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK:
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
adev->gfx.me_fw->data;
ucode_fw = adev->gfx.me_fw;
fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
break;
case AMDGPU_UCODE_ID_CP_CE:
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
adev->gfx.ce_fw->data;
adev->gfx.ce_fw_version =
le32_to_cpu(cp_hdr->header.ucode_version);
adev->gfx.ce_feature_version =
le32_to_cpu(cp_hdr->ucode_feature_version);
ucode_fw = adev->gfx.ce_fw;
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
break;
case AMDGPU_UCODE_ID_CP_MEC1:
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
adev->gfx.mec_fw->data;
adev->gfx.mec_fw_version =
le32_to_cpu(cp_hdr->header.ucode_version);
adev->gfx.mec_feature_version =
le32_to_cpu(cp_hdr->ucode_feature_version);
ucode_fw = adev->gfx.mec_fw;
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes) -
le32_to_cpu(cp_hdr->jt_size) * 4;
break;
case AMDGPU_UCODE_ID_CP_MEC1_JT:
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
adev->gfx.mec_fw->data;
ucode_fw = adev->gfx.mec_fw;
fw_size = le32_to_cpu(cp_hdr->jt_size) * 4;
break;
case AMDGPU_UCODE_ID_CP_MEC2:
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
adev->gfx.mec2_fw->data;
adev->gfx.mec2_fw_version =
le32_to_cpu(cp_hdr->header.ucode_version);
adev->gfx.mec2_feature_version =
le32_to_cpu(cp_hdr->ucode_feature_version);
ucode_fw = adev->gfx.mec2_fw;
fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes) -
le32_to_cpu(cp_hdr->jt_size) * 4;
break;
case AMDGPU_UCODE_ID_CP_MEC2_JT:
cp_hdr = (const struct gfx_firmware_header_v1_0 *)
adev->gfx.mec2_fw->data;
ucode_fw = adev->gfx.mec2_fw;
fw_size = le32_to_cpu(cp_hdr->jt_size) * 4;
break;
case AMDGPU_UCODE_ID_CP_RS64_MEC:
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
adev->gfx.mec_fw->data;
adev->gfx.mec_fw_version =
le32_to_cpu(cp_hdr_v2_0->header.ucode_version);
adev->gfx.mec_feature_version =
le32_to_cpu(cp_hdr_v2_0->ucode_feature_version);
ucode_fw = adev->gfx.mec_fw;
fw_size = le32_to_cpu(cp_hdr_v2_0->ucode_size_bytes);
break;
case AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK:
case AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK:
case AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK:
case AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK:
cp_hdr_v2_0 = (const struct gfx_firmware_header_v2_0 *)
adev->gfx.mec_fw->data;
ucode_fw = adev->gfx.mec_fw;
fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
break;
default:
break;
}
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
info = &adev->firmware.ucode[ucode_id];
info->ucode_id = ucode_id;
info->fw = ucode_fw;
adev->firmware.fw_size += ALIGN(fw_size, PAGE_SIZE);
}
}

View File

@ -336,10 +336,12 @@ struct amdgpu_gfx {
uint32_t srbm_soft_reset; uint32_t srbm_soft_reset;
/* gfx off */ /* gfx off */
bool gfx_off_state; /* true: enabled, false: disabled */ bool gfx_off_state; /* true: enabled, false: disabled */
struct mutex gfx_off_mutex; struct mutex gfx_off_mutex; /* mutex to change gfxoff state */
uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */ uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
struct delayed_work gfx_off_delay_work; struct delayed_work gfx_off_delay_work; /* async work to set gfx block off */
uint32_t gfx_off_residency; /* last logged residency */
uint64_t gfx_off_entrycount; /* count of times GPU has get into GFXOFF state */
/* pipe reservation */ /* pipe reservation */
struct mutex pipe_reserve_mutex; struct mutex pipe_reserve_mutex;
@ -411,6 +413,10 @@ bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me,
void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable); void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable);
int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value); int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value);
int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block); int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block);
void amdgpu_gfx_ras_fini(struct amdgpu_device *adev);
int amdgpu_get_gfx_off_entrycount(struct amdgpu_device *adev, u64 *value);
int amdgpu_get_gfx_off_residency(struct amdgpu_device *adev, u32 *residency);
int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value);
int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev, int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
void *err_data, void *err_data,
struct amdgpu_iv_entry *entry); struct amdgpu_iv_entry *entry);
@ -420,4 +426,6 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v); void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev); int amdgpu_gfx_get_num_kcq(struct amdgpu_device *adev);
void amdgpu_gfx_cp_init_microcode(struct amdgpu_device *adev, uint32_t ucode_id);
#endif #endif

View File

@ -35,6 +35,9 @@ struct amdgpu_gfxhub_funcs {
void (*init)(struct amdgpu_device *adev); void (*init)(struct amdgpu_device *adev);
int (*get_xgmi_info)(struct amdgpu_device *adev); int (*get_xgmi_info)(struct amdgpu_device *adev);
void (*utcl2_harvest)(struct amdgpu_device *adev); void (*utcl2_harvest)(struct amdgpu_device *adev);
void (*mode2_save_regs)(struct amdgpu_device *adev);
void (*mode2_restore_regs)(struct amdgpu_device *adev);
void (*halt)(struct amdgpu_device *adev);
}; };
struct amdgpu_gfxhub { struct amdgpu_gfxhub {

View File

@ -572,45 +572,15 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
void amdgpu_gmc_noretry_set(struct amdgpu_device *adev) void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
{ {
struct amdgpu_gmc *gmc = &adev->gmc; struct amdgpu_gmc *gmc = &adev->gmc;
uint32_t gc_ver = adev->ip_versions[GC_HWIP][0];
bool noretry_default = (gc_ver == IP_VERSION(9, 0, 1) ||
gc_ver == IP_VERSION(9, 3, 0) ||
gc_ver == IP_VERSION(9, 4, 0) ||
gc_ver == IP_VERSION(9, 4, 1) ||
gc_ver == IP_VERSION(9, 4, 2) ||
gc_ver >= IP_VERSION(10, 3, 0));
switch (adev->ip_versions[GC_HWIP][0]) { gmc->noretry = (amdgpu_noretry == -1) ? noretry_default : amdgpu_noretry;
case IP_VERSION(9, 0, 1):
case IP_VERSION(9, 3, 0):
case IP_VERSION(9, 4, 0):
case IP_VERSION(9, 4, 1):
case IP_VERSION(9, 4, 2):
case IP_VERSION(10, 3, 3):
case IP_VERSION(10, 3, 4):
case IP_VERSION(10, 3, 5):
case IP_VERSION(10, 3, 6):
case IP_VERSION(10, 3, 7):
/*
* noretry = 0 will cause kfd page fault tests fail
* for some ASICs, so set default to 1 for these ASICs.
*/
if (amdgpu_noretry == -1)
gmc->noretry = 1;
else
gmc->noretry = amdgpu_noretry;
break;
default:
/* Raven currently has issues with noretry
* regardless of what we decide for other
* asics, we should leave raven with
* noretry = 0 until we root cause the
* issues.
*
* default this to 0 for now, but we may want
* to change this in the future for certain
* GPUs as it can increase performance in
* certain cases.
*/
if (amdgpu_noretry == -1)
gmc->noretry = 0;
else
gmc->noretry = amdgpu_noretry;
break;
}
} }
void amdgpu_gmc_set_vm_fault_masks(struct amdgpu_device *adev, int hub_type, void amdgpu_gmc_set_vm_fault_masks(struct amdgpu_device *adev, int hub_type,

View File

@ -264,6 +264,32 @@ struct amdgpu_gmc {
u64 mall_size; u64 mall_size;
/* number of UMC instances */ /* number of UMC instances */
int num_umc; int num_umc;
/* mode2 save restore */
u64 VM_L2_CNTL;
u64 VM_L2_CNTL2;
u64 VM_DUMMY_PAGE_FAULT_CNTL;
u64 VM_DUMMY_PAGE_FAULT_ADDR_LO32;
u64 VM_DUMMY_PAGE_FAULT_ADDR_HI32;
u64 VM_L2_PROTECTION_FAULT_CNTL;
u64 VM_L2_PROTECTION_FAULT_CNTL2;
u64 VM_L2_PROTECTION_FAULT_MM_CNTL3;
u64 VM_L2_PROTECTION_FAULT_MM_CNTL4;
u64 VM_L2_PROTECTION_FAULT_ADDR_LO32;
u64 VM_L2_PROTECTION_FAULT_ADDR_HI32;
u64 VM_DEBUG;
u64 VM_L2_MM_GROUP_RT_CLASSES;
u64 VM_L2_BANK_SELECT_RESERVED_CID;
u64 VM_L2_BANK_SELECT_RESERVED_CID2;
u64 VM_L2_CACHE_PARITY_CNTL;
u64 VM_L2_IH_LOG_CNTL;
u64 VM_CONTEXT_CNTL[16];
u64 VM_CONTEXT_PAGE_TABLE_BASE_ADDR_LO32[16];
u64 VM_CONTEXT_PAGE_TABLE_BASE_ADDR_HI32[16];
u64 VM_CONTEXT_PAGE_TABLE_START_ADDR_LO32[16];
u64 VM_CONTEXT_PAGE_TABLE_START_ADDR_HI32[16];
u64 VM_CONTEXT_PAGE_TABLE_END_ADDR_LO32[16];
u64 VM_CONTEXT_PAGE_TABLE_END_ADDR_HI32[16];
u64 MC_VM_MX_L1_TLB_CNTL;
}; };
#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type))) #define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))

View File

@ -204,6 +204,42 @@ void amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr)
amdgpu_gart_invalidate_tlb(adev); amdgpu_gart_invalidate_tlb(adev);
} }
/**
* amdgpu_gtt_mgr_intersects - test for intersection
*
* @man: Our manager object
* @res: The resource to test
* @place: The place for the new allocation
* @size: The size of the new allocation
*
* Simplified intersection test, only interesting if we need GART or not.
*/
static bool amdgpu_gtt_mgr_intersects(struct ttm_resource_manager *man,
struct ttm_resource *res,
const struct ttm_place *place,
size_t size)
{
return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
}
/**
* amdgpu_gtt_mgr_compatible - test for compatibility
*
* @man: Our manager object
* @res: The resource to test
* @place: The place for the new allocation
* @size: The size of the new allocation
*
* Simplified compatibility test.
*/
static bool amdgpu_gtt_mgr_compatible(struct ttm_resource_manager *man,
struct ttm_resource *res,
const struct ttm_place *place,
size_t size)
{
return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
}
/** /**
* amdgpu_gtt_mgr_debug - dump VRAM table * amdgpu_gtt_mgr_debug - dump VRAM table
* *
@ -225,6 +261,8 @@ static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man,
static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = { static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
.alloc = amdgpu_gtt_mgr_new, .alloc = amdgpu_gtt_mgr_new,
.free = amdgpu_gtt_mgr_del, .free = amdgpu_gtt_mgr_del,
.intersects = amdgpu_gtt_mgr_intersects,
.compatible = amdgpu_gtt_mgr_compatible,
.debug = amdgpu_gtt_mgr_debug .debug = amdgpu_gtt_mgr_debug
}; };

View File

@ -49,6 +49,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
} }
memset(&ti, 0, sizeof(struct amdgpu_task_info)); memset(&ti, 0, sizeof(struct amdgpu_task_info));
adev->job_hang = true;
if (amdgpu_gpu_recovery && if (amdgpu_gpu_recovery &&
amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) { amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) {
@ -71,6 +72,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
reset_context.method = AMD_RESET_METHOD_NONE; reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev; reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context); r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context);
if (r) if (r)
@ -82,6 +84,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
} }
exit: exit:
adev->job_hang = false;
drm_dev_exit(idx); drm_dev_exit(idx);
return DRM_GPU_SCHED_STAT_NOMINAL; return DRM_GPU_SCHED_STAT_NOMINAL;
} }
@ -102,7 +105,6 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
*/ */
(*job)->base.sched = &adev->rings[0]->sched; (*job)->base.sched = &adev->rings[0]->sched;
(*job)->vm = vm; (*job)->vm = vm;
(*job)->num_ibs = num_ibs;
amdgpu_sync_create(&(*job)->sync); amdgpu_sync_create(&(*job)->sync);
amdgpu_sync_create(&(*job)->sched_sync); amdgpu_sync_create(&(*job)->sched_sync);
@ -122,6 +124,7 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
if (r) if (r)
return r; return r;
(*job)->num_ibs = 1;
r = amdgpu_ib_get(adev, NULL, size, pool_type, &(*job)->ibs[0]); r = amdgpu_ib_get(adev, NULL, size, pool_type, &(*job)->ibs[0]);
if (r) if (r)
kfree(*job); kfree(*job);
@ -129,6 +132,23 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
return r; return r;
} }
void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
struct amdgpu_bo *gws, struct amdgpu_bo *oa)
{
if (gds) {
job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT;
job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT;
}
if (gws) {
job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT;
job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT;
}
if (oa) {
job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT;
job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT;
}
}
void amdgpu_job_free_resources(struct amdgpu_job *job) void amdgpu_job_free_resources(struct amdgpu_job *job)
{ {
struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
@ -153,11 +173,29 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
dma_fence_put(&job->hw_fence); dma_fence_put(&job->hw_fence);
} }
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
struct amdgpu_job *leader)
{
struct dma_fence *fence = &leader->base.s_fence->scheduled;
WARN_ON(job->gang_submit);
/*
* Don't add a reference when we are the gang leader to avoid circle
* dependency.
*/
if (job != leader)
dma_fence_get(fence);
job->gang_submit = fence;
}
void amdgpu_job_free(struct amdgpu_job *job) void amdgpu_job_free(struct amdgpu_job *job)
{ {
amdgpu_job_free_resources(job); amdgpu_job_free_resources(job);
amdgpu_sync_free(&job->sync); amdgpu_sync_free(&job->sync);
amdgpu_sync_free(&job->sched_sync); amdgpu_sync_free(&job->sched_sync);
if (job->gang_submit != &job->base.s_fence->scheduled)
dma_fence_put(job->gang_submit);
if (!job->hw_fence.ops) if (!job->hw_fence.ops)
kfree(job); kfree(job);
@ -227,12 +265,16 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job,
fence = amdgpu_sync_get_fence(&job->sync); fence = amdgpu_sync_get_fence(&job->sync);
} }
if (!fence && job->gang_submit)
fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit);
return fence; return fence;
} }
static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job) static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
{ {
struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched); struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched);
struct amdgpu_device *adev = ring->adev;
struct dma_fence *fence = NULL, *finished; struct dma_fence *fence = NULL, *finished;
struct amdgpu_job *job; struct amdgpu_job *job;
int r = 0; int r = 0;
@ -244,8 +286,10 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
trace_amdgpu_sched_run_job(job); trace_amdgpu_sched_run_job(job);
if (job->vram_lost_counter != atomic_read(&ring->adev->vram_lost_counter)) /* Skip job if VRAM is lost and never resubmit gangs */
dma_fence_set_error(finished, -ECANCELED);/* skip IB as well if VRAM lost */ if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter) ||
(job->job_run_counter && job->gang_submit))
dma_fence_set_error(finished, -ECANCELED);
if (finished->error < 0) { if (finished->error < 0) {
DRM_INFO("Skip scheduling IBs!\n"); DRM_INFO("Skip scheduling IBs!\n");

View File

@ -50,6 +50,7 @@ struct amdgpu_job {
struct amdgpu_sync sync; struct amdgpu_sync sync;
struct amdgpu_sync sched_sync; struct amdgpu_sync sched_sync;
struct dma_fence hw_fence; struct dma_fence hw_fence;
struct dma_fence *gang_submit;
uint32_t preamble_status; uint32_t preamble_status;
uint32_t preemption_status; uint32_t preemption_status;
bool vm_needs_flush; bool vm_needs_flush;
@ -72,11 +73,20 @@ struct amdgpu_job {
struct amdgpu_ib ibs[]; struct amdgpu_ib ibs[];
}; };
static inline struct amdgpu_ring *amdgpu_job_ring(struct amdgpu_job *job)
{
return to_amdgpu_ring(job->base.entity->rq->sched);
}
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
struct amdgpu_job **job, struct amdgpu_vm *vm); struct amdgpu_job **job, struct amdgpu_vm *vm);
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
enum amdgpu_ib_pool_type pool, struct amdgpu_job **job); enum amdgpu_ib_pool_type pool, struct amdgpu_job **job);
void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
struct amdgpu_bo *gws, struct amdgpu_bo *oa);
void amdgpu_job_free_resources(struct amdgpu_job *job); void amdgpu_job_free_resources(struct amdgpu_job *job);
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
struct amdgpu_job *leader);
void amdgpu_job_free(struct amdgpu_job *job); void amdgpu_job_free(struct amdgpu_job *job);
int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity, int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
void *owner, struct dma_fence **f); void *owner, struct dma_fence **f);

View File

@ -247,6 +247,14 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
fw_info->ver = adev->gfx.rlc_srls_fw_version; fw_info->ver = adev->gfx.rlc_srls_fw_version;
fw_info->feature = adev->gfx.rlc_srls_feature_version; fw_info->feature = adev->gfx.rlc_srls_feature_version;
break; break;
case AMDGPU_INFO_FW_GFX_RLCP:
fw_info->ver = adev->gfx.rlcp_ucode_version;
fw_info->feature = adev->gfx.rlcp_ucode_feature_version;
break;
case AMDGPU_INFO_FW_GFX_RLCV:
fw_info->ver = adev->gfx.rlcv_ucode_version;
fw_info->feature = adev->gfx.rlcv_ucode_feature_version;
break;
case AMDGPU_INFO_FW_GFX_MEC: case AMDGPU_INFO_FW_GFX_MEC:
if (query_fw->index == 0) { if (query_fw->index == 0) {
fw_info->ver = adev->gfx.mec_fw_version; fw_info->ver = adev->gfx.mec_fw_version;
@ -328,6 +336,14 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
fw_info->ver = adev->psp.cap_fw_version; fw_info->ver = adev->psp.cap_fw_version;
fw_info->feature = adev->psp.cap_feature_version; fw_info->feature = adev->psp.cap_feature_version;
break; break;
case AMDGPU_INFO_FW_MES_KIQ:
fw_info->ver = adev->mes.ucode_fw_version[0];
fw_info->feature = 0;
break;
case AMDGPU_INFO_FW_MES:
fw_info->ver = adev->mes.ucode_fw_version[1];
fw_info->feature = 0;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
@ -1160,7 +1176,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
} }
mutex_init(&fpriv->bo_list_lock); mutex_init(&fpriv->bo_list_lock);
idr_init(&fpriv->bo_list_handles); idr_init_base(&fpriv->bo_list_handles, 1);
amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev); amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
@ -1469,6 +1485,22 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
seq_printf(m, "RLC SRLS feature version: %u, firmware version: 0x%08x\n", seq_printf(m, "RLC SRLS feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver); fw_info.feature, fw_info.ver);
/* RLCP */
query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLCP;
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
if (ret)
return ret;
seq_printf(m, "RLCP feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver);
/* RLCV */
query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLCV;
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
if (ret)
return ret;
seq_printf(m, "RLCV feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver);
/* MEC */ /* MEC */
query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC; query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC;
query_fw.index = 0; query_fw.index = 0;
@ -1581,6 +1613,22 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
fw_info.feature, fw_info.ver); fw_info.feature, fw_info.ver);
} }
/* MES_KIQ */
query_fw.fw_type = AMDGPU_INFO_FW_MES_KIQ;
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
if (ret)
return ret;
seq_printf(m, "MES_KIQ feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver);
/* MES */
query_fw.fw_type = AMDGPU_INFO_FW_MES;
ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
if (ret)
return ret;
seq_printf(m, "MES feature version: %u, firmware version: 0x%08x\n",
fw_info.feature, fw_info.ver);
seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version); seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version);
return 0; return 0;

View File

@ -38,7 +38,6 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_framebuffer.h> #include <drm/drm_framebuffer.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>

View File

@ -591,7 +591,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
if (!bp->destroy) if (!bp->destroy)
bp->destroy = &amdgpu_bo_destroy; bp->destroy = &amdgpu_bo_destroy;
r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, bp->type, r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, bp->type,
&bo->placement, page_align, &ctx, NULL, &bo->placement, page_align, &ctx, NULL,
bp->resv, bp->destroy); bp->resv, bp->destroy);
if (unlikely(r != 0)) if (unlikely(r != 0))
@ -1309,7 +1309,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
if (bo->base.resv == &bo->base._resv) if (bo->base.resv == &bo->base._resv)
amdgpu_amdkfd_remove_fence_on_pt_pd_bos(abo); amdgpu_amdkfd_remove_fence_on_pt_pd_bos(abo);
if (bo->resource->mem_type != TTM_PL_VRAM || if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM ||
!(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) || !(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) ||
adev->in_suspend || adev->shutdown) adev->in_suspend || adev->shutdown)
return; return;

View File

@ -138,6 +138,7 @@ static int psp_early_init(void *handle)
case IP_VERSION(13, 0, 3): case IP_VERSION(13, 0, 3):
case IP_VERSION(13, 0, 5): case IP_VERSION(13, 0, 5):
case IP_VERSION(13, 0, 8): case IP_VERSION(13, 0, 8):
case IP_VERSION(13, 0, 10):
psp_v13_0_set_psp_funcs(psp); psp_v13_0_set_psp_funcs(psp);
psp->autoload_supported = true; psp->autoload_supported = true;
break; break;
@ -327,23 +328,32 @@ static int psp_init_sriov_microcode(struct psp_context *psp)
switch (adev->ip_versions[MP0_HWIP][0]) { switch (adev->ip_versions[MP0_HWIP][0]) {
case IP_VERSION(9, 0, 0): case IP_VERSION(9, 0, 0):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
ret = psp_init_cap_microcode(psp, "vega10"); ret = psp_init_cap_microcode(psp, "vega10");
break; break;
case IP_VERSION(11, 0, 9): case IP_VERSION(11, 0, 9):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
ret = psp_init_cap_microcode(psp, "navi12"); ret = psp_init_cap_microcode(psp, "navi12");
break; break;
case IP_VERSION(11, 0, 7): case IP_VERSION(11, 0, 7):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
ret = psp_init_cap_microcode(psp, "sienna_cichlid"); ret = psp_init_cap_microcode(psp, "sienna_cichlid");
break; break;
case IP_VERSION(13, 0, 2): case IP_VERSION(13, 0, 2):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MEC2;
ret = psp_init_cap_microcode(psp, "aldebaran"); ret = psp_init_cap_microcode(psp, "aldebaran");
ret &= psp_init_ta_microcode(psp, "aldebaran"); ret &= psp_init_ta_microcode(psp, "aldebaran");
break; break;
case IP_VERSION(13, 0, 0):
adev->virt.autoload_ucode_id = 0;
break;
case IP_VERSION(13, 0, 10):
adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA;
break;
default: default:
BUG(); BUG();
break; break;
} }
return ret; return ret;
} }
@ -501,6 +511,11 @@ static int psp_sw_fini(void *handle)
kfree(cmd); kfree(cmd);
cmd = NULL; cmd = NULL;
if (psp->km_ring.ring_mem)
amdgpu_bo_free_kernel(&adev->firmware.rbuf,
&psp->km_ring.ring_mem_mc_addr,
(void **)&psp->km_ring.ring_mem);
amdgpu_bo_free_kernel(&psp->fw_pri_bo, amdgpu_bo_free_kernel(&psp->fw_pri_bo,
&psp->fw_pri_mc_addr, &psp->fw_pri_buf); &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
amdgpu_bo_free_kernel(&psp->fence_buf_bo, amdgpu_bo_free_kernel(&psp->fence_buf_bo,
@ -769,6 +784,7 @@ static bool psp_skip_tmr(struct psp_context *psp)
case IP_VERSION(11, 0, 9): case IP_VERSION(11, 0, 9):
case IP_VERSION(11, 0, 7): case IP_VERSION(11, 0, 7):
case IP_VERSION(13, 0, 2): case IP_VERSION(13, 0, 2):
case IP_VERSION(13, 0, 10):
return true; return true;
default: default:
return false; return false;
@ -815,7 +831,7 @@ static int psp_tmr_unload(struct psp_context *psp)
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp); struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
psp_prep_tmr_unload_cmd_buf(psp, cmd); psp_prep_tmr_unload_cmd_buf(psp, cmd);
DRM_INFO("free PSP TMR buffer\n"); dev_info(psp->adev->dev, "free PSP TMR buffer\n");
ret = psp_cmd_submit_buf(psp, NULL, cmd, ret = psp_cmd_submit_buf(psp, NULL, cmd,
psp->fence_buf_mc_addr); psp->fence_buf_mc_addr);
@ -2044,6 +2060,15 @@ static int psp_hw_start(struct psp_context *psp)
} }
} }
if ((is_psp_fw_valid(psp->ras_drv)) &&
(psp->funcs->bootloader_load_ras_drv != NULL)) {
ret = psp_bootloader_load_ras_drv(psp);
if (ret) {
DRM_ERROR("PSP load ras_drv failed!\n");
return ret;
}
}
if ((is_psp_fw_valid(psp->sos)) && if ((is_psp_fw_valid(psp->sos)) &&
(psp->funcs->bootloader_load_sos != NULL)) { (psp->funcs->bootloader_load_sos != NULL)) {
ret = psp_bootloader_load_sos(psp); ret = psp_bootloader_load_sos(psp);
@ -2414,20 +2439,7 @@ static bool fw_load_skip_check(struct psp_context *psp,
return true; return true;
if (amdgpu_sriov_vf(psp->adev) && if (amdgpu_sriov_vf(psp->adev) &&
(ucode->ucode_id == AMDGPU_UCODE_ID_SDMA0 amdgpu_virt_fw_load_skip_check(psp->adev, ucode->ucode_id))
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA4
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA5
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA6
|| ucode->ucode_id == AMDGPU_UCODE_ID_SDMA7
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_G
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
|| ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
|| ucode->ucode_id == AMDGPU_UCODE_ID_SMC))
/*skip ucode loading in SRIOV VF */
return true; return true;
if (psp->autoload_supported && if (psp->autoload_supported &&
@ -2501,7 +2513,7 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
/* Start rlc autoload after psp recieved all the gfx firmware */ /* Start rlc autoload after psp recieved all the gfx firmware */
if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ? if (psp->autoload_supported && ucode->ucode_id == (amdgpu_sriov_vf(adev) ?
AMDGPU_UCODE_ID_CP_MEC2 : AMDGPU_UCODE_ID_RLC_G)) { adev->virt.autoload_ucode_id : AMDGPU_UCODE_ID_RLC_G)) {
ret = psp_rlc_autoload_start(psp); ret = psp_rlc_autoload_start(psp);
if (ret) { if (ret) {
DRM_ERROR("Failed to start rlc autoload\n"); DRM_ERROR("Failed to start rlc autoload\n");
@ -3042,6 +3054,12 @@ static int parse_sos_bin_descriptor(struct psp_context *psp,
psp->dbg_drv.size_bytes = le32_to_cpu(desc->size_bytes); psp->dbg_drv.size_bytes = le32_to_cpu(desc->size_bytes);
psp->dbg_drv.start_addr = ucode_start_addr; psp->dbg_drv.start_addr = ucode_start_addr;
break; break;
case PSP_FW_TYPE_PSP_RAS_DRV:
psp->ras_drv.fw_version = le32_to_cpu(desc->fw_version);
psp->ras_drv.feature_version = le32_to_cpu(desc->fw_version);
psp->ras_drv.size_bytes = le32_to_cpu(desc->size_bytes);
psp->ras_drv.start_addr = ucode_start_addr;
break;
default: default:
dev_warn(psp->adev->dev, "Unsupported PSP FW type: %d\n", desc->fw_type); dev_warn(psp->adev->dev, "Unsupported PSP FW type: %d\n", desc->fw_type);
break; break;

View File

@ -72,6 +72,7 @@ enum psp_bootloader_cmd {
PSP_BL__LOAD_SOCDRV = 0xB0000, PSP_BL__LOAD_SOCDRV = 0xB0000,
PSP_BL__LOAD_DBGDRV = 0xC0000, PSP_BL__LOAD_DBGDRV = 0xC0000,
PSP_BL__LOAD_INTFDRV = 0xD0000, PSP_BL__LOAD_INTFDRV = 0xD0000,
PSP_BL__LOAD_RASDRV = 0xE0000,
PSP_BL__DRAM_LONG_TRAIN = 0x100000, PSP_BL__DRAM_LONG_TRAIN = 0x100000,
PSP_BL__DRAM_SHORT_TRAIN = 0x200000, PSP_BL__DRAM_SHORT_TRAIN = 0x200000,
PSP_BL__LOAD_TOS_SPL_TABLE = 0x10000000, PSP_BL__LOAD_TOS_SPL_TABLE = 0x10000000,
@ -115,6 +116,7 @@ struct psp_funcs
int (*bootloader_load_soc_drv)(struct psp_context *psp); int (*bootloader_load_soc_drv)(struct psp_context *psp);
int (*bootloader_load_intf_drv)(struct psp_context *psp); int (*bootloader_load_intf_drv)(struct psp_context *psp);
int (*bootloader_load_dbg_drv)(struct psp_context *psp); int (*bootloader_load_dbg_drv)(struct psp_context *psp);
int (*bootloader_load_ras_drv)(struct psp_context *psp);
int (*bootloader_load_sos)(struct psp_context *psp); int (*bootloader_load_sos)(struct psp_context *psp);
int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type); int (*ring_init)(struct psp_context *psp, enum psp_ring_type ring_type);
int (*ring_create)(struct psp_context *psp, int (*ring_create)(struct psp_context *psp,
@ -324,6 +326,7 @@ struct psp_context
struct psp_bin_desc soc_drv; struct psp_bin_desc soc_drv;
struct psp_bin_desc intf_drv; struct psp_bin_desc intf_drv;
struct psp_bin_desc dbg_drv; struct psp_bin_desc dbg_drv;
struct psp_bin_desc ras_drv;
/* tmr buffer */ /* tmr buffer */
struct amdgpu_bo *tmr_bo; struct amdgpu_bo *tmr_bo;
@ -404,6 +407,9 @@ struct amdgpu_psp_funcs {
((psp)->funcs->bootloader_load_intf_drv ? (psp)->funcs->bootloader_load_intf_drv((psp)) : 0) ((psp)->funcs->bootloader_load_intf_drv ? (psp)->funcs->bootloader_load_intf_drv((psp)) : 0)
#define psp_bootloader_load_dbg_drv(psp) \ #define psp_bootloader_load_dbg_drv(psp) \
((psp)->funcs->bootloader_load_dbg_drv ? (psp)->funcs->bootloader_load_dbg_drv((psp)) : 0) ((psp)->funcs->bootloader_load_dbg_drv ? (psp)->funcs->bootloader_load_dbg_drv((psp)) : 0)
#define psp_bootloader_load_ras_drv(psp) \
((psp)->funcs->bootloader_load_ras_drv ? \
(psp)->funcs->bootloader_load_ras_drv((psp)) : 0)
#define psp_bootloader_load_sos(psp) \ #define psp_bootloader_load_sos(psp) \
((psp)->funcs->bootloader_load_sos ? (psp)->funcs->bootloader_load_sos((psp)) : 0) ((psp)->funcs->bootloader_load_sos ? (psp)->funcs->bootloader_load_sos((psp)) : 0)
#define psp_smu_reload_quirk(psp) \ #define psp_smu_reload_quirk(psp) \

View File

@ -1950,6 +1950,7 @@ static void amdgpu_ras_do_recovery(struct work_struct *work)
reset_context.method = AMD_RESET_METHOD_NONE; reset_context.method = AMD_RESET_METHOD_NONE;
reset_context.reset_req_dev = adev; reset_context.reset_req_dev = adev;
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);
amdgpu_device_gpu_recover(ras->adev, NULL, &reset_context); amdgpu_device_gpu_recover(ras->adev, NULL, &reset_context);
} }
@ -2719,7 +2720,8 @@ int amdgpu_ras_pre_fini(struct amdgpu_device *adev)
/* Need disable ras on all IPs here before ip [hw/sw]fini */ /* Need disable ras on all IPs here before ip [hw/sw]fini */
amdgpu_ras_disable_all_features(adev, 0); if (con->features)
amdgpu_ras_disable_all_features(adev, 0);
amdgpu_ras_recovery_fini(adev); amdgpu_ras_recovery_fini(adev);
return 0; return 0;
} }
@ -2832,11 +2834,8 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
struct mce *m = (struct mce *)data; struct mce *m = (struct mce *)data;
struct amdgpu_device *adev = NULL; struct amdgpu_device *adev = NULL;
uint32_t gpu_id = 0; uint32_t gpu_id = 0;
uint32_t umc_inst = 0; uint32_t umc_inst = 0, ch_inst = 0;
uint32_t ch_inst, channel_index = 0;
struct ras_err_data err_data = {0, 0, 0, NULL}; struct ras_err_data err_data = {0, 0, 0, NULL};
struct eeprom_table_record err_rec;
uint64_t retired_page;
/* /*
* If the error was generated in UMC_V2, which belongs to GPU UMCs, * If the error was generated in UMC_V2, which belongs to GPU UMCs,
@ -2875,21 +2874,22 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d", dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d",
umc_inst, ch_inst); umc_inst, ch_inst);
err_data.err_addr =
kcalloc(adev->umc.max_ras_err_cnt_per_query,
sizeof(struct eeprom_table_record), GFP_KERNEL);
if(!err_data.err_addr) {
dev_warn(adev->dev, "Failed to alloc memory for "
"umc error address record in mca notifier!\n");
return NOTIFY_DONE;
}
/* /*
* Translate UMC channel address to Physical address * Translate UMC channel address to Physical address
*/ */
channel_index = if (adev->umc.ras &&
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num adev->umc.ras->convert_ras_error_address)
+ ch_inst]; adev->umc.ras->convert_ras_error_address(adev,
&err_data, 0, ch_inst, umc_inst, m->addr);
retired_page = ADDR_OF_8KB_BLOCK(m->addr) |
ADDR_OF_256B_BLOCK(channel_index) |
OFFSET_IN_256B_BLOCK(m->addr);
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
err_data.err_addr = &err_rec;
amdgpu_umc_fill_error_record(&err_data, m->addr,
retired_page, channel_index, umc_inst);
if (amdgpu_bad_page_threshold != 0) { if (amdgpu_bad_page_threshold != 0) {
amdgpu_ras_add_bad_pages(adev, err_data.err_addr, amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
@ -2897,6 +2897,7 @@ static int amdgpu_bad_page_notifier(struct notifier_block *nb,
amdgpu_ras_save_bad_pages(adev); amdgpu_ras_save_bad_pages(adev);
} }
kfree(err_data.err_addr);
return NOTIFY_OK; return NOTIFY_OK;
} }

View File

@ -38,6 +38,7 @@
#define EEPROM_I2C_MADDR_ARCTURUS_D342 0x0 #define EEPROM_I2C_MADDR_ARCTURUS_D342 0x0
#define EEPROM_I2C_MADDR_SIENNA_CICHLID 0x0 #define EEPROM_I2C_MADDR_SIENNA_CICHLID 0x0
#define EEPROM_I2C_MADDR_ALDEBARAN 0x0 #define EEPROM_I2C_MADDR_ALDEBARAN 0x0
#define EEPROM_I2C_MADDR_SMU_13_0_0 (0x54UL << 16)
/* /*
* The 2 macros bellow represent the actual size in bytes that * The 2 macros bellow represent the actual size in bytes that
@ -156,6 +157,15 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev,
return false; return false;
} }
switch (adev->ip_versions[MP1_HWIP][0]) {
case IP_VERSION(13, 0, 0):
control->i2c_address = EEPROM_I2C_MADDR_SMU_13_0_0;
break;
default:
break;
}
return true; return true;
} }

View File

@ -23,6 +23,7 @@
#include "amdgpu_reset.h" #include "amdgpu_reset.h"
#include "aldebaran.h" #include "aldebaran.h"
#include "sienna_cichlid.h"
int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl, int amdgpu_reset_add_handler(struct amdgpu_reset_control *reset_ctl,
struct amdgpu_reset_handler *handler) struct amdgpu_reset_handler *handler)
@ -36,10 +37,15 @@ int amdgpu_reset_init(struct amdgpu_device *adev)
{ {
int ret = 0; int ret = 0;
adev->amdgpu_reset_level_mask = 0x1;
switch (adev->ip_versions[MP1_HWIP][0]) { switch (adev->ip_versions[MP1_HWIP][0]) {
case IP_VERSION(13, 0, 2): case IP_VERSION(13, 0, 2):
ret = aldebaran_reset_init(adev); ret = aldebaran_reset_init(adev);
break; break;
case IP_VERSION(11, 0, 7):
ret = sienna_cichlid_reset_init(adev);
break;
default: default:
break; break;
} }
@ -55,6 +61,9 @@ int amdgpu_reset_fini(struct amdgpu_device *adev)
case IP_VERSION(13, 0, 2): case IP_VERSION(13, 0, 2):
ret = aldebaran_reset_fini(adev); ret = aldebaran_reset_fini(adev);
break; break;
case IP_VERSION(11, 0, 7):
ret = sienna_cichlid_reset_fini(adev);
break;
default: default:
break; break;
} }
@ -67,6 +76,12 @@ int amdgpu_reset_prepare_hwcontext(struct amdgpu_device *adev,
{ {
struct amdgpu_reset_handler *reset_handler = NULL; struct amdgpu_reset_handler *reset_handler = NULL;
if (!(adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_MODE2))
return -ENOSYS;
if (test_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags))
return -ENOSYS;
if (adev->reset_cntl && adev->reset_cntl->get_reset_handler) if (adev->reset_cntl && adev->reset_cntl->get_reset_handler)
reset_handler = adev->reset_cntl->get_reset_handler( reset_handler = adev->reset_cntl->get_reset_handler(
adev->reset_cntl, reset_context); adev->reset_cntl, reset_context);
@ -83,6 +98,12 @@ int amdgpu_reset_perform_reset(struct amdgpu_device *adev,
int ret; int ret;
struct amdgpu_reset_handler *reset_handler = NULL; struct amdgpu_reset_handler *reset_handler = NULL;
if (!(adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_MODE2))
return -ENOSYS;
if (test_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context->flags))
return -ENOSYS;
if (adev->reset_cntl) if (adev->reset_cntl)
reset_handler = adev->reset_cntl->get_reset_handler( reset_handler = adev->reset_cntl->get_reset_handler(
adev->reset_cntl, reset_context); adev->reset_cntl, reset_context);

View File

@ -30,6 +30,8 @@ enum AMDGPU_RESET_FLAGS {
AMDGPU_NEED_FULL_RESET = 0, AMDGPU_NEED_FULL_RESET = 0,
AMDGPU_SKIP_HW_RESET = 1, AMDGPU_SKIP_HW_RESET = 1,
AMDGPU_SKIP_MODE2_RESET = 2,
AMDGPU_RESET_FOR_DEVICE_REMOVE = 3,
}; };
struct amdgpu_reset_context { struct amdgpu_reset_context {
@ -111,7 +113,8 @@ static inline bool amdgpu_reset_get_reset_domain(struct amdgpu_reset_domain *dom
static inline void amdgpu_reset_put_reset_domain(struct amdgpu_reset_domain *domain) static inline void amdgpu_reset_put_reset_domain(struct amdgpu_reset_domain *domain)
{ {
kref_put(&domain->refcount, amdgpu_reset_destroy_reset_domain); if (domain)
kref_put(&domain->refcount, amdgpu_reset_destroy_reset_domain);
} }
static inline bool amdgpu_reset_domain_schedule(struct amdgpu_reset_domain *domain, static inline bool amdgpu_reset_domain_schedule(struct amdgpu_reset_domain *domain,

View File

@ -405,6 +405,9 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid,
{ {
ktime_t deadline = ktime_add_us(ktime_get(), 10000); ktime_t deadline = ktime_add_us(ktime_get(), 10000);
if (!(ring->adev->amdgpu_reset_level_mask & AMDGPU_RESET_LEVEL_SOFT_RECOVERY))
return false;
if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence) if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)
return false; return false;

View File

@ -359,6 +359,14 @@ static void amdgpu_gfx_rlc_init_microcode_v2_1(struct amdgpu_device *adev)
le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length); le32_to_cpu(rlc_hdr->reg_list_format_direct_reg_list_length);
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
if (adev->gfx.rlc.save_restore_list_cntl_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL];
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL;
info->fw = adev->gfx.rlc_fw;
adev->firmware.fw_size +=
ALIGN(adev->gfx.rlc.save_restore_list_cntl_size_bytes, PAGE_SIZE);
}
if (adev->gfx.rlc.save_restore_list_gpm_size_bytes) { if (adev->gfx.rlc.save_restore_list_gpm_size_bytes) {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM]; info = &adev->firmware.ucode[AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM];
info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM; info->ucode_id = AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM;

View File

@ -21,6 +21,7 @@
* *
*/ */
#include <linux/firmware.h>
#include "amdgpu.h" #include "amdgpu.h"
#include "amdgpu_sdma.h" #include "amdgpu_sdma.h"
#include "amdgpu_ras.h" #include "amdgpu_ras.h"
@ -150,3 +151,135 @@ int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev,
amdgpu_ras_interrupt_dispatch(adev, &ih_data); amdgpu_ras_interrupt_dispatch(adev, &ih_data);
return 0; return 0;
} }
static int amdgpu_sdma_init_inst_ctx(struct amdgpu_sdma_instance *sdma_inst)
{
int err = 0;
uint16_t version_major;
const struct common_firmware_header *header = NULL;
const struct sdma_firmware_header_v1_0 *hdr;
const struct sdma_firmware_header_v2_0 *hdr_v2;
err = amdgpu_ucode_validate(sdma_inst->fw);
if (err)
return err;
header = (const struct common_firmware_header *)
sdma_inst->fw->data;
version_major = le16_to_cpu(header->header_version_major);
switch (version_major) {
case 1:
hdr = (const struct sdma_firmware_header_v1_0 *)sdma_inst->fw->data;
sdma_inst->fw_version = le32_to_cpu(hdr->header.ucode_version);
sdma_inst->feature_version = le32_to_cpu(hdr->ucode_feature_version);
break;
case 2:
hdr_v2 = (const struct sdma_firmware_header_v2_0 *)sdma_inst->fw->data;
sdma_inst->fw_version = le32_to_cpu(hdr_v2->header.ucode_version);
sdma_inst->feature_version = le32_to_cpu(hdr_v2->ucode_feature_version);
break;
default:
return -EINVAL;
}
if (sdma_inst->feature_version >= 20)
sdma_inst->burst_nop = true;
return 0;
}
void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev,
bool duplicate)
{
int i;
for (i = 0; i < adev->sdma.num_instances; i++) {
release_firmware(adev->sdma.instance[i].fw);
if (duplicate)
break;
}
memset((void *)adev->sdma.instance, 0,
sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES);
}
int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
char *fw_name, u32 instance,
bool duplicate)
{
struct amdgpu_firmware_info *info = NULL;
const struct common_firmware_header *header = NULL;
int err = 0, i;
const struct sdma_firmware_header_v2_0 *sdma_hdr;
uint16_t version_major;
err = request_firmware(&adev->sdma.instance[instance].fw, fw_name, adev->dev);
if (err)
goto out;
header = (const struct common_firmware_header *)
adev->sdma.instance[instance].fw->data;
version_major = le16_to_cpu(header->header_version_major);
if ((duplicate && instance) || (!duplicate && version_major > 1))
return -EINVAL;
err = amdgpu_sdma_init_inst_ctx(&adev->sdma.instance[instance]);
if (err)
goto out;
if (duplicate) {
for (i = 1; i < adev->sdma.num_instances; i++)
memcpy((void *)&adev->sdma.instance[i],
(void *)&adev->sdma.instance[0],
sizeof(struct amdgpu_sdma_instance));
}
if (amdgpu_sriov_vf(adev))
return 0;
DRM_DEBUG("psp_load == '%s'\n",
adev->firmware.load_type == AMDGPU_FW_LOAD_PSP ? "true" : "false");
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
switch (version_major) {
case 1:
for (i = 0; i < adev->sdma.num_instances; i++) {
if (!duplicate && (instance != i))
continue;
else {
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA0 + i];
info->ucode_id = AMDGPU_UCODE_ID_SDMA0 + i;
info->fw = adev->sdma.instance[i].fw;
adev->firmware.fw_size +=
ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
}
}
break;
case 2:
sdma_hdr = (const struct sdma_firmware_header_v2_0 *)
adev->sdma.instance[0].fw->data;
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA_UCODE_TH0];
info->ucode_id = AMDGPU_UCODE_ID_SDMA_UCODE_TH0;
info->fw = adev->sdma.instance[0].fw;
adev->firmware.fw_size +=
ALIGN(le32_to_cpu(sdma_hdr->ctx_ucode_size_bytes), PAGE_SIZE);
info = &adev->firmware.ucode[AMDGPU_UCODE_ID_SDMA_UCODE_TH1];
info->ucode_id = AMDGPU_UCODE_ID_SDMA_UCODE_TH1;
info->fw = adev->sdma.instance[0].fw;
adev->firmware.fw_size +=
ALIGN(le32_to_cpu(sdma_hdr->ctl_ucode_size_bytes), PAGE_SIZE);
break;
default:
return -EINVAL;
}
}
out:
if (err) {
DRM_ERROR("SDMA: Failed to init firmware \"%s\"\n", fw_name);
amdgpu_sdma_destroy_inst_ctx(adev, duplicate);
}
return err;
}

View File

@ -124,4 +124,8 @@ int amdgpu_sdma_process_ras_data_cb(struct amdgpu_device *adev,
int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev, int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev,
struct amdgpu_irq_src *source, struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry); struct amdgpu_iv_entry *entry);
int amdgpu_sdma_init_microcode(struct amdgpu_device *adev,
char *fw_name, u32 instance, bool duplicate);
void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev,
bool duplicate);
#endif #endif

View File

@ -1,3 +1,4 @@
// SPDX-License-Identifier: MIT
/* /*
* Copyright 2014 Advanced Micro Devices, Inc. * Copyright 2014 Advanced Micro Devices, Inc.
* All Rights Reserved. * All Rights Reserved.
@ -315,6 +316,7 @@ struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync)
struct hlist_node *tmp; struct hlist_node *tmp;
struct dma_fence *f; struct dma_fence *f;
int i; int i;
hash_for_each_safe(sync->fences, i, tmp, e, node) { hash_for_each_safe(sync->fences, i, tmp, e, node) {
f = e->fence; f = e->fence;
@ -392,7 +394,7 @@ void amdgpu_sync_free(struct amdgpu_sync *sync)
{ {
struct amdgpu_sync_entry *e; struct amdgpu_sync_entry *e;
struct hlist_node *tmp; struct hlist_node *tmp;
unsigned i; unsigned int i;
hash_for_each_safe(sync->fences, i, tmp, e, node) { hash_for_each_safe(sync->fences, i, tmp, e, node) {
hash_del(&e->node); hash_del(&e->node);

View File

@ -140,8 +140,10 @@ TRACE_EVENT(amdgpu_bo_create,
); );
TRACE_EVENT(amdgpu_cs, TRACE_EVENT(amdgpu_cs,
TP_PROTO(struct amdgpu_cs_parser *p, int i), TP_PROTO(struct amdgpu_cs_parser *p,
TP_ARGS(p, i), struct amdgpu_job *job,
struct amdgpu_ib *ib),
TP_ARGS(p, job, ib),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(struct amdgpu_bo_list *, bo_list) __field(struct amdgpu_bo_list *, bo_list)
__field(u32, ring) __field(u32, ring)
@ -151,10 +153,10 @@ TRACE_EVENT(amdgpu_cs,
TP_fast_assign( TP_fast_assign(
__entry->bo_list = p->bo_list; __entry->bo_list = p->bo_list;
__entry->ring = to_amdgpu_ring(p->entity->rq->sched)->idx; __entry->ring = to_amdgpu_ring(job->base.sched)->idx;
__entry->dw = p->job->ibs[i].length_dw; __entry->dw = ib->length_dw;
__entry->fences = amdgpu_fence_count_emitted( __entry->fences = amdgpu_fence_count_emitted(
to_amdgpu_ring(p->entity->rq->sched)); to_amdgpu_ring(job->base.sched));
), ),
TP_printk("bo_list=%p, ring=%u, dw=%u, fences=%u", TP_printk("bo_list=%p, ring=%u, dw=%u, fences=%u",
__entry->bo_list, __entry->ring, __entry->dw, __entry->bo_list, __entry->ring, __entry->dw,

View File

@ -471,7 +471,8 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
adev = amdgpu_ttm_adev(bo->bdev); adev = amdgpu_ttm_adev(bo->bdev);
if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM &&
bo->ttm == NULL)) {
ttm_bo_move_null(bo, new_mem); ttm_bo_move_null(bo, new_mem);
goto out; goto out;
} }
@ -1329,11 +1330,12 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
const struct ttm_place *place) const struct ttm_place *place)
{ {
unsigned long num_pages = bo->resource->num_pages;
struct dma_resv_iter resv_cursor; struct dma_resv_iter resv_cursor;
struct amdgpu_res_cursor cursor;
struct dma_fence *f; struct dma_fence *f;
if (!amdgpu_bo_is_amdgpu_bo(bo))
return ttm_bo_eviction_valuable(bo, place);
/* Swapout? */ /* Swapout? */
if (bo->resource->mem_type == TTM_PL_SYSTEM) if (bo->resource->mem_type == TTM_PL_SYSTEM)
return true; return true;
@ -1352,39 +1354,19 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
return false; return false;
} }
switch (bo->resource->mem_type) { /* Preemptible BOs don't own system resources managed by the
case AMDGPU_PL_PREEMPT: * driver (pages, VRAM, GART space). They point to resources
/* Preemptible BOs don't own system resources managed by the * owned by someone else (e.g. pageable memory in user mode
* driver (pages, VRAM, GART space). They point to resources * or a DMABuf). They are used in a preemptible context so we
* owned by someone else (e.g. pageable memory in user mode * can guarantee no deadlocks and good QoS in case of MMU
* or a DMABuf). They are used in a preemptible context so we * notifiers or DMABuf move notifiers from the resource owner.
* can guarantee no deadlocks and good QoS in case of MMU */
* notifiers or DMABuf move notifiers from the resource owner. if (bo->resource->mem_type == AMDGPU_PL_PREEMPT)
*/
return false;
case TTM_PL_TT:
if (amdgpu_bo_is_amdgpu_bo(bo) &&
amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
return false;
return true;
case TTM_PL_VRAM:
/* Check each drm MM node individually */
amdgpu_res_first(bo->resource, 0, (u64)num_pages << PAGE_SHIFT,
&cursor);
while (cursor.remaining) {
if (place->fpfn < PFN_DOWN(cursor.start + cursor.size)
&& !(place->lpfn &&
place->lpfn <= PFN_DOWN(cursor.start)))
return true;
amdgpu_res_next(&cursor, cursor.size);
}
return false; return false;
default: if (bo->resource->mem_type == TTM_PL_TT &&
break; amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))
} return false;
return ttm_bo_eviction_valuable(bo, place); return ttm_bo_eviction_valuable(bo, place);
} }

View File

@ -164,70 +164,138 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
} else if (version_major == 2) { } else if (version_major == 2) {
const struct rlc_firmware_header_v2_0 *rlc_hdr = const struct rlc_firmware_header_v2_0 *rlc_hdr =
container_of(hdr, struct rlc_firmware_header_v2_0, header); container_of(hdr, struct rlc_firmware_header_v2_0, header);
const struct rlc_firmware_header_v2_1 *rlc_hdr_v2_1 =
container_of(rlc_hdr, struct rlc_firmware_header_v2_1, v2_0);
const struct rlc_firmware_header_v2_2 *rlc_hdr_v2_2 =
container_of(rlc_hdr_v2_1, struct rlc_firmware_header_v2_2, v2_1);
const struct rlc_firmware_header_v2_3 *rlc_hdr_v2_3 =
container_of(rlc_hdr_v2_2, struct rlc_firmware_header_v2_3, v2_2);
const struct rlc_firmware_header_v2_4 *rlc_hdr_v2_4 =
container_of(rlc_hdr_v2_3, struct rlc_firmware_header_v2_4, v2_3);
DRM_DEBUG("ucode_feature_version: %u\n", switch (version_minor) {
le32_to_cpu(rlc_hdr->ucode_feature_version)); case 0:
DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(rlc_hdr->jt_offset)); /* rlc_hdr v2_0 */
DRM_DEBUG("jt_size: %u\n", le32_to_cpu(rlc_hdr->jt_size)); DRM_DEBUG("ucode_feature_version: %u\n",
DRM_DEBUG("save_and_restore_offset: %u\n", le32_to_cpu(rlc_hdr->ucode_feature_version));
le32_to_cpu(rlc_hdr->save_and_restore_offset)); DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(rlc_hdr->jt_offset));
DRM_DEBUG("clear_state_descriptor_offset: %u\n", DRM_DEBUG("jt_size: %u\n", le32_to_cpu(rlc_hdr->jt_size));
le32_to_cpu(rlc_hdr->clear_state_descriptor_offset)); DRM_DEBUG("save_and_restore_offset: %u\n",
DRM_DEBUG("avail_scratch_ram_locations: %u\n", le32_to_cpu(rlc_hdr->save_and_restore_offset));
le32_to_cpu(rlc_hdr->avail_scratch_ram_locations)); DRM_DEBUG("clear_state_descriptor_offset: %u\n",
DRM_DEBUG("reg_restore_list_size: %u\n", le32_to_cpu(rlc_hdr->clear_state_descriptor_offset));
le32_to_cpu(rlc_hdr->reg_restore_list_size)); DRM_DEBUG("avail_scratch_ram_locations: %u\n",
DRM_DEBUG("reg_list_format_start: %u\n", le32_to_cpu(rlc_hdr->avail_scratch_ram_locations));
le32_to_cpu(rlc_hdr->reg_list_format_start)); DRM_DEBUG("reg_restore_list_size: %u\n",
DRM_DEBUG("reg_list_format_separate_start: %u\n", le32_to_cpu(rlc_hdr->reg_restore_list_size));
le32_to_cpu(rlc_hdr->reg_list_format_separate_start)); DRM_DEBUG("reg_list_format_start: %u\n",
DRM_DEBUG("starting_offsets_start: %u\n", le32_to_cpu(rlc_hdr->reg_list_format_start));
le32_to_cpu(rlc_hdr->starting_offsets_start)); DRM_DEBUG("reg_list_format_separate_start: %u\n",
DRM_DEBUG("reg_list_format_size_bytes: %u\n", le32_to_cpu(rlc_hdr->reg_list_format_separate_start));
le32_to_cpu(rlc_hdr->reg_list_format_size_bytes)); DRM_DEBUG("starting_offsets_start: %u\n",
DRM_DEBUG("reg_list_format_array_offset_bytes: %u\n", le32_to_cpu(rlc_hdr->starting_offsets_start));
le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes)); DRM_DEBUG("reg_list_format_size_bytes: %u\n",
DRM_DEBUG("reg_list_size_bytes: %u\n", le32_to_cpu(rlc_hdr->reg_list_format_size_bytes));
le32_to_cpu(rlc_hdr->reg_list_size_bytes)); DRM_DEBUG("reg_list_format_array_offset_bytes: %u\n",
DRM_DEBUG("reg_list_array_offset_bytes: %u\n", le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes)); DRM_DEBUG("reg_list_size_bytes: %u\n",
DRM_DEBUG("reg_list_format_separate_size_bytes: %u\n", le32_to_cpu(rlc_hdr->reg_list_size_bytes));
le32_to_cpu(rlc_hdr->reg_list_format_separate_size_bytes)); DRM_DEBUG("reg_list_array_offset_bytes: %u\n",
DRM_DEBUG("reg_list_format_separate_array_offset_bytes: %u\n", le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
le32_to_cpu(rlc_hdr->reg_list_format_separate_array_offset_bytes)); DRM_DEBUG("reg_list_format_separate_size_bytes: %u\n",
DRM_DEBUG("reg_list_separate_size_bytes: %u\n", le32_to_cpu(rlc_hdr->reg_list_format_separate_size_bytes));
le32_to_cpu(rlc_hdr->reg_list_separate_size_bytes)); DRM_DEBUG("reg_list_format_separate_array_offset_bytes: %u\n",
DRM_DEBUG("reg_list_separate_array_offset_bytes: %u\n", le32_to_cpu(rlc_hdr->reg_list_format_separate_array_offset_bytes));
le32_to_cpu(rlc_hdr->reg_list_separate_array_offset_bytes)); DRM_DEBUG("reg_list_separate_size_bytes: %u\n",
if (version_minor == 1) { le32_to_cpu(rlc_hdr->reg_list_separate_size_bytes));
const struct rlc_firmware_header_v2_1 *v2_1 = DRM_DEBUG("reg_list_separate_array_offset_bytes: %u\n",
container_of(rlc_hdr, struct rlc_firmware_header_v2_1, v2_0); le32_to_cpu(rlc_hdr->reg_list_separate_array_offset_bytes));
break;
case 1:
/* rlc_hdr v2_1 */
DRM_DEBUG("reg_list_format_direct_reg_list_length: %u\n", DRM_DEBUG("reg_list_format_direct_reg_list_length: %u\n",
le32_to_cpu(v2_1->reg_list_format_direct_reg_list_length)); le32_to_cpu(rlc_hdr_v2_1->reg_list_format_direct_reg_list_length));
DRM_DEBUG("save_restore_list_cntl_ucode_ver: %u\n", DRM_DEBUG("save_restore_list_cntl_ucode_ver: %u\n",
le32_to_cpu(v2_1->save_restore_list_cntl_ucode_ver)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_ucode_ver));
DRM_DEBUG("save_restore_list_cntl_feature_ver: %u\n", DRM_DEBUG("save_restore_list_cntl_feature_ver: %u\n",
le32_to_cpu(v2_1->save_restore_list_cntl_feature_ver)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_feature_ver));
DRM_DEBUG("save_restore_list_cntl_size_bytes %u\n", DRM_DEBUG("save_restore_list_cntl_size_bytes %u\n",
le32_to_cpu(v2_1->save_restore_list_cntl_size_bytes)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_size_bytes));
DRM_DEBUG("save_restore_list_cntl_offset_bytes: %u\n", DRM_DEBUG("save_restore_list_cntl_offset_bytes: %u\n",
le32_to_cpu(v2_1->save_restore_list_cntl_offset_bytes)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_cntl_offset_bytes));
DRM_DEBUG("save_restore_list_gpm_ucode_ver: %u\n", DRM_DEBUG("save_restore_list_gpm_ucode_ver: %u\n",
le32_to_cpu(v2_1->save_restore_list_gpm_ucode_ver)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_ucode_ver));
DRM_DEBUG("save_restore_list_gpm_feature_ver: %u\n", DRM_DEBUG("save_restore_list_gpm_feature_ver: %u\n",
le32_to_cpu(v2_1->save_restore_list_gpm_feature_ver)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_feature_ver));
DRM_DEBUG("save_restore_list_gpm_size_bytes %u\n", DRM_DEBUG("save_restore_list_gpm_size_bytes %u\n",
le32_to_cpu(v2_1->save_restore_list_gpm_size_bytes)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_size_bytes));
DRM_DEBUG("save_restore_list_gpm_offset_bytes: %u\n", DRM_DEBUG("save_restore_list_gpm_offset_bytes: %u\n",
le32_to_cpu(v2_1->save_restore_list_gpm_offset_bytes)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_gpm_offset_bytes));
DRM_DEBUG("save_restore_list_srm_ucode_ver: %u\n", DRM_DEBUG("save_restore_list_srm_ucode_ver: %u\n",
le32_to_cpu(v2_1->save_restore_list_srm_ucode_ver)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_ucode_ver));
DRM_DEBUG("save_restore_list_srm_feature_ver: %u\n", DRM_DEBUG("save_restore_list_srm_feature_ver: %u\n",
le32_to_cpu(v2_1->save_restore_list_srm_feature_ver)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_feature_ver));
DRM_DEBUG("save_restore_list_srm_size_bytes %u\n", DRM_DEBUG("save_restore_list_srm_size_bytes %u\n",
le32_to_cpu(v2_1->save_restore_list_srm_size_bytes)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_size_bytes));
DRM_DEBUG("save_restore_list_srm_offset_bytes: %u\n", DRM_DEBUG("save_restore_list_srm_offset_bytes: %u\n",
le32_to_cpu(v2_1->save_restore_list_srm_offset_bytes)); le32_to_cpu(rlc_hdr_v2_1->save_restore_list_srm_offset_bytes));
break;
case 2:
/* rlc_hdr v2_2 */
DRM_DEBUG("rlc_iram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_2->rlc_iram_ucode_size_bytes));
DRM_DEBUG("rlc_iram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_2->rlc_iram_ucode_offset_bytes));
DRM_DEBUG("rlc_dram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_2->rlc_dram_ucode_size_bytes));
DRM_DEBUG("rlc_dram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_2->rlc_dram_ucode_offset_bytes));
break;
case 3:
/* rlc_hdr v2_3 */
DRM_DEBUG("rlcp_ucode_version: %u\n",
le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_version));
DRM_DEBUG("rlcp_ucode_feature_version: %u\n",
le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_feature_version));
DRM_DEBUG("rlcp_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_size_bytes));
DRM_DEBUG("rlcp_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_3->rlcp_ucode_offset_bytes));
DRM_DEBUG("rlcv_ucode_version: %u\n",
le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_version));
DRM_DEBUG("rlcv_ucode_feature_version: %u\n",
le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_feature_version));
DRM_DEBUG("rlcv_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_size_bytes));
DRM_DEBUG("rlcv_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_3->rlcv_ucode_offset_bytes));
break;
case 4:
/* rlc_hdr v2_4 */
DRM_DEBUG("global_tap_delays_ucode_size_bytes :%u\n",
le32_to_cpu(rlc_hdr_v2_4->global_tap_delays_ucode_size_bytes));
DRM_DEBUG("global_tap_delays_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_4->global_tap_delays_ucode_offset_bytes));
DRM_DEBUG("se0_tap_delays_ucode_size_bytes :%u\n",
le32_to_cpu(rlc_hdr_v2_4->se0_tap_delays_ucode_size_bytes));
DRM_DEBUG("se0_tap_delays_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_4->se0_tap_delays_ucode_offset_bytes));
DRM_DEBUG("se1_tap_delays_ucode_size_bytes :%u\n",
le32_to_cpu(rlc_hdr_v2_4->se1_tap_delays_ucode_size_bytes));
DRM_DEBUG("se1_tap_delays_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_4->se1_tap_delays_ucode_offset_bytes));
DRM_DEBUG("se2_tap_delays_ucode_size_bytes :%u\n",
le32_to_cpu(rlc_hdr_v2_4->se2_tap_delays_ucode_size_bytes));
DRM_DEBUG("se2_tap_delays_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_4->se2_tap_delays_ucode_offset_bytes));
DRM_DEBUG("se3_tap_delays_ucode_size_bytes :%u\n",
le32_to_cpu(rlc_hdr_v2_4->se3_tap_delays_ucode_size_bytes));
DRM_DEBUG("se3_tap_delays_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_4->se3_tap_delays_ucode_offset_bytes));
break;
default:
DRM_ERROR("Unknown RLC v2 ucode: v2.%u\n", version_minor);
break;
} }
} else { } else {
DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor); DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor);

View File

@ -124,6 +124,7 @@ enum psp_fw_type {
PSP_FW_TYPE_PSP_SOC_DRV, PSP_FW_TYPE_PSP_SOC_DRV,
PSP_FW_TYPE_PSP_INTF_DRV, PSP_FW_TYPE_PSP_INTF_DRV,
PSP_FW_TYPE_PSP_DBG_DRV, PSP_FW_TYPE_PSP_DBG_DRV,
PSP_FW_TYPE_PSP_RAS_DRV,
}; };
/* version_major=2, version_minor=0 */ /* version_major=2, version_minor=0 */

View File

@ -22,6 +22,8 @@
#define __AMDGPU_UMC_H__ #define __AMDGPU_UMC_H__
#include "amdgpu_ras.h" #include "amdgpu_ras.h"
#define UMC_INVALID_ADDR 0x1ULL
/* /*
* (addr / 256) * 4096, the higher 26 bits in ErrorAddr * (addr / 256) * 4096, the higher 26 bits in ErrorAddr
* is the index of 4KB block * is the index of 4KB block
@ -51,6 +53,10 @@ struct amdgpu_umc_ras {
struct amdgpu_ras_block_object ras_block; struct amdgpu_ras_block_object ras_block;
void (*err_cnt_init)(struct amdgpu_device *adev); void (*err_cnt_init)(struct amdgpu_device *adev);
bool (*query_ras_poison_mode)(struct amdgpu_device *adev); bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
void (*convert_ras_error_address)(struct amdgpu_device *adev,
struct ras_err_data *err_data,
uint32_t umc_reg_offset, uint32_t ch_inst,
uint32_t umc_inst, uint64_t mca_addr);
void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev, void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev,
void *ras_error_status); void *ras_error_status);
void (*ecc_info_query_ras_error_address)(struct amdgpu_device *adev, void (*ecc_info_query_ras_error_address)(struct amdgpu_device *adev,

View File

@ -161,6 +161,8 @@
#define AMDGPU_VCN_SW_RING_FLAG (1 << 9) #define AMDGPU_VCN_SW_RING_FLAG (1 << 9)
#define AMDGPU_VCN_FW_LOGGING_FLAG (1 << 10) #define AMDGPU_VCN_FW_LOGGING_FLAG (1 << 10)
#define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11) #define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11)
#define AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG (1 << 11)
#define AMDGPU_VCN_VF_RB_SETUP_FLAG (1 << 14)
#define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER 0x00000001 #define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER 0x00000001
#define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER 0x00000001 #define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER 0x00000001
@ -170,6 +172,9 @@
#define VCN_CODEC_DISABLE_MASK_HEVC (1 << 2) #define VCN_CODEC_DISABLE_MASK_HEVC (1 << 2)
#define VCN_CODEC_DISABLE_MASK_H264 (1 << 3) #define VCN_CODEC_DISABLE_MASK_H264 (1 << 3)
#define AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU (0)
#define AMDGPU_VCN_SMU_DPM_INTERFACE_APU (1)
enum fw_queue_mode { enum fw_queue_mode {
FW_QUEUE_RING_RESET = 1, FW_QUEUE_RING_RESET = 1,
FW_QUEUE_DPG_HOLD_OFF = 2, FW_QUEUE_DPG_HOLD_OFF = 2,
@ -317,12 +322,26 @@ struct amdgpu_fw_shared {
struct amdgpu_fw_shared_smu_interface_info smu_interface_info; struct amdgpu_fw_shared_smu_interface_info smu_interface_info;
}; };
struct amdgpu_fw_shared_rb_setup {
uint32_t is_rb_enabled_flags;
uint32_t rb_addr_lo;
uint32_t rb_addr_hi;
uint32_t rb_size;
uint32_t rb4_addr_lo;
uint32_t rb4_addr_hi;
uint32_t rb4_size;
uint32_t reserved[6];
};
struct amdgpu_vcn4_fw_shared { struct amdgpu_vcn4_fw_shared {
uint32_t present_flag_0; uint32_t present_flag_0;
uint8_t pad[12]; uint8_t pad[12];
struct amdgpu_fw_shared_unified_queue_struct sq; struct amdgpu_fw_shared_unified_queue_struct sq;
uint8_t pad1[8]; uint8_t pad1[8];
struct amdgpu_fw_shared_fw_logging fw_log; struct amdgpu_fw_shared_fw_logging fw_log;
uint8_t pad2[20];
struct amdgpu_fw_shared_rb_setup rb_setup;
struct amdgpu_fw_shared_smu_interface_info smu_dpm_interface;
}; };
struct amdgpu_vcn_fwlog { struct amdgpu_vcn_fwlog {

View File

@ -690,7 +690,6 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev)
} }
} }
void amdgpu_detect_virtualization(struct amdgpu_device *adev) void amdgpu_detect_virtualization(struct amdgpu_device *adev)
{ {
uint32_t reg; uint32_t reg;
@ -707,6 +706,7 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
case CHIP_SIENNA_CICHLID: case CHIP_SIENNA_CICHLID:
case CHIP_ARCTURUS: case CHIP_ARCTURUS:
case CHIP_ALDEBARAN: case CHIP_ALDEBARAN:
case CHIP_IP_DISCOVERY:
reg = RREG32(mmRCC_IOV_FUNC_IDENTIFIER); reg = RREG32(mmRCC_IOV_FUNC_IDENTIFIER);
break; break;
default: /* other chip doesn't support SRIOV */ default: /* other chip doesn't support SRIOV */
@ -750,6 +750,7 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
case CHIP_NAVI10: case CHIP_NAVI10:
case CHIP_NAVI12: case CHIP_NAVI12:
case CHIP_SIENNA_CICHLID: case CHIP_SIENNA_CICHLID:
case CHIP_IP_DISCOVERY:
nv_set_virt_ops(adev); nv_set_virt_ops(adev);
/* try send GPU_INIT_DATA request to host */ /* try send GPU_INIT_DATA request to host */
amdgpu_virt_request_init_data(adev); amdgpu_virt_request_init_data(adev);
@ -807,6 +808,60 @@ enum amdgpu_sriov_vf_mode amdgpu_virt_get_sriov_vf_mode(struct amdgpu_device *ad
return mode; return mode;
} }
bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev, uint32_t ucode_id)
{
switch (adev->ip_versions[MP0_HWIP][0]) {
case IP_VERSION(13, 0, 0):
/* no vf autoload, white list */
if (ucode_id == AMDGPU_UCODE_ID_VCN1 ||
ucode_id == AMDGPU_UCODE_ID_VCN)
return false;
else
return true;
case IP_VERSION(13, 0, 10):
/* white list */
if (ucode_id == AMDGPU_UCODE_ID_CAP
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK
|| ucode_id == AMDGPU_UCODE_ID_CP_MES
|| ucode_id == AMDGPU_UCODE_ID_CP_MES_DATA
|| ucode_id == AMDGPU_UCODE_ID_CP_MES1
|| ucode_id == AMDGPU_UCODE_ID_CP_MES1_DATA
|| ucode_id == AMDGPU_UCODE_ID_VCN1
|| ucode_id == AMDGPU_UCODE_ID_VCN)
return false;
else
return true;
default:
/* lagacy black list */
if (ucode_id == AMDGPU_UCODE_ID_SDMA0
|| ucode_id == AMDGPU_UCODE_ID_SDMA1
|| ucode_id == AMDGPU_UCODE_ID_SDMA2
|| ucode_id == AMDGPU_UCODE_ID_SDMA3
|| ucode_id == AMDGPU_UCODE_ID_SDMA4
|| ucode_id == AMDGPU_UCODE_ID_SDMA5
|| ucode_id == AMDGPU_UCODE_ID_SDMA6
|| ucode_id == AMDGPU_UCODE_ID_SDMA7
|| ucode_id == AMDGPU_UCODE_ID_RLC_G
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM
|| ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM
|| ucode_id == AMDGPU_UCODE_ID_SMC)
return true;
else
return false;
}
}
void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev, void amdgpu_virt_update_sriov_video_codec(struct amdgpu_device *adev,
struct amdgpu_video_codec_info *encode, uint32_t encode_array_size, struct amdgpu_video_codec_info *encode, uint32_t encode_array_size,
struct amdgpu_video_codec_info *decode, uint32_t decode_array_size) struct amdgpu_video_codec_info *decode, uint32_t decode_array_size)

View File

@ -253,6 +253,9 @@ struct amdgpu_virt {
uint32_t decode_max_frame_pixels; uint32_t decode_max_frame_pixels;
uint32_t encode_max_dimension_pixels; uint32_t encode_max_dimension_pixels;
uint32_t encode_max_frame_pixels; uint32_t encode_max_frame_pixels;
/* the ucode id to signal the autoload */
uint32_t autoload_ucode_id;
}; };
struct amdgpu_video_codec_info; struct amdgpu_video_codec_info;
@ -343,4 +346,6 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev,
u32 acc_flags, u32 hwip); u32 acc_flags, u32 hwip);
u32 amdgpu_sriov_rreg(struct amdgpu_device *adev, u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
u32 offset, u32 acc_flags, u32 hwip); u32 offset, u32 acc_flags, u32 hwip);
bool amdgpu_virt_fw_load_skip_check(struct amdgpu_device *adev,
uint32_t ucode_id);
#endif #endif

View File

@ -282,8 +282,8 @@ static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
return PTR_ERR(crtc_state); return PTR_ERR(crtc_state);
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_NO_SCALING,
DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_NO_SCALING,
false, true); false, true);
if (ret != 0) if (ret != 0)
return ret; return ret;

View File

@ -183,10 +183,12 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
struct amdgpu_bo *bo = vm_bo->bo; struct amdgpu_bo *bo = vm_bo->bo;
vm_bo->moved = true; vm_bo->moved = true;
spin_lock(&vm_bo->vm->status_lock);
if (bo->tbo.type == ttm_bo_type_kernel) if (bo->tbo.type == ttm_bo_type_kernel)
list_move(&vm_bo->vm_status, &vm->evicted); list_move(&vm_bo->vm_status, &vm->evicted);
else else
list_move_tail(&vm_bo->vm_status, &vm->evicted); list_move_tail(&vm_bo->vm_status, &vm->evicted);
spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
* amdgpu_vm_bo_moved - vm_bo is moved * amdgpu_vm_bo_moved - vm_bo is moved
@ -198,7 +200,9 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
*/ */
static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
{ {
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->moved); list_move(&vm_bo->vm_status, &vm_bo->vm->moved);
spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
@ -211,7 +215,9 @@ static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
*/ */
static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
{ {
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->idle); list_move(&vm_bo->vm_status, &vm_bo->vm->idle);
spin_unlock(&vm_bo->vm->status_lock);
vm_bo->moved = false; vm_bo->moved = false;
} }
@ -225,9 +231,9 @@ static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
*/ */
static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
{ {
spin_lock(&vm_bo->vm->invalidated_lock); spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->invalidated); list_move(&vm_bo->vm_status, &vm_bo->vm->invalidated);
spin_unlock(&vm_bo->vm->invalidated_lock); spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
@ -240,10 +246,13 @@ static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
*/ */
static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
{ {
if (vm_bo->bo->parent) if (vm_bo->bo->parent) {
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->relocated); list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
else spin_unlock(&vm_bo->vm->status_lock);
} else {
amdgpu_vm_bo_idle(vm_bo); amdgpu_vm_bo_idle(vm_bo);
}
} }
/** /**
@ -256,9 +265,9 @@ static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
*/ */
static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo) static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo)
{ {
spin_lock(&vm_bo->vm->invalidated_lock); spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->done); list_move(&vm_bo->vm_status, &vm_bo->vm->done);
spin_unlock(&vm_bo->vm->invalidated_lock); spin_unlock(&vm_bo->vm->status_lock);
} }
/** /**
@ -363,12 +372,20 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int (*validate)(void *p, struct amdgpu_bo *bo), int (*validate)(void *p, struct amdgpu_bo *bo),
void *param) void *param)
{ {
struct amdgpu_vm_bo_base *bo_base, *tmp; struct amdgpu_vm_bo_base *bo_base;
struct amdgpu_bo *shadow;
struct amdgpu_bo *bo;
int r; int r;
list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) { spin_lock(&vm->status_lock);
struct amdgpu_bo *bo = bo_base->bo; while (!list_empty(&vm->evicted)) {
struct amdgpu_bo *shadow = amdgpu_bo_shadowed(bo); bo_base = list_first_entry(&vm->evicted,
struct amdgpu_vm_bo_base,
vm_status);
spin_unlock(&vm->status_lock);
bo = bo_base->bo;
shadow = amdgpu_bo_shadowed(bo);
r = validate(param, bo); r = validate(param, bo);
if (r) if (r)
@ -385,7 +402,9 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
vm->update_funcs->map_table(to_amdgpu_bo_vm(bo)); vm->update_funcs->map_table(to_amdgpu_bo_vm(bo));
amdgpu_vm_bo_relocated(bo_base); amdgpu_vm_bo_relocated(bo_base);
} }
spin_lock(&vm->status_lock);
} }
spin_unlock(&vm->status_lock);
amdgpu_vm_eviction_lock(vm); amdgpu_vm_eviction_lock(vm);
vm->evicting = false; vm->evicting = false;
@ -406,13 +425,18 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
*/ */
bool amdgpu_vm_ready(struct amdgpu_vm *vm) bool amdgpu_vm_ready(struct amdgpu_vm *vm)
{ {
bool empty;
bool ret; bool ret;
amdgpu_vm_eviction_lock(vm); amdgpu_vm_eviction_lock(vm);
ret = !vm->evicting; ret = !vm->evicting;
amdgpu_vm_eviction_unlock(vm); amdgpu_vm_eviction_unlock(vm);
return ret && list_empty(&vm->evicted); spin_lock(&vm->status_lock);
empty = list_empty(&vm->evicted);
spin_unlock(&vm->status_lock);
return ret && empty;
} }
/** /**
@ -680,9 +704,14 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
struct amdgpu_vm_update_params params; struct amdgpu_vm_update_params params;
struct amdgpu_vm_bo_base *entry; struct amdgpu_vm_bo_base *entry;
bool flush_tlb_needed = false; bool flush_tlb_needed = false;
LIST_HEAD(relocated);
int r, idx; int r, idx;
if (list_empty(&vm->relocated)) spin_lock(&vm->status_lock);
list_splice_init(&vm->relocated, &relocated);
spin_unlock(&vm->status_lock);
if (list_empty(&relocated))
return 0; return 0;
if (!drm_dev_enter(adev_to_drm(adev), &idx)) if (!drm_dev_enter(adev_to_drm(adev), &idx))
@ -697,7 +726,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
if (r) if (r)
goto error; goto error;
list_for_each_entry(entry, &vm->relocated, vm_status) { list_for_each_entry(entry, &relocated, vm_status) {
/* vm_flush_needed after updating moved PDEs */ /* vm_flush_needed after updating moved PDEs */
flush_tlb_needed |= entry->moved; flush_tlb_needed |= entry->moved;
@ -713,9 +742,8 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
if (flush_tlb_needed) if (flush_tlb_needed)
atomic64_inc(&vm->tlb_seq); atomic64_inc(&vm->tlb_seq);
while (!list_empty(&vm->relocated)) { while (!list_empty(&relocated)) {
entry = list_first_entry(&vm->relocated, entry = list_first_entry(&relocated, struct amdgpu_vm_bo_base,
struct amdgpu_vm_bo_base,
vm_status); vm_status);
amdgpu_vm_bo_idle(entry); amdgpu_vm_bo_idle(entry);
} }
@ -912,6 +940,7 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
{ {
struct amdgpu_bo_va *bo_va, *tmp; struct amdgpu_bo_va *bo_va, *tmp;
spin_lock(&vm->status_lock);
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
@ -936,7 +965,6 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem, amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
gtt_mem, cpu_mem); gtt_mem, cpu_mem);
} }
spin_lock(&vm->invalidated_lock);
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
@ -949,7 +977,7 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
amdgpu_bo_get_memory(bo_va->base.bo, vram_mem, amdgpu_bo_get_memory(bo_va->base.bo, vram_mem,
gtt_mem, cpu_mem); gtt_mem, cpu_mem);
} }
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
} }
/** /**
* amdgpu_vm_bo_update - update all BO mappings in the vm page table * amdgpu_vm_bo_update - update all BO mappings in the vm page table
@ -1278,24 +1306,29 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
int amdgpu_vm_handle_moved(struct amdgpu_device *adev, int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
struct amdgpu_vm *vm) struct amdgpu_vm *vm)
{ {
struct amdgpu_bo_va *bo_va, *tmp; struct amdgpu_bo_va *bo_va;
struct dma_resv *resv; struct dma_resv *resv;
bool clear; bool clear;
int r; int r;
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) { spin_lock(&vm->status_lock);
while (!list_empty(&vm->moved)) {
bo_va = list_first_entry(&vm->moved, struct amdgpu_bo_va,
base.vm_status);
spin_unlock(&vm->status_lock);
/* Per VM BOs never need to bo cleared in the page tables */ /* Per VM BOs never need to bo cleared in the page tables */
r = amdgpu_vm_bo_update(adev, bo_va, false); r = amdgpu_vm_bo_update(adev, bo_va, false);
if (r) if (r)
return r; return r;
spin_lock(&vm->status_lock);
} }
spin_lock(&vm->invalidated_lock);
while (!list_empty(&vm->invalidated)) { while (!list_empty(&vm->invalidated)) {
bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va, bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va,
base.vm_status); base.vm_status);
resv = bo_va->base.bo->tbo.base.resv; resv = bo_va->base.bo->tbo.base.resv;
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
/* Try to reserve the BO to avoid clearing its ptes */ /* Try to reserve the BO to avoid clearing its ptes */
if (!amdgpu_vm_debug && dma_resv_trylock(resv)) if (!amdgpu_vm_debug && dma_resv_trylock(resv))
@ -1310,9 +1343,9 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
if (!clear) if (!clear)
dma_resv_unlock(resv); dma_resv_unlock(resv);
spin_lock(&vm->invalidated_lock); spin_lock(&vm->status_lock);
} }
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
return 0; return 0;
} }
@ -1387,7 +1420,7 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv && if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv &&
!bo_va->base.moved) { !bo_va->base.moved) {
list_move(&bo_va->base.vm_status, &vm->moved); amdgpu_vm_bo_moved(&bo_va->base);
} }
trace_amdgpu_vm_bo_map(bo_va, mapping); trace_amdgpu_vm_bo_map(bo_va, mapping);
} }
@ -1763,9 +1796,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev,
} }
} }
spin_lock(&vm->invalidated_lock); spin_lock(&vm->status_lock);
list_del(&bo_va->base.vm_status); list_del(&bo_va->base.vm_status);
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
list_del(&mapping->list); list_del(&mapping->list);
@ -2019,9 +2052,11 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
INIT_LIST_HEAD(&vm->moved); INIT_LIST_HEAD(&vm->moved);
INIT_LIST_HEAD(&vm->idle); INIT_LIST_HEAD(&vm->idle);
INIT_LIST_HEAD(&vm->invalidated); INIT_LIST_HEAD(&vm->invalidated);
spin_lock_init(&vm->invalidated_lock); spin_lock_init(&vm->status_lock);
INIT_LIST_HEAD(&vm->freed); INIT_LIST_HEAD(&vm->freed);
INIT_LIST_HEAD(&vm->done); INIT_LIST_HEAD(&vm->done);
INIT_LIST_HEAD(&vm->pt_freed);
INIT_WORK(&vm->pt_free_work, amdgpu_vm_pt_free_work);
/* create scheduler entities for page table updates */ /* create scheduler entities for page table updates */
r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL, r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL,
@ -2223,6 +2258,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
amdgpu_amdkfd_gpuvm_destroy_cb(adev, vm); amdgpu_amdkfd_gpuvm_destroy_cb(adev, vm);
flush_work(&vm->pt_free_work);
root = amdgpu_bo_ref(vm->root.bo); root = amdgpu_bo_ref(vm->root.bo);
amdgpu_bo_reserve(root, true); amdgpu_bo_reserve(root, true);
amdgpu_vm_set_pasid(adev, vm, 0); amdgpu_vm_set_pasid(adev, vm, 0);
@ -2547,6 +2584,7 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
unsigned int total_done_objs = 0; unsigned int total_done_objs = 0;
unsigned int id = 0; unsigned int id = 0;
spin_lock(&vm->status_lock);
seq_puts(m, "\tIdle BOs:\n"); seq_puts(m, "\tIdle BOs:\n");
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
@ -2584,7 +2622,6 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
id = 0; id = 0;
seq_puts(m, "\tInvalidated BOs:\n"); seq_puts(m, "\tInvalidated BOs:\n");
spin_lock(&vm->invalidated_lock);
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) { list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
if (!bo_va->base.bo) if (!bo_va->base.bo)
continue; continue;
@ -2599,7 +2636,7 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
continue; continue;
total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m); total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
} }
spin_unlock(&vm->invalidated_lock); spin_unlock(&vm->status_lock);
total_done_objs = id; total_done_objs = id;
seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle, seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle,

View File

@ -254,6 +254,9 @@ struct amdgpu_vm {
bool evicting; bool evicting;
unsigned int saved_flags; unsigned int saved_flags;
/* Lock to protect vm_bo add/del/move on all lists of vm */
spinlock_t status_lock;
/* BOs who needs a validation */ /* BOs who needs a validation */
struct list_head evicted; struct list_head evicted;
@ -268,7 +271,6 @@ struct amdgpu_vm {
/* regular invalidated BOs, but not yet updated in the PT */ /* regular invalidated BOs, but not yet updated in the PT */
struct list_head invalidated; struct list_head invalidated;
spinlock_t invalidated_lock;
/* BO mappings freed, but not yet updated in the PT */ /* BO mappings freed, but not yet updated in the PT */
struct list_head freed; struct list_head freed;
@ -276,6 +278,10 @@ struct amdgpu_vm {
/* BOs which are invalidated, has been updated in the PTs */ /* BOs which are invalidated, has been updated in the PTs */
struct list_head done; struct list_head done;
/* PT BOs scheduled to free and fill with zero if vm_resv is not hold */
struct list_head pt_freed;
struct work_struct pt_free_work;
/* contains the page directory */ /* contains the page directory */
struct amdgpu_vm_bo_base root; struct amdgpu_vm_bo_base root;
struct dma_fence *last_update; struct dma_fence *last_update;
@ -471,6 +477,7 @@ int amdgpu_vm_pde_update(struct amdgpu_vm_update_params *params,
int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params, int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
uint64_t start, uint64_t end, uint64_t start, uint64_t end,
uint64_t dst, uint64_t flags); uint64_t dst, uint64_t flags);
void amdgpu_vm_pt_free_work(struct work_struct *work);
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m); void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m);

View File

@ -637,10 +637,34 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
} }
ttm_bo_set_bulk_move(&entry->bo->tbo, NULL); ttm_bo_set_bulk_move(&entry->bo->tbo, NULL);
entry->bo->vm_bo = NULL; entry->bo->vm_bo = NULL;
spin_lock(&entry->vm->status_lock);
list_del(&entry->vm_status); list_del(&entry->vm_status);
spin_unlock(&entry->vm->status_lock);
amdgpu_bo_unref(&entry->bo); amdgpu_bo_unref(&entry->bo);
} }
void amdgpu_vm_pt_free_work(struct work_struct *work)
{
struct amdgpu_vm_bo_base *entry, *next;
struct amdgpu_vm *vm;
LIST_HEAD(pt_freed);
vm = container_of(work, struct amdgpu_vm, pt_free_work);
spin_lock(&vm->status_lock);
list_splice_init(&vm->pt_freed, &pt_freed);
spin_unlock(&vm->status_lock);
/* flush_work in amdgpu_vm_fini ensure vm->root.bo is valid. */
amdgpu_bo_reserve(vm->root.bo, true);
list_for_each_entry_safe(entry, next, &pt_freed, vm_status)
amdgpu_vm_pt_free(entry);
amdgpu_bo_unreserve(vm->root.bo);
}
/** /**
* amdgpu_vm_pt_free_dfs - free PD/PT levels * amdgpu_vm_pt_free_dfs - free PD/PT levels
* *
@ -652,11 +676,24 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
*/ */
static void amdgpu_vm_pt_free_dfs(struct amdgpu_device *adev, static void amdgpu_vm_pt_free_dfs(struct amdgpu_device *adev,
struct amdgpu_vm *vm, struct amdgpu_vm *vm,
struct amdgpu_vm_pt_cursor *start) struct amdgpu_vm_pt_cursor *start,
bool unlocked)
{ {
struct amdgpu_vm_pt_cursor cursor; struct amdgpu_vm_pt_cursor cursor;
struct amdgpu_vm_bo_base *entry; struct amdgpu_vm_bo_base *entry;
if (unlocked) {
spin_lock(&vm->status_lock);
for_each_amdgpu_vm_pt_dfs_safe(adev, vm, start, cursor, entry)
list_move(&entry->vm_status, &vm->pt_freed);
if (start)
list_move(&start->entry->vm_status, &vm->pt_freed);
spin_unlock(&vm->status_lock);
schedule_work(&vm->pt_free_work);
return;
}
for_each_amdgpu_vm_pt_dfs_safe(adev, vm, start, cursor, entry) for_each_amdgpu_vm_pt_dfs_safe(adev, vm, start, cursor, entry)
amdgpu_vm_pt_free(entry); amdgpu_vm_pt_free(entry);
@ -673,7 +710,7 @@ static void amdgpu_vm_pt_free_dfs(struct amdgpu_device *adev,
*/ */
void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm) void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm)
{ {
amdgpu_vm_pt_free_dfs(adev, vm, NULL); amdgpu_vm_pt_free_dfs(adev, vm, NULL, false);
} }
/** /**
@ -966,7 +1003,8 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
if (cursor.entry->bo) { if (cursor.entry->bo) {
params->table_freed = true; params->table_freed = true;
amdgpu_vm_pt_free_dfs(adev, params->vm, amdgpu_vm_pt_free_dfs(adev, params->vm,
&cursor); &cursor,
params->unlocked);
} }
amdgpu_vm_pt_next(adev, &cursor); amdgpu_vm_pt_next(adev, &cursor);
} }

Some files were not shown because too many files have changed in this diff Show More