drm for 5.16-rc1
core: - improve dma_fence, lease and resv documentation - shmem-helpers: allocate WC pages on x86, use vmf_insert_pin - sched fixes/improvements - allow empty drm leases - add dma resv iterator - add more DP 2.0 headers - DP MST helper improvements for DP2.0 dma-buf: - avoid warnings, remove fence trace macros bridge: - new helper to get rid of panels - probe improvements for it66121 - enable DSI EOTP for anx7625 fbdev: - efifb: release runtime PM on destroy ttm: - kerneldoc switch - helper to clear all DMA mappings - pool shrinker optimizaton - remove ttm_tt_destroy_common - update ttm_move_memcpy for async use panel: - add new panel-edp driver amdgpu: - Initial DP 2.0 support - Initial USB4 DP tunnelling support - Aldebaran MCE support - Modifier support for DCC image stores for GFX 10.3 - Display rework for better FP code handling - Yellow Carp/Cyan Skillfish updates - Cyan Skillfish display support - convert vega/navi to IP discovery asic enumeration - validate IP discovery table - RAS improvements - Lots of fixes i915: - DG1 PCI IDs + LMEM discovery/placement - DG1 GuC submission by default - ADL-S PCI IDs updated + enabled by default - ADL-P (XE_LPD) fixed and updates - DG2 display fixes - PXP protected object support for Gen12 integrated - expose multi-LRC submission interface for GuC - export logical engine instance to user - Disable engine bonding on Gen12+ - PSR cleanup - PSR2 selective fetch by default - DP 2.0 prep work - VESA vendor block + MSO use of it - FBC refactor - try again to fix fast-narrow vs slow-wide eDP training - use THP when IOMMU enabled - LMEM backup/restore for suspend/resume - locking simplification - GuC major reworking - async flip VT-D workaround changes - DP link training improvements - misc display refactorings bochs: - new PCI ID rcar-du: - Non-contiguious buffer import support for rcar-du - r8a779a0 support prep omapdrm: - COMPILE_TEST fixes sti: - COMPILE_TEST fixes msm: - fence ordering improvements - eDP support in DP sub-driver - dpu irq handling cleanup - CRC support for making igt happy - NO_CONNECTOR bridge support - dsi: 14nm phy support for msm8953 - mdp5: msm8x53, sdm450, sdm632 support stm: - layer alpha + zpo support v3d: - fix Vulkan CTS failure - support multiple sync objects gud: - add R8/RGB332/RGB888 pixel formats vc4: - convert to new bridge helpers vgem: - use shmem helpers virtio: - support mapping exported vram zte: - remove obsolete driver rockchip: - use bridge attach no connector for LVDS/RGB -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmGByPYACgkQDHTzWXnE hr6fxA//cXUvTHlEtF7UJDBRAYv+9lXH39NbGYU4aLJuBNlZztCuUi5JOSyDFDH1 N9VI5biVseev2PEnCzJUubWxTqbUO7FBQTw0TyvZ4Eqn+UZMuFeo0dvdKZRAkvjV VHSUc0fm0+WSYanKUK7XK0fwG8aE6JVyYngzgKPSjifhszTdiiRsbU21iTinFhkS rgh3HEVELp+LqfoG4qzAYqFUjYqUjvCjd/hX/UkzCII8ZXKr38/4127e95443WOk +jes0gWGJe9TvSDrqo9TMx4qukcOniINFUvnzoD2RhOS+Jzr/i5rBh51Xy92g3NO Q7hy6byZdk/ZO/MXCDQ2giUOkBiqn5fQjlRGQp4iAZYw9pb3HU+/xrTq0BWVWd8o /vmzZYEKKU/sCGpxVDMZxsHV3mXIuVBvuZq6bjmSGcybgOBCiDx5F/Rum4nY2yHp lr3cuc0HP3m3f4b/HVvACO4tGd1nDDpVcon7CuhBB7HB7t6Zl9u18qc/qFw0tCTh 3sgAhno6XFXtPFcSX2KAeeg0mhKDKKrsOnq5y3bDRr05Z0jLocJk95aXEKs6em4j gbyHwNaX3CHtiCnFn2/5169+n1K7zqHBtVSGmQlmFDv55rcdx7L3Spk7tCahQeSQ ur24r+sEggm8d5Wjl+MYq6wW3oP31s04JFaeV6oCkaSp1wS+alg= =jdhH -----END PGP SIGNATURE----- Merge tag 'drm-next-2021-11-03' of git://anongit.freedesktop.org/drm/drm Pull drm updates from Dave Airlie: "Summary below. i915 starts to add support for DG2 GPUs, enables DG1 and ADL-S support by default, lots of work to enable DisplayPort 2.0 across drivers. Lots of documentation updates and fixes across the board. core: - improve dma_fence, lease and resv documentation - shmem-helpers: allocate WC pages on x86, use vmf_insert_pin - sched fixes/improvements - allow empty drm leases - add dma resv iterator - add more DP 2.0 headers - DP MST helper improvements for DP2.0 dma-buf: - avoid warnings, remove fence trace macros bridge: - new helper to get rid of panels - probe improvements for it66121 - enable DSI EOTP for anx7625 fbdev: - efifb: release runtime PM on destroy ttm: - kerneldoc switch - helper to clear all DMA mappings - pool shrinker optimizaton - remove ttm_tt_destroy_common - update ttm_move_memcpy for async use panel: - add new panel-edp driver amdgpu: - Initial DP 2.0 support - Initial USB4 DP tunnelling support - Aldebaran MCE support - Modifier support for DCC image stores for GFX 10.3 - Display rework for better FP code handling - Yellow Carp/Cyan Skillfish updates - Cyan Skillfish display support - convert vega/navi to IP discovery asic enumeration - validate IP discovery table - RAS improvements - Lots of fixes i915: - DG1 PCI IDs + LMEM discovery/placement - DG1 GuC submission by default - ADL-S PCI IDs updated + enabled by default - ADL-P (XE_LPD) fixed and updates - DG2 display fixes - PXP protected object support for Gen12 integrated - expose multi-LRC submission interface for GuC - export logical engine instance to user - Disable engine bonding on Gen12+ - PSR cleanup - PSR2 selective fetch by default - DP 2.0 prep work - VESA vendor block + MSO use of it - FBC refactor - try again to fix fast-narrow vs slow-wide eDP training - use THP when IOMMU enabled - LMEM backup/restore for suspend/resume - locking simplification - GuC major reworking - async flip VT-D workaround changes - DP link training improvements - misc display refactorings bochs: - new PCI ID rcar-du: - Non-contiguious buffer import support for rcar-du - r8a779a0 support prep omapdrm: - COMPILE_TEST fixes sti: - COMPILE_TEST fixes msm: - fence ordering improvements - eDP support in DP sub-driver - dpu irq handling cleanup - CRC support for making igt happy - NO_CONNECTOR bridge support - dsi: 14nm phy support for msm8953 - mdp5: msm8x53, sdm450, sdm632 support stm: - layer alpha + zpo support v3d: - fix Vulkan CTS failure - support multiple sync objects gud: - add R8/RGB332/RGB888 pixel formats vc4: - convert to new bridge helpers vgem: - use shmem helpers virtio: - support mapping exported vram zte: - remove obsolete driver rockchip: - use bridge attach no connector for LVDS/RGB" * tag 'drm-next-2021-11-03' of git://anongit.freedesktop.org/drm/drm: (1259 commits) drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits drm/amd/display: MST support for DPIA drm/amdgpu: Fix even more out of bound writes from debugfs drm/amdgpu/discovery: add SDMA IP instance info for soc15 parts drm/amdgpu/discovery: add UVD/VCN IP instance info for soc15 parts drm/amdgpu/UAPI: rearrange header to better align related items drm/amd/display: Enable dpia in dmub only for DCN31 B0 drm/amd/display: Fix USB4 hot plug crash issue drm/amd/display: Fix deadlock when falling back to v2 from v3 drm/amd/display: Fallback to clocks which meet requested voltage on DCN31 drm/amd/display: move FPU associated DCN301 code to DML folder drm/amd/display: fix link training regression for 1 or 2 lane drm/amd/display: add two lane settings training options drm/amd/display: decouple hw_lane_settings from dpcd_lane_settings drm/amd/display: implement decide lane settings drm/amd/display: adopt DP2.0 LT SCR revision 8 drm/amd/display: FEC configuration for dpia links in MST mode drm/amd/display: FEC configuration for dpia links drm/amd/display: Add workaround flag for EDID read on certain docks drm/amd/display: Set phy_mux_sel bit in dmub scratch register ...
This commit is contained in:
commit
56d3375448
@ -17,9 +17,16 @@ properties:
|
|||||||
compatible:
|
compatible:
|
||||||
enum:
|
enum:
|
||||||
- qcom,sc7180-dp
|
- qcom,sc7180-dp
|
||||||
|
- qcom,sc8180x-dp
|
||||||
|
- qcom,sc8180x-edp
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
items:
|
||||||
|
- description: ahb register block
|
||||||
|
- description: aux register block
|
||||||
|
- description: link register block
|
||||||
|
- description: p0 register block
|
||||||
|
- description: p1 register block
|
||||||
|
|
||||||
interrupts:
|
interrupts:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
@ -100,7 +107,11 @@ examples:
|
|||||||
|
|
||||||
displayport-controller@ae90000 {
|
displayport-controller@ae90000 {
|
||||||
compatible = "qcom,sc7180-dp";
|
compatible = "qcom,sc7180-dp";
|
||||||
reg = <0xae90000 0x1400>;
|
reg = <0xae90000 0x200>,
|
||||||
|
<0xae90200 0x200>,
|
||||||
|
<0xae90400 0xc00>,
|
||||||
|
<0xae91000 0x400>,
|
||||||
|
<0xae91400 0x400>;
|
||||||
interrupt-parent = <&mdss>;
|
interrupt-parent = <&mdss>;
|
||||||
interrupts = <12>;
|
interrupts = <12>;
|
||||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||||
|
232
Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
Normal file
232
Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/display/msm/dpu-sc7280.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Qualcomm Display DPU dt properties for SC7280
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Krishna Manikandan <mkrishn@codeaurora.org>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Device tree bindings for MSM Mobile Display Subsystem (MDSS) that encapsulates
|
||||||
|
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||||
|
bindings of MDSS and DPU are mentioned for SC7280.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: qcom,sc7280-mdss
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
reg-names:
|
||||||
|
const: mdss
|
||||||
|
|
||||||
|
power-domains:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
items:
|
||||||
|
- description: Display AHB clock from gcc
|
||||||
|
- description: Display AHB clock from dispcc
|
||||||
|
- description: Display core clock
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: iface
|
||||||
|
- const: ahb
|
||||||
|
- const: core
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interrupt-controller: true
|
||||||
|
|
||||||
|
"#address-cells": true
|
||||||
|
|
||||||
|
"#size-cells": true
|
||||||
|
|
||||||
|
"#interrupt-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
iommus:
|
||||||
|
items:
|
||||||
|
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
|
||||||
|
|
||||||
|
ranges: true
|
||||||
|
|
||||||
|
interconnects:
|
||||||
|
items:
|
||||||
|
- description: Interconnect path specifying the port ids for data bus
|
||||||
|
|
||||||
|
interconnect-names:
|
||||||
|
const: mdp0-mem
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
"^display-controller@[0-9a-f]+$":
|
||||||
|
type: object
|
||||||
|
description: Node containing the properties of DPU.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: qcom,sc7280-dpu
|
||||||
|
|
||||||
|
reg:
|
||||||
|
items:
|
||||||
|
- description: Address offset and size for mdp register set
|
||||||
|
- description: Address offset and size for vbif register set
|
||||||
|
|
||||||
|
reg-names:
|
||||||
|
items:
|
||||||
|
- const: mdp
|
||||||
|
- const: vbif
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
items:
|
||||||
|
- description: Display hf axi clock
|
||||||
|
- description: Display sf axi clock
|
||||||
|
- description: Display ahb clock
|
||||||
|
- description: Display lut clock
|
||||||
|
- description: Display core clock
|
||||||
|
- description: Display vsync clock
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: bus
|
||||||
|
- const: nrt_bus
|
||||||
|
- const: iface
|
||||||
|
- const: lut
|
||||||
|
- const: core
|
||||||
|
- const: vsync
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
power-domains:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
operating-points-v2: true
|
||||||
|
|
||||||
|
ports:
|
||||||
|
$ref: /schemas/graph.yaml#/properties/ports
|
||||||
|
description: |
|
||||||
|
Contains the list of output ports from DPU device. These ports
|
||||||
|
connect to interfaces that are external to the DPU hardware,
|
||||||
|
such as DSI, DP etc. Each output port contains an endpoint that
|
||||||
|
describes how it is connected to an external interface.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
port@0:
|
||||||
|
$ref: /schemas/graph.yaml#/properties/port
|
||||||
|
description: DPU_INTF1 (DSI)
|
||||||
|
|
||||||
|
port@1:
|
||||||
|
$ref: /schemas/graph.yaml#/properties/port
|
||||||
|
description: DPU_INTF5 (EDP)
|
||||||
|
|
||||||
|
required:
|
||||||
|
- port@0
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- reg-names
|
||||||
|
- clocks
|
||||||
|
- interrupts
|
||||||
|
- power-domains
|
||||||
|
- operating-points-v2
|
||||||
|
- ports
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- reg-names
|
||||||
|
- power-domains
|
||||||
|
- clocks
|
||||||
|
- interrupts
|
||||||
|
- interrupt-controller
|
||||||
|
- iommus
|
||||||
|
- ranges
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/qcom,dispcc-sc7280.h>
|
||||||
|
#include <dt-bindings/clock/qcom,gcc-sc7280.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
#include <dt-bindings/interconnect/qcom,sc7280.h>
|
||||||
|
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||||
|
|
||||||
|
display-subsystem@ae00000 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
compatible = "qcom,sc7280-mdss";
|
||||||
|
reg = <0xae00000 0x1000>;
|
||||||
|
reg-names = "mdss";
|
||||||
|
power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>;
|
||||||
|
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||||
|
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||||
|
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||||
|
clock-names = "iface",
|
||||||
|
"ahb",
|
||||||
|
"core";
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
|
||||||
|
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
|
||||||
|
interconnect-names = "mdp0-mem";
|
||||||
|
|
||||||
|
iommus = <&apps_smmu 0x900 0x402>;
|
||||||
|
ranges;
|
||||||
|
|
||||||
|
display-controller@ae01000 {
|
||||||
|
compatible = "qcom,sc7280-dpu";
|
||||||
|
reg = <0x0ae01000 0x8f000>,
|
||||||
|
<0x0aeb0000 0x2008>;
|
||||||
|
|
||||||
|
reg-names = "mdp", "vbif";
|
||||||
|
|
||||||
|
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||||
|
<&gcc GCC_DISP_SF_AXI_CLK>,
|
||||||
|
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||||
|
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||||
|
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||||
|
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||||
|
clock-names = "bus",
|
||||||
|
"nrt_bus",
|
||||||
|
"iface",
|
||||||
|
"lut",
|
||||||
|
"core",
|
||||||
|
"vsync";
|
||||||
|
|
||||||
|
interrupt-parent = <&mdss>;
|
||||||
|
interrupts = <0>;
|
||||||
|
power-domains = <&rpmhpd SC7280_CX>;
|
||||||
|
operating-points-v2 = <&mdp_opp_table>;
|
||||||
|
|
||||||
|
ports {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
port@0 {
|
||||||
|
reg = <0>;
|
||||||
|
dpu_intf1_out: endpoint {
|
||||||
|
remote-endpoint = <&dsi0_in>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
port@1 {
|
||||||
|
reg = <1>;
|
||||||
|
dpu_intf5_out: endpoint {
|
||||||
|
remote-endpoint = <&edp_in>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
...
|
@ -17,6 +17,7 @@ properties:
|
|||||||
enum:
|
enum:
|
||||||
- qcom,dsi-phy-14nm
|
- qcom,dsi-phy-14nm
|
||||||
- qcom,dsi-phy-14nm-660
|
- qcom,dsi-phy-14nm-660
|
||||||
|
- qcom,dsi-phy-14nm-8953
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
items:
|
items:
|
||||||
|
@ -1,157 +0,0 @@
|
|||||||
Qualcomm adreno/snapdragon GPU
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible: "qcom,adreno-XYZ.W", "qcom,adreno" or
|
|
||||||
"amd,imageon-XYZ.W", "amd,imageon"
|
|
||||||
for example: "qcom,adreno-306.0", "qcom,adreno"
|
|
||||||
Note that you need to list the less specific "qcom,adreno" (since this
|
|
||||||
is what the device is matched on), in addition to the more specific
|
|
||||||
with the chip-id.
|
|
||||||
If "amd,imageon" is used, there should be no top level msm device.
|
|
||||||
- reg: Physical base address and length of the controller's registers.
|
|
||||||
- interrupts: The interrupt signal from the gpu.
|
|
||||||
- clocks: device clocks (if applicable)
|
|
||||||
See ../clocks/clock-bindings.txt for details.
|
|
||||||
- clock-names: the following clocks are required by a3xx, a4xx and a5xx
|
|
||||||
cores:
|
|
||||||
* "core"
|
|
||||||
* "iface"
|
|
||||||
* "mem_iface"
|
|
||||||
For GMU attached devices the GPU clocks are not used and are not required. The
|
|
||||||
following devices should not list clocks:
|
|
||||||
- qcom,adreno-630.2
|
|
||||||
- iommus: optional phandle to an adreno iommu instance
|
|
||||||
- operating-points-v2: optional phandle to the OPP operating points
|
|
||||||
- interconnects: optional phandle to an interconnect provider. See
|
|
||||||
../interconnect/interconnect.txt for details. Some A3xx and all A4xx platforms
|
|
||||||
will have two paths; all others will have one path.
|
|
||||||
- interconnect-names: The names of the interconnect paths that correspond to the
|
|
||||||
interconnects property. Values must be gfx-mem and ocmem.
|
|
||||||
- qcom,gmu: For GMU attached devices a phandle to the GMU device that will
|
|
||||||
control the power for the GPU. Applicable targets:
|
|
||||||
- qcom,adreno-630.2
|
|
||||||
- zap-shader: For a5xx and a6xx devices this node contains a memory-region that
|
|
||||||
points to reserved memory to store the zap shader that can be used to help
|
|
||||||
bring the GPU out of secure mode.
|
|
||||||
- firmware-name: optional property of the 'zap-shader' node, listing the
|
|
||||||
relative path of the device specific zap firmware.
|
|
||||||
- sram: phandle to the On Chip Memory (OCMEM) that's present on some a3xx and
|
|
||||||
a4xx Snapdragon SoCs. See
|
|
||||||
Documentation/devicetree/bindings/sram/qcom,ocmem.yaml.
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
- #cooling-cells: The value must be 2. For details, please refer
|
|
||||||
Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml.
|
|
||||||
|
|
||||||
Example 3xx/4xx:
|
|
||||||
|
|
||||||
/ {
|
|
||||||
...
|
|
||||||
|
|
||||||
gpu: adreno@fdb00000 {
|
|
||||||
compatible = "qcom,adreno-330.2",
|
|
||||||
"qcom,adreno";
|
|
||||||
reg = <0xfdb00000 0x10000>;
|
|
||||||
reg-names = "kgsl_3d0_reg_memory";
|
|
||||||
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
interrupt-names = "kgsl_3d0_irq";
|
|
||||||
clock-names = "core",
|
|
||||||
"iface",
|
|
||||||
"mem_iface";
|
|
||||||
clocks = <&mmcc OXILI_GFX3D_CLK>,
|
|
||||||
<&mmcc OXILICX_AHB_CLK>,
|
|
||||||
<&mmcc OXILICX_AXI_CLK>;
|
|
||||||
sram = <&gpu_sram>;
|
|
||||||
power-domains = <&mmcc OXILICX_GDSC>;
|
|
||||||
operating-points-v2 = <&gpu_opp_table>;
|
|
||||||
iommus = <&gpu_iommu 0>;
|
|
||||||
#cooling-cells = <2>;
|
|
||||||
};
|
|
||||||
|
|
||||||
gpu_sram: ocmem@fdd00000 {
|
|
||||||
compatible = "qcom,msm8974-ocmem";
|
|
||||||
|
|
||||||
reg = <0xfdd00000 0x2000>,
|
|
||||||
<0xfec00000 0x180000>;
|
|
||||||
reg-names = "ctrl",
|
|
||||||
"mem";
|
|
||||||
|
|
||||||
clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
|
|
||||||
<&mmcc OCMEMCX_OCMEMNOC_CLK>;
|
|
||||||
clock-names = "core",
|
|
||||||
"iface";
|
|
||||||
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
|
|
||||||
gpu_sram: gpu-sram@0 {
|
|
||||||
reg = <0x0 0x100000>;
|
|
||||||
ranges = <0 0 0xfec00000 0x100000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Example a6xx (with GMU):
|
|
||||||
|
|
||||||
/ {
|
|
||||||
...
|
|
||||||
|
|
||||||
gpu@5000000 {
|
|
||||||
compatible = "qcom,adreno-630.2", "qcom,adreno";
|
|
||||||
#stream-id-cells = <16>;
|
|
||||||
|
|
||||||
reg = <0x5000000 0x40000>, <0x509e000 0x10>;
|
|
||||||
reg-names = "kgsl_3d0_reg_memory", "cx_mem";
|
|
||||||
|
|
||||||
#cooling-cells = <2>;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look ma, no clocks! The GPU clocks and power are
|
|
||||||
* controlled entirely by the GMU
|
|
||||||
*/
|
|
||||||
|
|
||||||
interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
|
|
||||||
iommus = <&adreno_smmu 0>;
|
|
||||||
|
|
||||||
operating-points-v2 = <&gpu_opp_table>;
|
|
||||||
|
|
||||||
interconnects = <&rsc_hlos MASTER_GFX3D &rsc_hlos SLAVE_EBI1>;
|
|
||||||
interconnect-names = "gfx-mem";
|
|
||||||
|
|
||||||
gpu_opp_table: opp-table {
|
|
||||||
compatible = "operating-points-v2";
|
|
||||||
|
|
||||||
opp-430000000 {
|
|
||||||
opp-hz = /bits/ 64 <430000000>;
|
|
||||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
|
|
||||||
opp-peak-kBps = <5412000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
opp-355000000 {
|
|
||||||
opp-hz = /bits/ 64 <355000000>;
|
|
||||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
|
|
||||||
opp-peak-kBps = <3072000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
opp-267000000 {
|
|
||||||
opp-hz = /bits/ 64 <267000000>;
|
|
||||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
|
|
||||||
opp-peak-kBps = <3072000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
opp-180000000 {
|
|
||||||
opp-hz = /bits/ 64 <180000000>;
|
|
||||||
opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
|
|
||||||
opp-peak-kBps = <1804000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
qcom,gmu = <&gmu>;
|
|
||||||
|
|
||||||
zap-shader {
|
|
||||||
memory-region = <&zap_shader_region>;
|
|
||||||
firmware-name = "qcom/LENOVO/81JL/qcdxkmsuc850.mbn"
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
288
Documentation/devicetree/bindings/display/msm/gpu.yaml
Normal file
288
Documentation/devicetree/bindings/display/msm/gpu.yaml
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
|
||||||
|
$id: "http://devicetree.org/schemas/display/msm/gpu.yaml#"
|
||||||
|
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||||
|
|
||||||
|
title: Devicetree bindings for the Adreno or Snapdragon GPUs
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Rob Clark <robdclark@gmail.com>
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
oneOf:
|
||||||
|
- description: |
|
||||||
|
The driver is parsing the compat string for Adreno to
|
||||||
|
figure out the gpu-id and patch level.
|
||||||
|
items:
|
||||||
|
- pattern: '^qcom,adreno-[3-6][0-9][0-9]\.[0-9]$'
|
||||||
|
- const: qcom,adreno
|
||||||
|
- description: |
|
||||||
|
The driver is parsing the compat string for Imageon to
|
||||||
|
figure out the gpu-id and patch level.
|
||||||
|
items:
|
||||||
|
- pattern: '^amd,imageon-200\.[0-1]$'
|
||||||
|
- const: amd,imageon
|
||||||
|
|
||||||
|
clocks: true
|
||||||
|
|
||||||
|
clock-names: true
|
||||||
|
|
||||||
|
reg:
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 3
|
||||||
|
|
||||||
|
reg-names:
|
||||||
|
minItems: 1
|
||||||
|
items:
|
||||||
|
- const: kgsl_3d0_reg_memory
|
||||||
|
- const: cx_mem
|
||||||
|
- const: cx_dbgc
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interrupt-names:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interconnects:
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 2
|
||||||
|
|
||||||
|
interconnect-names:
|
||||||
|
minItems: 1
|
||||||
|
items:
|
||||||
|
- const: gfx-mem
|
||||||
|
- const: ocmem
|
||||||
|
|
||||||
|
iommus:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
sram:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 4
|
||||||
|
description: |
|
||||||
|
phandles to one or more reserved on-chip SRAM regions.
|
||||||
|
phandle to the On Chip Memory (OCMEM) that's present on some a3xx and
|
||||||
|
a4xx Snapdragon SoCs. See
|
||||||
|
Documentation/devicetree/bindings/sram/qcom,ocmem.yaml
|
||||||
|
|
||||||
|
operating-points-v2: true
|
||||||
|
opp-table:
|
||||||
|
type: object
|
||||||
|
|
||||||
|
power-domains:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
zap-shader:
|
||||||
|
type: object
|
||||||
|
description: |
|
||||||
|
For a5xx and a6xx devices this node contains a memory-region that
|
||||||
|
points to reserved memory to store the zap shader that can be used to
|
||||||
|
help bring the GPU out of secure mode.
|
||||||
|
properties:
|
||||||
|
memory-region:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
|
||||||
|
firmware-name:
|
||||||
|
description: |
|
||||||
|
Default name of the firmware to load to the remote processor.
|
||||||
|
|
||||||
|
"#cooling-cells":
|
||||||
|
const: 2
|
||||||
|
|
||||||
|
nvmem-cell-names:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
nvmem-cells:
|
||||||
|
description: efuse registers
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
qcom,gmu:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description: |
|
||||||
|
For GMU attached devices a phandle to the GMU device that will
|
||||||
|
control the power for the GPU.
|
||||||
|
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- interrupts
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
contains:
|
||||||
|
pattern: '^qcom,adreno-[3-5][0-9][0-9]\.[0-9]$'
|
||||||
|
|
||||||
|
then:
|
||||||
|
properties:
|
||||||
|
clocks:
|
||||||
|
minItems: 2
|
||||||
|
maxItems: 7
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
anyOf:
|
||||||
|
- const: core
|
||||||
|
description: GPU Core clock
|
||||||
|
- const: iface
|
||||||
|
description: GPU Interface clock
|
||||||
|
- const: mem
|
||||||
|
description: GPU Memory clock
|
||||||
|
- const: mem_iface
|
||||||
|
description: GPU Memory Interface clock
|
||||||
|
- const: alt_mem_iface
|
||||||
|
description: GPU Alternative Memory Interface clock
|
||||||
|
- const: gfx3d
|
||||||
|
description: GPU 3D engine clock
|
||||||
|
- const: rbbmtimer
|
||||||
|
description: GPU RBBM Timer for Adreno 5xx series
|
||||||
|
minItems: 2
|
||||||
|
maxItems: 7
|
||||||
|
|
||||||
|
required:
|
||||||
|
- clocks
|
||||||
|
- clock-names
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
contains:
|
||||||
|
pattern: '^qcom,adreno-6[0-9][0-9]\.[0-9]$'
|
||||||
|
|
||||||
|
then: # Since Adreno 6xx series clocks should be defined in GMU
|
||||||
|
properties:
|
||||||
|
clocks: false
|
||||||
|
clock-names: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
|
||||||
|
// Example a3xx/4xx:
|
||||||
|
|
||||||
|
#include <dt-bindings/clock/qcom,mmcc-msm8974.h>
|
||||||
|
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
|
||||||
|
gpu: gpu@fdb00000 {
|
||||||
|
compatible = "qcom,adreno-330.2", "qcom,adreno";
|
||||||
|
|
||||||
|
reg = <0xfdb00000 0x10000>;
|
||||||
|
reg-names = "kgsl_3d0_reg_memory";
|
||||||
|
|
||||||
|
clock-names = "core", "iface", "mem_iface";
|
||||||
|
clocks = <&mmcc OXILI_GFX3D_CLK>,
|
||||||
|
<&mmcc OXILICX_AHB_CLK>,
|
||||||
|
<&mmcc OXILICX_AXI_CLK>;
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-names = "kgsl_3d0_irq";
|
||||||
|
|
||||||
|
sram = <&gpu_sram>;
|
||||||
|
power-domains = <&mmcc OXILICX_GDSC>;
|
||||||
|
operating-points-v2 = <&gpu_opp_table>;
|
||||||
|
iommus = <&gpu_iommu 0>;
|
||||||
|
#cooling-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
ocmem@fdd00000 {
|
||||||
|
compatible = "qcom,msm8974-ocmem";
|
||||||
|
|
||||||
|
reg = <0xfdd00000 0x2000>,
|
||||||
|
<0xfec00000 0x180000>;
|
||||||
|
reg-names = "ctrl", "mem";
|
||||||
|
|
||||||
|
clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
|
||||||
|
<&mmcc OCMEMCX_OCMEMNOC_CLK>;
|
||||||
|
clock-names = "core", "iface";
|
||||||
|
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges = <0 0xfec00000 0x100000>;
|
||||||
|
|
||||||
|
gpu_sram: gpu-sram@0 {
|
||||||
|
reg = <0x0 0x100000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
- |
|
||||||
|
|
||||||
|
// Example a6xx (with GMU):
|
||||||
|
|
||||||
|
#include <dt-bindings/clock/qcom,gpucc-sdm845.h>
|
||||||
|
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
|
||||||
|
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
#include <dt-bindings/interconnect/qcom,sdm845.h>
|
||||||
|
|
||||||
|
reserved-memory {
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
|
||||||
|
zap_shader_region: gpu@8f200000 {
|
||||||
|
compatible = "shared-dma-pool";
|
||||||
|
reg = <0x0 0x90b00000 0x0 0xa00000>;
|
||||||
|
no-map;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gpu@5000000 {
|
||||||
|
compatible = "qcom,adreno-630.2", "qcom,adreno";
|
||||||
|
|
||||||
|
reg = <0x5000000 0x40000>, <0x509e000 0x10>;
|
||||||
|
reg-names = "kgsl_3d0_reg_memory", "cx_mem";
|
||||||
|
|
||||||
|
#cooling-cells = <2>;
|
||||||
|
|
||||||
|
interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
|
||||||
|
iommus = <&adreno_smmu 0>;
|
||||||
|
|
||||||
|
operating-points-v2 = <&gpu_opp_table>;
|
||||||
|
|
||||||
|
interconnects = <&rsc_hlos MASTER_GFX3D &rsc_hlos SLAVE_EBI1>;
|
||||||
|
interconnect-names = "gfx-mem";
|
||||||
|
|
||||||
|
qcom,gmu = <&gmu>;
|
||||||
|
|
||||||
|
gpu_opp_table: opp-table {
|
||||||
|
compatible = "operating-points-v2";
|
||||||
|
|
||||||
|
opp-430000000 {
|
||||||
|
opp-hz = /bits/ 64 <430000000>;
|
||||||
|
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
|
||||||
|
opp-peak-kBps = <5412000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-355000000 {
|
||||||
|
opp-hz = /bits/ 64 <355000000>;
|
||||||
|
opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
|
||||||
|
opp-peak-kBps = <3072000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-267000000 {
|
||||||
|
opp-hz = /bits/ 64 <267000000>;
|
||||||
|
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
|
||||||
|
opp-peak-kBps = <3072000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
opp-180000000 {
|
||||||
|
opp-hz = /bits/ 64 <180000000>;
|
||||||
|
opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
|
||||||
|
opp-peak-kBps = <1804000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
zap-shader {
|
||||||
|
memory-region = <&zap_shader_region>;
|
||||||
|
firmware-name = "qcom/LENOVO/81JL/qcdxkmsuc850.mbn";
|
||||||
|
};
|
||||||
|
};
|
@ -26,6 +26,10 @@ properties:
|
|||||||
- auo,b101uan08.3
|
- auo,b101uan08.3
|
||||||
# BOE TV105WUM-NW0 10.5" WUXGA TFT LCD panel
|
# BOE TV105WUM-NW0 10.5" WUXGA TFT LCD panel
|
||||||
- boe,tv105wum-nw0
|
- boe,tv105wum-nw0
|
||||||
|
# BOE TV110C9M-LL3 10.95" WUXGA TFT LCD panel
|
||||||
|
- boe,tv110c9m-ll3
|
||||||
|
# INX HJ110IZ-01A 10.95" WUXGA TFT LCD panel
|
||||||
|
- innolux,hj110iz-01a
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
description: the virtual channel number of a DSI peripheral
|
description: the virtual channel number of a DSI peripheral
|
||||||
@ -36,6 +40,9 @@ properties:
|
|||||||
pp1800-supply:
|
pp1800-supply:
|
||||||
description: core voltage supply
|
description: core voltage supply
|
||||||
|
|
||||||
|
pp3300-supply:
|
||||||
|
description: core voltage supply
|
||||||
|
|
||||||
avdd-supply:
|
avdd-supply:
|
||||||
description: phandle of the regulator that provides positive voltage
|
description: phandle of the regulator that provides positive voltage
|
||||||
|
|
||||||
|
188
Documentation/devicetree/bindings/display/panel/panel-edp.yaml
Normal file
188
Documentation/devicetree/bindings/display/panel/panel-edp.yaml
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/display/panel/panel-edp.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Probeable (via DP AUX / EDID) eDP Panels with simple poweron sequences
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Douglas Anderson <dianders@chromium.org>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
This binding file can be used to indicate that an eDP panel is connected
|
||||||
|
to a Embedded DisplayPort AUX bus (see display/dp-aux-bus.yaml) without
|
||||||
|
actually specifying exactly what panel is connected. This is useful for
|
||||||
|
the case that more than one different panel could be connected to the
|
||||||
|
board, either for second-sourcing purposes or to support multiple SKUs
|
||||||
|
with different LCDs that hook up to a common board.
|
||||||
|
|
||||||
|
As per above, a requirement for using this binding is that the panel is
|
||||||
|
represented under the DP AUX bus. This means that we can use any
|
||||||
|
information provided by the DP AUX bus (including the EDID) to identify
|
||||||
|
the panel. We can use this to identify display size, resolution, and
|
||||||
|
timings among other things.
|
||||||
|
|
||||||
|
One piece of information about eDP panels that is typically _not_
|
||||||
|
provided anywhere on the DP AUX bus is the power sequencing timings.
|
||||||
|
This is the reason why, historically, we've always had to explicitly
|
||||||
|
list eDP panels. We solve that here with two tricks. The "worst case"
|
||||||
|
power on timings for any panels expected to be connected to a board are
|
||||||
|
specified in these bindings. Once we've powered on, it's expected that
|
||||||
|
the operating system will lookup the panel in a table (based on EDID
|
||||||
|
information) to figure out other power sequencing timings.
|
||||||
|
|
||||||
|
eDP panels in general can have somewhat arbitrary power sequencing
|
||||||
|
requirements. However, even though it's arbitrary in general, the
|
||||||
|
vast majority of panel datasheets have a power sequence diagram that
|
||||||
|
looks the exactly the same as every other panel. Each panel datasheet
|
||||||
|
cares about different timings in this diagram but the fact that the
|
||||||
|
diagram is so similar means we can come up with a single driver to
|
||||||
|
handle it.
|
||||||
|
|
||||||
|
These diagrams all look roughly like this, sometimes labeled with
|
||||||
|
slightly different numbers / lines but all pretty much the same
|
||||||
|
sequence. This is because much of this diagram comes straight from
|
||||||
|
the eDP Standard.
|
||||||
|
|
||||||
|
__________________________________________________
|
||||||
|
Vdd ___/: :\____ /
|
||||||
|
_/ : : \_____/
|
||||||
|
:<T1>:<T2>: :<--T10-->:<T11>:<T12>:
|
||||||
|
: +-----------------------+---------+---------+
|
||||||
|
eDP -----------+ Black video | Src vid | Blk vid +
|
||||||
|
Display : +-----------------------+---------+---------+
|
||||||
|
: _______________________:_________:_________:
|
||||||
|
HPD :<T3>| : : |
|
||||||
|
___________| : : |_____________
|
||||||
|
: : : :
|
||||||
|
Sink +-----------------------:---------:---------+
|
||||||
|
AUX CH -----------+ AUX Ch operational : : +-------------
|
||||||
|
+-----------------------:---------:---------+
|
||||||
|
: : : :
|
||||||
|
:<T4>: :<T7>: : :
|
||||||
|
Src main +------+------+--------------+---------+
|
||||||
|
lnk data----------------+LnkTrn| Idle |Valid vid data| Idle/off+-------------
|
||||||
|
+------+------+--------------+---------+
|
||||||
|
: <T5> :<-T6->:<-T8->: :
|
||||||
|
:__:<T9>:
|
||||||
|
LED_EN | |
|
||||||
|
_____________________________________| |____________________________
|
||||||
|
: :
|
||||||
|
__________:__:_
|
||||||
|
PWM | : : |
|
||||||
|
__________________________| : : |__________________________
|
||||||
|
: : : :
|
||||||
|
_____________:__________:__:_:______
|
||||||
|
Bklight ____/: : : : : :\____
|
||||||
|
power _______/ :<---T13---->: : : :<T16>: \______________
|
||||||
|
(Vbl) :<T17>:<---------T14--------->: :<-T15->:<T18>:
|
||||||
|
|
||||||
|
The above looks fairly complex but, as per above, each panel only cares
|
||||||
|
about a subset of those timings.
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: panel-common.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: edp-panel
|
||||||
|
|
||||||
|
hpd-reliable-delay-ms:
|
||||||
|
description:
|
||||||
|
A fixed amount of time that must be waited after powering on the
|
||||||
|
panel's power-supply before the HPD signal is a reliable way to know
|
||||||
|
when the AUX channel is ready. This is useful for panels that glitch
|
||||||
|
the HPD at the start of power-on. This value is not needed if HPD is
|
||||||
|
always reliable for all panels that might be connected.
|
||||||
|
|
||||||
|
hpd-absent-delay-ms:
|
||||||
|
description:
|
||||||
|
The panel specifies that HPD will be asserted this many milliseconds
|
||||||
|
from power on (timing T3 in the diagram above). If we have no way to
|
||||||
|
measure HPD then a fixed delay of this many milliseconds can be used.
|
||||||
|
This can also be used as a timeout when waiting for HPD. Does not
|
||||||
|
include the hpd-reliable-delay, so if hpd-reliable-delay was 80 ms
|
||||||
|
and hpd-absent-delay was 200 ms then we'd do a fixed 80 ms delay and
|
||||||
|
then we know HPD would assert in the next 120 ms. This value is not
|
||||||
|
needed if HPD hooked up, either through a GPIO in the panel node or
|
||||||
|
hooked up directly to the eDP controller.
|
||||||
|
|
||||||
|
backlight: true
|
||||||
|
enable-gpios: true
|
||||||
|
port: true
|
||||||
|
power-supply: true
|
||||||
|
no-hpd: true
|
||||||
|
hpd-gpios: true
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- power-supply
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
|
||||||
|
i2c {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
bridge@2d {
|
||||||
|
compatible = "ti,sn65dsi86";
|
||||||
|
reg = <0x2d>;
|
||||||
|
|
||||||
|
interrupt-parent = <&tlmm>;
|
||||||
|
interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
|
||||||
|
enable-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>;
|
||||||
|
|
||||||
|
vpll-supply = <&src_pp1800_s4a>;
|
||||||
|
vccio-supply = <&src_pp1800_s4a>;
|
||||||
|
vcca-supply = <&src_pp1200_l2a>;
|
||||||
|
vcc-supply = <&src_pp1200_l2a>;
|
||||||
|
|
||||||
|
clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
|
||||||
|
clock-names = "refclk";
|
||||||
|
|
||||||
|
no-hpd;
|
||||||
|
|
||||||
|
ports {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
port@0 {
|
||||||
|
reg = <0>;
|
||||||
|
endpoint {
|
||||||
|
remote-endpoint = <&dsi0_out>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
port@1 {
|
||||||
|
reg = <1>;
|
||||||
|
sn65dsi86_out: endpoint {
|
||||||
|
remote-endpoint = <&panel_in_edp>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
aux-bus {
|
||||||
|
panel {
|
||||||
|
compatible = "edp-panel";
|
||||||
|
power-supply = <&pp3300_dx_edp>;
|
||||||
|
backlight = <&backlight>;
|
||||||
|
hpd-gpios = <&sn65dsi86_bridge 2 GPIO_ACTIVE_HIGH>;
|
||||||
|
hpd-reliable-delay-ms = <15>;
|
||||||
|
|
||||||
|
port {
|
||||||
|
panel_in_edp: endpoint {
|
||||||
|
remote-endpoint = <&sn65dsi86_out>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,98 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/display/panel/samsung,s6d27a1.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Samsung S6D27A1 display panel
|
||||||
|
|
||||||
|
description: The S6D27A1 is a 480x800 DPI display panel from Samsung Mobile
|
||||||
|
Displays (SMD). The panel must obey the rules for a SPI slave device
|
||||||
|
as specified in spi/spi-controller.yaml
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Markuss Broks <markuss.broks@gmail.com>
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: panel-common.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: samsung,s6d27a1
|
||||||
|
|
||||||
|
reg: true
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
description: provides an optional ESD (electrostatic discharge)
|
||||||
|
interrupt that signals abnormalities in the display hardware.
|
||||||
|
This can also be raised for other reasons like erroneous
|
||||||
|
configuration.
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
reset-gpios: true
|
||||||
|
|
||||||
|
vci-supply:
|
||||||
|
description: regulator that supplies the VCI analog voltage
|
||||||
|
usually around 3.0 V
|
||||||
|
|
||||||
|
vccio-supply:
|
||||||
|
description: regulator that supplies the VCCIO voltage usually
|
||||||
|
around 1.8 V
|
||||||
|
|
||||||
|
backlight: true
|
||||||
|
|
||||||
|
spi-cpha: true
|
||||||
|
|
||||||
|
spi-cpol: true
|
||||||
|
|
||||||
|
spi-max-frequency:
|
||||||
|
maximum: 1200000
|
||||||
|
|
||||||
|
port: true
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- vci-supply
|
||||||
|
- vccio-supply
|
||||||
|
- spi-cpha
|
||||||
|
- spi-cpol
|
||||||
|
- port
|
||||||
|
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
|
||||||
|
spi {
|
||||||
|
compatible = "spi-gpio";
|
||||||
|
sck-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
|
||||||
|
miso-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
|
||||||
|
mosi-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
|
||||||
|
cs-gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
|
||||||
|
num-chipselects = <1>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
panel@0 {
|
||||||
|
compatible = "samsung,s6d27a1";
|
||||||
|
spi-max-frequency = <1200000>;
|
||||||
|
spi-cpha;
|
||||||
|
spi-cpol;
|
||||||
|
reg = <0>;
|
||||||
|
vci-supply = <&lcd_3v0_reg>;
|
||||||
|
vccio-supply = <&lcd_1v8_reg>;
|
||||||
|
reset-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
|
||||||
|
interrupt-parent = <&gpio>;
|
||||||
|
interrupts = <5 IRQ_TYPE_EDGE_RISING>;
|
||||||
|
|
||||||
|
port {
|
||||||
|
panel_in: endpoint {
|
||||||
|
remote-endpoint = <&display_out>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
...
|
@ -39,6 +39,7 @@ properties:
|
|||||||
- renesas,du-r8a77980 # for R-Car V3H compatible DU
|
- renesas,du-r8a77980 # for R-Car V3H compatible DU
|
||||||
- renesas,du-r8a77990 # for R-Car E3 compatible DU
|
- renesas,du-r8a77990 # for R-Car E3 compatible DU
|
||||||
- renesas,du-r8a77995 # for R-Car D3 compatible DU
|
- renesas,du-r8a77995 # for R-Car D3 compatible DU
|
||||||
|
- renesas,du-r8a779a0 # for R-Car V3U compatible DU
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
@ -773,6 +774,56 @@ allOf:
|
|||||||
- reset-names
|
- reset-names
|
||||||
- renesas,vsps
|
- renesas,vsps
|
||||||
|
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
contains:
|
||||||
|
enum:
|
||||||
|
- renesas,du-r8a779a0
|
||||||
|
then:
|
||||||
|
properties:
|
||||||
|
clocks:
|
||||||
|
items:
|
||||||
|
- description: Functional clock
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
maxItems: 1
|
||||||
|
items:
|
||||||
|
- const: du.0
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 2
|
||||||
|
|
||||||
|
resets:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
reset-names:
|
||||||
|
items:
|
||||||
|
- const: du.0
|
||||||
|
|
||||||
|
ports:
|
||||||
|
properties:
|
||||||
|
port@0:
|
||||||
|
description: DSI 0
|
||||||
|
port@1:
|
||||||
|
description: DSI 1
|
||||||
|
port@2: false
|
||||||
|
port@3: false
|
||||||
|
|
||||||
|
required:
|
||||||
|
- port@0
|
||||||
|
- port@1
|
||||||
|
|
||||||
|
renesas,vsps:
|
||||||
|
minItems: 2
|
||||||
|
|
||||||
|
required:
|
||||||
|
- clock-names
|
||||||
|
- interrupts
|
||||||
|
- resets
|
||||||
|
- reset-names
|
||||||
|
- renesas,vsps
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
|
@ -176,12 +176,6 @@ DMA Fences Functions Reference
|
|||||||
.. kernel-doc:: include/linux/dma-fence.h
|
.. kernel-doc:: include/linux/dma-fence.h
|
||||||
:internal:
|
:internal:
|
||||||
|
|
||||||
Seqno Hardware Fences
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. kernel-doc:: include/linux/seqno-fence.h
|
|
||||||
:internal:
|
|
||||||
|
|
||||||
DMA Fence Array
|
DMA Fence Array
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -151,6 +151,18 @@ Overview
|
|||||||
.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
|
.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
|
||||||
:doc: overview
|
:doc: overview
|
||||||
|
|
||||||
|
Display Driver Integration
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
|
||||||
|
:doc: display driver integration
|
||||||
|
|
||||||
|
Special Care with MIPI-DSI bridges
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
|
||||||
|
:doc: special care dsi
|
||||||
|
|
||||||
Bridge Operations
|
Bridge Operations
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
@ -28,56 +28,53 @@ UMA devices.
|
|||||||
The Translation Table Manager (TTM)
|
The Translation Table Manager (TTM)
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
TTM design background and information belongs here.
|
.. kernel-doc:: drivers/gpu/drm/ttm/ttm_module.c
|
||||||
|
:doc: TTM
|
||||||
|
|
||||||
TTM initialization
|
.. kernel-doc:: include/drm/ttm/ttm_caching.h
|
||||||
------------------
|
:internal:
|
||||||
|
|
||||||
**Warning**
|
TTM device object reference
|
||||||
This section is outdated.
|
---------------------------
|
||||||
|
|
||||||
Drivers wishing to support TTM must pass a filled :c:type:`ttm_bo_driver
|
.. kernel-doc:: include/drm/ttm/ttm_device.h
|
||||||
<ttm_bo_driver>` structure to ttm_device_init, together with an
|
:internal:
|
||||||
initialized global reference to the memory manager. The ttm_bo_driver
|
|
||||||
structure contains several fields with function pointers for
|
|
||||||
initializing the TTM, allocating and freeing memory, waiting for command
|
|
||||||
completion and fence synchronization, and memory migration.
|
|
||||||
|
|
||||||
The :c:type:`struct drm_global_reference <drm_global_reference>` is made
|
.. kernel-doc:: drivers/gpu/drm/ttm/ttm_device.c
|
||||||
up of several fields:
|
:export:
|
||||||
|
|
||||||
.. code-block:: c
|
TTM resource placement reference
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
struct drm_global_reference {
|
.. kernel-doc:: include/drm/ttm/ttm_placement.h
|
||||||
enum ttm_global_types global_type;
|
:internal:
|
||||||
size_t size;
|
|
||||||
void *object;
|
|
||||||
int (*init) (struct drm_global_reference *);
|
|
||||||
void (*release) (struct drm_global_reference *);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
TTM resource object reference
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
There should be one global reference structure for your memory manager
|
.. kernel-doc:: include/drm/ttm/ttm_resource.h
|
||||||
as a whole, and there will be others for each object created by the
|
:internal:
|
||||||
memory manager at runtime. Your global TTM should have a type of
|
|
||||||
TTM_GLOBAL_TTM_MEM. The size field for the global object should be
|
|
||||||
sizeof(struct ttm_mem_global), and the init and release hooks should
|
|
||||||
point at your driver-specific init and release routines, which probably
|
|
||||||
eventually call ttm_mem_global_init and ttm_mem_global_release,
|
|
||||||
respectively.
|
|
||||||
|
|
||||||
Once your global TTM accounting structure is set up and initialized by
|
.. kernel-doc:: drivers/gpu/drm/ttm/ttm_resource.c
|
||||||
calling ttm_global_item_ref() on it, you need to create a buffer
|
:export:
|
||||||
object TTM to provide a pool for buffer object allocation by clients and
|
|
||||||
the kernel itself. The type of this object should be
|
|
||||||
TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct
|
|
||||||
ttm_bo_global). Again, driver-specific init and release functions may
|
|
||||||
be provided, likely eventually calling ttm_bo_global_ref_init() and
|
|
||||||
ttm_bo_global_ref_release(), respectively. Also, like the previous
|
|
||||||
object, ttm_global_item_ref() is used to create an initial reference
|
|
||||||
count for the TTM, which will call your initialization function.
|
|
||||||
|
|
||||||
See the radeon_ttm.c file for an example of usage.
|
TTM TT object reference
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. kernel-doc:: include/drm/ttm/ttm_tt.h
|
||||||
|
:internal:
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/ttm/ttm_tt.c
|
||||||
|
:export:
|
||||||
|
|
||||||
|
TTM page pool reference
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. kernel-doc:: include/drm/ttm/ttm_pool.h
|
||||||
|
:internal:
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/ttm/ttm_pool.c
|
||||||
|
:export:
|
||||||
|
|
||||||
The Graphics Execution Manager (GEM)
|
The Graphics Execution Manager (GEM)
|
||||||
====================================
|
====================================
|
||||||
@ -504,3 +501,6 @@ Scheduler Function References
|
|||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/scheduler/sched_main.c
|
.. kernel-doc:: drivers/gpu/drm/scheduler/sched_main.c
|
||||||
:export:
|
:export:
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/scheduler/sched_entity.c
|
||||||
|
:export:
|
||||||
|
@ -183,26 +183,23 @@ Frame Buffer Compression (FBC)
|
|||||||
Display Refresh Rate Switching (DRRS)
|
Display Refresh Rate Switching (DRRS)
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
|
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
|
||||||
:doc: Display Refresh Rate Switching (DRRS)
|
:doc: Display Refresh Rate Switching (DRRS)
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
|
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
|
||||||
:functions: intel_dp_set_drrs_state
|
:functions: intel_drrs_enable
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
|
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
|
||||||
:functions: intel_edp_drrs_enable
|
:functions: intel_drrs_disable
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
|
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
|
||||||
:functions: intel_edp_drrs_disable
|
:functions: intel_drrs_invalidate
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
|
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
|
||||||
:functions: intel_edp_drrs_invalidate
|
:functions: intel_drrs_flush
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
|
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_drrs.c
|
||||||
:functions: intel_edp_drrs_flush
|
:functions: intel_drrs_init
|
||||||
|
|
||||||
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dp.c
|
|
||||||
:functions: intel_dp_drrs_init
|
|
||||||
|
|
||||||
DPIO
|
DPIO
|
||||||
----
|
----
|
||||||
@ -474,6 +471,14 @@ Object Tiling IOCTLs
|
|||||||
.. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_tiling.c
|
.. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_tiling.c
|
||||||
:doc: buffer object tiling
|
:doc: buffer object tiling
|
||||||
|
|
||||||
|
Protected Objects
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/i915/pxp/intel_pxp.c
|
||||||
|
:doc: PXP
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/i915/pxp/intel_pxp_types.h
|
||||||
|
|
||||||
Microcontrollers
|
Microcontrollers
|
||||||
================
|
================
|
||||||
|
|
||||||
@ -498,6 +503,8 @@ GuC
|
|||||||
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c
|
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c
|
||||||
:doc: GuC
|
:doc: GuC
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.h
|
||||||
|
|
||||||
GuC Firmware Layout
|
GuC Firmware Layout
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -1,122 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: MIT */
|
|
||||||
/*
|
|
||||||
* Copyright © 2021 Intel Corporation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define I915_CONTEXT_ENGINES_EXT_PARALLEL_SUBMIT 2 /* see i915_context_engines_parallel_submit */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct drm_i915_context_engines_parallel_submit - Configure engine for
|
|
||||||
* parallel submission.
|
|
||||||
*
|
|
||||||
* Setup a slot in the context engine map to allow multiple BBs to be submitted
|
|
||||||
* in a single execbuf IOCTL. Those BBs will then be scheduled to run on the GPU
|
|
||||||
* in parallel. Multiple hardware contexts are created internally in the i915
|
|
||||||
* run these BBs. Once a slot is configured for N BBs only N BBs can be
|
|
||||||
* submitted in each execbuf IOCTL and this is implicit behavior e.g. The user
|
|
||||||
* doesn't tell the execbuf IOCTL there are N BBs, the execbuf IOCTL knows how
|
|
||||||
* many BBs there are based on the slot's configuration. The N BBs are the last
|
|
||||||
* N buffer objects or first N if I915_EXEC_BATCH_FIRST is set.
|
|
||||||
*
|
|
||||||
* The default placement behavior is to create implicit bonds between each
|
|
||||||
* context if each context maps to more than 1 physical engine (e.g. context is
|
|
||||||
* a virtual engine). Also we only allow contexts of same engine class and these
|
|
||||||
* contexts must be in logically contiguous order. Examples of the placement
|
|
||||||
* behavior described below. Lastly, the default is to not allow BBs to
|
|
||||||
* preempted mid BB rather insert coordinated preemption on all hardware
|
|
||||||
* contexts between each set of BBs. Flags may be added in the future to change
|
|
||||||
* both of these default behaviors.
|
|
||||||
*
|
|
||||||
* Returns -EINVAL if hardware context placement configuration is invalid or if
|
|
||||||
* the placement configuration isn't supported on the platform / submission
|
|
||||||
* interface.
|
|
||||||
* Returns -ENODEV if extension isn't supported on the platform / submission
|
|
||||||
* interface.
|
|
||||||
*
|
|
||||||
* .. code-block:: none
|
|
||||||
*
|
|
||||||
* Example 1 pseudo code:
|
|
||||||
* CS[X] = generic engine of same class, logical instance X
|
|
||||||
* INVALID = I915_ENGINE_CLASS_INVALID, I915_ENGINE_CLASS_INVALID_NONE
|
|
||||||
* set_engines(INVALID)
|
|
||||||
* set_parallel(engine_index=0, width=2, num_siblings=1,
|
|
||||||
* engines=CS[0],CS[1])
|
|
||||||
*
|
|
||||||
* Results in the following valid placement:
|
|
||||||
* CS[0], CS[1]
|
|
||||||
*
|
|
||||||
* Example 2 pseudo code:
|
|
||||||
* CS[X] = generic engine of same class, logical instance X
|
|
||||||
* INVALID = I915_ENGINE_CLASS_INVALID, I915_ENGINE_CLASS_INVALID_NONE
|
|
||||||
* set_engines(INVALID)
|
|
||||||
* set_parallel(engine_index=0, width=2, num_siblings=2,
|
|
||||||
* engines=CS[0],CS[2],CS[1],CS[3])
|
|
||||||
*
|
|
||||||
* Results in the following valid placements:
|
|
||||||
* CS[0], CS[1]
|
|
||||||
* CS[2], CS[3]
|
|
||||||
*
|
|
||||||
* This can also be thought of as 2 virtual engines described by 2-D array
|
|
||||||
* in the engines the field with bonds placed between each index of the
|
|
||||||
* virtual engines. e.g. CS[0] is bonded to CS[1], CS[2] is bonded to
|
|
||||||
* CS[3].
|
|
||||||
* VE[0] = CS[0], CS[2]
|
|
||||||
* VE[1] = CS[1], CS[3]
|
|
||||||
*
|
|
||||||
* Example 3 pseudo code:
|
|
||||||
* CS[X] = generic engine of same class, logical instance X
|
|
||||||
* INVALID = I915_ENGINE_CLASS_INVALID, I915_ENGINE_CLASS_INVALID_NONE
|
|
||||||
* set_engines(INVALID)
|
|
||||||
* set_parallel(engine_index=0, width=2, num_siblings=2,
|
|
||||||
* engines=CS[0],CS[1],CS[1],CS[3])
|
|
||||||
*
|
|
||||||
* Results in the following valid and invalid placements:
|
|
||||||
* CS[0], CS[1]
|
|
||||||
* CS[1], CS[3] - Not logical contiguous, return -EINVAL
|
|
||||||
*/
|
|
||||||
struct drm_i915_context_engines_parallel_submit {
|
|
||||||
/**
|
|
||||||
* @base: base user extension.
|
|
||||||
*/
|
|
||||||
struct i915_user_extension base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @engine_index: slot for parallel engine
|
|
||||||
*/
|
|
||||||
__u16 engine_index;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @width: number of contexts per parallel engine
|
|
||||||
*/
|
|
||||||
__u16 width;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @num_siblings: number of siblings per context
|
|
||||||
*/
|
|
||||||
__u16 num_siblings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @mbz16: reserved for future use; must be zero
|
|
||||||
*/
|
|
||||||
__u16 mbz16;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @flags: all undefined flags must be zero, currently not defined flags
|
|
||||||
*/
|
|
||||||
__u64 flags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @mbz64: reserved for future use; must be zero
|
|
||||||
*/
|
|
||||||
__u64 mbz64[3];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @engines: 2-d array of engine instances to configure parallel engine
|
|
||||||
*
|
|
||||||
* length = width (i) * num_siblings (j)
|
|
||||||
* index = j + i * num_siblings
|
|
||||||
*/
|
|
||||||
struct i915_engine_class_instance engines[0];
|
|
||||||
|
|
||||||
} __packed;
|
|
||||||
|
|
@ -135,8 +135,8 @@ Add I915_CONTEXT_ENGINES_EXT_PARALLEL_SUBMIT and
|
|||||||
drm_i915_context_engines_parallel_submit to the uAPI to implement this
|
drm_i915_context_engines_parallel_submit to the uAPI to implement this
|
||||||
extension.
|
extension.
|
||||||
|
|
||||||
.. kernel-doc:: Documentation/gpu/rfc/i915_parallel_execbuf.h
|
.. kernel-doc:: include/uapi/drm/i915_drm.h
|
||||||
:functions: drm_i915_context_engines_parallel_submit
|
:functions: i915_context_engines_parallel_submit
|
||||||
|
|
||||||
Extend execbuf2 IOCTL to support submitting N BBs in a single IOCTL
|
Extend execbuf2 IOCTL to support submitting N BBs in a single IOCTL
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
|
@ -353,23 +353,6 @@ converted, except for struct drm_driver.gem_prime_mmap.
|
|||||||
|
|
||||||
Level: Intermediate
|
Level: Intermediate
|
||||||
|
|
||||||
Use DRM_MODESET_LOCK_ALL_* helpers instead of boilerplate
|
|
||||||
---------------------------------------------------------
|
|
||||||
|
|
||||||
For cases where drivers are attempting to grab the modeset locks with a local
|
|
||||||
acquire context. Replace the boilerplate code surrounding
|
|
||||||
drm_modeset_lock_all_ctx() with DRM_MODESET_LOCK_ALL_BEGIN() and
|
|
||||||
DRM_MODESET_LOCK_ALL_END() instead.
|
|
||||||
|
|
||||||
This should also be done for all places where drm_modeset_lock_all() is still
|
|
||||||
used.
|
|
||||||
|
|
||||||
As a reference, take a look at the conversions already completed in drm core.
|
|
||||||
|
|
||||||
Contact: Sean Paul, respective driver maintainers
|
|
||||||
|
|
||||||
Level: Starter
|
|
||||||
|
|
||||||
Rename CMA helpers to DMA helpers
|
Rename CMA helpers to DMA helpers
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ Concepts
|
|||||||
Compared to normal mutexes two additional concepts/objects show up in the lock
|
Compared to normal mutexes two additional concepts/objects show up in the lock
|
||||||
interface for w/w mutexes:
|
interface for w/w mutexes:
|
||||||
|
|
||||||
Acquire context: To ensure eventual forward progress it is important the a task
|
Acquire context: To ensure eventual forward progress it is important that a task
|
||||||
trying to acquire locks doesn't grab a new reservation id, but keeps the one it
|
trying to acquire locks doesn't grab a new reservation id, but keeps the one it
|
||||||
acquired when starting the lock acquisition. This ticket is stored in the
|
acquired when starting the lock acquisition. This ticket is stored in the
|
||||||
acquire context. Furthermore the acquire context keeps track of debugging state
|
acquire context. Furthermore the acquire context keeps track of debugging state
|
||||||
|
15
MAINTAINERS
15
MAINTAINERS
@ -893,6 +893,7 @@ F: include/uapi/linux/psp-sev.h
|
|||||||
AMD DISPLAY CORE
|
AMD DISPLAY CORE
|
||||||
M: Harry Wentland <harry.wentland@amd.com>
|
M: Harry Wentland <harry.wentland@amd.com>
|
||||||
M: Leo Li <sunpeng.li@amd.com>
|
M: Leo Li <sunpeng.li@amd.com>
|
||||||
|
M: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
|
||||||
L: amd-gfx@lists.freedesktop.org
|
L: amd-gfx@lists.freedesktop.org
|
||||||
S: Supported
|
S: Supported
|
||||||
T: git https://gitlab.freedesktop.org/agd5f/linux.git
|
T: git https://gitlab.freedesktop.org/agd5f/linux.git
|
||||||
@ -6046,6 +6047,12 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
|
|||||||
F: Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml
|
F: Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml
|
||||||
F: drivers/gpu/drm/panel/panel-samsung-db7430.c
|
F: drivers/gpu/drm/panel/panel-samsung-db7430.c
|
||||||
|
|
||||||
|
DRM DRIVER FOR SAMSUNG S6D27A1 PANELS
|
||||||
|
M: Markuss Broks <markuss.broks@gmail.com>
|
||||||
|
S: Maintained
|
||||||
|
F: Documentation/devicetree/bindings/display/panel/samsung,s6d27a1.yaml
|
||||||
|
F: drivers/gpu/drm/panel/panel-samsung-s6d27a1.c
|
||||||
|
|
||||||
DRM DRIVER FOR SITRONIX ST7703 PANELS
|
DRM DRIVER FOR SITRONIX ST7703 PANELS
|
||||||
M: Guido Günther <agx@sigxcpu.org>
|
M: Guido Günther <agx@sigxcpu.org>
|
||||||
R: Purism Kernel Team <kernel@puri.sm>
|
R: Purism Kernel Team <kernel@puri.sm>
|
||||||
@ -6452,6 +6459,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
|
|||||||
F: drivers/gpu/drm/ttm/
|
F: drivers/gpu/drm/ttm/
|
||||||
F: include/drm/ttm/
|
F: include/drm/ttm/
|
||||||
|
|
||||||
|
DRM GPU SCHEDULER
|
||||||
|
M: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
|
||||||
|
L: dri-devel@lists.freedesktop.org
|
||||||
|
S: Maintained
|
||||||
|
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||||
|
F: drivers/gpu/drm/scheduler/
|
||||||
|
F: include/drm/gpu_scheduler.h
|
||||||
|
|
||||||
DSBR100 USB FM RADIO DRIVER
|
DSBR100 USB FM RADIO DRIVER
|
||||||
M: Alexey Klimov <klimov.linux@gmail.com>
|
M: Alexey Klimov <klimov.linux@gmail.com>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
|
@ -144,6 +144,7 @@ CONFIG_VIDEO_MT9V032=m
|
|||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_ATMEL_HLCDC=y
|
CONFIG_DRM_ATMEL_HLCDC=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_FB_ATMEL=y
|
CONFIG_FB_ATMEL=y
|
||||||
CONFIG_BACKLIGHT_ATMEL_LCDC=y
|
CONFIG_BACKLIGHT_ATMEL_LCDC=y
|
||||||
CONFIG_BACKLIGHT_PWM=y
|
CONFIG_BACKLIGHT_PWM=y
|
||||||
|
@ -227,6 +227,7 @@ CONFIG_DRM_EXYNOS_DPI=y
|
|||||||
CONFIG_DRM_EXYNOS_DSI=y
|
CONFIG_DRM_EXYNOS_DSI=y
|
||||||
CONFIG_DRM_EXYNOS_HDMI=y
|
CONFIG_DRM_EXYNOS_HDMI=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
|
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
|
||||||
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
|
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
|
||||||
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
|
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
|
||||||
|
@ -281,6 +281,7 @@ CONFIG_DRM=y
|
|||||||
CONFIG_DRM_MSM=y
|
CONFIG_DRM_MSM=y
|
||||||
CONFIG_DRM_PANEL_LVDS=y
|
CONFIG_DRM_PANEL_LVDS=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
|
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
|
||||||
CONFIG_DRM_TI_TFP410=y
|
CONFIG_DRM_TI_TFP410=y
|
||||||
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
|
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
|
||||||
|
@ -108,6 +108,7 @@ CONFIG_REGULATOR=y
|
|||||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
CONFIG_FB_MODE_HELPERS=y
|
CONFIG_FB_MODE_HELPERS=y
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
|
@ -194,6 +194,7 @@ CONFIG_VIDEO_ATMEL_ISI=m
|
|||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_ATMEL_HLCDC=m
|
CONFIG_DRM_ATMEL_HLCDC=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_ASPEED_GFX=m
|
CONFIG_DRM_ASPEED_GFX=m
|
||||||
CONFIG_FB_IMX=y
|
CONFIG_FB_IMX=y
|
||||||
CONFIG_FB_ATMEL=y
|
CONFIG_FB_ATMEL=y
|
||||||
|
@ -704,6 +704,7 @@ CONFIG_DRM_TEGRA=y
|
|||||||
CONFIG_DRM_STM=m
|
CONFIG_DRM_STM=m
|
||||||
CONFIG_DRM_STM_DSI=m
|
CONFIG_DRM_STM_DSI=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
|
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
|
||||||
CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
|
CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
|
||||||
CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
|
CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
|
||||||
|
@ -511,6 +511,7 @@ CONFIG_OMAP2_DSS_DSI=y
|
|||||||
CONFIG_DRM_TILCDC=m
|
CONFIG_DRM_TILCDC=m
|
||||||
CONFIG_DRM_PANEL_DSI_CM=m
|
CONFIG_DRM_PANEL_DSI_CM=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=m
|
CONFIG_DRM_PANEL_SIMPLE=m
|
||||||
|
CONFIG_DRM_PANEL_EDP=m
|
||||||
CONFIG_DRM_PANEL_LG_LB035Q02=m
|
CONFIG_DRM_PANEL_LG_LB035Q02=m
|
||||||
CONFIG_DRM_PANEL_NEC_NL8048HL11=m
|
CONFIG_DRM_PANEL_NEC_NL8048HL11=m
|
||||||
CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
|
CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
|
||||||
|
@ -158,6 +158,7 @@ CONFIG_MEDIA_SUPPORT=y
|
|||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_MSM=m
|
CONFIG_DRM_MSM=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_ANALOGIX_ANX78XX=m
|
CONFIG_DRM_ANALOGIX_ANX78XX=m
|
||||||
CONFIG_FB=y
|
CONFIG_FB=y
|
||||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||||
|
@ -61,6 +61,7 @@ CONFIG_REGULATOR=y
|
|||||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
||||||
CONFIG_DRM_SIMPLE_BRIDGE=y
|
CONFIG_DRM_SIMPLE_BRIDGE=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
|
@ -160,6 +160,7 @@ CONFIG_VIDEO_MT9V032=m
|
|||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_ATMEL_HLCDC=y
|
CONFIG_DRM_ATMEL_HLCDC=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_LCD_CLASS_DEVICE=y
|
CONFIG_LCD_CLASS_DEVICE=y
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
CONFIG_BACKLIGHT_PWM=y
|
CONFIG_BACKLIGHT_PWM=y
|
||||||
|
@ -128,6 +128,7 @@ CONFIG_VIDEO_ML86V7667=y
|
|||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_RCAR_DU=y
|
CONFIG_DRM_RCAR_DU=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
||||||
CONFIG_DRM_LVDS_CODEC=y
|
CONFIG_DRM_LVDS_CODEC=y
|
||||||
CONFIG_DRM_SII902X=y
|
CONFIG_DRM_SII902X=y
|
||||||
|
@ -108,6 +108,7 @@ CONFIG_DRM_SUN4I_HDMI_CEC=y
|
|||||||
CONFIG_DRM_SUN8I_DW_HDMI=y
|
CONFIG_DRM_SUN8I_DW_HDMI=y
|
||||||
CONFIG_DRM_PANEL_LVDS=y
|
CONFIG_DRM_PANEL_LVDS=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_SIMPLE_BRIDGE=y
|
CONFIG_DRM_SIMPLE_BRIDGE=y
|
||||||
CONFIG_DRM_LIMA=y
|
CONFIG_DRM_LIMA=y
|
||||||
CONFIG_FB_SIMPLE=y
|
CONFIG_FB_SIMPLE=y
|
||||||
|
@ -199,6 +199,7 @@ CONFIG_DRM_TEGRA=y
|
|||||||
CONFIG_DRM_TEGRA_STAGING=y
|
CONFIG_DRM_TEGRA_STAGING=y
|
||||||
CONFIG_DRM_PANEL_LVDS=y
|
CONFIG_DRM_PANEL_LVDS=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_LVDS_CODEC=y
|
CONFIG_DRM_LVDS_CODEC=y
|
||||||
CONFIG_FB=y
|
CONFIG_FB=y
|
||||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||||
|
@ -57,6 +57,7 @@ CONFIG_GPIO_PL061=y
|
|||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_ARM_VERSATILE=y
|
CONFIG_DRM_PANEL_ARM_VERSATILE=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
CONFIG_DRM_DISPLAY_CONNECTOR=y
|
||||||
CONFIG_DRM_SIMPLE_BRIDGE=y
|
CONFIG_DRM_SIMPLE_BRIDGE=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
|
@ -77,6 +77,7 @@ CONFIG_SENSORS_VEXPRESS=y
|
|||||||
CONFIG_REGULATOR_VEXPRESS=y
|
CONFIG_REGULATOR_VEXPRESS=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_EDP=y
|
||||||
CONFIG_DRM_SII902X=y
|
CONFIG_DRM_SII902X=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
CONFIG_FB=y
|
CONFIG_FB=y
|
||||||
|
@ -696,6 +696,7 @@ CONFIG_DRM_MSM=m
|
|||||||
CONFIG_DRM_TEGRA=m
|
CONFIG_DRM_TEGRA=m
|
||||||
CONFIG_DRM_PANEL_LVDS=m
|
CONFIG_DRM_PANEL_LVDS=m
|
||||||
CONFIG_DRM_PANEL_SIMPLE=m
|
CONFIG_DRM_PANEL_SIMPLE=m
|
||||||
|
CONFIG_DRM_PANEL_EDP=m
|
||||||
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
|
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
|
||||||
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
|
CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
|
||||||
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
|
CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
|
||||||
|
@ -346,7 +346,7 @@ extern int mce_threshold_remove_device(unsigned int cpu);
|
|||||||
|
|
||||||
void mce_amd_feature_init(struct cpuinfo_x86 *c);
|
void mce_amd_feature_init(struct cpuinfo_x86 *c);
|
||||||
int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr);
|
int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr);
|
||||||
|
enum smca_bank_types smca_get_bank_type(unsigned int bank);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline int mce_threshold_create_device(unsigned int cpu) { return 0; };
|
static inline int mce_threshold_create_device(unsigned int cpu) { return 0; };
|
||||||
|
@ -119,7 +119,7 @@ const char *smca_get_long_name(enum smca_bank_types t)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(smca_get_long_name);
|
EXPORT_SYMBOL_GPL(smca_get_long_name);
|
||||||
|
|
||||||
static enum smca_bank_types smca_get_bank_type(unsigned int bank)
|
enum smca_bank_types smca_get_bank_type(unsigned int bank)
|
||||||
{
|
{
|
||||||
struct smca_bank *b;
|
struct smca_bank *b;
|
||||||
|
|
||||||
@ -132,6 +132,7 @@ static enum smca_bank_types smca_get_bank_type(unsigned int bank)
|
|||||||
|
|
||||||
return b->hwid->bank_type;
|
return b->hwid->bank_type;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(smca_get_bank_type);
|
||||||
|
|
||||||
static struct smca_hwid smca_hwid_mcatypes[] = {
|
static struct smca_hwid smca_hwid_mcatypes[] = {
|
||||||
/* { bank_type, hwid_mcatype } */
|
/* { bank_type, hwid_mcatype } */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
|
obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
|
||||||
dma-resv.o seqno-fence.o
|
dma-resv.o
|
||||||
obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
|
obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
|
||||||
obj-$(CONFIG_DMABUF_HEAPS) += heaps/
|
obj-$(CONFIG_DMABUF_HEAPS) += heaps/
|
||||||
obj-$(CONFIG_SYNC_FILE) += sync_file.o
|
obj-$(CONFIG_SYNC_FILE) += sync_file.o
|
||||||
|
@ -74,7 +74,7 @@ static void dma_buf_release(struct dentry *dentry)
|
|||||||
* If you hit this BUG() it means someone dropped their ref to the
|
* If you hit this BUG() it means someone dropped their ref to the
|
||||||
* dma-buf while still having pending operation to the buffer.
|
* dma-buf while still having pending operation to the buffer.
|
||||||
*/
|
*/
|
||||||
BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
|
BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);
|
||||||
|
|
||||||
dma_buf_stats_teardown(dmabuf);
|
dma_buf_stats_teardown(dmabuf);
|
||||||
dmabuf->ops->release(dmabuf);
|
dmabuf->ops->release(dmabuf);
|
||||||
@ -82,6 +82,7 @@ static void dma_buf_release(struct dentry *dentry)
|
|||||||
if (dmabuf->resv == (struct dma_resv *)&dmabuf[1])
|
if (dmabuf->resv == (struct dma_resv *)&dmabuf[1])
|
||||||
dma_resv_fini(dmabuf->resv);
|
dma_resv_fini(dmabuf->resv);
|
||||||
|
|
||||||
|
WARN_ON(!list_empty(&dmabuf->attachments));
|
||||||
module_put(dmabuf->owner);
|
module_put(dmabuf->owner);
|
||||||
kfree(dmabuf->name);
|
kfree(dmabuf->name);
|
||||||
kfree(dmabuf);
|
kfree(dmabuf);
|
||||||
@ -205,16 +206,55 @@ static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
|
|||||||
wake_up_locked_poll(dcb->poll, dcb->active);
|
wake_up_locked_poll(dcb->poll, dcb->active);
|
||||||
dcb->active = 0;
|
dcb->active = 0;
|
||||||
spin_unlock_irqrestore(&dcb->poll->lock, flags);
|
spin_unlock_irqrestore(&dcb->poll->lock, flags);
|
||||||
|
dma_fence_put(fence);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dma_buf_poll_shared(struct dma_resv *resv,
|
||||||
|
struct dma_buf_poll_cb_t *dcb)
|
||||||
|
{
|
||||||
|
struct dma_resv_list *fobj = dma_resv_shared_list(resv);
|
||||||
|
struct dma_fence *fence;
|
||||||
|
int i, r;
|
||||||
|
|
||||||
|
if (!fobj)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = 0; i < fobj->shared_count; ++i) {
|
||||||
|
fence = rcu_dereference_protected(fobj->shared[i],
|
||||||
|
dma_resv_held(resv));
|
||||||
|
dma_fence_get(fence);
|
||||||
|
r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb);
|
||||||
|
if (!r)
|
||||||
|
return true;
|
||||||
|
dma_fence_put(fence);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool dma_buf_poll_excl(struct dma_resv *resv,
|
||||||
|
struct dma_buf_poll_cb_t *dcb)
|
||||||
|
{
|
||||||
|
struct dma_fence *fence = dma_resv_excl_fence(resv);
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!fence)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
dma_fence_get(fence);
|
||||||
|
r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb);
|
||||||
|
if (!r)
|
||||||
|
return true;
|
||||||
|
dma_fence_put(fence);
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
|
static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
|
||||||
{
|
{
|
||||||
struct dma_buf *dmabuf;
|
struct dma_buf *dmabuf;
|
||||||
struct dma_resv *resv;
|
struct dma_resv *resv;
|
||||||
struct dma_resv_list *fobj;
|
|
||||||
struct dma_fence *fence_excl;
|
|
||||||
__poll_t events;
|
__poll_t events;
|
||||||
unsigned shared_count, seq;
|
|
||||||
|
|
||||||
dmabuf = file->private_data;
|
dmabuf = file->private_data;
|
||||||
if (!dmabuf || !dmabuf->resv)
|
if (!dmabuf || !dmabuf->resv)
|
||||||
@ -228,61 +268,12 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
|
|||||||
if (!events)
|
if (!events)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
retry:
|
dma_resv_lock(resv, NULL);
|
||||||
seq = read_seqcount_begin(&resv->seq);
|
|
||||||
rcu_read_lock();
|
|
||||||
|
|
||||||
fobj = rcu_dereference(resv->fence);
|
if (events & EPOLLOUT) {
|
||||||
if (fobj)
|
struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_out;
|
||||||
shared_count = fobj->shared_count;
|
|
||||||
else
|
|
||||||
shared_count = 0;
|
|
||||||
fence_excl = dma_resv_excl_fence(resv);
|
|
||||||
if (read_seqcount_retry(&resv->seq, seq)) {
|
|
||||||
rcu_read_unlock();
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fence_excl && (!(events & EPOLLOUT) || shared_count == 0)) {
|
/* Check that callback isn't busy */
|
||||||
struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_excl;
|
|
||||||
__poll_t pevents = EPOLLIN;
|
|
||||||
|
|
||||||
if (shared_count == 0)
|
|
||||||
pevents |= EPOLLOUT;
|
|
||||||
|
|
||||||
spin_lock_irq(&dmabuf->poll.lock);
|
|
||||||
if (dcb->active) {
|
|
||||||
dcb->active |= pevents;
|
|
||||||
events &= ~pevents;
|
|
||||||
} else
|
|
||||||
dcb->active = pevents;
|
|
||||||
spin_unlock_irq(&dmabuf->poll.lock);
|
|
||||||
|
|
||||||
if (events & pevents) {
|
|
||||||
if (!dma_fence_get_rcu(fence_excl)) {
|
|
||||||
/* force a recheck */
|
|
||||||
events &= ~pevents;
|
|
||||||
dma_buf_poll_cb(NULL, &dcb->cb);
|
|
||||||
} else if (!dma_fence_add_callback(fence_excl, &dcb->cb,
|
|
||||||
dma_buf_poll_cb)) {
|
|
||||||
events &= ~pevents;
|
|
||||||
dma_fence_put(fence_excl);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* No callback queued, wake up any additional
|
|
||||||
* waiters.
|
|
||||||
*/
|
|
||||||
dma_fence_put(fence_excl);
|
|
||||||
dma_buf_poll_cb(NULL, &dcb->cb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((events & EPOLLOUT) && shared_count > 0) {
|
|
||||||
struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_shared;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Only queue a new callback if no event has fired yet */
|
|
||||||
spin_lock_irq(&dmabuf->poll.lock);
|
spin_lock_irq(&dmabuf->poll.lock);
|
||||||
if (dcb->active)
|
if (dcb->active)
|
||||||
events &= ~EPOLLOUT;
|
events &= ~EPOLLOUT;
|
||||||
@ -290,39 +281,37 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
|
|||||||
dcb->active = EPOLLOUT;
|
dcb->active = EPOLLOUT;
|
||||||
spin_unlock_irq(&dmabuf->poll.lock);
|
spin_unlock_irq(&dmabuf->poll.lock);
|
||||||
|
|
||||||
if (!(events & EPOLLOUT))
|
if (events & EPOLLOUT) {
|
||||||
goto out;
|
if (!dma_buf_poll_shared(resv, dcb) &&
|
||||||
|
!dma_buf_poll_excl(resv, dcb))
|
||||||
for (i = 0; i < shared_count; ++i) {
|
/* No callback queued, wake up any other waiters */
|
||||||
struct dma_fence *fence = rcu_dereference(fobj->shared[i]);
|
|
||||||
|
|
||||||
if (!dma_fence_get_rcu(fence)) {
|
|
||||||
/*
|
|
||||||
* fence refcount dropped to zero, this means
|
|
||||||
* that fobj has been freed
|
|
||||||
*
|
|
||||||
* call dma_buf_poll_cb and force a recheck!
|
|
||||||
*/
|
|
||||||
events &= ~EPOLLOUT;
|
|
||||||
dma_buf_poll_cb(NULL, &dcb->cb);
|
dma_buf_poll_cb(NULL, &dcb->cb);
|
||||||
break;
|
else
|
||||||
}
|
|
||||||
if (!dma_fence_add_callback(fence, &dcb->cb,
|
|
||||||
dma_buf_poll_cb)) {
|
|
||||||
dma_fence_put(fence);
|
|
||||||
events &= ~EPOLLOUT;
|
events &= ~EPOLLOUT;
|
||||||
break;
|
|
||||||
}
|
|
||||||
dma_fence_put(fence);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No callback queued, wake up any additional waiters. */
|
|
||||||
if (i == shared_count)
|
|
||||||
dma_buf_poll_cb(NULL, &dcb->cb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
if (events & EPOLLIN) {
|
||||||
rcu_read_unlock();
|
struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_in;
|
||||||
|
|
||||||
|
/* Check that callback isn't busy */
|
||||||
|
spin_lock_irq(&dmabuf->poll.lock);
|
||||||
|
if (dcb->active)
|
||||||
|
events &= ~EPOLLIN;
|
||||||
|
else
|
||||||
|
dcb->active = EPOLLIN;
|
||||||
|
spin_unlock_irq(&dmabuf->poll.lock);
|
||||||
|
|
||||||
|
if (events & EPOLLIN) {
|
||||||
|
if (!dma_buf_poll_excl(resv, dcb))
|
||||||
|
/* No callback queued, wake up any other waiters */
|
||||||
|
dma_buf_poll_cb(NULL, &dcb->cb);
|
||||||
|
else
|
||||||
|
events &= ~EPOLLIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dma_resv_unlock(resv);
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,8 +554,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
|||||||
dmabuf->owner = exp_info->owner;
|
dmabuf->owner = exp_info->owner;
|
||||||
spin_lock_init(&dmabuf->name_lock);
|
spin_lock_init(&dmabuf->name_lock);
|
||||||
init_waitqueue_head(&dmabuf->poll);
|
init_waitqueue_head(&dmabuf->poll);
|
||||||
dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll;
|
dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf->poll;
|
||||||
dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0;
|
dmabuf->cb_in.active = dmabuf->cb_out.active = 0;
|
||||||
|
|
||||||
if (!resv) {
|
if (!resv) {
|
||||||
resv = (struct dma_resv *)&dmabuf[1];
|
resv = (struct dma_resv *)&dmabuf[1];
|
||||||
|
@ -616,20 +616,17 @@ EXPORT_SYMBOL(dma_fence_enable_sw_signaling);
|
|||||||
* @cb: the callback to register
|
* @cb: the callback to register
|
||||||
* @func: the function to call
|
* @func: the function to call
|
||||||
*
|
*
|
||||||
|
* Add a software callback to the fence. The caller should keep a reference to
|
||||||
|
* the fence.
|
||||||
|
*
|
||||||
* @cb will be initialized by dma_fence_add_callback(), no initialization
|
* @cb will be initialized by dma_fence_add_callback(), no initialization
|
||||||
* by the caller is required. Any number of callbacks can be registered
|
* by the caller is required. Any number of callbacks can be registered
|
||||||
* to a fence, but a callback can only be registered to one fence at a time.
|
* to a fence, but a callback can only be registered to one fence at a time.
|
||||||
*
|
*
|
||||||
* Note that the callback can be called from an atomic context. If
|
* If fence is already signaled, this function will return -ENOENT (and
|
||||||
* fence is already signaled, this function will return -ENOENT (and
|
|
||||||
* *not* call the callback).
|
* *not* call the callback).
|
||||||
*
|
*
|
||||||
* Add a software callback to the fence. Same restrictions apply to
|
* Note that the callback can be called from an atomic context or irq context.
|
||||||
* refcount as it does to dma_fence_wait(), however the caller doesn't need to
|
|
||||||
* keep a refcount to fence afterward dma_fence_add_callback() has returned:
|
|
||||||
* when software access is enabled, the creator of the fence is required to keep
|
|
||||||
* the fence alive until after it signals with dma_fence_signal(). The callback
|
|
||||||
* itself can be called from irq context.
|
|
||||||
*
|
*
|
||||||
* Returns 0 in case of success, -ENOENT if the fence is already signaled
|
* Returns 0 in case of success, -ENOENT if the fence is already signaled
|
||||||
* and -EINVAL in case of error.
|
* and -EINVAL in case of error.
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
* write operations) or N shared fences (read operations). The RCU
|
* write operations) or N shared fences (read operations). The RCU
|
||||||
* mechanism is used to protect read access to fences from locked
|
* mechanism is used to protect read access to fences from locked
|
||||||
* write-side updates.
|
* write-side updates.
|
||||||
|
*
|
||||||
|
* See struct dma_resv for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEFINE_WD_CLASS(reservation_ww_class);
|
DEFINE_WD_CLASS(reservation_ww_class);
|
||||||
@ -137,7 +139,11 @@ EXPORT_SYMBOL(dma_resv_fini);
|
|||||||
* @num_fences: number of fences we want to add
|
* @num_fences: number of fences we want to add
|
||||||
*
|
*
|
||||||
* Should be called before dma_resv_add_shared_fence(). Must
|
* Should be called before dma_resv_add_shared_fence(). Must
|
||||||
* be called with obj->lock held.
|
* be called with @obj locked through dma_resv_lock().
|
||||||
|
*
|
||||||
|
* Note that the preallocated slots need to be re-reserved if @obj is unlocked
|
||||||
|
* at any time before calling dma_resv_add_shared_fence(). This is validated
|
||||||
|
* when CONFIG_DEBUG_MUTEXES is enabled.
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Zero for success, or -errno
|
* Zero for success, or -errno
|
||||||
@ -234,8 +240,10 @@ EXPORT_SYMBOL(dma_resv_reset_shared_max);
|
|||||||
* @obj: the reservation object
|
* @obj: the reservation object
|
||||||
* @fence: the shared fence to add
|
* @fence: the shared fence to add
|
||||||
*
|
*
|
||||||
* Add a fence to a shared slot, obj->lock must be held, and
|
* Add a fence to a shared slot, @obj must be locked with dma_resv_lock(), and
|
||||||
* dma_resv_reserve_shared() has been called.
|
* dma_resv_reserve_shared() has been called.
|
||||||
|
*
|
||||||
|
* See also &dma_resv.fence for a discussion of the semantics.
|
||||||
*/
|
*/
|
||||||
void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence)
|
void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence)
|
||||||
{
|
{
|
||||||
@ -278,9 +286,11 @@ EXPORT_SYMBOL(dma_resv_add_shared_fence);
|
|||||||
/**
|
/**
|
||||||
* dma_resv_add_excl_fence - Add an exclusive fence.
|
* dma_resv_add_excl_fence - Add an exclusive fence.
|
||||||
* @obj: the reservation object
|
* @obj: the reservation object
|
||||||
* @fence: the shared fence to add
|
* @fence: the exclusive fence to add
|
||||||
*
|
*
|
||||||
* Add a fence to the exclusive slot. The obj->lock must be held.
|
* Add a fence to the exclusive slot. @obj must be locked with dma_resv_lock().
|
||||||
|
* Note that this function replaces all fences attached to @obj, see also
|
||||||
|
* &dma_resv.fence_excl for a discussion of the semantics.
|
||||||
*/
|
*/
|
||||||
void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence)
|
void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence)
|
||||||
{
|
{
|
||||||
@ -313,6 +323,106 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_resv_add_excl_fence);
|
EXPORT_SYMBOL(dma_resv_add_excl_fence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dma_resv_iter_restart_unlocked - restart the unlocked iterator
|
||||||
|
* @cursor: The dma_resv_iter object to restart
|
||||||
|
*
|
||||||
|
* Restart the unlocked iteration by initializing the cursor object.
|
||||||
|
*/
|
||||||
|
static void dma_resv_iter_restart_unlocked(struct dma_resv_iter *cursor)
|
||||||
|
{
|
||||||
|
cursor->seq = read_seqcount_begin(&cursor->obj->seq);
|
||||||
|
cursor->index = -1;
|
||||||
|
if (cursor->all_fences)
|
||||||
|
cursor->fences = dma_resv_shared_list(cursor->obj);
|
||||||
|
else
|
||||||
|
cursor->fences = NULL;
|
||||||
|
cursor->is_restarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dma_resv_iter_walk_unlocked - walk over fences in a dma_resv obj
|
||||||
|
* @cursor: cursor to record the current position
|
||||||
|
*
|
||||||
|
* Return all the fences in the dma_resv object which are not yet signaled.
|
||||||
|
* The returned fence has an extra local reference so will stay alive.
|
||||||
|
* If a concurrent modify is detected the whole iteration is started over again.
|
||||||
|
*/
|
||||||
|
static void dma_resv_iter_walk_unlocked(struct dma_resv_iter *cursor)
|
||||||
|
{
|
||||||
|
struct dma_resv *obj = cursor->obj;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Drop the reference from the previous round */
|
||||||
|
dma_fence_put(cursor->fence);
|
||||||
|
|
||||||
|
if (cursor->index == -1) {
|
||||||
|
cursor->fence = dma_resv_excl_fence(obj);
|
||||||
|
cursor->index++;
|
||||||
|
if (!cursor->fence)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else if (!cursor->fences ||
|
||||||
|
cursor->index >= cursor->fences->shared_count) {
|
||||||
|
cursor->fence = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
struct dma_resv_list *fences = cursor->fences;
|
||||||
|
unsigned int idx = cursor->index++;
|
||||||
|
|
||||||
|
cursor->fence = rcu_dereference(fences->shared[idx]);
|
||||||
|
}
|
||||||
|
cursor->fence = dma_fence_get_rcu(cursor->fence);
|
||||||
|
if (!cursor->fence || !dma_fence_is_signaled(cursor->fence))
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dma_resv_iter_first_unlocked - first fence in an unlocked dma_resv obj.
|
||||||
|
* @cursor: the cursor with the current position
|
||||||
|
*
|
||||||
|
* Returns the first fence from an unlocked dma_resv obj.
|
||||||
|
*/
|
||||||
|
struct dma_fence *dma_resv_iter_first_unlocked(struct dma_resv_iter *cursor)
|
||||||
|
{
|
||||||
|
rcu_read_lock();
|
||||||
|
do {
|
||||||
|
dma_resv_iter_restart_unlocked(cursor);
|
||||||
|
dma_resv_iter_walk_unlocked(cursor);
|
||||||
|
} while (read_seqcount_retry(&cursor->obj->seq, cursor->seq));
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
return cursor->fence;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dma_resv_iter_first_unlocked);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dma_resv_iter_next_unlocked - next fence in an unlocked dma_resv obj.
|
||||||
|
* @cursor: the cursor with the current position
|
||||||
|
*
|
||||||
|
* Returns the next fence from an unlocked dma_resv obj.
|
||||||
|
*/
|
||||||
|
struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor)
|
||||||
|
{
|
||||||
|
bool restart;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
cursor->is_restarted = false;
|
||||||
|
restart = read_seqcount_retry(&cursor->obj->seq, cursor->seq);
|
||||||
|
do {
|
||||||
|
if (restart)
|
||||||
|
dma_resv_iter_restart_unlocked(cursor);
|
||||||
|
dma_resv_iter_walk_unlocked(cursor);
|
||||||
|
restart = true;
|
||||||
|
} while (read_seqcount_retry(&cursor->obj->seq, cursor->seq));
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
return cursor->fence;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dma_resv_iter_next_unlocked);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dma_resv_copy_fences - Copy all fences from src to dst.
|
* dma_resv_copy_fences - Copy all fences from src to dst.
|
||||||
* @dst: the destination reservation object
|
* @dst: the destination reservation object
|
||||||
@ -322,74 +432,54 @@ EXPORT_SYMBOL(dma_resv_add_excl_fence);
|
|||||||
*/
|
*/
|
||||||
int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src)
|
int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src)
|
||||||
{
|
{
|
||||||
struct dma_resv_list *src_list, *dst_list;
|
struct dma_resv_iter cursor;
|
||||||
struct dma_fence *old, *new;
|
struct dma_resv_list *list;
|
||||||
unsigned int i;
|
struct dma_fence *f, *excl;
|
||||||
|
|
||||||
dma_resv_assert_held(dst);
|
dma_resv_assert_held(dst);
|
||||||
|
|
||||||
rcu_read_lock();
|
list = NULL;
|
||||||
src_list = dma_resv_shared_list(src);
|
excl = NULL;
|
||||||
|
|
||||||
retry:
|
dma_resv_iter_begin(&cursor, src, true);
|
||||||
if (src_list) {
|
dma_resv_for_each_fence_unlocked(&cursor, f) {
|
||||||
unsigned int shared_count = src_list->shared_count;
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
if (dma_resv_iter_is_restarted(&cursor)) {
|
||||||
|
dma_resv_list_free(list);
|
||||||
|
dma_fence_put(excl);
|
||||||
|
|
||||||
dst_list = dma_resv_list_alloc(shared_count);
|
if (cursor.fences) {
|
||||||
if (!dst_list)
|
unsigned int cnt = cursor.fences->shared_count;
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
list = dma_resv_list_alloc(cnt);
|
||||||
src_list = dma_resv_shared_list(src);
|
if (!list) {
|
||||||
if (!src_list || src_list->shared_count > shared_count) {
|
dma_resv_iter_end(&cursor);
|
||||||
kfree(dst_list);
|
return -ENOMEM;
|
||||||
goto retry;
|
}
|
||||||
|
|
||||||
|
list->shared_count = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
list = NULL;
|
||||||
|
}
|
||||||
|
excl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_list->shared_count = 0;
|
dma_fence_get(f);
|
||||||
for (i = 0; i < src_list->shared_count; ++i) {
|
if (dma_resv_iter_is_exclusive(&cursor))
|
||||||
struct dma_fence __rcu **dst;
|
excl = f;
|
||||||
struct dma_fence *fence;
|
else
|
||||||
|
RCU_INIT_POINTER(list->shared[list->shared_count++], f);
|
||||||
fence = rcu_dereference(src_list->shared[i]);
|
|
||||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
|
|
||||||
&fence->flags))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!dma_fence_get_rcu(fence)) {
|
|
||||||
dma_resv_list_free(dst_list);
|
|
||||||
src_list = dma_resv_shared_list(src);
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dma_fence_is_signaled(fence)) {
|
|
||||||
dma_fence_put(fence);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst = &dst_list->shared[dst_list->shared_count++];
|
|
||||||
rcu_assign_pointer(*dst, fence);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dst_list = NULL;
|
|
||||||
}
|
}
|
||||||
|
dma_resv_iter_end(&cursor);
|
||||||
new = dma_fence_get_rcu_safe(&src->fence_excl);
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
src_list = dma_resv_shared_list(dst);
|
|
||||||
old = dma_resv_excl_fence(dst);
|
|
||||||
|
|
||||||
write_seqcount_begin(&dst->seq);
|
write_seqcount_begin(&dst->seq);
|
||||||
/* write_seqcount_begin provides the necessary memory barrier */
|
excl = rcu_replace_pointer(dst->fence_excl, excl, dma_resv_held(dst));
|
||||||
RCU_INIT_POINTER(dst->fence_excl, new);
|
list = rcu_replace_pointer(dst->fence, list, dma_resv_held(dst));
|
||||||
RCU_INIT_POINTER(dst->fence, dst_list);
|
|
||||||
write_seqcount_end(&dst->seq);
|
write_seqcount_end(&dst->seq);
|
||||||
|
|
||||||
dma_resv_list_free(src_list);
|
dma_resv_list_free(list);
|
||||||
dma_fence_put(old);
|
dma_fence_put(excl);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -399,99 +489,61 @@ EXPORT_SYMBOL(dma_resv_copy_fences);
|
|||||||
* dma_resv_get_fences - Get an object's shared and exclusive
|
* dma_resv_get_fences - Get an object's shared and exclusive
|
||||||
* fences without update side lock held
|
* fences without update side lock held
|
||||||
* @obj: the reservation object
|
* @obj: the reservation object
|
||||||
* @pfence_excl: the returned exclusive fence (or NULL)
|
* @fence_excl: the returned exclusive fence (or NULL)
|
||||||
* @pshared_count: the number of shared fences returned
|
* @shared_count: the number of shared fences returned
|
||||||
* @pshared: the array of shared fence ptrs returned (array is krealloc'd to
|
* @shared: the array of shared fence ptrs returned (array is krealloc'd to
|
||||||
* the required size, and must be freed by caller)
|
* the required size, and must be freed by caller)
|
||||||
*
|
*
|
||||||
* Retrieve all fences from the reservation object. If the pointer for the
|
* Retrieve all fences from the reservation object. If the pointer for the
|
||||||
* exclusive fence is not specified the fence is put into the array of the
|
* exclusive fence is not specified the fence is put into the array of the
|
||||||
* shared fences as well. Returns either zero or -ENOMEM.
|
* shared fences as well. Returns either zero or -ENOMEM.
|
||||||
*/
|
*/
|
||||||
int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **pfence_excl,
|
int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **fence_excl,
|
||||||
unsigned int *pshared_count,
|
unsigned int *shared_count, struct dma_fence ***shared)
|
||||||
struct dma_fence ***pshared)
|
|
||||||
{
|
{
|
||||||
struct dma_fence **shared = NULL;
|
struct dma_resv_iter cursor;
|
||||||
struct dma_fence *fence_excl;
|
struct dma_fence *fence;
|
||||||
unsigned int shared_count;
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
do {
|
*shared_count = 0;
|
||||||
struct dma_resv_list *fobj;
|
*shared = NULL;
|
||||||
unsigned int i, seq;
|
|
||||||
size_t sz = 0;
|
|
||||||
|
|
||||||
shared_count = i = 0;
|
if (fence_excl)
|
||||||
|
*fence_excl = NULL;
|
||||||
|
|
||||||
rcu_read_lock();
|
dma_resv_iter_begin(&cursor, obj, true);
|
||||||
seq = read_seqcount_begin(&obj->seq);
|
dma_resv_for_each_fence_unlocked(&cursor, fence) {
|
||||||
|
|
||||||
fence_excl = dma_resv_excl_fence(obj);
|
if (dma_resv_iter_is_restarted(&cursor)) {
|
||||||
if (fence_excl && !dma_fence_get_rcu(fence_excl))
|
unsigned int count;
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
fobj = dma_resv_shared_list(obj);
|
while (*shared_count)
|
||||||
if (fobj)
|
dma_fence_put((*shared)[--(*shared_count)]);
|
||||||
sz += sizeof(*shared) * fobj->shared_max;
|
|
||||||
|
|
||||||
if (!pfence_excl && fence_excl)
|
if (fence_excl)
|
||||||
sz += sizeof(*shared);
|
dma_fence_put(*fence_excl);
|
||||||
|
|
||||||
if (sz) {
|
count = cursor.fences ? cursor.fences->shared_count : 0;
|
||||||
struct dma_fence **nshared;
|
count += fence_excl ? 0 : 1;
|
||||||
|
|
||||||
nshared = krealloc(shared, sz,
|
/* Eventually re-allocate the array */
|
||||||
GFP_NOWAIT | __GFP_NOWARN);
|
*shared = krealloc_array(*shared, count,
|
||||||
if (!nshared) {
|
sizeof(void *),
|
||||||
rcu_read_unlock();
|
GFP_KERNEL);
|
||||||
|
if (count && !*shared) {
|
||||||
dma_fence_put(fence_excl);
|
dma_resv_iter_end(&cursor);
|
||||||
fence_excl = NULL;
|
return -ENOMEM;
|
||||||
|
|
||||||
nshared = krealloc(shared, sz, GFP_KERNEL);
|
|
||||||
if (nshared) {
|
|
||||||
shared = nshared;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = -ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
shared = nshared;
|
|
||||||
shared_count = fobj ? fobj->shared_count : 0;
|
|
||||||
for (i = 0; i < shared_count; ++i) {
|
|
||||||
shared[i] = rcu_dereference(fobj->shared[i]);
|
|
||||||
if (!dma_fence_get_rcu(shared[i]))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) {
|
dma_fence_get(fence);
|
||||||
while (i--)
|
if (dma_resv_iter_is_exclusive(&cursor) && fence_excl)
|
||||||
dma_fence_put(shared[i]);
|
*fence_excl = fence;
|
||||||
dma_fence_put(fence_excl);
|
else
|
||||||
goto unlock;
|
(*shared)[(*shared_count)++] = fence;
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
unlock:
|
|
||||||
rcu_read_unlock();
|
|
||||||
} while (ret);
|
|
||||||
|
|
||||||
if (pfence_excl)
|
|
||||||
*pfence_excl = fence_excl;
|
|
||||||
else if (fence_excl)
|
|
||||||
shared[shared_count++] = fence_excl;
|
|
||||||
|
|
||||||
if (!shared_count) {
|
|
||||||
kfree(shared);
|
|
||||||
shared = NULL;
|
|
||||||
}
|
}
|
||||||
|
dma_resv_iter_end(&cursor);
|
||||||
|
|
||||||
*pshared_count = shared_count;
|
return 0;
|
||||||
*pshared = shared;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dma_resv_get_fences);
|
EXPORT_SYMBOL_GPL(dma_resv_get_fences);
|
||||||
|
|
||||||
@ -513,94 +565,25 @@ long dma_resv_wait_timeout(struct dma_resv *obj, bool wait_all, bool intr,
|
|||||||
unsigned long timeout)
|
unsigned long timeout)
|
||||||
{
|
{
|
||||||
long ret = timeout ? timeout : 1;
|
long ret = timeout ? timeout : 1;
|
||||||
unsigned int seq, shared_count;
|
struct dma_resv_iter cursor;
|
||||||
struct dma_fence *fence;
|
struct dma_fence *fence;
|
||||||
int i;
|
|
||||||
|
|
||||||
retry:
|
dma_resv_iter_begin(&cursor, obj, wait_all);
|
||||||
shared_count = 0;
|
dma_resv_for_each_fence_unlocked(&cursor, fence) {
|
||||||
seq = read_seqcount_begin(&obj->seq);
|
|
||||||
rcu_read_lock();
|
|
||||||
i = -1;
|
|
||||||
|
|
||||||
fence = dma_resv_excl_fence(obj);
|
|
||||||
if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
|
|
||||||
if (!dma_fence_get_rcu(fence))
|
|
||||||
goto unlock_retry;
|
|
||||||
|
|
||||||
if (dma_fence_is_signaled(fence)) {
|
|
||||||
dma_fence_put(fence);
|
|
||||||
fence = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fence = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wait_all) {
|
|
||||||
struct dma_resv_list *fobj = dma_resv_shared_list(obj);
|
|
||||||
|
|
||||||
if (fobj)
|
|
||||||
shared_count = fobj->shared_count;
|
|
||||||
|
|
||||||
for (i = 0; !fence && i < shared_count; ++i) {
|
|
||||||
struct dma_fence *lfence;
|
|
||||||
|
|
||||||
lfence = rcu_dereference(fobj->shared[i]);
|
|
||||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
|
|
||||||
&lfence->flags))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!dma_fence_get_rcu(lfence))
|
|
||||||
goto unlock_retry;
|
|
||||||
|
|
||||||
if (dma_fence_is_signaled(lfence)) {
|
|
||||||
dma_fence_put(lfence);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fence = lfence;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
if (fence) {
|
|
||||||
if (read_seqcount_retry(&obj->seq, seq)) {
|
|
||||||
dma_fence_put(fence);
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = dma_fence_wait_timeout(fence, intr, ret);
|
ret = dma_fence_wait_timeout(fence, intr, ret);
|
||||||
dma_fence_put(fence);
|
if (ret <= 0) {
|
||||||
if (ret > 0 && wait_all && (i + 1 < shared_count))
|
dma_resv_iter_end(&cursor);
|
||||||
goto retry;
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
dma_resv_iter_end(&cursor);
|
||||||
|
|
||||||
unlock_retry:
|
return ret;
|
||||||
rcu_read_unlock();
|
|
||||||
goto retry;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dma_resv_wait_timeout);
|
EXPORT_SYMBOL_GPL(dma_resv_wait_timeout);
|
||||||
|
|
||||||
|
|
||||||
static inline int dma_resv_test_signaled_single(struct dma_fence *passed_fence)
|
|
||||||
{
|
|
||||||
struct dma_fence *fence, *lfence = passed_fence;
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &lfence->flags)) {
|
|
||||||
fence = dma_fence_get_rcu(lfence);
|
|
||||||
if (!fence)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = !!dma_fence_is_signaled(fence);
|
|
||||||
dma_fence_put(fence);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dma_resv_test_signaled - Test if a reservation object's fences have been
|
* dma_resv_test_signaled - Test if a reservation object's fences have been
|
||||||
* signaled.
|
* signaled.
|
||||||
@ -609,49 +592,24 @@ static inline int dma_resv_test_signaled_single(struct dma_fence *passed_fence)
|
|||||||
* fence
|
* fence
|
||||||
*
|
*
|
||||||
* Callers are not required to hold specific locks, but maybe hold
|
* Callers are not required to hold specific locks, but maybe hold
|
||||||
* dma_resv_lock() already
|
* dma_resv_lock() already.
|
||||||
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* true if all fences signaled, else false
|
*
|
||||||
|
* True if all fences signaled, else false.
|
||||||
*/
|
*/
|
||||||
bool dma_resv_test_signaled(struct dma_resv *obj, bool test_all)
|
bool dma_resv_test_signaled(struct dma_resv *obj, bool test_all)
|
||||||
{
|
{
|
||||||
|
struct dma_resv_iter cursor;
|
||||||
struct dma_fence *fence;
|
struct dma_fence *fence;
|
||||||
unsigned int seq;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
dma_resv_iter_begin(&cursor, obj, test_all);
|
||||||
retry:
|
dma_resv_for_each_fence_unlocked(&cursor, fence) {
|
||||||
ret = true;
|
dma_resv_iter_end(&cursor);
|
||||||
seq = read_seqcount_begin(&obj->seq);
|
return false;
|
||||||
|
|
||||||
if (test_all) {
|
|
||||||
struct dma_resv_list *fobj = dma_resv_shared_list(obj);
|
|
||||||
unsigned int i, shared_count;
|
|
||||||
|
|
||||||
shared_count = fobj ? fobj->shared_count : 0;
|
|
||||||
for (i = 0; i < shared_count; ++i) {
|
|
||||||
fence = rcu_dereference(fobj->shared[i]);
|
|
||||||
ret = dma_resv_test_signaled_single(fence);
|
|
||||||
if (ret < 0)
|
|
||||||
goto retry;
|
|
||||||
else if (!ret)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
dma_resv_iter_end(&cursor);
|
||||||
fence = dma_resv_excl_fence(obj);
|
return true;
|
||||||
if (ret && fence) {
|
|
||||||
ret = dma_resv_test_signaled_single(fence);
|
|
||||||
if (ret < 0)
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read_seqcount_retry(&obj->seq, seq))
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dma_resv_test_signaled);
|
EXPORT_SYMBOL_GPL(dma_resv_test_signaled);
|
||||||
|
|
||||||
|
@ -40,11 +40,12 @@ struct dma_heap_attachment {
|
|||||||
bool mapped;
|
bool mapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO | __GFP_COMP)
|
||||||
|
#define MID_ORDER_GFP (LOW_ORDER_GFP | __GFP_NOWARN)
|
||||||
#define HIGH_ORDER_GFP (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \
|
#define HIGH_ORDER_GFP (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \
|
||||||
| __GFP_NORETRY) & ~__GFP_RECLAIM) \
|
| __GFP_NORETRY) & ~__GFP_RECLAIM) \
|
||||||
| __GFP_COMP)
|
| __GFP_COMP)
|
||||||
#define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO | __GFP_COMP)
|
static gfp_t order_flags[] = {HIGH_ORDER_GFP, MID_ORDER_GFP, LOW_ORDER_GFP};
|
||||||
static gfp_t order_flags[] = {HIGH_ORDER_GFP, LOW_ORDER_GFP, LOW_ORDER_GFP};
|
|
||||||
/*
|
/*
|
||||||
* The selection of the orders used for allocation (1MB, 64K, 4K) is designed
|
* The selection of the orders used for allocation (1MB, 64K, 4K) is designed
|
||||||
* to match with the sizes often found in IOMMUs. Using order 4 pages instead
|
* to match with the sizes often found in IOMMUs. Using order 4 pages instead
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
|
||||||
/*
|
|
||||||
* seqno-fence, using a dma-buf to synchronize fencing
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012 Texas Instruments
|
|
||||||
* Copyright (C) 2012-2014 Canonical Ltd
|
|
||||||
* Authors:
|
|
||||||
* Rob Clark <robdclark@gmail.com>
|
|
||||||
* Maarten Lankhorst <maarten.lankhorst@canonical.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/export.h>
|
|
||||||
#include <linux/seqno-fence.h>
|
|
||||||
|
|
||||||
static const char *seqno_fence_get_driver_name(struct dma_fence *fence)
|
|
||||||
{
|
|
||||||
struct seqno_fence *seqno_fence = to_seqno_fence(fence);
|
|
||||||
|
|
||||||
return seqno_fence->ops->get_driver_name(fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *seqno_fence_get_timeline_name(struct dma_fence *fence)
|
|
||||||
{
|
|
||||||
struct seqno_fence *seqno_fence = to_seqno_fence(fence);
|
|
||||||
|
|
||||||
return seqno_fence->ops->get_timeline_name(fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool seqno_enable_signaling(struct dma_fence *fence)
|
|
||||||
{
|
|
||||||
struct seqno_fence *seqno_fence = to_seqno_fence(fence);
|
|
||||||
|
|
||||||
return seqno_fence->ops->enable_signaling(fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool seqno_signaled(struct dma_fence *fence)
|
|
||||||
{
|
|
||||||
struct seqno_fence *seqno_fence = to_seqno_fence(fence);
|
|
||||||
|
|
||||||
return seqno_fence->ops->signaled && seqno_fence->ops->signaled(fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void seqno_release(struct dma_fence *fence)
|
|
||||||
{
|
|
||||||
struct seqno_fence *f = to_seqno_fence(fence);
|
|
||||||
|
|
||||||
dma_buf_put(f->sync_buf);
|
|
||||||
if (f->ops->release)
|
|
||||||
f->ops->release(fence);
|
|
||||||
else
|
|
||||||
dma_fence_free(&f->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static signed long seqno_wait(struct dma_fence *fence, bool intr,
|
|
||||||
signed long timeout)
|
|
||||||
{
|
|
||||||
struct seqno_fence *f = to_seqno_fence(fence);
|
|
||||||
|
|
||||||
return f->ops->wait(fence, intr, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct dma_fence_ops seqno_fence_ops = {
|
|
||||||
.get_driver_name = seqno_fence_get_driver_name,
|
|
||||||
.get_timeline_name = seqno_fence_get_timeline_name,
|
|
||||||
.enable_signaling = seqno_enable_signaling,
|
|
||||||
.signaled = seqno_signaled,
|
|
||||||
.wait = seqno_wait,
|
|
||||||
.release = seqno_release,
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL(seqno_fence_ops);
|
|
@ -103,7 +103,7 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
|
|||||||
config DRM_FBDEV_EMULATION
|
config DRM_FBDEV_EMULATION
|
||||||
bool "Enable legacy fbdev support for your modesetting driver"
|
bool "Enable legacy fbdev support for your modesetting driver"
|
||||||
depends on DRM
|
depends on DRM
|
||||||
depends on FB
|
depends on FB=y || FB=DRM
|
||||||
select DRM_KMS_HELPER
|
select DRM_KMS_HELPER
|
||||||
select FB_CFB_FILLRECT
|
select FB_CFB_FILLRECT
|
||||||
select FB_CFB_COPYAREA
|
select FB_CFB_COPYAREA
|
||||||
@ -211,7 +211,7 @@ config DRM_KMS_CMA_HELPER
|
|||||||
|
|
||||||
config DRM_GEM_SHMEM_HELPER
|
config DRM_GEM_SHMEM_HELPER
|
||||||
bool
|
bool
|
||||||
depends on DRM
|
depends on DRM && MMU
|
||||||
help
|
help
|
||||||
Choose this if you need the GEM shmem helper functions
|
Choose this if you need the GEM shmem helper functions
|
||||||
|
|
||||||
@ -271,7 +271,8 @@ source "drivers/gpu/drm/kmb/Kconfig"
|
|||||||
|
|
||||||
config DRM_VGEM
|
config DRM_VGEM
|
||||||
tristate "Virtual GEM provider"
|
tristate "Virtual GEM provider"
|
||||||
depends on DRM
|
depends on DRM && MMU
|
||||||
|
select DRM_GEM_SHMEM_HELPER
|
||||||
help
|
help
|
||||||
Choose this option to get a virtual graphics memory manager,
|
Choose this option to get a virtual graphics memory manager,
|
||||||
as used by Mesa's software renderer for enhanced performance.
|
as used by Mesa's software renderer for enhanced performance.
|
||||||
@ -279,7 +280,7 @@ config DRM_VGEM
|
|||||||
|
|
||||||
config DRM_VKMS
|
config DRM_VKMS
|
||||||
tristate "Virtual KMS (EXPERIMENTAL)"
|
tristate "Virtual KMS (EXPERIMENTAL)"
|
||||||
depends on DRM
|
depends on DRM && MMU
|
||||||
select DRM_KMS_HELPER
|
select DRM_KMS_HELPER
|
||||||
select DRM_GEM_SHMEM_HELPER
|
select DRM_GEM_SHMEM_HELPER
|
||||||
select CRC32
|
select CRC32
|
||||||
@ -351,8 +352,6 @@ source "drivers/gpu/drm/hisilicon/Kconfig"
|
|||||||
|
|
||||||
source "drivers/gpu/drm/mediatek/Kconfig"
|
source "drivers/gpu/drm/mediatek/Kconfig"
|
||||||
|
|
||||||
source "drivers/gpu/drm/zte/Kconfig"
|
|
||||||
|
|
||||||
source "drivers/gpu/drm/mxsfb/Kconfig"
|
source "drivers/gpu/drm/mxsfb/Kconfig"
|
||||||
|
|
||||||
source "drivers/gpu/drm/meson/Kconfig"
|
source "drivers/gpu/drm/meson/Kconfig"
|
||||||
|
@ -113,7 +113,6 @@ obj-y += bridge/
|
|||||||
obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
|
obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
|
||||||
obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
|
obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
|
||||||
obj-y += hisilicon/
|
obj-y += hisilicon/
|
||||||
obj-$(CONFIG_DRM_ZTE) += zte/
|
|
||||||
obj-$(CONFIG_DRM_MXSFB) += mxsfb/
|
obj-$(CONFIG_DRM_MXSFB) += mxsfb/
|
||||||
obj-y += tiny/
|
obj-y += tiny/
|
||||||
obj-$(CONFIG_DRM_PL111) += pl111/
|
obj-$(CONFIG_DRM_PL111) += pl111/
|
||||||
|
@ -73,10 +73,8 @@ amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce
|
|||||||
|
|
||||||
amdgpu-y += \
|
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 navi10_reg_init.o navi14_reg_init.o \
|
vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \
|
||||||
arct_reg_init.o navi12_reg_init.o mxgpu_nv.o sienna_cichlid_reg_init.o vangogh_reg_init.o \
|
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o
|
||||||
nbio_v7_2.o dimgrey_cavefish_reg_init.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o \
|
|
||||||
beige_goby_reg_init.o yellow_carp_reg_init.o cyan_skillfish_reg_init.o
|
|
||||||
|
|
||||||
# add DF block
|
# add DF block
|
||||||
amdgpu-y += \
|
amdgpu-y += \
|
||||||
|
@ -307,6 +307,8 @@ static int aldebaran_mode2_restore_ip(struct amdgpu_device *adev)
|
|||||||
adev->ip_blocks[i].status.late_initialized = true;
|
adev->ip_blocks[i].status.late_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
amdgpu_ras_set_error_query_ready(adev, true);
|
||||||
|
|
||||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
|
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE);
|
||||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
|
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE);
|
||||||
|
|
||||||
|
@ -205,6 +205,7 @@ extern struct amdgpu_mgpu_info mgpu_info;
|
|||||||
extern int amdgpu_ras_enable;
|
extern int amdgpu_ras_enable;
|
||||||
extern uint amdgpu_ras_mask;
|
extern uint amdgpu_ras_mask;
|
||||||
extern int amdgpu_bad_page_threshold;
|
extern int amdgpu_bad_page_threshold;
|
||||||
|
extern bool amdgpu_ignore_bad_page_threshold;
|
||||||
extern struct amdgpu_watchdog_timer amdgpu_watchdog_timer;
|
extern struct amdgpu_watchdog_timer amdgpu_watchdog_timer;
|
||||||
extern int amdgpu_async_gfx_ring;
|
extern int amdgpu_async_gfx_ring;
|
||||||
extern int amdgpu_mcbp;
|
extern int amdgpu_mcbp;
|
||||||
@ -744,6 +745,7 @@ enum amd_hw_ip_block_type {
|
|||||||
UVD_HWIP,
|
UVD_HWIP,
|
||||||
VCN_HWIP = UVD_HWIP,
|
VCN_HWIP = UVD_HWIP,
|
||||||
JPEG_HWIP = VCN_HWIP,
|
JPEG_HWIP = VCN_HWIP,
|
||||||
|
VCN1_HWIP,
|
||||||
VCE_HWIP,
|
VCE_HWIP,
|
||||||
DF_HWIP,
|
DF_HWIP,
|
||||||
DCE_HWIP,
|
DCE_HWIP,
|
||||||
@ -755,11 +757,16 @@ enum amd_hw_ip_block_type {
|
|||||||
CLK_HWIP,
|
CLK_HWIP,
|
||||||
UMC_HWIP,
|
UMC_HWIP,
|
||||||
RSMU_HWIP,
|
RSMU_HWIP,
|
||||||
|
XGMI_HWIP,
|
||||||
|
DCI_HWIP,
|
||||||
MAX_HWIP
|
MAX_HWIP
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HWIP_MAX_INSTANCE 10
|
#define HWIP_MAX_INSTANCE 10
|
||||||
|
|
||||||
|
#define HW_ID_MAX 300
|
||||||
|
#define IP_VERSION(mj, mn, rv) (((mj) << 16) | ((mn) << 8) | (rv))
|
||||||
|
|
||||||
struct amd_powerplay {
|
struct amd_powerplay {
|
||||||
void *pp_handle;
|
void *pp_handle;
|
||||||
const struct amd_pm_funcs *pp_funcs;
|
const struct amd_pm_funcs *pp_funcs;
|
||||||
@ -830,6 +837,7 @@ struct amdgpu_device {
|
|||||||
struct notifier_block acpi_nb;
|
struct notifier_block acpi_nb;
|
||||||
struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS];
|
struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS];
|
||||||
struct debugfs_blob_wrapper debugfs_vbios_blob;
|
struct debugfs_blob_wrapper debugfs_vbios_blob;
|
||||||
|
struct debugfs_blob_wrapper debugfs_discovery_blob;
|
||||||
struct mutex srbm_mutex;
|
struct mutex srbm_mutex;
|
||||||
/* GRBM index mutex. Protects concurrent access to GRBM index */
|
/* GRBM index mutex. Protects concurrent access to GRBM index */
|
||||||
struct mutex grbm_idx_mutex;
|
struct mutex grbm_idx_mutex;
|
||||||
@ -1078,8 +1086,6 @@ struct amdgpu_device {
|
|||||||
char product_name[32];
|
char product_name[32];
|
||||||
char serial[20];
|
char serial[20];
|
||||||
|
|
||||||
struct amdgpu_autodump autodump;
|
|
||||||
|
|
||||||
atomic_t throttling_logging_enabled;
|
atomic_t throttling_logging_enabled;
|
||||||
struct ratelimit_state throttling_logging_rs;
|
struct ratelimit_state throttling_logging_rs;
|
||||||
uint32_t ras_hw_enabled;
|
uint32_t ras_hw_enabled;
|
||||||
@ -1090,6 +1096,7 @@ struct amdgpu_device {
|
|||||||
pci_channel_state_t pci_channel_state;
|
pci_channel_state_t pci_channel_state;
|
||||||
|
|
||||||
struct amdgpu_reset_control *reset_cntl;
|
struct amdgpu_reset_control *reset_cntl;
|
||||||
|
uint32_t ip_versions[HW_ID_MAX][HWIP_MAX_INSTANCE];
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
|
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include <linux/dma-buf.h>
|
#include <linux/dma-buf.h>
|
||||||
#include "amdgpu_xgmi.h"
|
#include "amdgpu_xgmi.h"
|
||||||
#include <uapi/linux/kfd_ioctl.h>
|
#include <uapi/linux/kfd_ioctl.h>
|
||||||
|
#include "amdgpu_ras.h"
|
||||||
|
#include "amdgpu_umc.h"
|
||||||
|
|
||||||
/* Total memory size in system memory and all GPU VRAM. Used to
|
/* Total memory size in system memory and all GPU VRAM. Used to
|
||||||
* estimate worst case amount of memory to reserve for page tables
|
* estimate worst case amount of memory to reserve for page tables
|
||||||
@ -70,8 +72,7 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
|
|||||||
if (!kfd_initialized)
|
if (!kfd_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
adev->kfd.dev = kgd2kfd_probe((struct kgd_dev *)adev,
|
adev->kfd.dev = kgd2kfd_probe((struct kgd_dev *)adev, vf);
|
||||||
adev->pdev, adev->asic_type, vf);
|
|
||||||
|
|
||||||
if (adev->kfd.dev)
|
if (adev->kfd.dev)
|
||||||
amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
|
amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
|
||||||
@ -780,3 +781,15 @@ bool amdgpu_amdkfd_have_atomics_support(struct kgd_dev *kgd)
|
|||||||
|
|
||||||
return adev->have_atomics_support;
|
return adev->have_atomics_support;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void amdgpu_amdkfd_ras_poison_consumption_handler(struct kgd_dev *kgd)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
|
||||||
|
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||||
|
|
||||||
|
/* CPU MCA will handle page retirement if connected_to_cpu is 1 */
|
||||||
|
if (!adev->gmc.xgmi.connected_to_cpu)
|
||||||
|
amdgpu_umc_process_ras_data_cb(adev, &err_data, NULL);
|
||||||
|
else
|
||||||
|
amdgpu_amdkfd_gpu_reset(kgd);
|
||||||
|
}
|
||||||
|
@ -279,6 +279,8 @@ int amdgpu_amdkfd_gpuvm_sync_memory(
|
|||||||
struct kgd_dev *kgd, struct kgd_mem *mem, bool intr);
|
struct kgd_dev *kgd, struct kgd_mem *mem, bool intr);
|
||||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd,
|
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd,
|
||||||
struct kgd_mem *mem, void **kptr, uint64_t *size);
|
struct kgd_mem *mem, void **kptr, uint64_t *size);
|
||||||
|
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_dev *kgd, struct kgd_mem *mem);
|
||||||
|
|
||||||
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
|
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
|
||||||
struct dma_fence **ef);
|
struct dma_fence **ef);
|
||||||
int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
|
int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
|
||||||
@ -290,6 +292,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd,
|
|||||||
uint64_t *mmap_offset);
|
uint64_t *mmap_offset);
|
||||||
int amdgpu_amdkfd_get_tile_config(struct kgd_dev *kgd,
|
int amdgpu_amdkfd_get_tile_config(struct kgd_dev *kgd,
|
||||||
struct tile_config *config);
|
struct tile_config *config);
|
||||||
|
void amdgpu_amdkfd_ras_poison_consumption_handler(struct kgd_dev *kgd);
|
||||||
#if IS_ENABLED(CONFIG_HSA_AMD)
|
#if IS_ENABLED(CONFIG_HSA_AMD)
|
||||||
void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
|
void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
|
||||||
void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
|
void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
|
||||||
@ -321,8 +324,7 @@ int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm,
|
|||||||
#if IS_ENABLED(CONFIG_HSA_AMD)
|
#if IS_ENABLED(CONFIG_HSA_AMD)
|
||||||
int kgd2kfd_init(void);
|
int kgd2kfd_init(void);
|
||||||
void kgd2kfd_exit(void);
|
void kgd2kfd_exit(void);
|
||||||
struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev,
|
struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, bool vf);
|
||||||
unsigned int asic_type, bool vf);
|
|
||||||
bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||||
struct drm_device *ddev,
|
struct drm_device *ddev,
|
||||||
const struct kgd2kfd_shared_resources *gpu_resources);
|
const struct kgd2kfd_shared_resources *gpu_resources);
|
||||||
@ -346,8 +348,7 @@ static inline void kgd2kfd_exit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev,
|
struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, bool vf)
|
||||||
unsigned int asic_type, bool vf)
|
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1503,7 +1503,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
|||||||
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
|
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
|
||||||
drm_vma_node_revoke(&gobj->vma_node, drm_priv);
|
drm_vma_node_revoke(&gobj->vma_node, drm_priv);
|
||||||
err_node_allow:
|
err_node_allow:
|
||||||
amdgpu_bo_unref(&bo);
|
drm_gem_object_put(gobj);
|
||||||
/* Don't unreserve system mem limit twice */
|
/* Don't unreserve system mem limit twice */
|
||||||
goto err_reserve_limit;
|
goto err_reserve_limit;
|
||||||
err_bo_create:
|
err_bo_create:
|
||||||
@ -1871,6 +1871,16 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_dev *kgd, struct kgd_mem *mem)
|
||||||
|
{
|
||||||
|
struct amdgpu_bo *bo = mem->bo;
|
||||||
|
|
||||||
|
amdgpu_bo_reserve(bo, true);
|
||||||
|
amdgpu_bo_kunmap(bo);
|
||||||
|
amdgpu_bo_unpin(bo);
|
||||||
|
amdgpu_bo_unreserve(bo);
|
||||||
|
}
|
||||||
|
|
||||||
int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
|
int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
|
||||||
struct kfd_vm_fault_info *mem)
|
struct kfd_vm_fault_info *mem)
|
||||||
{
|
{
|
||||||
@ -2041,19 +2051,26 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
|
|||||||
/* Get updated user pages */
|
/* Get updated user pages */
|
||||||
ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
|
ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_debug("%s: Failed to get user pages: %d\n",
|
pr_debug("Failed %d to get user pages\n", ret);
|
||||||
__func__, ret);
|
|
||||||
|
|
||||||
/* Return error -EBUSY or -ENOMEM, retry restore */
|
/* Return -EFAULT bad address error as success. It will
|
||||||
return ret;
|
* fail later with a VM fault if the GPU tries to access
|
||||||
|
* it. Better than hanging indefinitely with stalled
|
||||||
|
* user mode queues.
|
||||||
|
*
|
||||||
|
* Return other error -EBUSY or -ENOMEM to retry restore
|
||||||
|
*/
|
||||||
|
if (ret != -EFAULT)
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Cannot ignore the return code, must hold
|
||||||
|
* notifier_lock
|
||||||
|
*/
|
||||||
|
amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: Cannot ignore the return code, must hold
|
|
||||||
* notifier_lock
|
|
||||||
*/
|
|
||||||
amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
|
|
||||||
|
|
||||||
/* Mark the BO as valid unless it was invalidated
|
/* Mark the BO as valid unless it was invalidated
|
||||||
* again concurrently.
|
* again concurrently.
|
||||||
*/
|
*/
|
||||||
|
@ -61,7 +61,7 @@ static void amdgpu_bo_list_free(struct kref *ref)
|
|||||||
|
|
||||||
int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
|
int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
|
||||||
struct drm_amdgpu_bo_list_entry *info,
|
struct drm_amdgpu_bo_list_entry *info,
|
||||||
unsigned num_entries, struct amdgpu_bo_list **result)
|
size_t num_entries, struct amdgpu_bo_list **result)
|
||||||
{
|
{
|
||||||
unsigned last_entry = 0, first_userptr = num_entries;
|
unsigned last_entry = 0, first_userptr = num_entries;
|
||||||
struct amdgpu_bo_list_entry *array;
|
struct amdgpu_bo_list_entry *array;
|
||||||
|
@ -61,7 +61,7 @@ int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
|
|||||||
int amdgpu_bo_list_create(struct amdgpu_device *adev,
|
int amdgpu_bo_list_create(struct amdgpu_device *adev,
|
||||||
struct drm_file *filp,
|
struct drm_file *filp,
|
||||||
struct drm_amdgpu_bo_list_entry *info,
|
struct drm_amdgpu_bo_list_entry *info,
|
||||||
unsigned num_entries,
|
size_t num_entries,
|
||||||
struct amdgpu_bo_list **list);
|
struct amdgpu_bo_list **list);
|
||||||
|
|
||||||
static inline struct amdgpu_bo_list_entry *
|
static inline struct amdgpu_bo_list_entry *
|
||||||
|
@ -1222,6 +1222,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
|||||||
if (r)
|
if (r)
|
||||||
goto error_unlock;
|
goto error_unlock;
|
||||||
|
|
||||||
|
drm_sched_job_arm(&job->base);
|
||||||
|
|
||||||
/* No memory allocation is allowed while holding the notifier lock.
|
/* No memory allocation is allowed while holding the notifier lock.
|
||||||
* The lock is held until amdgpu_cs_submit is finished and fence is
|
* The lock is held until amdgpu_cs_submit is finished and fence is
|
||||||
* added to BOs.
|
* added to BOs.
|
||||||
@ -1259,7 +1261,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
|||||||
|
|
||||||
trace_amdgpu_cs_ioctl(job);
|
trace_amdgpu_cs_ioctl(job);
|
||||||
amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket);
|
amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket);
|
||||||
drm_sched_entity_push_job(&job->base, entity);
|
drm_sched_entity_push_job(&job->base);
|
||||||
|
|
||||||
amdgpu_vm_move_to_lru_tail(p->adev, &fpriv->vm);
|
amdgpu_vm_move_to_lru_tail(p->adev, &fpriv->vm);
|
||||||
|
|
||||||
|
@ -43,14 +43,61 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = {
|
|||||||
[AMDGPU_HW_IP_VCN_JPEG] = 1,
|
[AMDGPU_HW_IP_VCN_JPEG] = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int amdgpu_ctx_priority_permit(struct drm_file *filp,
|
bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio)
|
||||||
enum drm_sched_priority priority)
|
|
||||||
{
|
{
|
||||||
if (priority < 0 || priority >= DRM_SCHED_PRIORITY_COUNT)
|
switch (ctx_prio) {
|
||||||
|
case AMDGPU_CTX_PRIORITY_UNSET:
|
||||||
|
case AMDGPU_CTX_PRIORITY_VERY_LOW:
|
||||||
|
case AMDGPU_CTX_PRIORITY_LOW:
|
||||||
|
case AMDGPU_CTX_PRIORITY_NORMAL:
|
||||||
|
case AMDGPU_CTX_PRIORITY_HIGH:
|
||||||
|
case AMDGPU_CTX_PRIORITY_VERY_HIGH:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum drm_sched_priority
|
||||||
|
amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio)
|
||||||
|
{
|
||||||
|
switch (ctx_prio) {
|
||||||
|
case AMDGPU_CTX_PRIORITY_UNSET:
|
||||||
|
return DRM_SCHED_PRIORITY_UNSET;
|
||||||
|
|
||||||
|
case AMDGPU_CTX_PRIORITY_VERY_LOW:
|
||||||
|
return DRM_SCHED_PRIORITY_MIN;
|
||||||
|
|
||||||
|
case AMDGPU_CTX_PRIORITY_LOW:
|
||||||
|
return DRM_SCHED_PRIORITY_MIN;
|
||||||
|
|
||||||
|
case AMDGPU_CTX_PRIORITY_NORMAL:
|
||||||
|
return DRM_SCHED_PRIORITY_NORMAL;
|
||||||
|
|
||||||
|
case AMDGPU_CTX_PRIORITY_HIGH:
|
||||||
|
return DRM_SCHED_PRIORITY_HIGH;
|
||||||
|
|
||||||
|
case AMDGPU_CTX_PRIORITY_VERY_HIGH:
|
||||||
|
return DRM_SCHED_PRIORITY_HIGH;
|
||||||
|
|
||||||
|
/* This should not happen as we sanitized userspace provided priority
|
||||||
|
* already, WARN if this happens.
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
WARN(1, "Invalid context priority %d\n", ctx_prio);
|
||||||
|
return DRM_SCHED_PRIORITY_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_ctx_priority_permit(struct drm_file *filp,
|
||||||
|
int32_t priority)
|
||||||
|
{
|
||||||
|
if (!amdgpu_ctx_priority_is_valid(priority))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* NORMAL and below are accessible by everyone */
|
/* NORMAL and below are accessible by everyone */
|
||||||
if (priority <= DRM_SCHED_PRIORITY_NORMAL)
|
if (priority <= AMDGPU_CTX_PRIORITY_NORMAL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (capable(CAP_SYS_NICE))
|
if (capable(CAP_SYS_NICE))
|
||||||
@ -62,26 +109,51 @@ static int amdgpu_ctx_priority_permit(struct drm_file *filp,
|
|||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum gfx_pipe_priority amdgpu_ctx_sched_prio_to_compute_prio(enum drm_sched_priority prio)
|
static enum amdgpu_gfx_pipe_priority amdgpu_ctx_prio_to_compute_prio(int32_t prio)
|
||||||
{
|
{
|
||||||
switch (prio) {
|
switch (prio) {
|
||||||
case DRM_SCHED_PRIORITY_HIGH:
|
case AMDGPU_CTX_PRIORITY_HIGH:
|
||||||
case DRM_SCHED_PRIORITY_KERNEL:
|
case AMDGPU_CTX_PRIORITY_VERY_HIGH:
|
||||||
return AMDGPU_GFX_PIPE_PRIO_HIGH;
|
return AMDGPU_GFX_PIPE_PRIO_HIGH;
|
||||||
default:
|
default:
|
||||||
return AMDGPU_GFX_PIPE_PRIO_NORMAL;
|
return AMDGPU_GFX_PIPE_PRIO_NORMAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int amdgpu_ctx_prio_sched_to_hw(struct amdgpu_device *adev,
|
static enum amdgpu_ring_priority_level amdgpu_ctx_sched_prio_to_ring_prio(int32_t prio)
|
||||||
enum drm_sched_priority prio,
|
|
||||||
u32 hw_ip)
|
|
||||||
{
|
{
|
||||||
|
switch (prio) {
|
||||||
|
case AMDGPU_CTX_PRIORITY_HIGH:
|
||||||
|
return AMDGPU_RING_PRIO_1;
|
||||||
|
case AMDGPU_CTX_PRIORITY_VERY_HIGH:
|
||||||
|
return AMDGPU_RING_PRIO_2;
|
||||||
|
default:
|
||||||
|
return AMDGPU_RING_PRIO_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip)
|
||||||
|
{
|
||||||
|
struct amdgpu_device *adev = ctx->adev;
|
||||||
|
int32_t ctx_prio;
|
||||||
unsigned int hw_prio;
|
unsigned int hw_prio;
|
||||||
|
|
||||||
hw_prio = (hw_ip == AMDGPU_HW_IP_COMPUTE) ?
|
ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ?
|
||||||
amdgpu_ctx_sched_prio_to_compute_prio(prio) :
|
ctx->init_priority : ctx->override_priority;
|
||||||
AMDGPU_RING_PRIO_DEFAULT;
|
|
||||||
|
switch (hw_ip) {
|
||||||
|
case AMDGPU_HW_IP_COMPUTE:
|
||||||
|
hw_prio = amdgpu_ctx_prio_to_compute_prio(ctx_prio);
|
||||||
|
break;
|
||||||
|
case AMDGPU_HW_IP_VCE:
|
||||||
|
case AMDGPU_HW_IP_VCN_ENC:
|
||||||
|
hw_prio = amdgpu_ctx_sched_prio_to_ring_prio(ctx_prio);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
hw_prio = AMDGPU_RING_PRIO_DEFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
|
hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
|
||||||
if (adev->gpu_sched[hw_ip][hw_prio].num_scheds == 0)
|
if (adev->gpu_sched[hw_ip][hw_prio].num_scheds == 0)
|
||||||
hw_prio = AMDGPU_RING_PRIO_DEFAULT;
|
hw_prio = AMDGPU_RING_PRIO_DEFAULT;
|
||||||
@ -89,15 +161,17 @@ static unsigned int amdgpu_ctx_prio_sched_to_hw(struct amdgpu_device *adev,
|
|||||||
return hw_prio;
|
return hw_prio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
|
static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
|
||||||
const u32 ring)
|
const u32 ring)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = ctx->adev;
|
struct amdgpu_device *adev = ctx->adev;
|
||||||
struct amdgpu_ctx_entity *entity;
|
struct amdgpu_ctx_entity *entity;
|
||||||
struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
|
struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
|
||||||
unsigned num_scheds = 0;
|
unsigned num_scheds = 0;
|
||||||
|
int32_t ctx_prio;
|
||||||
unsigned int hw_prio;
|
unsigned int hw_prio;
|
||||||
enum drm_sched_priority priority;
|
enum drm_sched_priority drm_prio;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
entity = kzalloc(struct_size(entity, fences, amdgpu_sched_jobs),
|
entity = kzalloc(struct_size(entity, fences, amdgpu_sched_jobs),
|
||||||
@ -105,10 +179,11 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
|
|||||||
if (!entity)
|
if (!entity)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ?
|
||||||
|
ctx->init_priority : ctx->override_priority;
|
||||||
entity->sequence = 1;
|
entity->sequence = 1;
|
||||||
priority = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
|
hw_prio = amdgpu_ctx_get_hw_prio(ctx, hw_ip);
|
||||||
ctx->init_priority : ctx->override_priority;
|
drm_prio = amdgpu_ctx_to_drm_sched_prio(ctx_prio);
|
||||||
hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority, hw_ip);
|
|
||||||
|
|
||||||
hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
|
hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM);
|
||||||
scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
|
scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
|
||||||
@ -124,7 +199,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
|
|||||||
num_scheds = 1;
|
num_scheds = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = drm_sched_entity_init(&entity->entity, priority, scheds, num_scheds,
|
r = drm_sched_entity_init(&entity->entity, drm_prio, scheds, num_scheds,
|
||||||
&ctx->guilty);
|
&ctx->guilty);
|
||||||
if (r)
|
if (r)
|
||||||
goto error_free_entity;
|
goto error_free_entity;
|
||||||
@ -139,7 +214,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int amdgpu_ctx_init(struct amdgpu_device *adev,
|
static int amdgpu_ctx_init(struct amdgpu_device *adev,
|
||||||
enum drm_sched_priority priority,
|
int32_t priority,
|
||||||
struct drm_file *filp,
|
struct drm_file *filp,
|
||||||
struct amdgpu_ctx *ctx)
|
struct amdgpu_ctx *ctx)
|
||||||
{
|
{
|
||||||
@ -161,7 +236,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
|
|||||||
ctx->reset_counter_query = ctx->reset_counter;
|
ctx->reset_counter_query = ctx->reset_counter;
|
||||||
ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
|
ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
|
||||||
ctx->init_priority = priority;
|
ctx->init_priority = priority;
|
||||||
ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
|
ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -234,7 +309,7 @@ int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
|
|||||||
static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
|
static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
|
||||||
struct amdgpu_fpriv *fpriv,
|
struct amdgpu_fpriv *fpriv,
|
||||||
struct drm_file *filp,
|
struct drm_file *filp,
|
||||||
enum drm_sched_priority priority,
|
int32_t priority,
|
||||||
uint32_t *id)
|
uint32_t *id)
|
||||||
{
|
{
|
||||||
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
|
struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
|
||||||
@ -397,19 +472,19 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
enum drm_sched_priority priority;
|
int32_t priority;
|
||||||
|
|
||||||
union drm_amdgpu_ctx *args = data;
|
union drm_amdgpu_ctx *args = data;
|
||||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||||
struct amdgpu_fpriv *fpriv = filp->driver_priv;
|
struct amdgpu_fpriv *fpriv = filp->driver_priv;
|
||||||
|
|
||||||
id = args->in.ctx_id;
|
id = args->in.ctx_id;
|
||||||
r = amdgpu_to_sched_priority(args->in.priority, &priority);
|
priority = args->in.priority;
|
||||||
|
|
||||||
/* For backwards compatibility reasons, we need to accept
|
/* For backwards compatibility reasons, we need to accept
|
||||||
* ioctls with garbage in the priority field */
|
* ioctls with garbage in the priority field */
|
||||||
if (r == -EINVAL)
|
if (!amdgpu_ctx_priority_is_valid(priority))
|
||||||
priority = DRM_SCHED_PRIORITY_NORMAL;
|
priority = AMDGPU_CTX_PRIORITY_NORMAL;
|
||||||
|
|
||||||
switch (args->in.op) {
|
switch (args->in.op) {
|
||||||
case AMDGPU_CTX_OP_ALLOC_CTX:
|
case AMDGPU_CTX_OP_ALLOC_CTX:
|
||||||
@ -515,9 +590,9 @@ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
|
static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
|
||||||
struct amdgpu_ctx_entity *aentity,
|
struct amdgpu_ctx_entity *aentity,
|
||||||
int hw_ip,
|
int hw_ip,
|
||||||
enum drm_sched_priority priority)
|
int32_t priority)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = ctx->adev;
|
struct amdgpu_device *adev = ctx->adev;
|
||||||
unsigned int hw_prio;
|
unsigned int hw_prio;
|
||||||
@ -525,12 +600,12 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
|
|||||||
unsigned num_scheds;
|
unsigned num_scheds;
|
||||||
|
|
||||||
/* set sw priority */
|
/* set sw priority */
|
||||||
drm_sched_entity_set_priority(&aentity->entity, priority);
|
drm_sched_entity_set_priority(&aentity->entity,
|
||||||
|
amdgpu_ctx_to_drm_sched_prio(priority));
|
||||||
|
|
||||||
/* set hw priority */
|
/* set hw priority */
|
||||||
if (hw_ip == AMDGPU_HW_IP_COMPUTE) {
|
if (hw_ip == AMDGPU_HW_IP_COMPUTE) {
|
||||||
hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority,
|
hw_prio = amdgpu_ctx_get_hw_prio(ctx, hw_ip);
|
||||||
AMDGPU_HW_IP_COMPUTE);
|
|
||||||
hw_prio = array_index_nospec(hw_prio, AMDGPU_RING_PRIO_MAX);
|
hw_prio = array_index_nospec(hw_prio, AMDGPU_RING_PRIO_MAX);
|
||||||
scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
|
scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
|
||||||
num_scheds = adev->gpu_sched[hw_ip][hw_prio].num_scheds;
|
num_scheds = adev->gpu_sched[hw_ip][hw_prio].num_scheds;
|
||||||
@ -540,14 +615,14 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
|
void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
|
||||||
enum drm_sched_priority priority)
|
int32_t priority)
|
||||||
{
|
{
|
||||||
enum drm_sched_priority ctx_prio;
|
int32_t ctx_prio;
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
|
|
||||||
ctx->override_priority = priority;
|
ctx->override_priority = priority;
|
||||||
|
|
||||||
ctx_prio = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
|
ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ?
|
||||||
ctx->init_priority : ctx->override_priority;
|
ctx->init_priority : ctx->override_priority;
|
||||||
for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
|
for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
|
||||||
for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
|
for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
|
||||||
|
@ -47,8 +47,8 @@ struct amdgpu_ctx {
|
|||||||
spinlock_t ring_lock;
|
spinlock_t ring_lock;
|
||||||
struct amdgpu_ctx_entity *entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM];
|
struct amdgpu_ctx_entity *entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM];
|
||||||
bool preamble_presented;
|
bool preamble_presented;
|
||||||
enum drm_sched_priority init_priority;
|
int32_t init_priority;
|
||||||
enum drm_sched_priority override_priority;
|
int32_t override_priority;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
atomic_t guilty;
|
atomic_t guilty;
|
||||||
unsigned long ras_counter_ce;
|
unsigned long ras_counter_ce;
|
||||||
@ -75,8 +75,8 @@ void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
|
|||||||
struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
|
struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
|
||||||
struct drm_sched_entity *entity,
|
struct drm_sched_entity *entity,
|
||||||
uint64_t seq);
|
uint64_t seq);
|
||||||
void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
|
bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio);
|
||||||
enum drm_sched_priority priority);
|
void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, int32_t ctx_prio);
|
||||||
|
|
||||||
int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
|
int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
|
||||||
struct drm_file *filp);
|
struct drm_file *filp);
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/poll.h>
|
|
||||||
|
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_pm.h"
|
#include "amdgpu_pm.h"
|
||||||
@ -36,87 +35,10 @@
|
|||||||
#include "amdgpu_rap.h"
|
#include "amdgpu_rap.h"
|
||||||
#include "amdgpu_securedisplay.h"
|
#include "amdgpu_securedisplay.h"
|
||||||
#include "amdgpu_fw_attestation.h"
|
#include "amdgpu_fw_attestation.h"
|
||||||
|
#include "amdgpu_umr.h"
|
||||||
int amdgpu_debugfs_wait_dump(struct amdgpu_device *adev)
|
|
||||||
{
|
|
||||||
#if defined(CONFIG_DEBUG_FS)
|
|
||||||
unsigned long timeout = 600 * HZ;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
wake_up_interruptible(&adev->autodump.gpu_hang);
|
|
||||||
|
|
||||||
ret = wait_for_completion_interruptible_timeout(&adev->autodump.dumping, timeout);
|
|
||||||
if (ret == 0) {
|
|
||||||
pr_err("autodump: timeout, move on to gpu recovery\n");
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_DEBUG_FS)
|
#if defined(CONFIG_DEBUG_FS)
|
||||||
|
|
||||||
static int amdgpu_debugfs_autodump_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct amdgpu_device *adev = inode->i_private;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
file->private_data = adev;
|
|
||||||
|
|
||||||
ret = down_read_killable(&adev->reset_sem);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (adev->autodump.dumping.done) {
|
|
||||||
reinit_completion(&adev->autodump.dumping);
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
ret = -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
up_read(&adev->reset_sem);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int amdgpu_debugfs_autodump_release(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct amdgpu_device *adev = file->private_data;
|
|
||||||
|
|
||||||
complete_all(&adev->autodump.dumping);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int amdgpu_debugfs_autodump_poll(struct file *file, struct poll_table_struct *poll_table)
|
|
||||||
{
|
|
||||||
struct amdgpu_device *adev = file->private_data;
|
|
||||||
|
|
||||||
poll_wait(file, &adev->autodump.gpu_hang, poll_table);
|
|
||||||
|
|
||||||
if (amdgpu_in_reset(adev))
|
|
||||||
return POLLIN | POLLRDNORM | POLLWRNORM;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations autodump_debug_fops = {
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.open = amdgpu_debugfs_autodump_open,
|
|
||||||
.poll = amdgpu_debugfs_autodump_poll,
|
|
||||||
.release = amdgpu_debugfs_autodump_release,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void amdgpu_debugfs_autodump_init(struct amdgpu_device *adev)
|
|
||||||
{
|
|
||||||
init_completion(&adev->autodump.dumping);
|
|
||||||
complete_all(&adev->autodump.dumping);
|
|
||||||
init_waitqueue_head(&adev->autodump.gpu_hang);
|
|
||||||
|
|
||||||
debugfs_create_file("amdgpu_autodump", 0600,
|
|
||||||
adev_to_drm(adev)->primary->debugfs_root,
|
|
||||||
adev, &autodump_debug_fops);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes
|
* amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes
|
||||||
*
|
*
|
||||||
@ -279,6 +201,145 @@ static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
|
|||||||
return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
|
return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int amdgpu_debugfs_regs2_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
struct amdgpu_debugfs_regs2_data *rd;
|
||||||
|
|
||||||
|
rd = kzalloc(sizeof *rd, GFP_KERNEL);
|
||||||
|
if (!rd)
|
||||||
|
return -ENOMEM;
|
||||||
|
rd->adev = file_inode(file)->i_private;
|
||||||
|
file->private_data = rd;
|
||||||
|
mutex_init(&rd->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_debugfs_regs2_release(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
struct amdgpu_debugfs_regs2_data *rd = file->private_data;
|
||||||
|
mutex_destroy(&rd->lock);
|
||||||
|
kfree(file->private_data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 offset, size_t size, int write_en)
|
||||||
|
{
|
||||||
|
struct amdgpu_debugfs_regs2_data *rd = f->private_data;
|
||||||
|
struct amdgpu_device *adev = rd->adev;
|
||||||
|
ssize_t result = 0;
|
||||||
|
int r;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
if (size & 0x3 || offset & 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = amdgpu_virt_enable_access_debugfs(adev);
|
||||||
|
if (r < 0) {
|
||||||
|
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&rd->lock);
|
||||||
|
|
||||||
|
if (rd->id.use_grbm) {
|
||||||
|
if ((rd->id.grbm.sh != 0xFFFFFFFF && rd->id.grbm.sh >= adev->gfx.config.max_sh_per_se) ||
|
||||||
|
(rd->id.grbm.se != 0xFFFFFFFF && rd->id.grbm.se >= adev->gfx.config.max_shader_engines)) {
|
||||||
|
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||||
|
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||||
|
amdgpu_virt_disable_access_debugfs(adev);
|
||||||
|
mutex_unlock(&rd->lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
mutex_lock(&adev->grbm_idx_mutex);
|
||||||
|
amdgpu_gfx_select_se_sh(adev, rd->id.grbm.se,
|
||||||
|
rd->id.grbm.sh,
|
||||||
|
rd->id.grbm.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rd->id.use_srbm) {
|
||||||
|
mutex_lock(&adev->srbm_mutex);
|
||||||
|
amdgpu_gfx_select_me_pipe_q(adev, rd->id.srbm.me, rd->id.srbm.pipe,
|
||||||
|
rd->id.srbm.queue, rd->id.srbm.vmid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rd->id.pg_lock)
|
||||||
|
mutex_lock(&adev->pm.mutex);
|
||||||
|
|
||||||
|
while (size) {
|
||||||
|
if (!write_en) {
|
||||||
|
value = RREG32(offset >> 2);
|
||||||
|
r = put_user(value, (uint32_t *)buf);
|
||||||
|
} else {
|
||||||
|
r = get_user(value, (uint32_t *)buf);
|
||||||
|
if (!r)
|
||||||
|
amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value);
|
||||||
|
}
|
||||||
|
if (r) {
|
||||||
|
result = r;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
offset += 4;
|
||||||
|
size -= 4;
|
||||||
|
result += 4;
|
||||||
|
buf += 4;
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
if (rd->id.use_grbm) {
|
||||||
|
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||||
|
mutex_unlock(&adev->grbm_idx_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rd->id.use_srbm) {
|
||||||
|
amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&adev->srbm_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rd->id.pg_lock)
|
||||||
|
mutex_unlock(&adev->pm.mutex);
|
||||||
|
|
||||||
|
mutex_unlock(&rd->lock);
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||||
|
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||||
|
|
||||||
|
amdgpu_virt_disable_access_debugfs(adev);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long amdgpu_debugfs_regs2_ioctl(struct file *f, unsigned int cmd, unsigned long data)
|
||||||
|
{
|
||||||
|
struct amdgpu_debugfs_regs2_data *rd = f->private_data;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case AMDGPU_DEBUGFS_REGS2_IOC_SET_STATE:
|
||||||
|
mutex_lock(&rd->lock);
|
||||||
|
r = copy_from_user(&rd->id, (struct amdgpu_debugfs_regs2_iocdata *)data, sizeof rd->id);
|
||||||
|
mutex_unlock(&rd->lock);
|
||||||
|
return r ? -EINVAL : 0;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t amdgpu_debugfs_regs2_read(struct file *f, char __user *buf, size_t size, loff_t *pos)
|
||||||
|
{
|
||||||
|
return amdgpu_debugfs_regs2_op(f, buf, *pos, size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t amdgpu_debugfs_regs2_write(struct file *f, const char __user *buf, size_t size, loff_t *pos)
|
||||||
|
{
|
||||||
|
return amdgpu_debugfs_regs2_op(f, (char __user *)buf, *pos, size, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_debugfs_regs_pcie_read - Read from a PCIE register
|
* amdgpu_debugfs_regs_pcie_read - Read from a PCIE register
|
||||||
@ -1091,6 +1152,16 @@ static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations amdgpu_debugfs_regs2_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.unlocked_ioctl = amdgpu_debugfs_regs2_ioctl,
|
||||||
|
.read = amdgpu_debugfs_regs2_read,
|
||||||
|
.write = amdgpu_debugfs_regs2_write,
|
||||||
|
.open = amdgpu_debugfs_regs2_open,
|
||||||
|
.release = amdgpu_debugfs_regs2_release,
|
||||||
|
.llseek = default_llseek
|
||||||
|
};
|
||||||
|
|
||||||
static const struct file_operations amdgpu_debugfs_regs_fops = {
|
static const struct file_operations amdgpu_debugfs_regs_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.read = amdgpu_debugfs_regs_read,
|
.read = amdgpu_debugfs_regs_read,
|
||||||
@ -1148,6 +1219,7 @@ static const struct file_operations amdgpu_debugfs_gfxoff_fops = {
|
|||||||
|
|
||||||
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_regs_didt_fops,
|
&amdgpu_debugfs_regs_didt_fops,
|
||||||
&amdgpu_debugfs_regs_pcie_fops,
|
&amdgpu_debugfs_regs_pcie_fops,
|
||||||
&amdgpu_debugfs_regs_smc_fops,
|
&amdgpu_debugfs_regs_smc_fops,
|
||||||
@ -1160,6 +1232,7 @@ static const struct file_operations *debugfs_regs[] = {
|
|||||||
|
|
||||||
static const char *debugfs_regs_names[] = {
|
static const char *debugfs_regs_names[] = {
|
||||||
"amdgpu_regs",
|
"amdgpu_regs",
|
||||||
|
"amdgpu_regs2",
|
||||||
"amdgpu_regs_didt",
|
"amdgpu_regs_didt",
|
||||||
"amdgpu_regs_pcie",
|
"amdgpu_regs_pcie",
|
||||||
"amdgpu_regs_smc",
|
"amdgpu_regs_smc",
|
||||||
@ -1206,7 +1279,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Avoid accidently unparking the sched thread during GPU reset */
|
/* Avoid accidently unparking the sched thread during GPU reset */
|
||||||
r = down_read_killable(&adev->reset_sem);
|
r = down_write_killable(&adev->reset_sem);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1235,7 +1308,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
|
|||||||
kthread_unpark(ring->sched.thread);
|
kthread_unpark(ring->sched.thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
up_read(&adev->reset_sem);
|
up_write(&adev->reset_sem);
|
||||||
|
|
||||||
pm_runtime_mark_last_busy(dev->dev);
|
pm_runtime_mark_last_busy(dev->dev);
|
||||||
pm_runtime_put_autosuspend(dev->dev);
|
pm_runtime_put_autosuspend(dev->dev);
|
||||||
@ -1255,7 +1328,7 @@ static int amdgpu_debugfs_evict_vram(void *data, u64 *val)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = amdgpu_bo_evict_vram(adev);
|
*val = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM);
|
||||||
|
|
||||||
pm_runtime_mark_last_busy(dev->dev);
|
pm_runtime_mark_last_busy(dev->dev);
|
||||||
pm_runtime_put_autosuspend(dev->dev);
|
pm_runtime_put_autosuspend(dev->dev);
|
||||||
@ -1268,17 +1341,15 @@ static int amdgpu_debugfs_evict_gtt(void *data, u64 *val)
|
|||||||
{
|
{
|
||||||
struct amdgpu_device *adev = (struct amdgpu_device *)data;
|
struct amdgpu_device *adev = (struct amdgpu_device *)data;
|
||||||
struct drm_device *dev = adev_to_drm(adev);
|
struct drm_device *dev = adev_to_drm(adev);
|
||||||
struct ttm_resource_manager *man;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = pm_runtime_get_sync(dev->dev);
|
r = pm_runtime_get_sync(dev->dev);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
pm_runtime_put_autosuspend(dev->dev);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
|
*val = amdgpu_ttm_evict_resources(adev, TTM_PL_TT);
|
||||||
*val = ttm_resource_manager_evict_all(&adev->mman.bdev, man);
|
|
||||||
|
|
||||||
pm_runtime_mark_last_busy(dev->dev);
|
pm_runtime_mark_last_busy(dev->dev);
|
||||||
pm_runtime_put_autosuspend(dev->dev);
|
pm_runtime_put_autosuspend(dev->dev);
|
||||||
@ -1544,6 +1615,9 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
|||||||
struct dentry *ent;
|
struct dentry *ent;
|
||||||
int r, i;
|
int r, i;
|
||||||
|
|
||||||
|
if (!debugfs_initialized())
|
||||||
|
return 0;
|
||||||
|
|
||||||
ent = debugfs_create_file("amdgpu_preempt_ib", 0600, root, adev,
|
ent = debugfs_create_file("amdgpu_preempt_ib", 0600, root, adev,
|
||||||
&fops_ib_preempt);
|
&fops_ib_preempt);
|
||||||
if (IS_ERR(ent)) {
|
if (IS_ERR(ent)) {
|
||||||
@ -1582,13 +1656,10 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
|||||||
if (!ring)
|
if (!ring)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (amdgpu_debugfs_ring_init(adev, ring)) {
|
amdgpu_debugfs_ring_init(adev, ring);
|
||||||
DRM_ERROR("Failed to register debugfs file for rings !\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
amdgpu_ras_debugfs_create_all(adev);
|
amdgpu_ras_debugfs_create_all(adev);
|
||||||
amdgpu_debugfs_autodump_init(adev);
|
|
||||||
amdgpu_rap_debugfs_init(adev);
|
amdgpu_rap_debugfs_init(adev);
|
||||||
amdgpu_securedisplay_debugfs_init(adev);
|
amdgpu_securedisplay_debugfs_init(adev);
|
||||||
amdgpu_fw_attestation_debugfs_init(adev);
|
amdgpu_fw_attestation_debugfs_init(adev);
|
||||||
@ -1607,6 +1678,11 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
|||||||
debugfs_create_blob("amdgpu_vbios", 0444, root,
|
debugfs_create_blob("amdgpu_vbios", 0444, root,
|
||||||
&adev->debugfs_vbios_blob);
|
&adev->debugfs_vbios_blob);
|
||||||
|
|
||||||
|
adev->debugfs_discovery_blob.data = adev->mman.discovery_bin;
|
||||||
|
adev->debugfs_discovery_blob.size = adev->mman.discovery_tmr_size;
|
||||||
|
debugfs_create_blob("amdgpu_discovery", 0444, root,
|
||||||
|
&adev->debugfs_discovery_blob);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,9 @@
|
|||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Debugfs
|
* Debugfs
|
||||||
*/
|
*/
|
||||||
struct amdgpu_autodump {
|
|
||||||
struct completion dumping;
|
|
||||||
struct wait_queue_head gpu_hang;
|
|
||||||
};
|
|
||||||
|
|
||||||
int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
|
int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
|
||||||
int amdgpu_debugfs_init(struct amdgpu_device *adev);
|
int amdgpu_debugfs_init(struct amdgpu_device *adev);
|
||||||
@ -37,4 +32,3 @@ void amdgpu_debugfs_fini(struct amdgpu_device *adev);
|
|||||||
void amdgpu_debugfs_fence_init(struct amdgpu_device *adev);
|
void amdgpu_debugfs_fence_init(struct amdgpu_device *adev);
|
||||||
void amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);
|
void amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);
|
||||||
void amdgpu_debugfs_gem_init(struct amdgpu_device *adev);
|
void amdgpu_debugfs_gem_init(struct amdgpu_device *adev);
|
||||||
int amdgpu_debugfs_wait_dump(struct amdgpu_device *adev);
|
|
||||||
|
@ -125,6 +125,7 @@ const char *amdgpu_asic_name[] = {
|
|||||||
"DIMGREY_CAVEFISH",
|
"DIMGREY_CAVEFISH",
|
||||||
"BEIGE_GOBY",
|
"BEIGE_GOBY",
|
||||||
"YELLOW_CARP",
|
"YELLOW_CARP",
|
||||||
|
"IP DISCOVERY",
|
||||||
"LAST",
|
"LAST",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -305,7 +306,7 @@ void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos,
|
|||||||
uint64_t last;
|
uint64_t last;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
if (!drm_dev_enter(&adev->ddev, &idx))
|
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BUG_ON(!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4));
|
BUG_ON(!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4));
|
||||||
@ -2126,46 +2127,11 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
case CHIP_VEGA10:
|
|
||||||
case CHIP_VEGA12:
|
|
||||||
case CHIP_VEGA20:
|
|
||||||
case CHIP_RAVEN:
|
|
||||||
case CHIP_ARCTURUS:
|
|
||||||
case CHIP_RENOIR:
|
|
||||||
case CHIP_ALDEBARAN:
|
|
||||||
if (adev->flags & AMD_IS_APU)
|
|
||||||
adev->family = AMDGPU_FAMILY_RV;
|
|
||||||
else
|
|
||||||
adev->family = AMDGPU_FAMILY_AI;
|
|
||||||
|
|
||||||
r = soc15_set_ip_blocks(adev);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
break;
|
|
||||||
case CHIP_NAVI10:
|
|
||||||
case CHIP_NAVI14:
|
|
||||||
case CHIP_NAVI12:
|
|
||||||
case CHIP_SIENNA_CICHLID:
|
|
||||||
case CHIP_NAVY_FLOUNDER:
|
|
||||||
case CHIP_DIMGREY_CAVEFISH:
|
|
||||||
case CHIP_BEIGE_GOBY:
|
|
||||||
case CHIP_VANGOGH:
|
|
||||||
case CHIP_YELLOW_CARP:
|
|
||||||
case CHIP_CYAN_SKILLFISH:
|
|
||||||
if (adev->asic_type == CHIP_VANGOGH)
|
|
||||||
adev->family = AMDGPU_FAMILY_VGH;
|
|
||||||
else if (adev->asic_type == CHIP_YELLOW_CARP)
|
|
||||||
adev->family = AMDGPU_FAMILY_YC;
|
|
||||||
else
|
|
||||||
adev->family = AMDGPU_FAMILY_NV;
|
|
||||||
|
|
||||||
r = nv_set_ip_blocks(adev);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* FIXME: not supported yet */
|
r = amdgpu_discovery_set_ip_blocks(adev);
|
||||||
return -EINVAL;
|
if (r)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
amdgpu_amdkfd_device_probe(adev);
|
amdgpu_amdkfd_device_probe(adev);
|
||||||
@ -2745,6 +2711,11 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
|
|||||||
adev->ip_blocks[i].status.hw = false;
|
adev->ip_blocks[i].status.hw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (amdgpu_sriov_vf(adev)) {
|
||||||
|
if (amdgpu_virt_release_full_gpu(adev, false))
|
||||||
|
DRM_ERROR("failed to release exclusive mode on fini\n");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2805,10 +2776,6 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
amdgpu_ras_fini(adev);
|
amdgpu_ras_fini(adev);
|
||||||
|
|
||||||
if (amdgpu_sriov_vf(adev))
|
|
||||||
if (amdgpu_virt_release_full_gpu(adev, false))
|
|
||||||
DRM_ERROR("failed to release exclusive mode on fini\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3240,6 +3207,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
|||||||
case CHIP_NAVI14:
|
case CHIP_NAVI14:
|
||||||
case CHIP_NAVI12:
|
case CHIP_NAVI12:
|
||||||
case CHIP_RENOIR:
|
case CHIP_RENOIR:
|
||||||
|
case CHIP_CYAN_SKILLFISH:
|
||||||
case CHIP_SIENNA_CICHLID:
|
case CHIP_SIENNA_CICHLID:
|
||||||
case CHIP_NAVY_FLOUNDER:
|
case CHIP_NAVY_FLOUNDER:
|
||||||
case CHIP_DIMGREY_CAVEFISH:
|
case CHIP_DIMGREY_CAVEFISH:
|
||||||
@ -3247,13 +3215,15 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
|||||||
case CHIP_VANGOGH:
|
case CHIP_VANGOGH:
|
||||||
case CHIP_YELLOW_CARP:
|
case CHIP_YELLOW_CARP:
|
||||||
#endif
|
#endif
|
||||||
|
default:
|
||||||
return amdgpu_dc != 0;
|
return amdgpu_dc != 0;
|
||||||
#endif
|
#else
|
||||||
default:
|
default:
|
||||||
if (amdgpu_dc > 0)
|
if (amdgpu_dc > 0)
|
||||||
DRM_INFO_ONCE("Display Core has been requested via kernel parameter "
|
DRM_INFO_ONCE("Display Core has been requested via kernel parameter "
|
||||||
"but isn't supported by ASIC, ignoring\n");
|
"but isn't supported by ASIC, ignoring\n");
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3354,6 +3324,8 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
|
|||||||
continue;
|
continue;
|
||||||
} else if (timeout < 0) {
|
} else if (timeout < 0) {
|
||||||
timeout = MAX_SCHEDULE_TIMEOUT;
|
timeout = MAX_SCHEDULE_TIMEOUT;
|
||||||
|
dev_warn(adev->dev, "lockup timeout disabled");
|
||||||
|
add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK);
|
||||||
} else {
|
} else {
|
||||||
timeout = msecs_to_jiffies(timeout);
|
timeout = msecs_to_jiffies(timeout);
|
||||||
}
|
}
|
||||||
@ -3538,17 +3510,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||||||
DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base);
|
DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base);
|
||||||
DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size);
|
DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size);
|
||||||
|
|
||||||
/* enable PCIE atomic ops */
|
|
||||||
r = pci_enable_atomic_ops_to_root(adev->pdev,
|
|
||||||
PCI_EXP_DEVCAP2_ATOMIC_COMP32 |
|
|
||||||
PCI_EXP_DEVCAP2_ATOMIC_COMP64);
|
|
||||||
if (r) {
|
|
||||||
adev->have_atomics_support = false;
|
|
||||||
DRM_INFO("PCIE atomic ops is not supported\n");
|
|
||||||
} else {
|
|
||||||
adev->have_atomics_support = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
amdgpu_device_get_pcie_info(adev);
|
amdgpu_device_get_pcie_info(adev);
|
||||||
|
|
||||||
if (amdgpu_mcbp)
|
if (amdgpu_mcbp)
|
||||||
@ -3571,6 +3532,19 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
/* enable PCIE atomic ops */
|
||||||
|
if (amdgpu_sriov_vf(adev))
|
||||||
|
adev->have_atomics_support = ((struct amd_sriov_msg_pf2vf_info *)
|
||||||
|
adev->virt.fw_reserve.p_pf2vf)->pcie_atomic_ops_enabled_flags ==
|
||||||
|
(PCI_EXP_DEVCAP2_ATOMIC_COMP32 | PCI_EXP_DEVCAP2_ATOMIC_COMP64);
|
||||||
|
else
|
||||||
|
adev->have_atomics_support =
|
||||||
|
!pci_enable_atomic_ops_to_root(adev->pdev,
|
||||||
|
PCI_EXP_DEVCAP2_ATOMIC_COMP32 |
|
||||||
|
PCI_EXP_DEVCAP2_ATOMIC_COMP64);
|
||||||
|
if (!adev->have_atomics_support)
|
||||||
|
dev_info(adev->dev, "PCIE atomic ops is not supported\n");
|
||||||
|
|
||||||
/* doorbell bar mapping and doorbell index init*/
|
/* doorbell bar mapping and doorbell index init*/
|
||||||
amdgpu_device_doorbell_init(adev);
|
amdgpu_device_doorbell_init(adev);
|
||||||
|
|
||||||
@ -3865,9 +3839,11 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
amdgpu_fbdev_fini(adev);
|
amdgpu_fbdev_fini(adev);
|
||||||
|
|
||||||
|
amdgpu_device_ip_fini_early(adev);
|
||||||
|
|
||||||
amdgpu_irq_fini_hw(adev);
|
amdgpu_irq_fini_hw(adev);
|
||||||
|
|
||||||
amdgpu_device_ip_fini_early(adev);
|
ttm_device_clear_dma_mappings(&adev->mman.bdev);
|
||||||
|
|
||||||
amdgpu_gart_dummy_page_fini(adev);
|
amdgpu_gart_dummy_page_fini(adev);
|
||||||
|
|
||||||
@ -3876,8 +3852,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
amdgpu_device_ip_fini(adev);
|
|
||||||
amdgpu_fence_driver_sw_fini(adev);
|
amdgpu_fence_driver_sw_fini(adev);
|
||||||
|
amdgpu_device_ip_fini(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;
|
||||||
@ -3909,6 +3885,25 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* amdgpu_device_evict_resources - evict device resources
|
||||||
|
* @adev: amdgpu device object
|
||||||
|
*
|
||||||
|
* Evicts all ttm device resources(vram BOs, gart table) from the lru list
|
||||||
|
* of the vram memory type. Mainly used for evicting device resources
|
||||||
|
* at suspend time.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void amdgpu_device_evict_resources(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
/* No need to evict vram on APUs for suspend to ram */
|
||||||
|
if (adev->in_s3 && (adev->flags & AMD_IS_APU))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM))
|
||||||
|
DRM_WARN("evicting device resources failed\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Suspend & resume.
|
* Suspend & resume.
|
||||||
@ -3949,17 +3944,16 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
|||||||
if (!adev->in_s0ix)
|
if (!adev->in_s0ix)
|
||||||
amdgpu_amdkfd_suspend(adev, adev->in_runpm);
|
amdgpu_amdkfd_suspend(adev, adev->in_runpm);
|
||||||
|
|
||||||
/* evict vram memory */
|
/* First evict vram memory */
|
||||||
amdgpu_bo_evict_vram(adev);
|
amdgpu_device_evict_resources(adev);
|
||||||
|
|
||||||
amdgpu_fence_driver_hw_fini(adev);
|
amdgpu_fence_driver_hw_fini(adev);
|
||||||
|
|
||||||
amdgpu_device_ip_suspend_phase2(adev);
|
amdgpu_device_ip_suspend_phase2(adev);
|
||||||
/* evict remaining vram memory
|
/* This second call to evict device resources is to evict
|
||||||
* This second call to evict vram is to evict the gart page table
|
* the gart page table using the CPU.
|
||||||
* using the CPU.
|
|
||||||
*/
|
*/
|
||||||
amdgpu_bo_evict_vram(adev);
|
amdgpu_device_evict_resources(adev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -4466,10 +4460,6 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
|||||||
if (reset_context->reset_req_dev == adev)
|
if (reset_context->reset_req_dev == adev)
|
||||||
job = reset_context->job;
|
job = reset_context->job;
|
||||||
|
|
||||||
/* no need to dump if device is not in good state during probe period */
|
|
||||||
if (!adev->gmc.xgmi.pending_reset)
|
|
||||||
amdgpu_debugfs_wait_dump(adev);
|
|
||||||
|
|
||||||
if (amdgpu_sriov_vf(adev)) {
|
if (amdgpu_sriov_vf(adev)) {
|
||||||
/* stop the data exchange thread */
|
/* stop the data exchange thread */
|
||||||
amdgpu_virt_fini_data_exchange(adev);
|
amdgpu_virt_fini_data_exchange(adev);
|
||||||
|
@ -52,6 +52,7 @@ struct amdgpu_df_funcs {
|
|||||||
uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val);
|
uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val);
|
||||||
void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val,
|
void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val,
|
||||||
uint32_t ficadl_val, uint32_t ficadh_val);
|
uint32_t ficadl_val, uint32_t ficadh_val);
|
||||||
|
bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amdgpu_df {
|
struct amdgpu_df {
|
||||||
|
@ -21,16 +21,58 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/firmware.h>
|
||||||
|
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_discovery.h"
|
#include "amdgpu_discovery.h"
|
||||||
#include "soc15_hw_ip.h"
|
#include "soc15_hw_ip.h"
|
||||||
#include "discovery.h"
|
#include "discovery.h"
|
||||||
|
|
||||||
|
#include "soc15.h"
|
||||||
|
#include "gfx_v9_0.h"
|
||||||
|
#include "gmc_v9_0.h"
|
||||||
|
#include "df_v1_7.h"
|
||||||
|
#include "df_v3_6.h"
|
||||||
|
#include "nbio_v6_1.h"
|
||||||
|
#include "nbio_v7_0.h"
|
||||||
|
#include "nbio_v7_4.h"
|
||||||
|
#include "hdp_v4_0.h"
|
||||||
|
#include "vega10_ih.h"
|
||||||
|
#include "vega20_ih.h"
|
||||||
|
#include "sdma_v4_0.h"
|
||||||
|
#include "uvd_v7_0.h"
|
||||||
|
#include "vce_v4_0.h"
|
||||||
|
#include "vcn_v1_0.h"
|
||||||
|
#include "vcn_v2_5.h"
|
||||||
|
#include "jpeg_v2_5.h"
|
||||||
|
#include "smuio_v9_0.h"
|
||||||
|
#include "gmc_v10_0.h"
|
||||||
|
#include "gfxhub_v2_0.h"
|
||||||
|
#include "mmhub_v2_0.h"
|
||||||
|
#include "nbio_v2_3.h"
|
||||||
|
#include "nbio_v7_2.h"
|
||||||
|
#include "hdp_v5_0.h"
|
||||||
|
#include "nv.h"
|
||||||
|
#include "navi10_ih.h"
|
||||||
|
#include "gfx_v10_0.h"
|
||||||
|
#include "sdma_v5_0.h"
|
||||||
|
#include "sdma_v5_2.h"
|
||||||
|
#include "vcn_v2_0.h"
|
||||||
|
#include "jpeg_v2_0.h"
|
||||||
|
#include "vcn_v3_0.h"
|
||||||
|
#include "jpeg_v3_0.h"
|
||||||
|
#include "amdgpu_vkms.h"
|
||||||
|
#include "mes_v10_1.h"
|
||||||
|
#include "smuio_v11_0.h"
|
||||||
|
#include "smuio_v11_0_6.h"
|
||||||
|
#include "smuio_v13_0.h"
|
||||||
|
|
||||||
|
MODULE_FIRMWARE("amdgpu/ip_discovery.bin");
|
||||||
|
|
||||||
#define mmRCC_CONFIG_MEMSIZE 0xde3
|
#define mmRCC_CONFIG_MEMSIZE 0xde3
|
||||||
#define mmMM_INDEX 0x0
|
#define mmMM_INDEX 0x0
|
||||||
#define mmMM_INDEX_HI 0x6
|
#define mmMM_INDEX_HI 0x6
|
||||||
#define mmMM_DATA 0x1
|
#define mmMM_DATA 0x1
|
||||||
#define HW_ID_MAX 300
|
|
||||||
|
|
||||||
static const char *hw_id_names[HW_ID_MAX] = {
|
static const char *hw_id_names[HW_ID_MAX] = {
|
||||||
[MP1_HWID] = "MP1",
|
[MP1_HWID] = "MP1",
|
||||||
@ -66,6 +108,8 @@ static const char *hw_id_names[HW_ID_MAX] = {
|
|||||||
[HDP_HWID] = "HDP",
|
[HDP_HWID] = "HDP",
|
||||||
[SDMA0_HWID] = "SDMA0",
|
[SDMA0_HWID] = "SDMA0",
|
||||||
[SDMA1_HWID] = "SDMA1",
|
[SDMA1_HWID] = "SDMA1",
|
||||||
|
[SDMA2_HWID] = "SDMA2",
|
||||||
|
[SDMA3_HWID] = "SDMA3",
|
||||||
[ISP_HWID] = "ISP",
|
[ISP_HWID] = "ISP",
|
||||||
[DBGU_IO_HWID] = "DBGU_IO",
|
[DBGU_IO_HWID] = "DBGU_IO",
|
||||||
[DF_HWID] = "DF",
|
[DF_HWID] = "DF",
|
||||||
@ -129,6 +173,8 @@ static int hw_id_map[MAX_HWIP] = {
|
|||||||
[THM_HWIP] = THM_HWID,
|
[THM_HWIP] = THM_HWID,
|
||||||
[CLK_HWIP] = CLKA_HWID,
|
[CLK_HWIP] = CLKA_HWID,
|
||||||
[UMC_HWIP] = UMC_HWID,
|
[UMC_HWIP] = UMC_HWID,
|
||||||
|
[XGMI_HWIP] = XGMI_HWID,
|
||||||
|
[DCI_HWIP] = DCI_HWID,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t *binary)
|
static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t *binary)
|
||||||
@ -164,6 +210,7 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
|
|||||||
struct binary_header *bhdr;
|
struct binary_header *bhdr;
|
||||||
struct ip_discovery_header *ihdr;
|
struct ip_discovery_header *ihdr;
|
||||||
struct gpu_info_header *ghdr;
|
struct gpu_info_header *ghdr;
|
||||||
|
const struct firmware *fw;
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
@ -174,10 +221,21 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
|
|||||||
if (!adev->mman.discovery_bin)
|
if (!adev->mman.discovery_bin)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
r = amdgpu_discovery_read_binary(adev, adev->mman.discovery_bin);
|
if (amdgpu_discovery == 2) {
|
||||||
if (r) {
|
r = request_firmware(&fw, "amdgpu/ip_discovery.bin", adev->dev);
|
||||||
DRM_ERROR("failed to read ip discovery binary\n");
|
if (r)
|
||||||
goto out;
|
goto get_from_vram;
|
||||||
|
dev_info(adev->dev, "Using IP discovery from file\n");
|
||||||
|
memcpy((u8 *)adev->mman.discovery_bin, (u8 *)fw->data,
|
||||||
|
adev->mman.discovery_tmr_size);
|
||||||
|
release_firmware(fw);
|
||||||
|
} else {
|
||||||
|
get_from_vram:
|
||||||
|
r = amdgpu_discovery_read_binary(adev, adev->mman.discovery_bin);
|
||||||
|
if (r) {
|
||||||
|
DRM_ERROR("failed to read ip discovery binary\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bhdr = (struct binary_header *)adev->mman.discovery_bin;
|
bhdr = (struct binary_header *)adev->mman.discovery_bin;
|
||||||
@ -245,6 +303,22 @@ void amdgpu_discovery_fini(struct amdgpu_device *adev)
|
|||||||
adev->mman.discovery_bin = NULL;
|
adev->mman.discovery_bin = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_validate_ip(const struct ip *ip)
|
||||||
|
{
|
||||||
|
if (ip->number_instance >= HWIP_MAX_INSTANCE) {
|
||||||
|
DRM_ERROR("Unexpected number_instance (%d) from ip discovery blob\n",
|
||||||
|
ip->number_instance);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (le16_to_cpu(ip->hw_id) >= HW_ID_MAX) {
|
||||||
|
DRM_ERROR("Unexpected hw_id (%d) from ip discovery blob\n",
|
||||||
|
le16_to_cpu(ip->hw_id));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
struct binary_header *bhdr;
|
struct binary_header *bhdr;
|
||||||
@ -290,6 +364,10 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
for (j = 0; j < num_ips; j++) {
|
for (j = 0; j < num_ips; j++) {
|
||||||
ip = (struct ip *)(adev->mman.discovery_bin + ip_offset);
|
ip = (struct ip *)(adev->mman.discovery_bin + ip_offset);
|
||||||
|
|
||||||
|
if (amdgpu_discovery_validate_ip(ip))
|
||||||
|
goto next_ip;
|
||||||
|
|
||||||
num_base_address = ip->num_base_address;
|
num_base_address = ip->num_base_address;
|
||||||
|
|
||||||
DRM_DEBUG("%s(%d) #%d v%d.%d.%d:\n",
|
DRM_DEBUG("%s(%d) #%d v%d.%d.%d:\n",
|
||||||
@ -301,6 +379,11 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
if (le16_to_cpu(ip->hw_id) == VCN_HWID)
|
if (le16_to_cpu(ip->hw_id) == VCN_HWID)
|
||||||
adev->vcn.num_vcn_inst++;
|
adev->vcn.num_vcn_inst++;
|
||||||
|
if (le16_to_cpu(ip->hw_id) == SDMA0_HWID ||
|
||||||
|
le16_to_cpu(ip->hw_id) == SDMA1_HWID ||
|
||||||
|
le16_to_cpu(ip->hw_id) == SDMA2_HWID ||
|
||||||
|
le16_to_cpu(ip->hw_id) == SDMA3_HWID)
|
||||||
|
adev->sdma.num_instances++;
|
||||||
|
|
||||||
for (k = 0; k < num_base_address; k++) {
|
for (k = 0; k < num_base_address; k++) {
|
||||||
/*
|
/*
|
||||||
@ -317,10 +400,21 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)
|
|||||||
hw_id_names[le16_to_cpu(ip->hw_id)]);
|
hw_id_names[le16_to_cpu(ip->hw_id)]);
|
||||||
adev->reg_offset[hw_ip][ip->number_instance] =
|
adev->reg_offset[hw_ip][ip->number_instance] =
|
||||||
ip->base_address;
|
ip->base_address;
|
||||||
|
/* Instance support is somewhat inconsistent.
|
||||||
|
* SDMA is a good example. Sienna cichlid has 4 total
|
||||||
|
* SDMA instances, each enumerated separately (HWIDs
|
||||||
|
* 42, 43, 68, 69). Arcturus has 8 total SDMA instances,
|
||||||
|
* but they are enumerated as multiple instances of the
|
||||||
|
* same HWIDs (4x HWID 42, 4x HWID 43). UMC is another
|
||||||
|
* example. On most chips there are multiple instances
|
||||||
|
* with the same HWID.
|
||||||
|
*/
|
||||||
|
adev->ip_versions[hw_ip][ip->number_instance] =
|
||||||
|
IP_VERSION(ip->major, ip->minor, ip->revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next_ip:
|
||||||
ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);
|
ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -401,6 +495,10 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)
|
|||||||
switch (le32_to_cpu(harvest_info->list[i].hw_id)) {
|
switch (le32_to_cpu(harvest_info->list[i].hw_id)) {
|
||||||
case VCN_HWID:
|
case VCN_HWID:
|
||||||
vcn_harvest_count++;
|
vcn_harvest_count++;
|
||||||
|
if (harvest_info->list[i].number_instance == 0)
|
||||||
|
adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;
|
||||||
|
else
|
||||||
|
adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;
|
||||||
break;
|
break;
|
||||||
case DMU_HWID:
|
case DMU_HWID:
|
||||||
adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
|
adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK;
|
||||||
@ -409,10 +507,21 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* some IP discovery tables on Navy Flounder don't have this set correctly */
|
||||||
|
if ((adev->ip_versions[UVD_HWIP][1] == IP_VERSION(3, 0, 1)) &&
|
||||||
|
(adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 2)))
|
||||||
|
adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1;
|
||||||
if (vcn_harvest_count == adev->vcn.num_vcn_inst) {
|
if (vcn_harvest_count == adev->vcn.num_vcn_inst) {
|
||||||
adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK;
|
adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK;
|
||||||
adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK;
|
adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK;
|
||||||
}
|
}
|
||||||
|
if ((adev->pdev->device == 0x731E &&
|
||||||
|
(adev->pdev->revision == 0xC6 || adev->pdev->revision == 0xC7)) ||
|
||||||
|
(adev->pdev->device == 0x7340 && adev->pdev->revision == 0xC9) ||
|
||||||
|
(adev->pdev->device == 0x7360 && adev->pdev->revision == 0xC7)) {
|
||||||
|
adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK;
|
||||||
|
adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev)
|
int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev)
|
||||||
@ -450,3 +559,753 @@ int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
/* what IP to use for this? */
|
||||||
|
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||||
|
case IP_VERSION(9, 0, 1):
|
||||||
|
case IP_VERSION(9, 1, 0):
|
||||||
|
case IP_VERSION(9, 2, 1):
|
||||||
|
case IP_VERSION(9, 2, 2):
|
||||||
|
case IP_VERSION(9, 3, 0):
|
||||||
|
case IP_VERSION(9, 4, 0):
|
||||||
|
case IP_VERSION(9, 4, 1):
|
||||||
|
case IP_VERSION(9, 4, 2):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vega10_common_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(10, 1, 10):
|
||||||
|
case IP_VERSION(10, 1, 1):
|
||||||
|
case IP_VERSION(10, 1, 2):
|
||||||
|
case IP_VERSION(10, 1, 3):
|
||||||
|
case IP_VERSION(10, 3, 0):
|
||||||
|
case IP_VERSION(10, 3, 1):
|
||||||
|
case IP_VERSION(10, 3, 2):
|
||||||
|
case IP_VERSION(10, 3, 3):
|
||||||
|
case IP_VERSION(10, 3, 4):
|
||||||
|
case IP_VERSION(10, 3, 5):
|
||||||
|
amdgpu_device_ip_block_add(adev, &nv_common_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
/* use GC or MMHUB IP version */
|
||||||
|
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||||
|
case IP_VERSION(9, 0, 1):
|
||||||
|
case IP_VERSION(9, 1, 0):
|
||||||
|
case IP_VERSION(9, 2, 1):
|
||||||
|
case IP_VERSION(9, 2, 2):
|
||||||
|
case IP_VERSION(9, 3, 0):
|
||||||
|
case IP_VERSION(9, 4, 0):
|
||||||
|
case IP_VERSION(9, 4, 1):
|
||||||
|
case IP_VERSION(9, 4, 2):
|
||||||
|
amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(10, 1, 10):
|
||||||
|
case IP_VERSION(10, 1, 1):
|
||||||
|
case IP_VERSION(10, 1, 2):
|
||||||
|
case IP_VERSION(10, 1, 3):
|
||||||
|
case IP_VERSION(10, 3, 0):
|
||||||
|
case IP_VERSION(10, 3, 1):
|
||||||
|
case IP_VERSION(10, 3, 2):
|
||||||
|
case IP_VERSION(10, 3, 3):
|
||||||
|
case IP_VERSION(10, 3, 4):
|
||||||
|
case IP_VERSION(10, 3, 5):
|
||||||
|
amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
switch (adev->ip_versions[OSSSYS_HWIP][0]) {
|
||||||
|
case IP_VERSION(4, 0, 0):
|
||||||
|
case IP_VERSION(4, 0, 1):
|
||||||
|
case IP_VERSION(4, 1, 0):
|
||||||
|
case IP_VERSION(4, 1, 1):
|
||||||
|
case IP_VERSION(4, 3, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(4, 2, 0):
|
||||||
|
case IP_VERSION(4, 2, 1):
|
||||||
|
case IP_VERSION(4, 4, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(5, 0, 0):
|
||||||
|
case IP_VERSION(5, 0, 1):
|
||||||
|
case IP_VERSION(5, 0, 2):
|
||||||
|
case IP_VERSION(5, 0, 3):
|
||||||
|
case IP_VERSION(5, 2, 0):
|
||||||
|
case IP_VERSION(5, 2, 1):
|
||||||
|
amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
switch (adev->ip_versions[MP0_HWIP][0]) {
|
||||||
|
case IP_VERSION(9, 0, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(10, 0, 0):
|
||||||
|
case IP_VERSION(10, 0, 1):
|
||||||
|
amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(11, 0, 0):
|
||||||
|
case IP_VERSION(11, 0, 2):
|
||||||
|
case IP_VERSION(11, 0, 4):
|
||||||
|
case IP_VERSION(11, 0, 5):
|
||||||
|
case IP_VERSION(11, 0, 9):
|
||||||
|
case IP_VERSION(11, 0, 7):
|
||||||
|
case IP_VERSION(11, 0, 11):
|
||||||
|
case IP_VERSION(11, 0, 12):
|
||||||
|
case IP_VERSION(11, 0, 13):
|
||||||
|
case IP_VERSION(11, 5, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(11, 0, 8):
|
||||||
|
amdgpu_device_ip_block_add(adev, &psp_v11_0_8_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(11, 0, 3):
|
||||||
|
case IP_VERSION(12, 0, 1):
|
||||||
|
amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(13, 0, 1):
|
||||||
|
case IP_VERSION(13, 0, 2):
|
||||||
|
case IP_VERSION(13, 0, 3):
|
||||||
|
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
switch (adev->ip_versions[MP1_HWIP][0]) {
|
||||||
|
case IP_VERSION(9, 0, 0):
|
||||||
|
case IP_VERSION(10, 0, 0):
|
||||||
|
case IP_VERSION(10, 0, 1):
|
||||||
|
case IP_VERSION(11, 0, 2):
|
||||||
|
if (adev->asic_type == CHIP_ARCTURUS)
|
||||||
|
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||||
|
else
|
||||||
|
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(11, 0, 0):
|
||||||
|
case IP_VERSION(11, 0, 5):
|
||||||
|
case IP_VERSION(11, 0, 9):
|
||||||
|
case IP_VERSION(11, 0, 7):
|
||||||
|
case IP_VERSION(11, 0, 8):
|
||||||
|
case IP_VERSION(11, 0, 11):
|
||||||
|
case IP_VERSION(11, 0, 12):
|
||||||
|
case IP_VERSION(11, 0, 13):
|
||||||
|
case IP_VERSION(11, 5, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(12, 0, 0):
|
||||||
|
case IP_VERSION(12, 0, 1):
|
||||||
|
amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(13, 0, 1):
|
||||||
|
case IP_VERSION(13, 0, 2):
|
||||||
|
case IP_VERSION(13, 0, 3):
|
||||||
|
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) {
|
||||||
|
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||||
|
#if defined(CONFIG_DRM_AMD_DC)
|
||||||
|
} else if (adev->ip_versions[DCE_HWIP][0]) {
|
||||||
|
switch (adev->ip_versions[DCE_HWIP][0]) {
|
||||||
|
case IP_VERSION(1, 0, 0):
|
||||||
|
case IP_VERSION(1, 0, 1):
|
||||||
|
case IP_VERSION(2, 0, 2):
|
||||||
|
case IP_VERSION(2, 0, 0):
|
||||||
|
case IP_VERSION(2, 0, 3):
|
||||||
|
case IP_VERSION(2, 1, 0):
|
||||||
|
case IP_VERSION(3, 0, 0):
|
||||||
|
case IP_VERSION(3, 0, 2):
|
||||||
|
case IP_VERSION(3, 0, 3):
|
||||||
|
case IP_VERSION(3, 0, 1):
|
||||||
|
case IP_VERSION(3, 1, 2):
|
||||||
|
case IP_VERSION(3, 1, 3):
|
||||||
|
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else if (adev->ip_versions[DCI_HWIP][0]) {
|
||||||
|
switch (adev->ip_versions[DCI_HWIP][0]) {
|
||||||
|
case IP_VERSION(12, 0, 0):
|
||||||
|
case IP_VERSION(12, 0, 1):
|
||||||
|
case IP_VERSION(12, 1, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||||
|
case IP_VERSION(9, 0, 1):
|
||||||
|
case IP_VERSION(9, 1, 0):
|
||||||
|
case IP_VERSION(9, 2, 1):
|
||||||
|
case IP_VERSION(9, 2, 2):
|
||||||
|
case IP_VERSION(9, 3, 0):
|
||||||
|
case IP_VERSION(9, 4, 0):
|
||||||
|
case IP_VERSION(9, 4, 1):
|
||||||
|
case IP_VERSION(9, 4, 2):
|
||||||
|
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(10, 1, 10):
|
||||||
|
case IP_VERSION(10, 1, 2):
|
||||||
|
case IP_VERSION(10, 1, 1):
|
||||||
|
case IP_VERSION(10, 1, 3):
|
||||||
|
case IP_VERSION(10, 3, 0):
|
||||||
|
case IP_VERSION(10, 3, 2):
|
||||||
|
case IP_VERSION(10, 3, 1):
|
||||||
|
case IP_VERSION(10, 3, 4):
|
||||||
|
case IP_VERSION(10, 3, 5):
|
||||||
|
case IP_VERSION(10, 3, 3):
|
||||||
|
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
switch (adev->ip_versions[SDMA0_HWIP][0]) {
|
||||||
|
case IP_VERSION(4, 0, 0):
|
||||||
|
case IP_VERSION(4, 0, 1):
|
||||||
|
case IP_VERSION(4, 1, 0):
|
||||||
|
case IP_VERSION(4, 1, 1):
|
||||||
|
case IP_VERSION(4, 1, 2):
|
||||||
|
case IP_VERSION(4, 2, 0):
|
||||||
|
case IP_VERSION(4, 2, 2):
|
||||||
|
case IP_VERSION(4, 4, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(5, 0, 0):
|
||||||
|
case IP_VERSION(5, 0, 1):
|
||||||
|
case IP_VERSION(5, 0, 2):
|
||||||
|
case IP_VERSION(5, 0, 5):
|
||||||
|
amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(5, 2, 0):
|
||||||
|
case IP_VERSION(5, 2, 2):
|
||||||
|
case IP_VERSION(5, 2, 4):
|
||||||
|
case IP_VERSION(5, 2, 5):
|
||||||
|
case IP_VERSION(5, 2, 3):
|
||||||
|
case IP_VERSION(5, 2, 1):
|
||||||
|
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
if (adev->ip_versions[VCE_HWIP][0]) {
|
||||||
|
switch (adev->ip_versions[UVD_HWIP][0]) {
|
||||||
|
case IP_VERSION(7, 0, 0):
|
||||||
|
case IP_VERSION(7, 2, 0):
|
||||||
|
/* UVD is not supported on vega20 SR-IOV */
|
||||||
|
if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev)))
|
||||||
|
amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
switch (adev->ip_versions[VCE_HWIP][0]) {
|
||||||
|
case IP_VERSION(4, 0, 0):
|
||||||
|
case IP_VERSION(4, 1, 0):
|
||||||
|
/* VCE is not supported on vega20 SR-IOV */
|
||||||
|
if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev)))
|
||||||
|
amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (adev->ip_versions[UVD_HWIP][0]) {
|
||||||
|
case IP_VERSION(1, 0, 0):
|
||||||
|
case IP_VERSION(1, 0, 1):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(2, 0, 0):
|
||||||
|
case IP_VERSION(2, 0, 2):
|
||||||
|
case IP_VERSION(2, 2, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block);
|
||||||
|
amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(2, 0, 3):
|
||||||
|
break;
|
||||||
|
case IP_VERSION(2, 5, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block);
|
||||||
|
amdgpu_device_ip_block_add(adev, &jpeg_v2_5_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(2, 6, 0):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vcn_v2_6_ip_block);
|
||||||
|
amdgpu_device_ip_block_add(adev, &jpeg_v2_6_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(3, 0, 0):
|
||||||
|
case IP_VERSION(3, 0, 16):
|
||||||
|
case IP_VERSION(3, 1, 1):
|
||||||
|
case IP_VERSION(3, 0, 2):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||||
|
if (!amdgpu_sriov_vf(adev))
|
||||||
|
amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block);
|
||||||
|
break;
|
||||||
|
case IP_VERSION(3, 0, 33):
|
||||||
|
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||||
|
case IP_VERSION(10, 1, 10):
|
||||||
|
case IP_VERSION(10, 1, 1):
|
||||||
|
case IP_VERSION(10, 1, 2):
|
||||||
|
case IP_VERSION(10, 1, 3):
|
||||||
|
case IP_VERSION(10, 3, 0):
|
||||||
|
case IP_VERSION(10, 3, 1):
|
||||||
|
case IP_VERSION(10, 3, 2):
|
||||||
|
case IP_VERSION(10, 3, 3):
|
||||||
|
case IP_VERSION(10, 3, 4):
|
||||||
|
case IP_VERSION(10, 3, 5):
|
||||||
|
amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
switch (adev->asic_type) {
|
||||||
|
case CHIP_VEGA10:
|
||||||
|
vega10_reg_base_init(adev);
|
||||||
|
adev->sdma.num_instances = 2;
|
||||||
|
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 0);
|
||||||
|
adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 0);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 0);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 0);
|
||||||
|
adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0);
|
||||||
|
adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 1, 0);
|
||||||
|
adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 0, 0);
|
||||||
|
adev->ip_versions[MP0_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[MP1_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[THM_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 0, 1);
|
||||||
|
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 0, 0);
|
||||||
|
adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 0, 0);
|
||||||
|
adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 0, 0);
|
||||||
|
break;
|
||||||
|
case CHIP_VEGA12:
|
||||||
|
vega10_reg_base_init(adev);
|
||||||
|
adev->sdma.num_instances = 2;
|
||||||
|
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 3, 0);
|
||||||
|
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 3, 0);
|
||||||
|
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 1);
|
||||||
|
adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 1);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 1);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 1);
|
||||||
|
adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 5, 0);
|
||||||
|
adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 2, 0);
|
||||||
|
adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 0);
|
||||||
|
adev->ip_versions[MP0_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[MP1_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[THM_HWIP][0] = IP_VERSION(9, 0, 0);
|
||||||
|
adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(9, 0, 1);
|
||||||
|
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 1);
|
||||||
|
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 0, 0);
|
||||||
|
adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 0, 0);
|
||||||
|
adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 0, 1);
|
||||||
|
break;
|
||||||
|
case CHIP_RAVEN:
|
||||||
|
vega10_reg_base_init(adev);
|
||||||
|
adev->sdma.num_instances = 1;
|
||||||
|
adev->vcn.num_vcn_inst = 1;
|
||||||
|
if (adev->apu_flags & AMD_APU_IS_RAVEN2) {
|
||||||
|
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 2, 0);
|
||||||
|
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 2, 0);
|
||||||
|
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 1, 1);
|
||||||
|
adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 1, 1);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 1, 1);
|
||||||
|
adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 1);
|
||||||
|
adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 0, 1);
|
||||||
|
adev->ip_versions[UMC_HWIP][0] = IP_VERSION(7, 5, 0);
|
||||||
|
adev->ip_versions[MP0_HWIP][0] = IP_VERSION(10, 0, 1);
|
||||||
|
adev->ip_versions[MP1_HWIP][0] = IP_VERSION(10, 0, 1);
|
||||||
|
adev->ip_versions[THM_HWIP][0] = IP_VERSION(10, 1, 0);
|
||||||
|
adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(10, 0, 1);
|
||||||
|
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 2);
|
||||||
|
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 1);
|
||||||
|
adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 1);
|
||||||
|
} else {
|
||||||
|
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 1, 0);
|
||||||
|
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 1, 0);
|
||||||
|
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 1, 0);
|
||||||
|
adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 1, 0);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 1, 0);
|
||||||
|
adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0);
|
||||||
|
adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 0, 0);
|
||||||
|
adev->ip_versions[UMC_HWIP][0] = IP_VERSION(7, 0, 0);
|
||||||
|
adev->ip_versions[MP0_HWIP][0] = IP_VERSION(10, 0, 0);
|
||||||
|
adev->ip_versions[MP1_HWIP][0] = IP_VERSION(10, 0, 0);
|
||||||
|
adev->ip_versions[THM_HWIP][0] = IP_VERSION(10, 0, 0);
|
||||||
|
adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(10, 0, 0);
|
||||||
|
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 1, 0);
|
||||||
|
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 0);
|
||||||
|
adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CHIP_VEGA20:
|
||||||
|
vega20_reg_base_init(adev);
|
||||||
|
adev->sdma.num_instances = 2;
|
||||||
|
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 0);
|
||||||
|
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 0);
|
||||||
|
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 0);
|
||||||
|
adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 0);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 0);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 0);
|
||||||
|
adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 0);
|
||||||
|
adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 0);
|
||||||
|
adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 1);
|
||||||
|
adev->ip_versions[MP0_HWIP][0] = IP_VERSION(11, 0, 2);
|
||||||
|
adev->ip_versions[MP1_HWIP][0] = IP_VERSION(11, 0, 2);
|
||||||
|
adev->ip_versions[THM_HWIP][0] = IP_VERSION(11, 0, 2);
|
||||||
|
adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 2);
|
||||||
|
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 0);
|
||||||
|
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 2, 0);
|
||||||
|
adev->ip_versions[UVD_HWIP][1] = IP_VERSION(7, 2, 0);
|
||||||
|
adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 1, 0);
|
||||||
|
adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 1, 0);
|
||||||
|
break;
|
||||||
|
case CHIP_ARCTURUS:
|
||||||
|
arct_reg_base_init(adev);
|
||||||
|
adev->sdma.num_instances = 8;
|
||||||
|
adev->vcn.num_vcn_inst = 2;
|
||||||
|
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 1);
|
||||||
|
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 1);
|
||||||
|
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 1);
|
||||||
|
adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 1);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 2);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 2);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][1] = IP_VERSION(4, 2, 2);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][2] = IP_VERSION(4, 2, 2);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][3] = IP_VERSION(4, 2, 2);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][4] = IP_VERSION(4, 2, 2);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][5] = IP_VERSION(4, 2, 2);
|
||||||
|
adev->ip_versions[SDMA1_HWIP][6] = IP_VERSION(4, 2, 2);
|
||||||
|
adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 1);
|
||||||
|
adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 1);
|
||||||
|
adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 2);
|
||||||
|
adev->ip_versions[MP0_HWIP][0] = IP_VERSION(11, 0, 4);
|
||||||
|
adev->ip_versions[MP1_HWIP][0] = IP_VERSION(11, 0, 2);
|
||||||
|
adev->ip_versions[THM_HWIP][0] = IP_VERSION(11, 0, 3);
|
||||||
|
adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 3);
|
||||||
|
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 1);
|
||||||
|
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 5, 0);
|
||||||
|
adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 5, 0);
|
||||||
|
break;
|
||||||
|
case CHIP_ALDEBARAN:
|
||||||
|
aldebaran_reg_base_init(adev);
|
||||||
|
adev->sdma.num_instances = 5;
|
||||||
|
adev->vcn.num_vcn_inst = 2;
|
||||||
|
adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 2);
|
||||||
|
adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 2);
|
||||||
|
adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 4, 0);
|
||||||
|
adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 4, 0);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 4, 0);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][1] = IP_VERSION(4, 4, 0);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][2] = IP_VERSION(4, 4, 0);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][3] = IP_VERSION(4, 4, 0);
|
||||||
|
adev->ip_versions[SDMA0_HWIP][4] = IP_VERSION(4, 4, 0);
|
||||||
|
adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 2);
|
||||||
|
adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 4);
|
||||||
|
adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 7, 0);
|
||||||
|
adev->ip_versions[MP0_HWIP][0] = IP_VERSION(13, 0, 2);
|
||||||
|
adev->ip_versions[MP1_HWIP][0] = IP_VERSION(13, 0, 2);
|
||||||
|
adev->ip_versions[THM_HWIP][0] = IP_VERSION(13, 0, 2);
|
||||||
|
adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(13, 0, 2);
|
||||||
|
adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 2);
|
||||||
|
adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 6, 0);
|
||||||
|
adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 6, 0);
|
||||||
|
adev->ip_versions[XGMI_HWIP][0] = IP_VERSION(6, 1, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
r = amdgpu_discovery_reg_base_init(adev);
|
||||||
|
if (r)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
amdgpu_discovery_harvest_ip(adev);
|
||||||
|
|
||||||
|
if (!adev->mman.discovery_bin) {
|
||||||
|
DRM_ERROR("ip discovery uninitialized\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adev->ip_versions[GC_HWIP][0]) {
|
||||||
|
case IP_VERSION(9, 0, 1):
|
||||||
|
case IP_VERSION(9, 2, 1):
|
||||||
|
case IP_VERSION(9, 4, 0):
|
||||||
|
case IP_VERSION(9, 4, 1):
|
||||||
|
case IP_VERSION(9, 4, 2):
|
||||||
|
adev->family = AMDGPU_FAMILY_AI;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(9, 1, 0):
|
||||||
|
case IP_VERSION(9, 2, 2):
|
||||||
|
case IP_VERSION(9, 3, 0):
|
||||||
|
adev->family = AMDGPU_FAMILY_RV;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(10, 1, 10):
|
||||||
|
case IP_VERSION(10, 1, 1):
|
||||||
|
case IP_VERSION(10, 1, 2):
|
||||||
|
case IP_VERSION(10, 1, 3):
|
||||||
|
case IP_VERSION(10, 3, 0):
|
||||||
|
case IP_VERSION(10, 3, 2):
|
||||||
|
case IP_VERSION(10, 3, 4):
|
||||||
|
case IP_VERSION(10, 3, 5):
|
||||||
|
adev->family = AMDGPU_FAMILY_NV;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(10, 3, 1):
|
||||||
|
adev->family = AMDGPU_FAMILY_VGH;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(10, 3, 3):
|
||||||
|
adev->family = AMDGPU_FAMILY_YC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adev->ip_versions[XGMI_HWIP][0] == IP_VERSION(4, 8, 0))
|
||||||
|
adev->gmc.xgmi.supported = true;
|
||||||
|
|
||||||
|
/* set NBIO version */
|
||||||
|
switch (adev->ip_versions[NBIO_HWIP][0]) {
|
||||||
|
case IP_VERSION(6, 1, 0):
|
||||||
|
case IP_VERSION(6, 2, 0):
|
||||||
|
adev->nbio.funcs = &nbio_v6_1_funcs;
|
||||||
|
adev->nbio.hdp_flush_reg = &nbio_v6_1_hdp_flush_reg;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(7, 0, 0):
|
||||||
|
case IP_VERSION(7, 0, 1):
|
||||||
|
case IP_VERSION(2, 5, 0):
|
||||||
|
adev->nbio.funcs = &nbio_v7_0_funcs;
|
||||||
|
adev->nbio.hdp_flush_reg = &nbio_v7_0_hdp_flush_reg;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(7, 4, 0):
|
||||||
|
case IP_VERSION(7, 4, 1):
|
||||||
|
adev->nbio.funcs = &nbio_v7_4_funcs;
|
||||||
|
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(7, 4, 4):
|
||||||
|
adev->nbio.funcs = &nbio_v7_4_funcs;
|
||||||
|
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg_ald;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(7, 2, 0):
|
||||||
|
case IP_VERSION(7, 2, 1):
|
||||||
|
case IP_VERSION(7, 5, 0):
|
||||||
|
adev->nbio.funcs = &nbio_v7_2_funcs;
|
||||||
|
adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(2, 1, 1):
|
||||||
|
case IP_VERSION(2, 3, 0):
|
||||||
|
case IP_VERSION(2, 3, 1):
|
||||||
|
case IP_VERSION(2, 3, 2):
|
||||||
|
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||||
|
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(3, 3, 0):
|
||||||
|
case IP_VERSION(3, 3, 1):
|
||||||
|
case IP_VERSION(3, 3, 2):
|
||||||
|
case IP_VERSION(3, 3, 3):
|
||||||
|
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||||
|
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg_sc;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adev->ip_versions[HDP_HWIP][0]) {
|
||||||
|
case IP_VERSION(4, 0, 0):
|
||||||
|
case IP_VERSION(4, 0, 1):
|
||||||
|
case IP_VERSION(4, 1, 0):
|
||||||
|
case IP_VERSION(4, 1, 1):
|
||||||
|
case IP_VERSION(4, 1, 2):
|
||||||
|
case IP_VERSION(4, 2, 0):
|
||||||
|
case IP_VERSION(4, 2, 1):
|
||||||
|
case IP_VERSION(4, 4, 0):
|
||||||
|
adev->hdp.funcs = &hdp_v4_0_funcs;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(5, 0, 0):
|
||||||
|
case IP_VERSION(5, 0, 1):
|
||||||
|
case IP_VERSION(5, 0, 2):
|
||||||
|
case IP_VERSION(5, 0, 3):
|
||||||
|
case IP_VERSION(5, 0, 4):
|
||||||
|
case IP_VERSION(5, 2, 0):
|
||||||
|
adev->hdp.funcs = &hdp_v5_0_funcs;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adev->ip_versions[DF_HWIP][0]) {
|
||||||
|
case IP_VERSION(3, 6, 0):
|
||||||
|
case IP_VERSION(3, 6, 1):
|
||||||
|
case IP_VERSION(3, 6, 2):
|
||||||
|
adev->df.funcs = &df_v3_6_funcs;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(2, 1, 0):
|
||||||
|
case IP_VERSION(2, 1, 1):
|
||||||
|
case IP_VERSION(2, 5, 0):
|
||||||
|
case IP_VERSION(3, 5, 1):
|
||||||
|
case IP_VERSION(3, 5, 2):
|
||||||
|
adev->df.funcs = &df_v1_7_funcs;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adev->ip_versions[SMUIO_HWIP][0]) {
|
||||||
|
case IP_VERSION(9, 0, 0):
|
||||||
|
case IP_VERSION(9, 0, 1):
|
||||||
|
case IP_VERSION(10, 0, 0):
|
||||||
|
case IP_VERSION(10, 0, 1):
|
||||||
|
case IP_VERSION(10, 0, 2):
|
||||||
|
adev->smuio.funcs = &smuio_v9_0_funcs;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(11, 0, 0):
|
||||||
|
case IP_VERSION(11, 0, 2):
|
||||||
|
case IP_VERSION(11, 0, 3):
|
||||||
|
case IP_VERSION(11, 0, 4):
|
||||||
|
case IP_VERSION(11, 0, 7):
|
||||||
|
case IP_VERSION(11, 0, 8):
|
||||||
|
adev->smuio.funcs = &smuio_v11_0_funcs;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(11, 0, 6):
|
||||||
|
case IP_VERSION(11, 0, 10):
|
||||||
|
case IP_VERSION(11, 0, 11):
|
||||||
|
case IP_VERSION(11, 5, 0):
|
||||||
|
case IP_VERSION(13, 0, 1):
|
||||||
|
adev->smuio.funcs = &smuio_v11_0_6_funcs;
|
||||||
|
break;
|
||||||
|
case IP_VERSION(13, 0, 2):
|
||||||
|
adev->smuio.funcs = &smuio_v13_0_funcs;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = amdgpu_discovery_set_common_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = amdgpu_discovery_set_gmc_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* For SR-IOV, PSP needs to be initialized before IH */
|
||||||
|
if (amdgpu_sriov_vf(adev)) {
|
||||||
|
r = amdgpu_discovery_set_psp_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
r = amdgpu_discovery_set_ih_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
r = amdgpu_discovery_set_ih_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
|
||||||
|
r = amdgpu_discovery_set_psp_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) {
|
||||||
|
r = amdgpu_discovery_set_smu_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = amdgpu_discovery_set_display_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = amdgpu_discovery_set_gc_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = amdgpu_discovery_set_sdma_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT &&
|
||||||
|
!amdgpu_sriov_vf(adev)) {
|
||||||
|
r = amdgpu_discovery_set_smu_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = amdgpu_discovery_set_mm_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (adev->enable_mes) {
|
||||||
|
r = amdgpu_discovery_set_mes_ip_blocks(adev);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -36,5 +36,6 @@ int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, int n
|
|||||||
int amdgpu_discovery_get_vcn_version(struct amdgpu_device *adev, int vcn_instance,
|
int amdgpu_discovery_get_vcn_version(struct amdgpu_device *adev, int vcn_instance,
|
||||||
int *major, int *minor, int *revision);
|
int *major, int *minor, int *revision);
|
||||||
int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev);
|
int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev);
|
||||||
|
int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev);
|
||||||
|
|
||||||
#endif /* __AMDGPU_DISCOVERY__ */
|
#endif /* __AMDGPU_DISCOVERY__ */
|
||||||
|
@ -97,9 +97,11 @@
|
|||||||
* - 3.40.0 - Add AMDGPU_IDS_FLAGS_TMZ
|
* - 3.40.0 - Add AMDGPU_IDS_FLAGS_TMZ
|
||||||
* - 3.41.0 - Add video codec query
|
* - 3.41.0 - Add video codec query
|
||||||
* - 3.42.0 - Add 16bpc fixed point display support
|
* - 3.42.0 - Add 16bpc fixed point display support
|
||||||
|
* - 3.43.0 - Add device hot plug/unplug support
|
||||||
|
* - 3.44.0 - DCN3 supports DCC independent block settings: !64B && 128B, 64B && 128B
|
||||||
*/
|
*/
|
||||||
#define KMS_DRIVER_MAJOR 3
|
#define KMS_DRIVER_MAJOR 3
|
||||||
#define KMS_DRIVER_MINOR 42
|
#define KMS_DRIVER_MINOR 44
|
||||||
#define KMS_DRIVER_PATCHLEVEL 0
|
#define KMS_DRIVER_PATCHLEVEL 0
|
||||||
|
|
||||||
int amdgpu_vram_limit;
|
int amdgpu_vram_limit;
|
||||||
@ -628,7 +630,7 @@ module_param_named(mcbp, amdgpu_mcbp, int, 0444);
|
|||||||
/**
|
/**
|
||||||
* DOC: discovery (int)
|
* DOC: discovery (int)
|
||||||
* Allow driver to discover hardware IP information from IP Discovery table at the top of VRAM.
|
* Allow driver to discover hardware IP information from IP Discovery table at the top of VRAM.
|
||||||
* (-1 = auto (default), 0 = disabled, 1 = enabled)
|
* (-1 = auto (default), 0 = disabled, 1 = enabled, 2 = use ip_discovery table from file)
|
||||||
*/
|
*/
|
||||||
MODULE_PARM_DESC(discovery,
|
MODULE_PARM_DESC(discovery,
|
||||||
"Allow driver to discover hardware IPs from IP Discovery table at the top of VRAM");
|
"Allow driver to discover hardware IPs from IP Discovery table at the top of VRAM");
|
||||||
@ -876,7 +878,7 @@ module_param_named(reset_method, amdgpu_reset_method, int, 0444);
|
|||||||
* result in the GPU entering bad status when the number of total
|
* result in the GPU entering bad status when the number of total
|
||||||
* faulty pages by ECC exceeds the threshold value.
|
* faulty pages by ECC exceeds the threshold value.
|
||||||
*/
|
*/
|
||||||
MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = auto(default value), 0 = disable bad page retirement)");
|
MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = auto(default value), 0 = disable bad page retirement, -2 = ignore bad page threshold)");
|
||||||
module_param_named(bad_page_threshold, amdgpu_bad_page_threshold, int, 0444);
|
module_param_named(bad_page_threshold, amdgpu_bad_page_threshold, int, 0444);
|
||||||
|
|
||||||
MODULE_PARM_DESC(num_kcq, "number of kernel compute queue user want to setup (8 if set to greater than 8 or less than 0, only affect gfx 8+)");
|
MODULE_PARM_DESC(num_kcq, "number of kernel compute queue user want to setup (8 if set to greater than 8 or less than 0, only affect gfx 8+)");
|
||||||
@ -891,6 +893,636 @@ MODULE_PARM_DESC(smu_pptable_id,
|
|||||||
"specify pptable id to be used (-1 = auto(default) value, 0 = use pptable from vbios, > 0 = soft pptable id)");
|
"specify pptable id to be used (-1 = auto(default) value, 0 = use pptable from vbios, > 0 = soft pptable id)");
|
||||||
module_param_named(smu_pptable_id, amdgpu_smu_pptable_id, int, 0444);
|
module_param_named(smu_pptable_id, amdgpu_smu_pptable_id, int, 0444);
|
||||||
|
|
||||||
|
/* These devices are not supported by amdgpu.
|
||||||
|
* They are supported by the mach64, r128, radeon drivers
|
||||||
|
*/
|
||||||
|
static const u16 amdgpu_unsupported_pciidlist[] = {
|
||||||
|
/* mach64 */
|
||||||
|
0x4354,
|
||||||
|
0x4358,
|
||||||
|
0x4554,
|
||||||
|
0x4742,
|
||||||
|
0x4744,
|
||||||
|
0x4749,
|
||||||
|
0x474C,
|
||||||
|
0x474D,
|
||||||
|
0x474E,
|
||||||
|
0x474F,
|
||||||
|
0x4750,
|
||||||
|
0x4751,
|
||||||
|
0x4752,
|
||||||
|
0x4753,
|
||||||
|
0x4754,
|
||||||
|
0x4755,
|
||||||
|
0x4756,
|
||||||
|
0x4757,
|
||||||
|
0x4758,
|
||||||
|
0x4759,
|
||||||
|
0x475A,
|
||||||
|
0x4C42,
|
||||||
|
0x4C44,
|
||||||
|
0x4C47,
|
||||||
|
0x4C49,
|
||||||
|
0x4C4D,
|
||||||
|
0x4C4E,
|
||||||
|
0x4C50,
|
||||||
|
0x4C51,
|
||||||
|
0x4C52,
|
||||||
|
0x4C53,
|
||||||
|
0x5654,
|
||||||
|
0x5655,
|
||||||
|
0x5656,
|
||||||
|
/* r128 */
|
||||||
|
0x4c45,
|
||||||
|
0x4c46,
|
||||||
|
0x4d46,
|
||||||
|
0x4d4c,
|
||||||
|
0x5041,
|
||||||
|
0x5042,
|
||||||
|
0x5043,
|
||||||
|
0x5044,
|
||||||
|
0x5045,
|
||||||
|
0x5046,
|
||||||
|
0x5047,
|
||||||
|
0x5048,
|
||||||
|
0x5049,
|
||||||
|
0x504A,
|
||||||
|
0x504B,
|
||||||
|
0x504C,
|
||||||
|
0x504D,
|
||||||
|
0x504E,
|
||||||
|
0x504F,
|
||||||
|
0x5050,
|
||||||
|
0x5051,
|
||||||
|
0x5052,
|
||||||
|
0x5053,
|
||||||
|
0x5054,
|
||||||
|
0x5055,
|
||||||
|
0x5056,
|
||||||
|
0x5057,
|
||||||
|
0x5058,
|
||||||
|
0x5245,
|
||||||
|
0x5246,
|
||||||
|
0x5247,
|
||||||
|
0x524b,
|
||||||
|
0x524c,
|
||||||
|
0x534d,
|
||||||
|
0x5446,
|
||||||
|
0x544C,
|
||||||
|
0x5452,
|
||||||
|
/* radeon */
|
||||||
|
0x3150,
|
||||||
|
0x3151,
|
||||||
|
0x3152,
|
||||||
|
0x3154,
|
||||||
|
0x3155,
|
||||||
|
0x3E50,
|
||||||
|
0x3E54,
|
||||||
|
0x4136,
|
||||||
|
0x4137,
|
||||||
|
0x4144,
|
||||||
|
0x4145,
|
||||||
|
0x4146,
|
||||||
|
0x4147,
|
||||||
|
0x4148,
|
||||||
|
0x4149,
|
||||||
|
0x414A,
|
||||||
|
0x414B,
|
||||||
|
0x4150,
|
||||||
|
0x4151,
|
||||||
|
0x4152,
|
||||||
|
0x4153,
|
||||||
|
0x4154,
|
||||||
|
0x4155,
|
||||||
|
0x4156,
|
||||||
|
0x4237,
|
||||||
|
0x4242,
|
||||||
|
0x4336,
|
||||||
|
0x4337,
|
||||||
|
0x4437,
|
||||||
|
0x4966,
|
||||||
|
0x4967,
|
||||||
|
0x4A48,
|
||||||
|
0x4A49,
|
||||||
|
0x4A4A,
|
||||||
|
0x4A4B,
|
||||||
|
0x4A4C,
|
||||||
|
0x4A4D,
|
||||||
|
0x4A4E,
|
||||||
|
0x4A4F,
|
||||||
|
0x4A50,
|
||||||
|
0x4A54,
|
||||||
|
0x4B48,
|
||||||
|
0x4B49,
|
||||||
|
0x4B4A,
|
||||||
|
0x4B4B,
|
||||||
|
0x4B4C,
|
||||||
|
0x4C57,
|
||||||
|
0x4C58,
|
||||||
|
0x4C59,
|
||||||
|
0x4C5A,
|
||||||
|
0x4C64,
|
||||||
|
0x4C66,
|
||||||
|
0x4C67,
|
||||||
|
0x4E44,
|
||||||
|
0x4E45,
|
||||||
|
0x4E46,
|
||||||
|
0x4E47,
|
||||||
|
0x4E48,
|
||||||
|
0x4E49,
|
||||||
|
0x4E4A,
|
||||||
|
0x4E4B,
|
||||||
|
0x4E50,
|
||||||
|
0x4E51,
|
||||||
|
0x4E52,
|
||||||
|
0x4E53,
|
||||||
|
0x4E54,
|
||||||
|
0x4E56,
|
||||||
|
0x5144,
|
||||||
|
0x5145,
|
||||||
|
0x5146,
|
||||||
|
0x5147,
|
||||||
|
0x5148,
|
||||||
|
0x514C,
|
||||||
|
0x514D,
|
||||||
|
0x5157,
|
||||||
|
0x5158,
|
||||||
|
0x5159,
|
||||||
|
0x515A,
|
||||||
|
0x515E,
|
||||||
|
0x5460,
|
||||||
|
0x5462,
|
||||||
|
0x5464,
|
||||||
|
0x5548,
|
||||||
|
0x5549,
|
||||||
|
0x554A,
|
||||||
|
0x554B,
|
||||||
|
0x554C,
|
||||||
|
0x554D,
|
||||||
|
0x554E,
|
||||||
|
0x554F,
|
||||||
|
0x5550,
|
||||||
|
0x5551,
|
||||||
|
0x5552,
|
||||||
|
0x5554,
|
||||||
|
0x564A,
|
||||||
|
0x564B,
|
||||||
|
0x564F,
|
||||||
|
0x5652,
|
||||||
|
0x5653,
|
||||||
|
0x5657,
|
||||||
|
0x5834,
|
||||||
|
0x5835,
|
||||||
|
0x5954,
|
||||||
|
0x5955,
|
||||||
|
0x5974,
|
||||||
|
0x5975,
|
||||||
|
0x5960,
|
||||||
|
0x5961,
|
||||||
|
0x5962,
|
||||||
|
0x5964,
|
||||||
|
0x5965,
|
||||||
|
0x5969,
|
||||||
|
0x5a41,
|
||||||
|
0x5a42,
|
||||||
|
0x5a61,
|
||||||
|
0x5a62,
|
||||||
|
0x5b60,
|
||||||
|
0x5b62,
|
||||||
|
0x5b63,
|
||||||
|
0x5b64,
|
||||||
|
0x5b65,
|
||||||
|
0x5c61,
|
||||||
|
0x5c63,
|
||||||
|
0x5d48,
|
||||||
|
0x5d49,
|
||||||
|
0x5d4a,
|
||||||
|
0x5d4c,
|
||||||
|
0x5d4d,
|
||||||
|
0x5d4e,
|
||||||
|
0x5d4f,
|
||||||
|
0x5d50,
|
||||||
|
0x5d52,
|
||||||
|
0x5d57,
|
||||||
|
0x5e48,
|
||||||
|
0x5e4a,
|
||||||
|
0x5e4b,
|
||||||
|
0x5e4c,
|
||||||
|
0x5e4d,
|
||||||
|
0x5e4f,
|
||||||
|
0x6700,
|
||||||
|
0x6701,
|
||||||
|
0x6702,
|
||||||
|
0x6703,
|
||||||
|
0x6704,
|
||||||
|
0x6705,
|
||||||
|
0x6706,
|
||||||
|
0x6707,
|
||||||
|
0x6708,
|
||||||
|
0x6709,
|
||||||
|
0x6718,
|
||||||
|
0x6719,
|
||||||
|
0x671c,
|
||||||
|
0x671d,
|
||||||
|
0x671f,
|
||||||
|
0x6720,
|
||||||
|
0x6721,
|
||||||
|
0x6722,
|
||||||
|
0x6723,
|
||||||
|
0x6724,
|
||||||
|
0x6725,
|
||||||
|
0x6726,
|
||||||
|
0x6727,
|
||||||
|
0x6728,
|
||||||
|
0x6729,
|
||||||
|
0x6738,
|
||||||
|
0x6739,
|
||||||
|
0x673e,
|
||||||
|
0x6740,
|
||||||
|
0x6741,
|
||||||
|
0x6742,
|
||||||
|
0x6743,
|
||||||
|
0x6744,
|
||||||
|
0x6745,
|
||||||
|
0x6746,
|
||||||
|
0x6747,
|
||||||
|
0x6748,
|
||||||
|
0x6749,
|
||||||
|
0x674A,
|
||||||
|
0x6750,
|
||||||
|
0x6751,
|
||||||
|
0x6758,
|
||||||
|
0x6759,
|
||||||
|
0x675B,
|
||||||
|
0x675D,
|
||||||
|
0x675F,
|
||||||
|
0x6760,
|
||||||
|
0x6761,
|
||||||
|
0x6762,
|
||||||
|
0x6763,
|
||||||
|
0x6764,
|
||||||
|
0x6765,
|
||||||
|
0x6766,
|
||||||
|
0x6767,
|
||||||
|
0x6768,
|
||||||
|
0x6770,
|
||||||
|
0x6771,
|
||||||
|
0x6772,
|
||||||
|
0x6778,
|
||||||
|
0x6779,
|
||||||
|
0x677B,
|
||||||
|
0x6840,
|
||||||
|
0x6841,
|
||||||
|
0x6842,
|
||||||
|
0x6843,
|
||||||
|
0x6849,
|
||||||
|
0x684C,
|
||||||
|
0x6850,
|
||||||
|
0x6858,
|
||||||
|
0x6859,
|
||||||
|
0x6880,
|
||||||
|
0x6888,
|
||||||
|
0x6889,
|
||||||
|
0x688A,
|
||||||
|
0x688C,
|
||||||
|
0x688D,
|
||||||
|
0x6898,
|
||||||
|
0x6899,
|
||||||
|
0x689b,
|
||||||
|
0x689c,
|
||||||
|
0x689d,
|
||||||
|
0x689e,
|
||||||
|
0x68a0,
|
||||||
|
0x68a1,
|
||||||
|
0x68a8,
|
||||||
|
0x68a9,
|
||||||
|
0x68b0,
|
||||||
|
0x68b8,
|
||||||
|
0x68b9,
|
||||||
|
0x68ba,
|
||||||
|
0x68be,
|
||||||
|
0x68bf,
|
||||||
|
0x68c0,
|
||||||
|
0x68c1,
|
||||||
|
0x68c7,
|
||||||
|
0x68c8,
|
||||||
|
0x68c9,
|
||||||
|
0x68d8,
|
||||||
|
0x68d9,
|
||||||
|
0x68da,
|
||||||
|
0x68de,
|
||||||
|
0x68e0,
|
||||||
|
0x68e1,
|
||||||
|
0x68e4,
|
||||||
|
0x68e5,
|
||||||
|
0x68e8,
|
||||||
|
0x68e9,
|
||||||
|
0x68f1,
|
||||||
|
0x68f2,
|
||||||
|
0x68f8,
|
||||||
|
0x68f9,
|
||||||
|
0x68fa,
|
||||||
|
0x68fe,
|
||||||
|
0x7100,
|
||||||
|
0x7101,
|
||||||
|
0x7102,
|
||||||
|
0x7103,
|
||||||
|
0x7104,
|
||||||
|
0x7105,
|
||||||
|
0x7106,
|
||||||
|
0x7108,
|
||||||
|
0x7109,
|
||||||
|
0x710A,
|
||||||
|
0x710B,
|
||||||
|
0x710C,
|
||||||
|
0x710E,
|
||||||
|
0x710F,
|
||||||
|
0x7140,
|
||||||
|
0x7141,
|
||||||
|
0x7142,
|
||||||
|
0x7143,
|
||||||
|
0x7144,
|
||||||
|
0x7145,
|
||||||
|
0x7146,
|
||||||
|
0x7147,
|
||||||
|
0x7149,
|
||||||
|
0x714A,
|
||||||
|
0x714B,
|
||||||
|
0x714C,
|
||||||
|
0x714D,
|
||||||
|
0x714E,
|
||||||
|
0x714F,
|
||||||
|
0x7151,
|
||||||
|
0x7152,
|
||||||
|
0x7153,
|
||||||
|
0x715E,
|
||||||
|
0x715F,
|
||||||
|
0x7180,
|
||||||
|
0x7181,
|
||||||
|
0x7183,
|
||||||
|
0x7186,
|
||||||
|
0x7187,
|
||||||
|
0x7188,
|
||||||
|
0x718A,
|
||||||
|
0x718B,
|
||||||
|
0x718C,
|
||||||
|
0x718D,
|
||||||
|
0x718F,
|
||||||
|
0x7193,
|
||||||
|
0x7196,
|
||||||
|
0x719B,
|
||||||
|
0x719F,
|
||||||
|
0x71C0,
|
||||||
|
0x71C1,
|
||||||
|
0x71C2,
|
||||||
|
0x71C3,
|
||||||
|
0x71C4,
|
||||||
|
0x71C5,
|
||||||
|
0x71C6,
|
||||||
|
0x71C7,
|
||||||
|
0x71CD,
|
||||||
|
0x71CE,
|
||||||
|
0x71D2,
|
||||||
|
0x71D4,
|
||||||
|
0x71D5,
|
||||||
|
0x71D6,
|
||||||
|
0x71DA,
|
||||||
|
0x71DE,
|
||||||
|
0x7200,
|
||||||
|
0x7210,
|
||||||
|
0x7211,
|
||||||
|
0x7240,
|
||||||
|
0x7243,
|
||||||
|
0x7244,
|
||||||
|
0x7245,
|
||||||
|
0x7246,
|
||||||
|
0x7247,
|
||||||
|
0x7248,
|
||||||
|
0x7249,
|
||||||
|
0x724A,
|
||||||
|
0x724B,
|
||||||
|
0x724C,
|
||||||
|
0x724D,
|
||||||
|
0x724E,
|
||||||
|
0x724F,
|
||||||
|
0x7280,
|
||||||
|
0x7281,
|
||||||
|
0x7283,
|
||||||
|
0x7284,
|
||||||
|
0x7287,
|
||||||
|
0x7288,
|
||||||
|
0x7289,
|
||||||
|
0x728B,
|
||||||
|
0x728C,
|
||||||
|
0x7290,
|
||||||
|
0x7291,
|
||||||
|
0x7293,
|
||||||
|
0x7297,
|
||||||
|
0x7834,
|
||||||
|
0x7835,
|
||||||
|
0x791e,
|
||||||
|
0x791f,
|
||||||
|
0x793f,
|
||||||
|
0x7941,
|
||||||
|
0x7942,
|
||||||
|
0x796c,
|
||||||
|
0x796d,
|
||||||
|
0x796e,
|
||||||
|
0x796f,
|
||||||
|
0x9400,
|
||||||
|
0x9401,
|
||||||
|
0x9402,
|
||||||
|
0x9403,
|
||||||
|
0x9405,
|
||||||
|
0x940A,
|
||||||
|
0x940B,
|
||||||
|
0x940F,
|
||||||
|
0x94A0,
|
||||||
|
0x94A1,
|
||||||
|
0x94A3,
|
||||||
|
0x94B1,
|
||||||
|
0x94B3,
|
||||||
|
0x94B4,
|
||||||
|
0x94B5,
|
||||||
|
0x94B9,
|
||||||
|
0x9440,
|
||||||
|
0x9441,
|
||||||
|
0x9442,
|
||||||
|
0x9443,
|
||||||
|
0x9444,
|
||||||
|
0x9446,
|
||||||
|
0x944A,
|
||||||
|
0x944B,
|
||||||
|
0x944C,
|
||||||
|
0x944E,
|
||||||
|
0x9450,
|
||||||
|
0x9452,
|
||||||
|
0x9456,
|
||||||
|
0x945A,
|
||||||
|
0x945B,
|
||||||
|
0x945E,
|
||||||
|
0x9460,
|
||||||
|
0x9462,
|
||||||
|
0x946A,
|
||||||
|
0x946B,
|
||||||
|
0x947A,
|
||||||
|
0x947B,
|
||||||
|
0x9480,
|
||||||
|
0x9487,
|
||||||
|
0x9488,
|
||||||
|
0x9489,
|
||||||
|
0x948A,
|
||||||
|
0x948F,
|
||||||
|
0x9490,
|
||||||
|
0x9491,
|
||||||
|
0x9495,
|
||||||
|
0x9498,
|
||||||
|
0x949C,
|
||||||
|
0x949E,
|
||||||
|
0x949F,
|
||||||
|
0x94C0,
|
||||||
|
0x94C1,
|
||||||
|
0x94C3,
|
||||||
|
0x94C4,
|
||||||
|
0x94C5,
|
||||||
|
0x94C6,
|
||||||
|
0x94C7,
|
||||||
|
0x94C8,
|
||||||
|
0x94C9,
|
||||||
|
0x94CB,
|
||||||
|
0x94CC,
|
||||||
|
0x94CD,
|
||||||
|
0x9500,
|
||||||
|
0x9501,
|
||||||
|
0x9504,
|
||||||
|
0x9505,
|
||||||
|
0x9506,
|
||||||
|
0x9507,
|
||||||
|
0x9508,
|
||||||
|
0x9509,
|
||||||
|
0x950F,
|
||||||
|
0x9511,
|
||||||
|
0x9515,
|
||||||
|
0x9517,
|
||||||
|
0x9519,
|
||||||
|
0x9540,
|
||||||
|
0x9541,
|
||||||
|
0x9542,
|
||||||
|
0x954E,
|
||||||
|
0x954F,
|
||||||
|
0x9552,
|
||||||
|
0x9553,
|
||||||
|
0x9555,
|
||||||
|
0x9557,
|
||||||
|
0x955f,
|
||||||
|
0x9580,
|
||||||
|
0x9581,
|
||||||
|
0x9583,
|
||||||
|
0x9586,
|
||||||
|
0x9587,
|
||||||
|
0x9588,
|
||||||
|
0x9589,
|
||||||
|
0x958A,
|
||||||
|
0x958B,
|
||||||
|
0x958C,
|
||||||
|
0x958D,
|
||||||
|
0x958E,
|
||||||
|
0x958F,
|
||||||
|
0x9590,
|
||||||
|
0x9591,
|
||||||
|
0x9593,
|
||||||
|
0x9595,
|
||||||
|
0x9596,
|
||||||
|
0x9597,
|
||||||
|
0x9598,
|
||||||
|
0x9599,
|
||||||
|
0x959B,
|
||||||
|
0x95C0,
|
||||||
|
0x95C2,
|
||||||
|
0x95C4,
|
||||||
|
0x95C5,
|
||||||
|
0x95C6,
|
||||||
|
0x95C7,
|
||||||
|
0x95C9,
|
||||||
|
0x95CC,
|
||||||
|
0x95CD,
|
||||||
|
0x95CE,
|
||||||
|
0x95CF,
|
||||||
|
0x9610,
|
||||||
|
0x9611,
|
||||||
|
0x9612,
|
||||||
|
0x9613,
|
||||||
|
0x9614,
|
||||||
|
0x9615,
|
||||||
|
0x9616,
|
||||||
|
0x9640,
|
||||||
|
0x9641,
|
||||||
|
0x9642,
|
||||||
|
0x9643,
|
||||||
|
0x9644,
|
||||||
|
0x9645,
|
||||||
|
0x9647,
|
||||||
|
0x9648,
|
||||||
|
0x9649,
|
||||||
|
0x964a,
|
||||||
|
0x964b,
|
||||||
|
0x964c,
|
||||||
|
0x964e,
|
||||||
|
0x964f,
|
||||||
|
0x9710,
|
||||||
|
0x9711,
|
||||||
|
0x9712,
|
||||||
|
0x9713,
|
||||||
|
0x9714,
|
||||||
|
0x9715,
|
||||||
|
0x9802,
|
||||||
|
0x9803,
|
||||||
|
0x9804,
|
||||||
|
0x9805,
|
||||||
|
0x9806,
|
||||||
|
0x9807,
|
||||||
|
0x9808,
|
||||||
|
0x9809,
|
||||||
|
0x980A,
|
||||||
|
0x9900,
|
||||||
|
0x9901,
|
||||||
|
0x9903,
|
||||||
|
0x9904,
|
||||||
|
0x9905,
|
||||||
|
0x9906,
|
||||||
|
0x9907,
|
||||||
|
0x9908,
|
||||||
|
0x9909,
|
||||||
|
0x990A,
|
||||||
|
0x990B,
|
||||||
|
0x990C,
|
||||||
|
0x990D,
|
||||||
|
0x990E,
|
||||||
|
0x990F,
|
||||||
|
0x9910,
|
||||||
|
0x9913,
|
||||||
|
0x9917,
|
||||||
|
0x9918,
|
||||||
|
0x9919,
|
||||||
|
0x9990,
|
||||||
|
0x9991,
|
||||||
|
0x9992,
|
||||||
|
0x9993,
|
||||||
|
0x9994,
|
||||||
|
0x9995,
|
||||||
|
0x9996,
|
||||||
|
0x9997,
|
||||||
|
0x9998,
|
||||||
|
0x9999,
|
||||||
|
0x999A,
|
||||||
|
0x999B,
|
||||||
|
0x999C,
|
||||||
|
0x999D,
|
||||||
|
0x99A0,
|
||||||
|
0x99A2,
|
||||||
|
0x99A4,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct pci_device_id pciidlist[] = {
|
static const struct pci_device_id pciidlist[] = {
|
||||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||||
{0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
|
{0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
|
||||||
@ -1240,6 +1872,16 @@ static const struct pci_device_id pciidlist[] = {
|
|||||||
{0x1002, 0x7423, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
{0x1002, 0x7423, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
||||||
{0x1002, 0x743F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
{0x1002, 0x743F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
||||||
|
|
||||||
|
{ PCI_DEVICE(0x1002, PCI_ANY_ID),
|
||||||
|
.class = PCI_CLASS_DISPLAY_VGA << 8,
|
||||||
|
.class_mask = 0xffffff,
|
||||||
|
.driver_data = CHIP_IP_DISCOVERY },
|
||||||
|
|
||||||
|
{ PCI_DEVICE(0x1002, PCI_ANY_ID),
|
||||||
|
.class = PCI_CLASS_DISPLAY_OTHER << 8,
|
||||||
|
.class_mask = 0xffffff,
|
||||||
|
.driver_data = CHIP_IP_DISCOVERY },
|
||||||
|
|
||||||
{0, 0, 0}
|
{0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1253,9 +1895,20 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
struct drm_device *ddev;
|
struct drm_device *ddev;
|
||||||
struct amdgpu_device *adev;
|
struct amdgpu_device *adev;
|
||||||
unsigned long flags = ent->driver_data;
|
unsigned long flags = ent->driver_data;
|
||||||
int ret, retry = 0;
|
int ret, retry = 0, i;
|
||||||
bool supports_atomic = false;
|
bool supports_atomic = false;
|
||||||
|
|
||||||
|
/* skip devices which are owned by radeon */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) {
|
||||||
|
if (amdgpu_unsupported_pciidlist[i] == pdev->device)
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags == 0) {
|
||||||
|
DRM_INFO("Unsupported asic. Remove me when IP discovery init is in place.\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
if (amdgpu_virtual_display ||
|
if (amdgpu_virtual_display ||
|
||||||
amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
|
amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
|
||||||
supports_atomic = true;
|
supports_atomic = true;
|
||||||
@ -1510,6 +2163,10 @@ static int amdgpu_pmops_resume(struct device *dev)
|
|||||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
/* Avoids registers access if device is physically gone */
|
||||||
|
if (!pci_device_is_present(adev->pdev))
|
||||||
|
adev->no_hw_access = true;
|
||||||
|
|
||||||
r = amdgpu_device_resume(drm_dev, true);
|
r = amdgpu_device_resume(drm_dev, true);
|
||||||
if (amdgpu_acpi_is_s0ix_active(adev))
|
if (amdgpu_acpi_is_s0ix_active(adev))
|
||||||
adev->in_s0ix = false;
|
adev->in_s0ix = false;
|
||||||
|
@ -266,7 +266,6 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
|
|||||||
struct amdgpu_fence_driver *drv = &ring->fence_drv;
|
struct amdgpu_fence_driver *drv = &ring->fence_drv;
|
||||||
struct amdgpu_device *adev = ring->adev;
|
struct amdgpu_device *adev = ring->adev;
|
||||||
uint32_t seq, last_seq;
|
uint32_t seq, last_seq;
|
||||||
int r;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
last_seq = atomic_read(&ring->fence_drv.last_seq);
|
last_seq = atomic_read(&ring->fence_drv.last_seq);
|
||||||
@ -298,12 +297,7 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring)
|
|||||||
if (!fence)
|
if (!fence)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = dma_fence_signal(fence);
|
dma_fence_signal(fence);
|
||||||
if (!r)
|
|
||||||
DMA_FENCE_TRACE(fence, "signaled from irq context\n");
|
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
dma_fence_put(fence);
|
dma_fence_put(fence);
|
||||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||||
@ -556,7 +550,7 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev)
|
|||||||
drm_sched_stop(&ring->sched, NULL);
|
drm_sched_stop(&ring->sched, NULL);
|
||||||
|
|
||||||
/* You can't wait for HW to signal if it's gone */
|
/* You can't wait for HW to signal if it's gone */
|
||||||
if (!drm_dev_is_unplugged(&adev->ddev))
|
if (!drm_dev_is_unplugged(adev_to_drm(adev)))
|
||||||
r = amdgpu_fence_wait_empty(ring);
|
r = amdgpu_fence_wait_empty(ring);
|
||||||
else
|
else
|
||||||
r = -ENODEV;
|
r = -ENODEV;
|
||||||
@ -684,8 +678,6 @@ static bool amdgpu_fence_enable_signaling(struct dma_fence *f)
|
|||||||
if (!timer_pending(&ring->fence_drv.fallback_timer))
|
if (!timer_pending(&ring->fence_drv.fallback_timer))
|
||||||
amdgpu_fence_schedule_fallback(ring);
|
amdgpu_fence_schedule_fallback(ring);
|
||||||
|
|
||||||
DMA_FENCE_TRACE(f, "armed on ring %i!\n", ring->idx);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <asm/set_memory.h>
|
#include <asm/set_memory.h>
|
||||||
#endif
|
#endif
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
|
#include <drm/drm_drv.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GART
|
* GART
|
||||||
@ -230,12 +231,16 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
|
|||||||
u64 page_base;
|
u64 page_base;
|
||||||
/* Starting from VEGA10, system bit must be 0 to mean invalid. */
|
/* Starting from VEGA10, system bit must be 0 to mean invalid. */
|
||||||
uint64_t flags = 0;
|
uint64_t flags = 0;
|
||||||
|
int idx;
|
||||||
|
|
||||||
if (!adev->gart.ready) {
|
if (!adev->gart.ready) {
|
||||||
WARN(1, "trying to unbind memory from uninitialized GART !\n");
|
WARN(1, "trying to unbind memory from uninitialized GART !\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
t = offset / AMDGPU_GPU_PAGE_SIZE;
|
t = offset / AMDGPU_GPU_PAGE_SIZE;
|
||||||
p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
|
||||||
for (i = 0; i < pages; i++, p++) {
|
for (i = 0; i < pages; i++, p++) {
|
||||||
@ -254,6 +259,7 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
|
|||||||
for (i = 0; i < adev->num_vmhubs; i++)
|
for (i = 0; i < adev->num_vmhubs; i++)
|
||||||
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
|
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
|
||||||
|
|
||||||
|
drm_dev_exit(idx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,12 +282,16 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
|
|||||||
{
|
{
|
||||||
uint64_t page_base;
|
uint64_t page_base;
|
||||||
unsigned i, j, t;
|
unsigned i, j, t;
|
||||||
|
int idx;
|
||||||
|
|
||||||
if (!adev->gart.ready) {
|
if (!adev->gart.ready) {
|
||||||
WARN(1, "trying to bind memory to uninitialized GART !\n");
|
WARN(1, "trying to bind memory to uninitialized GART !\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
t = offset / AMDGPU_GPU_PAGE_SIZE;
|
t = offset / AMDGPU_GPU_PAGE_SIZE;
|
||||||
|
|
||||||
for (i = 0; i < pages; i++) {
|
for (i = 0; i < pages; i++) {
|
||||||
@ -291,6 +301,7 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
|
|||||||
page_base += AMDGPU_GPU_PAGE_SIZE;
|
page_base += AMDGPU_GPU_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
drm_dev_exit(idx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,10 +60,9 @@ static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf)
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
|
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
|
||||||
TTM_BO_VM_NUM_PREFAULT, 1);
|
TTM_BO_VM_NUM_PREFAULT, 1);
|
||||||
|
drm_dev_exit(idx);
|
||||||
drm_dev_exit(idx);
|
|
||||||
} else {
|
} else {
|
||||||
ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
|
ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,9 @@
|
|||||||
#define AMDGPU_MAX_GFX_QUEUES KGD_MAX_QUEUES
|
#define AMDGPU_MAX_GFX_QUEUES KGD_MAX_QUEUES
|
||||||
#define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES
|
#define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES
|
||||||
|
|
||||||
enum gfx_pipe_priority {
|
enum amdgpu_gfx_pipe_priority {
|
||||||
AMDGPU_GFX_PIPE_PRIO_NORMAL = 1,
|
AMDGPU_GFX_PIPE_PRIO_NORMAL = AMDGPU_RING_PRIO_1,
|
||||||
AMDGPU_GFX_PIPE_PRIO_HIGH,
|
AMDGPU_GFX_PIPE_PRIO_HIGH = AMDGPU_RING_PRIO_2
|
||||||
AMDGPU_GFX_PIPE_PRIO_MAX
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Argument for PPSMC_MSG_GpuChangeState */
|
/* Argument for PPSMC_MSG_GpuChangeState */
|
||||||
|
@ -153,10 +153,6 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr,
|
|||||||
{
|
{
|
||||||
void __iomem *ptr = (void *)cpu_pt_addr;
|
void __iomem *ptr = (void *)cpu_pt_addr;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
int idx;
|
|
||||||
|
|
||||||
if (!drm_dev_enter(&adev->ddev, &idx))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following is for PTE only. GART does not have PDEs.
|
* The following is for PTE only. GART does not have PDEs.
|
||||||
@ -165,8 +161,6 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr,
|
|||||||
value |= flags;
|
value |= flags;
|
||||||
writeq(value, ptr + (gpu_page_idx * 8));
|
writeq(value, ptr + (gpu_page_idx * 8));
|
||||||
|
|
||||||
drm_dev_exit(idx);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,6 +743,10 @@ void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev)
|
|||||||
adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
|
adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
|
||||||
u64 vram_end = vram_addr + vram_size;
|
u64 vram_end = vram_addr + vram_size;
|
||||||
u64 gart_ptb_gpu_pa = amdgpu_gmc_vram_pa(adev, adev->gart.bo);
|
u64 gart_ptb_gpu_pa = amdgpu_gmc_vram_pa(adev, adev->gart.bo);
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||||
|
return;
|
||||||
|
|
||||||
flags |= AMDGPU_PTE_VALID | AMDGPU_PTE_READABLE;
|
flags |= AMDGPU_PTE_VALID | AMDGPU_PTE_READABLE;
|
||||||
flags |= AMDGPU_PTE_WRITEABLE;
|
flags |= AMDGPU_PTE_WRITEABLE;
|
||||||
@ -770,6 +768,7 @@ void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev)
|
|||||||
flags |= AMDGPU_PDE_BFS(0) | AMDGPU_PTE_SNOOPED;
|
flags |= AMDGPU_PDE_BFS(0) | AMDGPU_PTE_SNOOPED;
|
||||||
/* Requires gart_ptb_gpu_pa to be 4K aligned */
|
/* Requires gart_ptb_gpu_pa to be 4K aligned */
|
||||||
amdgpu_gmc_set_pte_pde(adev, adev->gmc.ptr_pdb0, i, gart_ptb_gpu_pa, flags);
|
amdgpu_gmc_set_pte_pde(adev, adev->gmc.ptr_pdb0, i, gart_ptb_gpu_pa, flags);
|
||||||
|
drm_dev_exit(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -300,20 +300,15 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||||||
*/
|
*/
|
||||||
int amdgpu_ib_pool_init(struct amdgpu_device *adev)
|
int amdgpu_ib_pool_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
unsigned size;
|
|
||||||
int r, i;
|
int r, i;
|
||||||
|
|
||||||
if (adev->ib_pool_ready)
|
if (adev->ib_pool_ready)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) {
|
for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) {
|
||||||
if (i == AMDGPU_IB_POOL_DIRECT)
|
|
||||||
size = PAGE_SIZE * 6;
|
|
||||||
else
|
|
||||||
size = AMDGPU_IB_POOL_SIZE;
|
|
||||||
|
|
||||||
r = amdgpu_sa_bo_manager_init(adev, &adev->ib_pools[i],
|
r = amdgpu_sa_bo_manager_init(adev, &adev->ib_pools[i],
|
||||||
size, AMDGPU_GPU_PAGE_SIZE,
|
AMDGPU_IB_POOL_SIZE,
|
||||||
|
AMDGPU_GPU_PAGE_SIZE,
|
||||||
AMDGPU_GEM_DOMAIN_GTT);
|
AMDGPU_GEM_DOMAIN_GTT);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -38,7 +38,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
|
|||||||
struct amdgpu_device *adev = ring->adev;
|
struct amdgpu_device *adev = ring->adev;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
if (!drm_dev_enter(&adev->ddev, &idx)) {
|
if (!drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
DRM_INFO("%s - device unplugged skipping recovery on scheduler:%s",
|
DRM_INFO("%s - device unplugged skipping recovery on scheduler:%s",
|
||||||
__func__, s_job->sched->name);
|
__func__, s_job->sched->name);
|
||||||
|
|
||||||
@ -182,9 +182,11 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
drm_sched_job_arm(&job->base);
|
||||||
|
|
||||||
*f = dma_fence_get(&job->base.s_fence->finished);
|
*f = dma_fence_get(&job->base.s_fence->finished);
|
||||||
amdgpu_job_free_resources(job);
|
amdgpu_job_free_resources(job);
|
||||||
drm_sched_entity_push_job(&job->base, entity);
|
drm_sched_entity_push_job(&job->base);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -340,28 +340,35 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
|
|||||||
case AMDGPU_INFO_FW_TA:
|
case AMDGPU_INFO_FW_TA:
|
||||||
switch (query_fw->index) {
|
switch (query_fw->index) {
|
||||||
case TA_FW_TYPE_PSP_XGMI:
|
case TA_FW_TYPE_PSP_XGMI:
|
||||||
fw_info->ver = adev->psp.ta_fw_version;
|
fw_info->ver = adev->psp.xgmi_context.context.bin_desc.fw_version;
|
||||||
fw_info->feature = adev->psp.xgmi.feature_version;
|
fw_info->feature = adev->psp.xgmi_context.context
|
||||||
|
.bin_desc.feature_version;
|
||||||
break;
|
break;
|
||||||
case TA_FW_TYPE_PSP_RAS:
|
case TA_FW_TYPE_PSP_RAS:
|
||||||
fw_info->ver = adev->psp.ta_fw_version;
|
fw_info->ver = adev->psp.ras_context.context.bin_desc.fw_version;
|
||||||
fw_info->feature = adev->psp.ras.feature_version;
|
fw_info->feature = adev->psp.ras_context.context
|
||||||
|
.bin_desc.feature_version;
|
||||||
break;
|
break;
|
||||||
case TA_FW_TYPE_PSP_HDCP:
|
case TA_FW_TYPE_PSP_HDCP:
|
||||||
fw_info->ver = adev->psp.ta_fw_version;
|
fw_info->ver = adev->psp.hdcp_context.context.bin_desc.fw_version;
|
||||||
fw_info->feature = adev->psp.hdcp.feature_version;
|
fw_info->feature = adev->psp.hdcp_context.context
|
||||||
|
.bin_desc.feature_version;
|
||||||
break;
|
break;
|
||||||
case TA_FW_TYPE_PSP_DTM:
|
case TA_FW_TYPE_PSP_DTM:
|
||||||
fw_info->ver = adev->psp.ta_fw_version;
|
fw_info->ver = adev->psp.dtm_context.context.bin_desc.fw_version;
|
||||||
fw_info->feature = adev->psp.dtm.feature_version;
|
fw_info->feature = adev->psp.dtm_context.context
|
||||||
|
.bin_desc.feature_version;
|
||||||
break;
|
break;
|
||||||
case TA_FW_TYPE_PSP_RAP:
|
case TA_FW_TYPE_PSP_RAP:
|
||||||
fw_info->ver = adev->psp.ta_fw_version;
|
fw_info->ver = adev->psp.rap_context.context.bin_desc.fw_version;
|
||||||
fw_info->feature = adev->psp.rap.feature_version;
|
fw_info->feature = adev->psp.rap_context.context
|
||||||
|
.bin_desc.feature_version;
|
||||||
break;
|
break;
|
||||||
case TA_FW_TYPE_PSP_SECUREDISPLAY:
|
case TA_FW_TYPE_PSP_SECUREDISPLAY:
|
||||||
fw_info->ver = adev->psp.ta_fw_version;
|
fw_info->ver = adev->psp.securedisplay_context.context.bin_desc.fw_version;
|
||||||
fw_info->feature = adev->psp.securedisplay.feature_version;
|
fw_info->feature =
|
||||||
|
adev->psp.securedisplay_context.context.bin_desc
|
||||||
|
.feature_version;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -378,8 +385,8 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
|
|||||||
fw_info->feature = adev->psp.sos.feature_version;
|
fw_info->feature = adev->psp.sos.feature_version;
|
||||||
break;
|
break;
|
||||||
case AMDGPU_INFO_FW_ASD:
|
case AMDGPU_INFO_FW_ASD:
|
||||||
fw_info->ver = adev->psp.asd.fw_version;
|
fw_info->ver = adev->psp.asd_context.bin_desc.fw_version;
|
||||||
fw_info->feature = adev->psp.asd.feature_version;
|
fw_info->feature = adev->psp.asd_context.bin_desc.feature_version;
|
||||||
break;
|
break;
|
||||||
case AMDGPU_INFO_FW_DMCU:
|
case AMDGPU_INFO_FW_DMCU:
|
||||||
fw_info->ver = adev->dm.dmcu_fw_version;
|
fw_info->ver = adev->dm.dmcu_fw_version;
|
||||||
|
@ -31,7 +31,7 @@ void amdgpu_mca_query_correctable_error_count(struct amdgpu_device *adev,
|
|||||||
uint64_t mc_status_addr,
|
uint64_t mc_status_addr,
|
||||||
unsigned long *error_count)
|
unsigned long *error_count)
|
||||||
{
|
{
|
||||||
uint64_t mc_status = RREG64_PCIE(mc_status_addr * 4);
|
uint64_t mc_status = RREG64_PCIE(mc_status_addr);
|
||||||
|
|
||||||
if (REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
if (REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
|
||||||
REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)
|
REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)
|
||||||
@ -42,7 +42,7 @@ void amdgpu_mca_query_uncorrectable_error_count(struct amdgpu_device *adev,
|
|||||||
uint64_t mc_status_addr,
|
uint64_t mc_status_addr,
|
||||||
unsigned long *error_count)
|
unsigned long *error_count)
|
||||||
{
|
{
|
||||||
uint64_t mc_status = RREG64_PCIE(mc_status_addr * 4);
|
uint64_t mc_status = RREG64_PCIE(mc_status_addr);
|
||||||
|
|
||||||
if ((REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
|
if ((REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
|
||||||
(REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 ||
|
(REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 ||
|
||||||
@ -56,7 +56,7 @@ void amdgpu_mca_query_uncorrectable_error_count(struct amdgpu_device *adev,
|
|||||||
void amdgpu_mca_reset_error_count(struct amdgpu_device *adev,
|
void amdgpu_mca_reset_error_count(struct amdgpu_device *adev,
|
||||||
uint64_t mc_status_addr)
|
uint64_t mc_status_addr)
|
||||||
{
|
{
|
||||||
WREG64_PCIE(mc_status_addr * 4, 0x0ULL);
|
WREG64_PCIE(mc_status_addr, 0x0ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amdgpu_mca_query_ras_error_count(struct amdgpu_device *adev,
|
void amdgpu_mca_query_ras_error_count(struct amdgpu_device *adev,
|
||||||
@ -87,8 +87,8 @@ int amdgpu_mca_ras_late_init(struct amdgpu_device *adev,
|
|||||||
if (!mca_dev->ras_if)
|
if (!mca_dev->ras_if)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
mca_dev->ras_if->block = mca_dev->ras_funcs->ras_block;
|
mca_dev->ras_if->block = mca_dev->ras_funcs->ras_block;
|
||||||
|
mca_dev->ras_if->sub_block_index = mca_dev->ras_funcs->ras_sub_block;
|
||||||
mca_dev->ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
mca_dev->ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
|
||||||
mca_dev->ras_if->sub_block_index = 0;
|
|
||||||
}
|
}
|
||||||
ih_info.head = fs_info.head = *mca_dev->ras_if;
|
ih_info.head = fs_info.head = *mca_dev->ras_if;
|
||||||
r = amdgpu_ras_late_init(adev, mca_dev->ras_if,
|
r = amdgpu_ras_late_init(adev, mca_dev->ras_if,
|
||||||
|
@ -29,6 +29,7 @@ struct amdgpu_mca_ras_funcs {
|
|||||||
void (*query_ras_error_address)(struct amdgpu_device *adev,
|
void (*query_ras_error_address)(struct amdgpu_device *adev,
|
||||||
void *ras_error_status);
|
void *ras_error_status);
|
||||||
uint32_t ras_block;
|
uint32_t ras_block;
|
||||||
|
uint32_t ras_sub_block;
|
||||||
const char* sysfs_name;
|
const char* sysfs_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -694,40 +694,6 @@ int amdgpu_bo_create_vm(struct amdgpu_device *adev,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* amdgpu_bo_validate - validate an &amdgpu_bo buffer object
|
|
||||||
* @bo: pointer to the buffer object
|
|
||||||
*
|
|
||||||
* Sets placement according to domain; and changes placement and caching
|
|
||||||
* policy of the buffer object according to the placement.
|
|
||||||
* This is used for validating shadow bos. It calls ttm_bo_validate() to
|
|
||||||
* make sure the buffer is resident where it needs to be.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* 0 for success or a negative error code on failure.
|
|
||||||
*/
|
|
||||||
int amdgpu_bo_validate(struct amdgpu_bo *bo)
|
|
||||||
{
|
|
||||||
struct ttm_operation_ctx ctx = { false, false };
|
|
||||||
uint32_t domain;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (bo->tbo.pin_count)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
domain = bo->preferred_domains;
|
|
||||||
|
|
||||||
retry:
|
|
||||||
amdgpu_bo_placement_from_domain(bo, domain);
|
|
||||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
|
||||||
if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
|
|
||||||
domain = bo->allowed_domains;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_bo_add_to_shadow_list - add a BO to the shadow list
|
* amdgpu_bo_add_to_shadow_list - add a BO to the shadow list
|
||||||
*
|
*
|
||||||
@ -1038,29 +1004,6 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* amdgpu_bo_evict_vram - evict VRAM buffers
|
|
||||||
* @adev: amdgpu device object
|
|
||||||
*
|
|
||||||
* Evicts all VRAM buffers on the lru list of the memory type.
|
|
||||||
* Mainly used for evicting vram at suspend time.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* 0 for success or a negative error code on failure.
|
|
||||||
*/
|
|
||||||
int amdgpu_bo_evict_vram(struct amdgpu_device *adev)
|
|
||||||
{
|
|
||||||
struct ttm_resource_manager *man;
|
|
||||||
|
|
||||||
if (adev->in_s3 && (adev->flags & AMD_IS_APU)) {
|
|
||||||
/* No need to evict vram on APUs for suspend to ram */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
|
|
||||||
return ttm_resource_manager_evict_all(&adev->mman.bdev, man);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *amdgpu_vram_names[] = {
|
static const char *amdgpu_vram_names[] = {
|
||||||
"UNKNOWN",
|
"UNKNOWN",
|
||||||
"GDDR1",
|
"GDDR1",
|
||||||
|
@ -304,7 +304,6 @@ int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain);
|
|||||||
int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
|
int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
|
||||||
u64 min_offset, u64 max_offset);
|
u64 min_offset, u64 max_offset);
|
||||||
void amdgpu_bo_unpin(struct amdgpu_bo *bo);
|
void amdgpu_bo_unpin(struct amdgpu_bo *bo);
|
||||||
int amdgpu_bo_evict_vram(struct amdgpu_device *adev);
|
|
||||||
int amdgpu_bo_init(struct amdgpu_device *adev);
|
int amdgpu_bo_init(struct amdgpu_device *adev);
|
||||||
void amdgpu_bo_fini(struct amdgpu_device *adev);
|
void amdgpu_bo_fini(struct amdgpu_device *adev);
|
||||||
int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags);
|
int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags);
|
||||||
@ -327,7 +326,6 @@ int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv,
|
|||||||
int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr);
|
int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr);
|
||||||
u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo);
|
u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo);
|
||||||
u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo);
|
u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo);
|
||||||
int amdgpu_bo_validate(struct amdgpu_bo *bo);
|
|
||||||
void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem,
|
void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem,
|
||||||
uint64_t *gtt_mem, uint64_t *cpu_mem);
|
uint64_t *gtt_mem, uint64_t *cpu_mem);
|
||||||
void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo);
|
void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,17 +34,20 @@
|
|||||||
|
|
||||||
#define PSP_FENCE_BUFFER_SIZE 0x1000
|
#define PSP_FENCE_BUFFER_SIZE 0x1000
|
||||||
#define PSP_CMD_BUFFER_SIZE 0x1000
|
#define PSP_CMD_BUFFER_SIZE 0x1000
|
||||||
#define PSP_XGMI_SHARED_MEM_SIZE 0x4000
|
|
||||||
#define PSP_RAS_SHARED_MEM_SIZE 0x4000
|
|
||||||
#define PSP_1_MEG 0x100000
|
#define PSP_1_MEG 0x100000
|
||||||
#define PSP_TMR_SIZE(adev) ((adev)->asic_type == CHIP_ALDEBARAN ? 0x800000 : 0x400000)
|
#define PSP_TMR_SIZE(adev) ((adev)->asic_type == CHIP_ALDEBARAN ? 0x800000 : 0x400000)
|
||||||
#define PSP_HDCP_SHARED_MEM_SIZE 0x4000
|
|
||||||
#define PSP_DTM_SHARED_MEM_SIZE 0x4000
|
|
||||||
#define PSP_RAP_SHARED_MEM_SIZE 0x4000
|
|
||||||
#define PSP_SECUREDISPLAY_SHARED_MEM_SIZE 0x4000
|
|
||||||
#define PSP_SHARED_MEM_SIZE 0x4000
|
|
||||||
#define PSP_FW_NAME_LEN 0x24
|
#define PSP_FW_NAME_LEN 0x24
|
||||||
|
|
||||||
|
enum psp_shared_mem_size {
|
||||||
|
PSP_ASD_SHARED_MEM_SIZE = 0x0,
|
||||||
|
PSP_XGMI_SHARED_MEM_SIZE = 0x4000,
|
||||||
|
PSP_RAS_SHARED_MEM_SIZE = 0x4000,
|
||||||
|
PSP_HDCP_SHARED_MEM_SIZE = 0x4000,
|
||||||
|
PSP_DTM_SHARED_MEM_SIZE = 0x4000,
|
||||||
|
PSP_RAP_SHARED_MEM_SIZE = 0x4000,
|
||||||
|
PSP_SECUREDISPLAY_SHARED_MEM_SIZE = 0x4000,
|
||||||
|
};
|
||||||
|
|
||||||
struct psp_context;
|
struct psp_context;
|
||||||
struct psp_xgmi_node_info;
|
struct psp_xgmi_node_info;
|
||||||
struct psp_xgmi_topology_info;
|
struct psp_xgmi_topology_info;
|
||||||
@ -131,21 +134,26 @@ struct psp_xgmi_topology_info {
|
|||||||
struct psp_xgmi_node_info nodes[AMDGPU_XGMI_MAX_CONNECTED_NODES];
|
struct psp_xgmi_node_info nodes[AMDGPU_XGMI_MAX_CONNECTED_NODES];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct psp_asd_context {
|
struct psp_bin_desc {
|
||||||
bool asd_initialized;
|
uint32_t fw_version;
|
||||||
uint32_t session_id;
|
uint32_t feature_version;
|
||||||
|
uint32_t size_bytes;
|
||||||
|
uint8_t *start_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ta_mem_context {
|
struct ta_mem_context {
|
||||||
struct amdgpu_bo *shared_bo;
|
struct amdgpu_bo *shared_bo;
|
||||||
uint64_t shared_mc_addr;
|
uint64_t shared_mc_addr;
|
||||||
void *shared_buf;
|
void *shared_buf;
|
||||||
|
enum psp_shared_mem_size shared_mem_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ta_context {
|
struct ta_context {
|
||||||
bool initialized;
|
bool initialized;
|
||||||
uint32_t session_id;
|
uint32_t session_id;
|
||||||
struct ta_mem_context mem_context;
|
struct ta_mem_context mem_context;
|
||||||
|
struct psp_bin_desc bin_desc;
|
||||||
|
enum psp_gfx_cmd_id ta_load_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ta_cp_context {
|
struct ta_cp_context {
|
||||||
@ -263,13 +271,6 @@ struct psp_runtime_boot_cfg_entry {
|
|||||||
uint32_t reserved;
|
uint32_t reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct psp_bin_desc {
|
|
||||||
uint32_t fw_version;
|
|
||||||
uint32_t feature_version;
|
|
||||||
uint32_t size_bytes;
|
|
||||||
uint8_t *start_addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct psp_context
|
struct psp_context
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev;
|
struct amdgpu_device *adev;
|
||||||
@ -301,7 +302,6 @@ struct psp_context
|
|||||||
|
|
||||||
/* asd firmware */
|
/* asd firmware */
|
||||||
const struct firmware *asd_fw;
|
const struct firmware *asd_fw;
|
||||||
struct psp_bin_desc asd;
|
|
||||||
|
|
||||||
/* toc firmware */
|
/* toc firmware */
|
||||||
const struct firmware *toc_fw;
|
const struct firmware *toc_fw;
|
||||||
@ -326,14 +326,8 @@ struct psp_context
|
|||||||
/* xgmi ta firmware and buffer */
|
/* xgmi ta firmware and buffer */
|
||||||
const struct firmware *ta_fw;
|
const struct firmware *ta_fw;
|
||||||
uint32_t ta_fw_version;
|
uint32_t ta_fw_version;
|
||||||
struct psp_bin_desc xgmi;
|
|
||||||
struct psp_bin_desc ras;
|
|
||||||
struct psp_bin_desc hdcp;
|
|
||||||
struct psp_bin_desc dtm;
|
|
||||||
struct psp_bin_desc rap;
|
|
||||||
struct psp_bin_desc securedisplay;
|
|
||||||
|
|
||||||
struct psp_asd_context asd_context;
|
struct ta_context asd_context;
|
||||||
struct psp_xgmi_context xgmi_context;
|
struct psp_xgmi_context xgmi_context;
|
||||||
struct psp_ras_context ras_context;
|
struct psp_ras_context ras_context;
|
||||||
struct ta_cp_context hdcp_context;
|
struct ta_cp_context hdcp_context;
|
||||||
|
@ -35,7 +35,11 @@
|
|||||||
#include "amdgpu_xgmi.h"
|
#include "amdgpu_xgmi.h"
|
||||||
#include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
|
#include "ivsrcid/nbio/irqsrcs_nbif_7_4.h"
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#ifdef CONFIG_X86_MCE_AMD
|
||||||
|
#include <asm/mce.h>
|
||||||
|
|
||||||
|
static bool notifier_registered;
|
||||||
|
#endif
|
||||||
static const char *RAS_FS_NAME = "ras";
|
static const char *RAS_FS_NAME = "ras";
|
||||||
|
|
||||||
const char *ras_error_string[] = {
|
const char *ras_error_string[] = {
|
||||||
@ -61,8 +65,30 @@ const char *ras_block_string[] = {
|
|||||||
"mp0",
|
"mp0",
|
||||||
"mp1",
|
"mp1",
|
||||||
"fuse",
|
"fuse",
|
||||||
|
"mca",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *ras_mca_block_string[] = {
|
||||||
|
"mca_mp0",
|
||||||
|
"mca_mp1",
|
||||||
|
"mca_mpio",
|
||||||
|
"mca_iohc",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *get_ras_block_str(struct ras_common_if *ras_block)
|
||||||
|
{
|
||||||
|
if (!ras_block)
|
||||||
|
return "NULL";
|
||||||
|
|
||||||
|
if (ras_block->block >= AMDGPU_RAS_BLOCK_COUNT)
|
||||||
|
return "OUT OF RANGE";
|
||||||
|
|
||||||
|
if (ras_block->block == AMDGPU_RAS_BLOCK__MCA)
|
||||||
|
return ras_mca_block_string[ras_block->sub_block_index];
|
||||||
|
|
||||||
|
return ras_block_string[ras_block->block];
|
||||||
|
}
|
||||||
|
|
||||||
#define ras_err_str(i) (ras_error_string[ffs(i)])
|
#define ras_err_str(i) (ras_error_string[ffs(i)])
|
||||||
|
|
||||||
#define RAS_DEFAULT_FLAGS (AMDGPU_RAS_FLAG_INIT_BY_VBIOS)
|
#define RAS_DEFAULT_FLAGS (AMDGPU_RAS_FLAG_INIT_BY_VBIOS)
|
||||||
@ -85,6 +111,14 @@ static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con,
|
|||||||
uint64_t addr);
|
uint64_t addr);
|
||||||
static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
|
static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev,
|
||||||
uint64_t addr);
|
uint64_t addr);
|
||||||
|
#ifdef CONFIG_X86_MCE_AMD
|
||||||
|
static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev);
|
||||||
|
struct mce_notifier_adev_list {
|
||||||
|
struct amdgpu_device *devs[MAX_GPU_INSTANCE];
|
||||||
|
int num_gpu;
|
||||||
|
};
|
||||||
|
static struct mce_notifier_adev_list mce_adev_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready)
|
void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready)
|
||||||
{
|
{
|
||||||
@ -187,7 +221,7 @@ static int amdgpu_ras_find_block_id_by_name(const char *name, int *block_id)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(ras_block_string); i++) {
|
for (i = 0; i < ARRAY_SIZE(ras_block_string); i++) {
|
||||||
*block_id = i;
|
*block_id = i;
|
||||||
if (strcmp(name, ras_block_str(i)) == 0)
|
if (strcmp(name, ras_block_string[i]) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -509,7 +543,6 @@ static ssize_t amdgpu_ras_sysfs_read(struct device *dev,
|
|||||||
if (amdgpu_ras_query_error_status(obj->adev, &info))
|
if (amdgpu_ras_query_error_status(obj->adev, &info))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
||||||
if (obj->adev->asic_type == CHIP_ALDEBARAN) {
|
if (obj->adev->asic_type == CHIP_ALDEBARAN) {
|
||||||
if (amdgpu_ras_reset_error_status(obj->adev, info.head.block))
|
if (amdgpu_ras_reset_error_status(obj->adev, info.head.block))
|
||||||
DRM_WARN("Failed to reset error counter and error status");
|
DRM_WARN("Failed to reset error counter and error status");
|
||||||
@ -529,7 +562,7 @@ static inline void put_obj(struct ras_manager *obj)
|
|||||||
if (obj && (--obj->use == 0))
|
if (obj && (--obj->use == 0))
|
||||||
list_del(&obj->node);
|
list_del(&obj->node);
|
||||||
if (obj && (obj->use < 0))
|
if (obj && (obj->use < 0))
|
||||||
DRM_ERROR("RAS ERROR: Unbalance obj(%s) use\n", ras_block_str(obj->head.block));
|
DRM_ERROR("RAS ERROR: Unbalance obj(%s) use\n", get_ras_block_str(&obj->head));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make one obj and return it. */
|
/* make one obj and return it. */
|
||||||
@ -545,7 +578,14 @@ static struct ras_manager *amdgpu_ras_create_obj(struct amdgpu_device *adev,
|
|||||||
if (head->block >= AMDGPU_RAS_BLOCK_COUNT)
|
if (head->block >= AMDGPU_RAS_BLOCK_COUNT)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
obj = &con->objs[head->block];
|
if (head->block == AMDGPU_RAS_BLOCK__MCA) {
|
||||||
|
if (head->sub_block_index >= AMDGPU_RAS_MCA_BLOCK__LAST)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
obj = &con->objs[AMDGPU_RAS_BLOCK__LAST + head->sub_block_index];
|
||||||
|
} else
|
||||||
|
obj = &con->objs[head->block];
|
||||||
|
|
||||||
/* already exist. return obj? */
|
/* already exist. return obj? */
|
||||||
if (alive_obj(obj))
|
if (alive_obj(obj))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -573,19 +613,21 @@ struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev,
|
|||||||
if (head->block >= AMDGPU_RAS_BLOCK_COUNT)
|
if (head->block >= AMDGPU_RAS_BLOCK_COUNT)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
obj = &con->objs[head->block];
|
if (head->block == AMDGPU_RAS_BLOCK__MCA) {
|
||||||
|
if (head->sub_block_index >= AMDGPU_RAS_MCA_BLOCK__LAST)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (alive_obj(obj)) {
|
obj = &con->objs[AMDGPU_RAS_BLOCK__LAST + head->sub_block_index];
|
||||||
WARN_ON(head->block != obj->head.block);
|
} else
|
||||||
|
obj = &con->objs[head->block];
|
||||||
|
|
||||||
|
if (alive_obj(obj))
|
||||||
return obj;
|
return obj;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < AMDGPU_RAS_BLOCK_COUNT; i++) {
|
for (i = 0; i < AMDGPU_RAS_BLOCK_COUNT + AMDGPU_RAS_MCA_BLOCK_COUNT; i++) {
|
||||||
obj = &con->objs[i];
|
obj = &con->objs[i];
|
||||||
if (alive_obj(obj)) {
|
if (alive_obj(obj))
|
||||||
WARN_ON(i != obj->head.block);
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,8 +668,6 @@ static int __amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
|||||||
*/
|
*/
|
||||||
if (!amdgpu_ras_is_feature_allowed(adev, head))
|
if (!amdgpu_ras_is_feature_allowed(adev, head))
|
||||||
return 0;
|
return 0;
|
||||||
if (!(!!enable ^ !!amdgpu_ras_is_feature_enabled(adev, head)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
@ -678,19 +718,14 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
|
|||||||
|
|
||||||
/* Do not enable if it is not allowed. */
|
/* Do not enable if it is not allowed. */
|
||||||
WARN_ON(enable && !amdgpu_ras_is_feature_allowed(adev, head));
|
WARN_ON(enable && !amdgpu_ras_is_feature_allowed(adev, head));
|
||||||
/* Are we alerady in that state we are going to set? */
|
|
||||||
if (!(!!enable ^ !!amdgpu_ras_is_feature_enabled(adev, head))) {
|
|
||||||
ret = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!amdgpu_ras_intr_triggered()) {
|
if (!amdgpu_ras_intr_triggered()) {
|
||||||
ret = psp_ras_enable_features(&adev->psp, info, enable);
|
ret = psp_ras_enable_features(&adev->psp, info, enable);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(adev->dev, "ras %s %s failed %d\n",
|
dev_err(adev->dev, "ras %s %s failed poison:%d ret:%d\n",
|
||||||
enable ? "enable":"disable",
|
enable ? "enable":"disable",
|
||||||
ras_block_str(head->block),
|
get_ras_block_str(head),
|
||||||
ret);
|
amdgpu_ras_is_poison_mode_supported(adev), ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -731,7 +766,7 @@ int amdgpu_ras_feature_enable_on_boot(struct amdgpu_device *adev,
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
dev_info(adev->dev,
|
dev_info(adev->dev,
|
||||||
"RAS INFO: %s setup object\n",
|
"RAS INFO: %s setup object\n",
|
||||||
ras_block_str(head->block));
|
get_ras_block_str(head));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* setup the object then issue a ras TA disable cmd.*/
|
/* setup the object then issue a ras TA disable cmd.*/
|
||||||
@ -781,17 +816,39 @@ static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev,
|
|||||||
bool bypass)
|
bool bypass)
|
||||||
{
|
{
|
||||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||||
int ras_block_count = AMDGPU_RAS_BLOCK_COUNT;
|
|
||||||
int i;
|
int i;
|
||||||
const enum amdgpu_ras_error_type default_ras_type =
|
const enum amdgpu_ras_error_type default_ras_type = AMDGPU_RAS_ERROR__NONE;
|
||||||
AMDGPU_RAS_ERROR__NONE;
|
|
||||||
|
|
||||||
for (i = 0; i < ras_block_count; i++) {
|
for (i = 0; i < AMDGPU_RAS_BLOCK_COUNT; i++) {
|
||||||
struct ras_common_if head = {
|
struct ras_common_if head = {
|
||||||
.block = i,
|
.block = i,
|
||||||
.type = default_ras_type,
|
.type = default_ras_type,
|
||||||
.sub_block_index = 0,
|
.sub_block_index = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (i == AMDGPU_RAS_BLOCK__MCA)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (bypass) {
|
||||||
|
/*
|
||||||
|
* bypass psp. vbios enable ras for us.
|
||||||
|
* so just create the obj
|
||||||
|
*/
|
||||||
|
if (__amdgpu_ras_feature_enable(adev, &head, 1))
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (amdgpu_ras_feature_enable(adev, &head, 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < AMDGPU_RAS_MCA_BLOCK_COUNT; i++) {
|
||||||
|
struct ras_common_if head = {
|
||||||
|
.block = AMDGPU_RAS_BLOCK__MCA,
|
||||||
|
.type = default_ras_type,
|
||||||
|
.sub_block_index = i,
|
||||||
|
};
|
||||||
|
|
||||||
if (bypass) {
|
if (bypass) {
|
||||||
/*
|
/*
|
||||||
* bypass psp. vbios enable ras for us.
|
* bypass psp. vbios enable ras for us.
|
||||||
@ -809,6 +866,32 @@ static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev,
|
|||||||
}
|
}
|
||||||
/* feature ctl end */
|
/* feature ctl end */
|
||||||
|
|
||||||
|
|
||||||
|
void amdgpu_ras_mca_query_error_status(struct amdgpu_device *adev,
|
||||||
|
struct ras_common_if *ras_block,
|
||||||
|
struct ras_err_data *err_data)
|
||||||
|
{
|
||||||
|
switch (ras_block->sub_block_index) {
|
||||||
|
case AMDGPU_RAS_MCA_BLOCK__MP0:
|
||||||
|
if (adev->mca.mp0.ras_funcs &&
|
||||||
|
adev->mca.mp0.ras_funcs->query_ras_error_count)
|
||||||
|
adev->mca.mp0.ras_funcs->query_ras_error_count(adev, &err_data);
|
||||||
|
break;
|
||||||
|
case AMDGPU_RAS_MCA_BLOCK__MP1:
|
||||||
|
if (adev->mca.mp1.ras_funcs &&
|
||||||
|
adev->mca.mp1.ras_funcs->query_ras_error_count)
|
||||||
|
adev->mca.mp1.ras_funcs->query_ras_error_count(adev, &err_data);
|
||||||
|
break;
|
||||||
|
case AMDGPU_RAS_MCA_BLOCK__MPIO:
|
||||||
|
if (adev->mca.mpio.ras_funcs &&
|
||||||
|
adev->mca.mpio.ras_funcs->query_ras_error_count)
|
||||||
|
adev->mca.mpio.ras_funcs->query_ras_error_count(adev, &err_data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* query/inject/cure begin */
|
/* query/inject/cure begin */
|
||||||
int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
||||||
struct ras_query_if *info)
|
struct ras_query_if *info)
|
||||||
@ -872,6 +955,9 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
|||||||
adev->hdp.ras_funcs->query_ras_error_count)
|
adev->hdp.ras_funcs->query_ras_error_count)
|
||||||
adev->hdp.ras_funcs->query_ras_error_count(adev, &err_data);
|
adev->hdp.ras_funcs->query_ras_error_count(adev, &err_data);
|
||||||
break;
|
break;
|
||||||
|
case AMDGPU_RAS_BLOCK__MCA:
|
||||||
|
amdgpu_ras_mca_query_error_status(adev, &info->head, &err_data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -893,13 +979,13 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
|||||||
adev->smuio.funcs->get_socket_id(adev),
|
adev->smuio.funcs->get_socket_id(adev),
|
||||||
adev->smuio.funcs->get_die_id(adev),
|
adev->smuio.funcs->get_die_id(adev),
|
||||||
obj->err_data.ce_count,
|
obj->err_data.ce_count,
|
||||||
ras_block_str(info->head.block));
|
get_ras_block_str(&info->head));
|
||||||
} else {
|
} else {
|
||||||
dev_info(adev->dev, "%ld correctable hardware errors "
|
dev_info(adev->dev, "%ld correctable hardware errors "
|
||||||
"detected in %s block, no user "
|
"detected in %s block, no user "
|
||||||
"action is needed.\n",
|
"action is needed.\n",
|
||||||
obj->err_data.ce_count,
|
obj->err_data.ce_count,
|
||||||
ras_block_str(info->head.block));
|
get_ras_block_str(&info->head));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (err_data.ue_count) {
|
if (err_data.ue_count) {
|
||||||
@ -912,15 +998,18 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
|
|||||||
adev->smuio.funcs->get_socket_id(adev),
|
adev->smuio.funcs->get_socket_id(adev),
|
||||||
adev->smuio.funcs->get_die_id(adev),
|
adev->smuio.funcs->get_die_id(adev),
|
||||||
obj->err_data.ue_count,
|
obj->err_data.ue_count,
|
||||||
ras_block_str(info->head.block));
|
get_ras_block_str(&info->head));
|
||||||
} else {
|
} else {
|
||||||
dev_info(adev->dev, "%ld uncorrectable hardware errors "
|
dev_info(adev->dev, "%ld uncorrectable hardware errors "
|
||||||
"detected in %s block\n",
|
"detected in %s block\n",
|
||||||
obj->err_data.ue_count,
|
obj->err_data.ue_count,
|
||||||
ras_block_str(info->head.block));
|
get_ras_block_str(&info->head));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!amdgpu_persistent_edc_harvesting_supported(adev))
|
||||||
|
amdgpu_ras_reset_error_status(adev, info->head.block);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1027,6 +1116,7 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
|
|||||||
case AMDGPU_RAS_BLOCK__SDMA:
|
case AMDGPU_RAS_BLOCK__SDMA:
|
||||||
case AMDGPU_RAS_BLOCK__MMHUB:
|
case AMDGPU_RAS_BLOCK__MMHUB:
|
||||||
case AMDGPU_RAS_BLOCK__PCIE_BIF:
|
case AMDGPU_RAS_BLOCK__PCIE_BIF:
|
||||||
|
case AMDGPU_RAS_BLOCK__MCA:
|
||||||
ret = psp_ras_trigger_error(&adev->psp, &block_info);
|
ret = psp_ras_trigger_error(&adev->psp, &block_info);
|
||||||
break;
|
break;
|
||||||
case AMDGPU_RAS_BLOCK__XGMI_WAFL:
|
case AMDGPU_RAS_BLOCK__XGMI_WAFL:
|
||||||
@ -1034,13 +1124,13 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_info(adev->dev, "%s error injection is not supported yet\n",
|
dev_info(adev->dev, "%s error injection is not supported yet\n",
|
||||||
ras_block_str(info->head.block));
|
get_ras_block_str(&info->head));
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(adev->dev, "ras inject %s failed %d\n",
|
dev_err(adev->dev, "ras inject %s failed %d\n",
|
||||||
ras_block_str(info->head.block), ret);
|
get_ras_block_str(&info->head), ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1383,7 +1473,7 @@ void amdgpu_ras_debugfs_create_all(struct amdgpu_device *adev)
|
|||||||
if (amdgpu_ras_is_supported(adev, obj->head.block) &&
|
if (amdgpu_ras_is_supported(adev, obj->head.block) &&
|
||||||
(obj->attr_inuse == 1)) {
|
(obj->attr_inuse == 1)) {
|
||||||
sprintf(fs_info.debugfs_name, "%s_err_inject",
|
sprintf(fs_info.debugfs_name, "%s_err_inject",
|
||||||
ras_block_str(obj->head.block));
|
get_ras_block_str(&obj->head));
|
||||||
fs_info.head = obj->head;
|
fs_info.head = obj->head;
|
||||||
amdgpu_ras_debugfs_create(adev, &fs_info, dir);
|
amdgpu_ras_debugfs_create(adev, &fs_info, dir);
|
||||||
}
|
}
|
||||||
@ -1469,22 +1559,28 @@ static void amdgpu_ras_interrupt_handler(struct ras_manager *obj)
|
|||||||
data->rptr = (data->aligned_element_size +
|
data->rptr = (data->aligned_element_size +
|
||||||
data->rptr) % data->ring_size;
|
data->rptr) % data->ring_size;
|
||||||
|
|
||||||
/* Let IP handle its data, maybe we need get the output
|
|
||||||
* from the callback to udpate the error type/count, etc
|
|
||||||
*/
|
|
||||||
if (data->cb) {
|
if (data->cb) {
|
||||||
ret = data->cb(obj->adev, &err_data, &entry);
|
if (amdgpu_ras_is_poison_mode_supported(obj->adev) &&
|
||||||
/* ue will trigger an interrupt, and in that case
|
obj->head.block == AMDGPU_RAS_BLOCK__UMC)
|
||||||
* we need do a reset to recovery the whole system.
|
dev_info(obj->adev->dev,
|
||||||
* But leave IP do that recovery, here we just dispatch
|
"Poison is created, no user action is needed.\n");
|
||||||
* the error.
|
else {
|
||||||
*/
|
/* Let IP handle its data, maybe we need get the output
|
||||||
if (ret == AMDGPU_RAS_SUCCESS) {
|
* from the callback to udpate the error type/count, etc
|
||||||
/* these counts could be left as 0 if
|
|
||||||
* some blocks do not count error number
|
|
||||||
*/
|
*/
|
||||||
obj->err_data.ue_count += err_data.ue_count;
|
ret = data->cb(obj->adev, &err_data, &entry);
|
||||||
obj->err_data.ce_count += err_data.ce_count;
|
/* ue will trigger an interrupt, and in that case
|
||||||
|
* we need do a reset to recovery the whole system.
|
||||||
|
* But leave IP do that recovery, here we just dispatch
|
||||||
|
* the error.
|
||||||
|
*/
|
||||||
|
if (ret == AMDGPU_RAS_SUCCESS) {
|
||||||
|
/* these counts could be left as 0 if
|
||||||
|
* some blocks do not count error number
|
||||||
|
*/
|
||||||
|
obj->err_data.ue_count += err_data.ue_count;
|
||||||
|
obj->err_data.ce_count += err_data.ce_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2014,6 +2110,11 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev)
|
|||||||
adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs);
|
adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_MCE_AMD
|
||||||
|
if ((adev->asic_type == CHIP_ALDEBARAN) &&
|
||||||
|
(adev->gmc.xgmi.connected_to_cpu))
|
||||||
|
amdgpu_register_bad_pages_mca_notifier(adev);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free:
|
free:
|
||||||
@ -2056,19 +2157,6 @@ static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev)
|
|||||||
}
|
}
|
||||||
/* recovery end */
|
/* recovery end */
|
||||||
|
|
||||||
/* return 0 if ras will reset gpu and repost.*/
|
|
||||||
int amdgpu_ras_request_reset_on_boot(struct amdgpu_device *adev,
|
|
||||||
unsigned int block)
|
|
||||||
{
|
|
||||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
|
||||||
|
|
||||||
if (!ras)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ras->flags |= AMDGPU_RAS_FLAG_INIT_NEED_RESET;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool amdgpu_ras_asic_supported(struct amdgpu_device *adev)
|
static bool amdgpu_ras_asic_supported(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
return adev->asic_type == CHIP_VEGA10 ||
|
return adev->asic_type == CHIP_VEGA10 ||
|
||||||
@ -2176,12 +2264,14 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
|
|||||||
{
|
{
|
||||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||||
int r;
|
int r;
|
||||||
|
bool df_poison, umc_poison;
|
||||||
|
|
||||||
if (con)
|
if (con)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
con = kmalloc(sizeof(struct amdgpu_ras) +
|
con = kmalloc(sizeof(struct amdgpu_ras) +
|
||||||
sizeof(struct ras_manager) * AMDGPU_RAS_BLOCK_COUNT,
|
sizeof(struct ras_manager) * AMDGPU_RAS_BLOCK_COUNT +
|
||||||
|
sizeof(struct ras_manager) * AMDGPU_RAS_MCA_BLOCK_COUNT,
|
||||||
GFP_KERNEL|__GFP_ZERO);
|
GFP_KERNEL|__GFP_ZERO);
|
||||||
if (!con)
|
if (!con)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -2245,6 +2335,23 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
|
|||||||
goto release_con;
|
goto release_con;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Init poison supported flag, the default value is false */
|
||||||
|
if (adev->df.funcs &&
|
||||||
|
adev->df.funcs->query_ras_poison_mode &&
|
||||||
|
adev->umc.ras_funcs &&
|
||||||
|
adev->umc.ras_funcs->query_ras_poison_mode) {
|
||||||
|
df_poison =
|
||||||
|
adev->df.funcs->query_ras_poison_mode(adev);
|
||||||
|
umc_poison =
|
||||||
|
adev->umc.ras_funcs->query_ras_poison_mode(adev);
|
||||||
|
/* Only poison is set in both DF and UMC, we can support it */
|
||||||
|
if (df_poison && umc_poison)
|
||||||
|
con->poison_supported = true;
|
||||||
|
else if (df_poison != umc_poison)
|
||||||
|
dev_warn(adev->dev, "Poison setting is inconsistent in DF/UMC(%d:%d)!\n",
|
||||||
|
df_poison, umc_poison);
|
||||||
|
}
|
||||||
|
|
||||||
if (amdgpu_ras_fs_init(adev)) {
|
if (amdgpu_ras_fs_init(adev)) {
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
goto release_con;
|
goto release_con;
|
||||||
@ -2288,6 +2395,16 @@ static int amdgpu_persistent_edc_harvesting(struct amdgpu_device *adev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool amdgpu_ras_is_poison_mode_supported(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||||
|
|
||||||
|
if (!con)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return con->poison_supported;
|
||||||
|
}
|
||||||
|
|
||||||
/* helper function to handle common stuff in ip late init phase */
|
/* helper function to handle common stuff in ip late init phase */
|
||||||
int amdgpu_ras_late_init(struct amdgpu_device *adev,
|
int amdgpu_ras_late_init(struct amdgpu_device *adev,
|
||||||
struct ras_common_if *ras_block,
|
struct ras_common_if *ras_block,
|
||||||
@ -2306,12 +2423,7 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev,
|
|||||||
|
|
||||||
r = amdgpu_ras_feature_enable_on_boot(adev, ras_block, 1);
|
r = amdgpu_ras_feature_enable_on_boot(adev, ras_block, 1);
|
||||||
if (r) {
|
if (r) {
|
||||||
if (r == -EAGAIN) {
|
if (adev->in_suspend || amdgpu_in_reset(adev)) {
|
||||||
/* request gpu reset. will run again */
|
|
||||||
amdgpu_ras_request_reset_on_boot(adev,
|
|
||||||
ras_block->block);
|
|
||||||
return 0;
|
|
||||||
} else if (adev->in_suspend || amdgpu_in_reset(adev)) {
|
|
||||||
/* in resume phase, if fail to enable ras,
|
/* in resume phase, if fail to enable ras,
|
||||||
* clean up all ras fs nodes, and disable ras */
|
* clean up all ras fs nodes, and disable ras */
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -2403,19 +2515,6 @@ void amdgpu_ras_resume(struct amdgpu_device *adev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (con->flags & AMDGPU_RAS_FLAG_INIT_NEED_RESET) {
|
|
||||||
con->flags &= ~AMDGPU_RAS_FLAG_INIT_NEED_RESET;
|
|
||||||
/* setup ras obj state as disabled.
|
|
||||||
* for init_by_vbios case.
|
|
||||||
* if we want to enable ras, just enable it in a normal way.
|
|
||||||
* If we want do disable it, need setup ras obj as enabled,
|
|
||||||
* then issue another TA disable cmd.
|
|
||||||
* See feature_enable_on_boot
|
|
||||||
*/
|
|
||||||
amdgpu_ras_disable_all_features(adev, 1);
|
|
||||||
amdgpu_ras_reset_gpu(adev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void amdgpu_ras_suspend(struct amdgpu_device *adev)
|
void amdgpu_ras_suspend(struct amdgpu_device *adev)
|
||||||
@ -2507,3 +2606,136 @@ void amdgpu_release_ras_context(struct amdgpu_device *adev)
|
|||||||
kfree(con);
|
kfree(con);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_MCE_AMD
|
||||||
|
static struct amdgpu_device *find_adev(uint32_t node_id)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct amdgpu_device *adev = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < mce_adev_list.num_gpu; i++) {
|
||||||
|
adev = mce_adev_list.devs[i];
|
||||||
|
|
||||||
|
if (adev && adev->gmc.xgmi.connected_to_cpu &&
|
||||||
|
adev->gmc.xgmi.physical_node_id == node_id)
|
||||||
|
break;
|
||||||
|
adev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return adev;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_MCA_IPID_GPUID(m) (((m) >> 44) & 0xF)
|
||||||
|
#define GET_UMC_INST(m) (((m) >> 21) & 0x7)
|
||||||
|
#define GET_CHAN_INDEX(m) ((((m) >> 12) & 0x3) | (((m) >> 18) & 0x4))
|
||||||
|
#define GPU_ID_OFFSET 8
|
||||||
|
|
||||||
|
static int amdgpu_bad_page_notifier(struct notifier_block *nb,
|
||||||
|
unsigned long val, void *data)
|
||||||
|
{
|
||||||
|
struct mce *m = (struct mce *)data;
|
||||||
|
struct amdgpu_device *adev = NULL;
|
||||||
|
uint32_t gpu_id = 0;
|
||||||
|
uint32_t umc_inst = 0;
|
||||||
|
uint32_t ch_inst, channel_index = 0;
|
||||||
|
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,
|
||||||
|
* and error occurred in DramECC (Extended error code = 0) then only
|
||||||
|
* process the error, else bail out.
|
||||||
|
*/
|
||||||
|
if (!m || !((smca_get_bank_type(m->bank) == SMCA_UMC_V2) &&
|
||||||
|
(XEC(m->status, 0x3f) == 0x0)))
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it is correctable error, return.
|
||||||
|
*/
|
||||||
|
if (mce_is_correctable(m))
|
||||||
|
return NOTIFY_OK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPU Id is offset by GPU_ID_OFFSET in MCA_IPID_UMC register.
|
||||||
|
*/
|
||||||
|
gpu_id = GET_MCA_IPID_GPUID(m->ipid) - GPU_ID_OFFSET;
|
||||||
|
|
||||||
|
adev = find_adev(gpu_id);
|
||||||
|
if (!adev) {
|
||||||
|
DRM_WARN("%s: Unable to find adev for gpu_id: %d\n", __func__,
|
||||||
|
gpu_id);
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it is uncorrectable error, then find out UMC instance and
|
||||||
|
* channel index.
|
||||||
|
*/
|
||||||
|
umc_inst = GET_UMC_INST(m->ipid);
|
||||||
|
ch_inst = GET_CHAN_INDEX(m->ipid);
|
||||||
|
|
||||||
|
dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d",
|
||||||
|
umc_inst, ch_inst);
|
||||||
|
|
||||||
|
memset(&err_rec, 0x0, sizeof(struct eeprom_table_record));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate UMC channel address to Physical address
|
||||||
|
*/
|
||||||
|
channel_index =
|
||||||
|
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num
|
||||||
|
+ ch_inst];
|
||||||
|
|
||||||
|
retired_page = ADDR_OF_8KB_BLOCK(m->addr) |
|
||||||
|
ADDR_OF_256B_BLOCK(channel_index) |
|
||||||
|
OFFSET_IN_256B_BLOCK(m->addr);
|
||||||
|
|
||||||
|
err_rec.address = m->addr;
|
||||||
|
err_rec.retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
|
||||||
|
err_rec.ts = (uint64_t)ktime_get_real_seconds();
|
||||||
|
err_rec.err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
|
||||||
|
err_rec.cu = 0;
|
||||||
|
err_rec.mem_channel = channel_index;
|
||||||
|
err_rec.mcumc_id = umc_inst;
|
||||||
|
|
||||||
|
err_data.err_addr = &err_rec;
|
||||||
|
err_data.err_addr_cnt = 1;
|
||||||
|
|
||||||
|
if (amdgpu_bad_page_threshold != 0) {
|
||||||
|
amdgpu_ras_add_bad_pages(adev, err_data.err_addr,
|
||||||
|
err_data.err_addr_cnt);
|
||||||
|
amdgpu_ras_save_bad_pages(adev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block amdgpu_bad_page_nb = {
|
||||||
|
.notifier_call = amdgpu_bad_page_notifier,
|
||||||
|
.priority = MCE_PRIO_UC,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Add the adev to the mce_adev_list.
|
||||||
|
* During mode2 reset, amdgpu device is temporarily
|
||||||
|
* removed from the mgpu_info list which can cause
|
||||||
|
* page retirement to fail.
|
||||||
|
* Use this list instead of mgpu_info to find the amdgpu
|
||||||
|
* device on which the UMC error was reported.
|
||||||
|
*/
|
||||||
|
mce_adev_list.devs[mce_adev_list.num_gpu++] = adev;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register the x86 notifier only once
|
||||||
|
* with MCE subsystem.
|
||||||
|
*/
|
||||||
|
if (notifier_registered == false) {
|
||||||
|
mce_register_decode_chain(&amdgpu_bad_page_nb);
|
||||||
|
notifier_registered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#include "amdgpu_ras_eeprom.h"
|
#include "amdgpu_ras_eeprom.h"
|
||||||
|
|
||||||
#define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0)
|
#define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0)
|
||||||
#define AMDGPU_RAS_FLAG_INIT_NEED_RESET (0x1 << 1)
|
|
||||||
|
|
||||||
enum amdgpu_ras_block {
|
enum amdgpu_ras_block {
|
||||||
AMDGPU_RAS_BLOCK__UMC = 0,
|
AMDGPU_RAS_BLOCK__UMC = 0,
|
||||||
@ -49,15 +48,22 @@ enum amdgpu_ras_block {
|
|||||||
AMDGPU_RAS_BLOCK__MP0,
|
AMDGPU_RAS_BLOCK__MP0,
|
||||||
AMDGPU_RAS_BLOCK__MP1,
|
AMDGPU_RAS_BLOCK__MP1,
|
||||||
AMDGPU_RAS_BLOCK__FUSE,
|
AMDGPU_RAS_BLOCK__FUSE,
|
||||||
AMDGPU_RAS_BLOCK__MPIO,
|
AMDGPU_RAS_BLOCK__MCA,
|
||||||
|
|
||||||
AMDGPU_RAS_BLOCK__LAST
|
AMDGPU_RAS_BLOCK__LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char *ras_block_string[];
|
enum amdgpu_ras_mca_block {
|
||||||
|
AMDGPU_RAS_MCA_BLOCK__MP0 = 0,
|
||||||
|
AMDGPU_RAS_MCA_BLOCK__MP1,
|
||||||
|
AMDGPU_RAS_MCA_BLOCK__MPIO,
|
||||||
|
AMDGPU_RAS_MCA_BLOCK__IOHC,
|
||||||
|
|
||||||
|
AMDGPU_RAS_MCA_BLOCK__LAST
|
||||||
|
};
|
||||||
|
|
||||||
#define ras_block_str(i) (ras_block_string[i])
|
|
||||||
#define AMDGPU_RAS_BLOCK_COUNT AMDGPU_RAS_BLOCK__LAST
|
#define AMDGPU_RAS_BLOCK_COUNT AMDGPU_RAS_BLOCK__LAST
|
||||||
|
#define AMDGPU_RAS_MCA_BLOCK_COUNT AMDGPU_RAS_MCA_BLOCK__LAST
|
||||||
#define AMDGPU_RAS_BLOCK_MASK ((1ULL << AMDGPU_RAS_BLOCK_COUNT) - 1)
|
#define AMDGPU_RAS_BLOCK_MASK ((1ULL << AMDGPU_RAS_BLOCK_COUNT) - 1)
|
||||||
|
|
||||||
enum amdgpu_ras_gfx_subblock {
|
enum amdgpu_ras_gfx_subblock {
|
||||||
@ -345,6 +351,9 @@ struct amdgpu_ras {
|
|||||||
/* disable ras error count harvest in recovery */
|
/* disable ras error count harvest in recovery */
|
||||||
bool disable_ras_err_cnt_harvest;
|
bool disable_ras_err_cnt_harvest;
|
||||||
|
|
||||||
|
/* is poison mode supported */
|
||||||
|
bool poison_supported;
|
||||||
|
|
||||||
/* RAS count errors delayed work */
|
/* RAS count errors delayed work */
|
||||||
struct delayed_work ras_counte_delay_work;
|
struct delayed_work ras_counte_delay_work;
|
||||||
atomic_t ras_ue_count;
|
atomic_t ras_ue_count;
|
||||||
@ -488,8 +497,6 @@ static inline int amdgpu_ras_is_supported(struct amdgpu_device *adev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int amdgpu_ras_recovery_init(struct amdgpu_device *adev);
|
int amdgpu_ras_recovery_init(struct amdgpu_device *adev);
|
||||||
int amdgpu_ras_request_reset_on_boot(struct amdgpu_device *adev,
|
|
||||||
unsigned int block);
|
|
||||||
|
|
||||||
void amdgpu_ras_resume(struct amdgpu_device *adev);
|
void amdgpu_ras_resume(struct amdgpu_device *adev);
|
||||||
void amdgpu_ras_suspend(struct amdgpu_device *adev);
|
void amdgpu_ras_suspend(struct amdgpu_device *adev);
|
||||||
@ -544,6 +551,8 @@ amdgpu_ras_block_to_ta(enum amdgpu_ras_block block) {
|
|||||||
return TA_RAS_BLOCK__MP1;
|
return TA_RAS_BLOCK__MP1;
|
||||||
case AMDGPU_RAS_BLOCK__FUSE:
|
case AMDGPU_RAS_BLOCK__FUSE:
|
||||||
return TA_RAS_BLOCK__FUSE;
|
return TA_RAS_BLOCK__FUSE;
|
||||||
|
case AMDGPU_RAS_BLOCK__MCA:
|
||||||
|
return TA_RAS_BLOCK__MCA;
|
||||||
default:
|
default:
|
||||||
WARN_ONCE(1, "RAS ERROR: unexpected block id %d\n", block);
|
WARN_ONCE(1, "RAS ERROR: unexpected block id %d\n", block);
|
||||||
return TA_RAS_BLOCK__UMC;
|
return TA_RAS_BLOCK__UMC;
|
||||||
@ -638,4 +647,8 @@ void amdgpu_release_ras_context(struct amdgpu_device *adev);
|
|||||||
|
|
||||||
int amdgpu_persistent_edc_harvesting_supported(struct amdgpu_device *adev);
|
int amdgpu_persistent_edc_harvesting_supported(struct amdgpu_device *adev);
|
||||||
|
|
||||||
|
const char *get_ras_block_str(struct ras_common_if *ras_block);
|
||||||
|
|
||||||
|
bool amdgpu_ras_is_poison_mode_supported(struct amdgpu_device *adev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1077,6 +1077,13 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control,
|
|||||||
if (res)
|
if (res)
|
||||||
DRM_ERROR("RAS table incorrect checksum or error:%d\n",
|
DRM_ERROR("RAS table incorrect checksum or error:%d\n",
|
||||||
res);
|
res);
|
||||||
|
|
||||||
|
/* Warn if we are at 90% of the threshold or above
|
||||||
|
*/
|
||||||
|
if (10 * control->ras_num_recs >= 9 * ras->bad_page_cnt_threshold)
|
||||||
|
dev_warn(adev->dev, "RAS records:%u exceeds 90%% of threshold:%d",
|
||||||
|
control->ras_num_recs,
|
||||||
|
ras->bad_page_cnt_threshold);
|
||||||
} else if (hdr->header == RAS_TABLE_HDR_BAD &&
|
} else if (hdr->header == RAS_TABLE_HDR_BAD &&
|
||||||
amdgpu_bad_page_threshold != 0) {
|
amdgpu_bad_page_threshold != 0) {
|
||||||
res = __verify_ras_table_checksum(control);
|
res = __verify_ras_table_checksum(control);
|
||||||
@ -1098,11 +1105,18 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control,
|
|||||||
res = amdgpu_ras_eeprom_correct_header_tag(control,
|
res = amdgpu_ras_eeprom_correct_header_tag(control,
|
||||||
RAS_TABLE_HDR_VAL);
|
RAS_TABLE_HDR_VAL);
|
||||||
} else {
|
} else {
|
||||||
*exceed_err_limit = true;
|
dev_err(adev->dev, "RAS records:%d exceed threshold:%d",
|
||||||
dev_err(adev->dev,
|
|
||||||
"RAS records:%d exceed threshold:%d, "
|
|
||||||
"maybe retire this GPU?",
|
|
||||||
control->ras_num_recs, ras->bad_page_cnt_threshold);
|
control->ras_num_recs, ras->bad_page_cnt_threshold);
|
||||||
|
if (amdgpu_bad_page_threshold == -2) {
|
||||||
|
dev_warn(adev->dev, "GPU will be initialized due to bad_page_threshold = -2.");
|
||||||
|
res = 0;
|
||||||
|
} else {
|
||||||
|
*exceed_err_limit = true;
|
||||||
|
dev_err(adev->dev,
|
||||||
|
"RAS records:%d exceed threshold:%d, "
|
||||||
|
"GPU will not be initialized. Replace this GPU or increase the threshold",
|
||||||
|
control->ras_num_recs, ras->bad_page_cnt_threshold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DRM_INFO("Creating a new EEPROM table");
|
DRM_INFO("Creating a new EEPROM table");
|
||||||
|
@ -415,26 +415,20 @@ static const struct file_operations amdgpu_debugfs_ring_fops = {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
|
void amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
|
||||||
struct amdgpu_ring *ring)
|
struct amdgpu_ring *ring)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_DEBUG_FS)
|
#if defined(CONFIG_DEBUG_FS)
|
||||||
struct drm_minor *minor = adev_to_drm(adev)->primary;
|
struct drm_minor *minor = adev_to_drm(adev)->primary;
|
||||||
struct dentry *ent, *root = minor->debugfs_root;
|
struct dentry *root = minor->debugfs_root;
|
||||||
char name[32];
|
char name[32];
|
||||||
|
|
||||||
sprintf(name, "amdgpu_ring_%s", ring->name);
|
sprintf(name, "amdgpu_ring_%s", ring->name);
|
||||||
|
debugfs_create_file_size(name, S_IFREG | S_IRUGO, root, ring,
|
||||||
|
&amdgpu_debugfs_ring_fops,
|
||||||
|
ring->ring_size + 12);
|
||||||
|
|
||||||
ent = debugfs_create_file(name,
|
|
||||||
S_IFREG | S_IRUGO, root,
|
|
||||||
ring, &amdgpu_debugfs_ring_fops);
|
|
||||||
if (IS_ERR(ent))
|
|
||||||
return PTR_ERR(ent);
|
|
||||||
|
|
||||||
i_size_write(ent->d_inode, ring->ring_size + 12);
|
|
||||||
ring->ent = ent;
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,8 +36,13 @@
|
|||||||
#define AMDGPU_MAX_VCE_RINGS 3
|
#define AMDGPU_MAX_VCE_RINGS 3
|
||||||
#define AMDGPU_MAX_UVD_ENC_RINGS 2
|
#define AMDGPU_MAX_UVD_ENC_RINGS 2
|
||||||
|
|
||||||
#define AMDGPU_RING_PRIO_DEFAULT 1
|
enum amdgpu_ring_priority_level {
|
||||||
#define AMDGPU_RING_PRIO_MAX AMDGPU_GFX_PIPE_PRIO_MAX
|
AMDGPU_RING_PRIO_0,
|
||||||
|
AMDGPU_RING_PRIO_1,
|
||||||
|
AMDGPU_RING_PRIO_DEFAULT = 1,
|
||||||
|
AMDGPU_RING_PRIO_2,
|
||||||
|
AMDGPU_RING_PRIO_MAX
|
||||||
|
};
|
||||||
|
|
||||||
/* some special values for the owner field */
|
/* some special values for the owner field */
|
||||||
#define AMDGPU_FENCE_OWNER_UNDEFINED ((void *)0ul)
|
#define AMDGPU_FENCE_OWNER_UNDEFINED ((void *)0ul)
|
||||||
@ -248,10 +253,6 @@ struct amdgpu_ring {
|
|||||||
bool has_compute_vm_bug;
|
bool has_compute_vm_bug;
|
||||||
bool no_scheduler;
|
bool no_scheduler;
|
||||||
int hw_prio;
|
int hw_prio;
|
||||||
|
|
||||||
#if defined(CONFIG_DEBUG_FS)
|
|
||||||
struct dentry *ent;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
|
#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
|
||||||
@ -351,8 +352,6 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring,
|
|||||||
|
|
||||||
int amdgpu_ring_test_helper(struct amdgpu_ring *ring);
|
int amdgpu_ring_test_helper(struct amdgpu_ring *ring);
|
||||||
|
|
||||||
int amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
|
void amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
|
||||||
struct amdgpu_ring *ring);
|
struct amdgpu_ring *ring);
|
||||||
void amdgpu_debugfs_ring_fini(struct amdgpu_ring *ring);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,37 +32,9 @@
|
|||||||
#include "amdgpu_sched.h"
|
#include "amdgpu_sched.h"
|
||||||
#include "amdgpu_vm.h"
|
#include "amdgpu_vm.h"
|
||||||
|
|
||||||
int amdgpu_to_sched_priority(int amdgpu_priority,
|
|
||||||
enum drm_sched_priority *prio)
|
|
||||||
{
|
|
||||||
switch (amdgpu_priority) {
|
|
||||||
case AMDGPU_CTX_PRIORITY_VERY_HIGH:
|
|
||||||
*prio = DRM_SCHED_PRIORITY_HIGH;
|
|
||||||
break;
|
|
||||||
case AMDGPU_CTX_PRIORITY_HIGH:
|
|
||||||
*prio = DRM_SCHED_PRIORITY_HIGH;
|
|
||||||
break;
|
|
||||||
case AMDGPU_CTX_PRIORITY_NORMAL:
|
|
||||||
*prio = DRM_SCHED_PRIORITY_NORMAL;
|
|
||||||
break;
|
|
||||||
case AMDGPU_CTX_PRIORITY_LOW:
|
|
||||||
case AMDGPU_CTX_PRIORITY_VERY_LOW:
|
|
||||||
*prio = DRM_SCHED_PRIORITY_MIN;
|
|
||||||
break;
|
|
||||||
case AMDGPU_CTX_PRIORITY_UNSET:
|
|
||||||
*prio = DRM_SCHED_PRIORITY_UNSET;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARN(1, "Invalid context priority %d\n", amdgpu_priority);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
|
static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
|
||||||
int fd,
|
int fd,
|
||||||
enum drm_sched_priority priority)
|
int32_t priority)
|
||||||
{
|
{
|
||||||
struct fd f = fdget(fd);
|
struct fd f = fdget(fd);
|
||||||
struct amdgpu_fpriv *fpriv;
|
struct amdgpu_fpriv *fpriv;
|
||||||
@ -89,7 +61,7 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
|
|||||||
static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev,
|
static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev,
|
||||||
int fd,
|
int fd,
|
||||||
unsigned ctx_id,
|
unsigned ctx_id,
|
||||||
enum drm_sched_priority priority)
|
int32_t priority)
|
||||||
{
|
{
|
||||||
struct fd f = fdget(fd);
|
struct fd f = fdget(fd);
|
||||||
struct amdgpu_fpriv *fpriv;
|
struct amdgpu_fpriv *fpriv;
|
||||||
@ -124,7 +96,6 @@ int amdgpu_sched_ioctl(struct drm_device *dev, void *data,
|
|||||||
{
|
{
|
||||||
union drm_amdgpu_sched *args = data;
|
union drm_amdgpu_sched *args = data;
|
||||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||||
enum drm_sched_priority priority;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* First check the op, then the op's argument.
|
/* First check the op, then the op's argument.
|
||||||
@ -138,21 +109,22 @@ int amdgpu_sched_ioctl(struct drm_device *dev, void *data,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = amdgpu_to_sched_priority(args->in.priority, &priority);
|
if (!amdgpu_ctx_priority_is_valid(args->in.priority)) {
|
||||||
if (r)
|
WARN(1, "Invalid context priority %d\n", args->in.priority);
|
||||||
return r;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
switch (args->in.op) {
|
switch (args->in.op) {
|
||||||
case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE:
|
case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE:
|
||||||
r = amdgpu_sched_process_priority_override(adev,
|
r = amdgpu_sched_process_priority_override(adev,
|
||||||
args->in.fd,
|
args->in.fd,
|
||||||
priority);
|
args->in.priority);
|
||||||
break;
|
break;
|
||||||
case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE:
|
case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE:
|
||||||
r = amdgpu_sched_context_priority_override(adev,
|
r = amdgpu_sched_context_priority_override(adev,
|
||||||
args->in.fd,
|
args->in.fd,
|
||||||
args->in.ctx_id,
|
args->in.ctx_id,
|
||||||
priority);
|
args->in.priority);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Impossible.
|
/* Impossible.
|
||||||
|
@ -696,6 +696,9 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
|
|||||||
true, NULL);
|
true, NULL);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mmap_read_unlock(mm);
|
mmap_read_unlock(mm);
|
||||||
|
if (r)
|
||||||
|
pr_debug("failed %d to get user pages 0x%lx\n", r, start);
|
||||||
|
|
||||||
mmput(mm);
|
mmput(mm);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
@ -894,7 +897,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
|
|||||||
DRM_ERROR("failed to pin userptr\n");
|
DRM_ERROR("failed to pin userptr\n");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
} else if (ttm->page_flags & TTM_PAGE_FLAG_SG) {
|
} else if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) {
|
||||||
if (!ttm->sg) {
|
if (!ttm->sg) {
|
||||||
struct dma_buf_attachment *attach;
|
struct dma_buf_attachment *attach;
|
||||||
struct sg_table *sgt;
|
struct sg_table *sgt;
|
||||||
@ -1066,8 +1069,6 @@ static void amdgpu_ttm_backend_destroy(struct ttm_device *bdev,
|
|||||||
{
|
{
|
||||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||||
|
|
||||||
amdgpu_ttm_backend_unbind(bdev, ttm);
|
|
||||||
ttm_tt_destroy_common(bdev, ttm);
|
|
||||||
if (gtt->usertask)
|
if (gtt->usertask)
|
||||||
put_task_struct(gtt->usertask);
|
put_task_struct(gtt->usertask);
|
||||||
|
|
||||||
@ -1121,6 +1122,8 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev,
|
|||||||
{
|
{
|
||||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
|
struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
|
||||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||||
|
pgoff_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* user pages are bound by amdgpu_ttm_tt_pin_userptr() */
|
/* user pages are bound by amdgpu_ttm_tt_pin_userptr() */
|
||||||
if (gtt->userptr) {
|
if (gtt->userptr) {
|
||||||
@ -1130,10 +1133,17 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ttm->page_flags & TTM_PAGE_FLAG_SG)
|
if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx);
|
ret = ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < ttm->num_pages; ++i)
|
||||||
|
ttm->pages[i]->mapping = bdev->dev_mapping;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1147,6 +1157,9 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev,
|
|||||||
{
|
{
|
||||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||||
struct amdgpu_device *adev;
|
struct amdgpu_device *adev;
|
||||||
|
pgoff_t i;
|
||||||
|
|
||||||
|
amdgpu_ttm_backend_unbind(bdev, ttm);
|
||||||
|
|
||||||
if (gtt->userptr) {
|
if (gtt->userptr) {
|
||||||
amdgpu_ttm_tt_set_user_pages(ttm, NULL);
|
amdgpu_ttm_tt_set_user_pages(ttm, NULL);
|
||||||
@ -1155,9 +1168,12 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ttm->page_flags & TTM_PAGE_FLAG_SG)
|
if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < ttm->num_pages; ++i)
|
||||||
|
ttm->pages[i]->mapping = NULL;
|
||||||
|
|
||||||
adev = amdgpu_ttm_adev(bdev);
|
adev = amdgpu_ttm_adev(bdev);
|
||||||
return ttm_pool_free(&adev->mman.bdev.pool, ttm);
|
return ttm_pool_free(&adev->mman.bdev.pool, ttm);
|
||||||
}
|
}
|
||||||
@ -1185,8 +1201,8 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set TTM_PAGE_FLAG_SG before populate but after create. */
|
/* Set TTM_TT_FLAG_EXTERNAL before populate but after create. */
|
||||||
bo->ttm->page_flags |= TTM_PAGE_FLAG_SG;
|
bo->ttm->page_flags |= TTM_TT_FLAG_EXTERNAL;
|
||||||
|
|
||||||
gtt = (void *)bo->ttm;
|
gtt = (void *)bo->ttm;
|
||||||
gtt->userptr = addr;
|
gtt->userptr = addr;
|
||||||
@ -1222,7 +1238,7 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
|
bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
|
||||||
unsigned long end)
|
unsigned long end, unsigned long *userptr)
|
||||||
{
|
{
|
||||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
@ -1237,6 +1253,8 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
|
|||||||
if (gtt->userptr > end || gtt->userptr + size <= start)
|
if (gtt->userptr > end || gtt->userptr + size <= start)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (userptr)
|
||||||
|
*userptr = gtt->userptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2036,6 +2054,36 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* amdgpu_ttm_evict_resources - evict memory buffers
|
||||||
|
* @adev: amdgpu device object
|
||||||
|
* @mem_type: evicted BO's memory type
|
||||||
|
*
|
||||||
|
* Evicts all @mem_type buffers on the lru list of the memory type.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 for success or a negative error code on failure.
|
||||||
|
*/
|
||||||
|
int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type)
|
||||||
|
{
|
||||||
|
struct ttm_resource_manager *man;
|
||||||
|
|
||||||
|
switch (mem_type) {
|
||||||
|
case TTM_PL_VRAM:
|
||||||
|
case TTM_PL_TT:
|
||||||
|
case AMDGPU_PL_GWS:
|
||||||
|
case AMDGPU_PL_GDS:
|
||||||
|
case AMDGPU_PL_OA:
|
||||||
|
man = ttm_manager_type(&adev->mman.bdev, mem_type);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DRM_ERROR("Trying to evict invalid memory type\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ttm_resource_manager_evict_all(&adev->mman.bdev, man);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_DEBUG_FS)
|
#if defined(CONFIG_DEBUG_FS)
|
||||||
|
|
||||||
static int amdgpu_mm_vram_table_show(struct seq_file *m, void *unused)
|
static int amdgpu_mm_vram_table_show(struct seq_file *m, void *unused)
|
||||||
|
@ -182,7 +182,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
|
|||||||
bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
|
bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
|
||||||
struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm);
|
struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm);
|
||||||
bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
|
bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
|
||||||
unsigned long end);
|
unsigned long end, unsigned long *userptr);
|
||||||
bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm,
|
bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm,
|
||||||
int *last_invalidated);
|
int *last_invalidated);
|
||||||
bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm);
|
bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm);
|
||||||
@ -190,6 +190,7 @@ bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
|
|||||||
uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem);
|
uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem);
|
||||||
uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
|
uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
|
||||||
struct ttm_resource *mem);
|
struct ttm_resource *mem);
|
||||||
|
int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type);
|
||||||
|
|
||||||
void amdgpu_ttm_debugfs_init(struct amdgpu_device *adev);
|
void amdgpu_ttm_debugfs_init(struct amdgpu_device *adev);
|
||||||
|
|
||||||
|
@ -416,10 +416,11 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
|
|||||||
else
|
else
|
||||||
return AMDGPU_FW_LOAD_PSP;
|
return AMDGPU_FW_LOAD_PSP;
|
||||||
default:
|
default:
|
||||||
DRM_ERROR("Unknown firmware load type\n");
|
if (!load_type)
|
||||||
|
return AMDGPU_FW_LOAD_DIRECT;
|
||||||
|
else
|
||||||
|
return AMDGPU_FW_LOAD_PSP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AMDGPU_FW_LOAD_DIRECT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id)
|
const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id)
|
||||||
@ -508,7 +509,7 @@ static ssize_t show_##name(struct device *dev, \
|
|||||||
struct drm_device *ddev = dev_get_drvdata(dev); \
|
struct drm_device *ddev = dev_get_drvdata(dev); \
|
||||||
struct amdgpu_device *adev = drm_to_adev(ddev); \
|
struct amdgpu_device *adev = drm_to_adev(ddev); \
|
||||||
\
|
\
|
||||||
return snprintf(buf, PAGE_SIZE, "0x%08x\n", adev->field); \
|
return sysfs_emit(buf, "0x%08x\n", adev->field); \
|
||||||
} \
|
} \
|
||||||
static DEVICE_ATTR(name, mode, show_##name, NULL)
|
static DEVICE_ATTR(name, mode, show_##name, NULL)
|
||||||
|
|
||||||
@ -525,9 +526,9 @@ FW_VERSION_ATTR(rlc_srls_fw_version, 0444, gfx.rlc_srls_fw_version);
|
|||||||
FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version);
|
FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version);
|
||||||
FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version);
|
FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version);
|
||||||
FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos.fw_version);
|
FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos.fw_version);
|
||||||
FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd.fw_version);
|
FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_context.bin_desc.fw_version);
|
||||||
FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras.feature_version);
|
FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras_context.context.bin_desc.fw_version);
|
||||||
FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.xgmi.feature_version);
|
FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.xgmi_context.context.bin_desc.fw_version);
|
||||||
FW_VERSION_ATTR(smc_fw_version, 0444, pm.fw_version);
|
FW_VERSION_ATTR(smc_fw_version, 0444, pm.fw_version);
|
||||||
FW_VERSION_ATTR(sdma_fw_version, 0444, sdma.instance[0].fw_version);
|
FW_VERSION_ATTR(sdma_fw_version, 0444, sdma.instance[0].fw_version);
|
||||||
FW_VERSION_ATTR(sdma2_fw_version, 0444, sdma.instance[1].fw_version);
|
FW_VERSION_ATTR(sdma2_fw_version, 0444, sdma.instance[1].fw_version);
|
||||||
@ -572,6 +573,7 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
|
|||||||
const struct dmcu_firmware_header_v1_0 *dmcu_hdr = NULL;
|
const struct dmcu_firmware_header_v1_0 *dmcu_hdr = NULL;
|
||||||
const struct dmcub_firmware_header_v1_0 *dmcub_hdr = NULL;
|
const struct dmcub_firmware_header_v1_0 *dmcub_hdr = NULL;
|
||||||
const struct mes_firmware_header_v1_0 *mes_hdr = NULL;
|
const struct mes_firmware_header_v1_0 *mes_hdr = NULL;
|
||||||
|
u8 *ucode_addr;
|
||||||
|
|
||||||
if (NULL == ucode->fw)
|
if (NULL == ucode->fw)
|
||||||
return 0;
|
return 0;
|
||||||
@ -588,94 +590,83 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev,
|
|||||||
dmcub_hdr = (const struct dmcub_firmware_header_v1_0 *)ucode->fw->data;
|
dmcub_hdr = (const struct dmcub_firmware_header_v1_0 *)ucode->fw->data;
|
||||||
mes_hdr = (const struct mes_firmware_header_v1_0 *)ucode->fw->data;
|
mes_hdr = (const struct mes_firmware_header_v1_0 *)ucode->fw->data;
|
||||||
|
|
||||||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP ||
|
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||||
(ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 &&
|
switch (ucode->ucode_id) {
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2 &&
|
case AMDGPU_UCODE_ID_CP_MEC1:
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1_JT &&
|
case AMDGPU_UCODE_ID_CP_MEC2:
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT &&
|
ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) -
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_CP_MES &&
|
le32_to_cpu(cp_hdr->jt_size) * 4;
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_CP_MES_DATA &&
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL &&
|
le32_to_cpu(header->ucode_array_offset_bytes);
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM &&
|
break;
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM &&
|
case AMDGPU_UCODE_ID_CP_MEC1_JT:
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_RLC_IRAM &&
|
case AMDGPU_UCODE_ID_CP_MEC2_JT:
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_RLC_DRAM &&
|
ucode->ucode_size = le32_to_cpu(cp_hdr->jt_size) * 4;
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_ERAM &&
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_INTV &&
|
le32_to_cpu(header->ucode_array_offset_bytes) +
|
||||||
ucode->ucode_id != AMDGPU_UCODE_ID_DMCUB)) {
|
le32_to_cpu(cp_hdr->jt_offset) * 4;
|
||||||
ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);
|
break;
|
||||||
|
case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL:
|
||||||
memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
|
ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes;
|
||||||
le32_to_cpu(header->ucode_array_offset_bytes)),
|
ucode_addr = adev->gfx.rlc.save_restore_list_cntl;
|
||||||
ucode->ucode_size);
|
break;
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1 ||
|
case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM:
|
||||||
ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2) {
|
ucode->ucode_size = adev->gfx.rlc.save_restore_list_gpm_size_bytes;
|
||||||
ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) -
|
ucode_addr = adev->gfx.rlc.save_restore_list_gpm;
|
||||||
le32_to_cpu(cp_hdr->jt_size) * 4;
|
break;
|
||||||
|
case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM:
|
||||||
memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
|
ucode->ucode_size = adev->gfx.rlc.save_restore_list_srm_size_bytes;
|
||||||
le32_to_cpu(header->ucode_array_offset_bytes)),
|
ucode_addr = adev->gfx.rlc.save_restore_list_srm;
|
||||||
ucode->ucode_size);
|
break;
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT ||
|
case AMDGPU_UCODE_ID_RLC_IRAM:
|
||||||
ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT) {
|
ucode->ucode_size = adev->gfx.rlc.rlc_iram_ucode_size_bytes;
|
||||||
ucode->ucode_size = le32_to_cpu(cp_hdr->jt_size) * 4;
|
ucode_addr = adev->gfx.rlc.rlc_iram_ucode;
|
||||||
|
break;
|
||||||
memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
|
case AMDGPU_UCODE_ID_RLC_DRAM:
|
||||||
le32_to_cpu(header->ucode_array_offset_bytes) +
|
ucode->ucode_size = adev->gfx.rlc.rlc_dram_ucode_size_bytes;
|
||||||
le32_to_cpu(cp_hdr->jt_offset) * 4),
|
ucode_addr = adev->gfx.rlc.rlc_dram_ucode;
|
||||||
ucode->ucode_size);
|
break;
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_ERAM) {
|
case AMDGPU_UCODE_ID_CP_MES:
|
||||||
ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) -
|
ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes);
|
||||||
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
|
le32_to_cpu(mes_hdr->mes_ucode_offset_bytes);
|
||||||
|
break;
|
||||||
|
case AMDGPU_UCODE_ID_CP_MES_DATA:
|
||||||
|
ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes);
|
||||||
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
|
le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes);
|
||||||
|
break;
|
||||||
|
case AMDGPU_UCODE_ID_DMCU_ERAM:
|
||||||
|
ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) -
|
||||||
le32_to_cpu(dmcu_hdr->intv_size_bytes);
|
le32_to_cpu(dmcu_hdr->intv_size_bytes);
|
||||||
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
|
le32_to_cpu(header->ucode_array_offset_bytes);
|
||||||
le32_to_cpu(header->ucode_array_offset_bytes)),
|
break;
|
||||||
ucode->ucode_size);
|
case AMDGPU_UCODE_ID_DMCU_INTV:
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_INTV) {
|
ucode->ucode_size = le32_to_cpu(dmcu_hdr->intv_size_bytes);
|
||||||
ucode->ucode_size = le32_to_cpu(dmcu_hdr->intv_size_bytes);
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
|
le32_to_cpu(header->ucode_array_offset_bytes) +
|
||||||
memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data +
|
le32_to_cpu(dmcu_hdr->intv_offset_bytes);
|
||||||
le32_to_cpu(header->ucode_array_offset_bytes) +
|
break;
|
||||||
le32_to_cpu(dmcu_hdr->intv_offset_bytes)),
|
case AMDGPU_UCODE_ID_DMCUB:
|
||||||
ucode->ucode_size);
|
ucode->ucode_size = le32_to_cpu(dmcub_hdr->inst_const_bytes);
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCUB) {
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
ucode->ucode_size = le32_to_cpu(dmcub_hdr->inst_const_bytes);
|
le32_to_cpu(header->ucode_array_offset_bytes);
|
||||||
memcpy(ucode->kaddr,
|
break;
|
||||||
(void *)((uint8_t *)ucode->fw->data +
|
default:
|
||||||
le32_to_cpu(header->ucode_array_offset_bytes)),
|
ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);
|
||||||
ucode->ucode_size);
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) {
|
le32_to_cpu(header->ucode_array_offset_bytes);
|
||||||
ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes;
|
break;
|
||||||
memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl,
|
}
|
||||||
ucode->ucode_size);
|
} else {
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM) {
|
ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes);
|
||||||
ucode->ucode_size = adev->gfx.rlc.save_restore_list_gpm_size_bytes;
|
ucode_addr = (u8 *)ucode->fw->data +
|
||||||
memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_gpm,
|
le32_to_cpu(header->ucode_array_offset_bytes);
|
||||||
ucode->ucode_size);
|
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM) {
|
|
||||||
ucode->ucode_size = adev->gfx.rlc.save_restore_list_srm_size_bytes;
|
|
||||||
memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_srm,
|
|
||||||
ucode->ucode_size);
|
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_IRAM) {
|
|
||||||
ucode->ucode_size = adev->gfx.rlc.rlc_iram_ucode_size_bytes;
|
|
||||||
memcpy(ucode->kaddr, adev->gfx.rlc.rlc_iram_ucode,
|
|
||||||
ucode->ucode_size);
|
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_DRAM) {
|
|
||||||
ucode->ucode_size = adev->gfx.rlc.rlc_dram_ucode_size_bytes;
|
|
||||||
memcpy(ucode->kaddr, adev->gfx.rlc.rlc_dram_ucode,
|
|
||||||
ucode->ucode_size);
|
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MES) {
|
|
||||||
ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes);
|
|
||||||
memcpy(ucode->kaddr, (void *)((uint8_t *)adev->mes.fw->data +
|
|
||||||
le32_to_cpu(mes_hdr->mes_ucode_offset_bytes)),
|
|
||||||
ucode->ucode_size);
|
|
||||||
} else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MES_DATA) {
|
|
||||||
ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes);
|
|
||||||
memcpy(ucode->kaddr, (void *)((uint8_t *)adev->mes.fw->data +
|
|
||||||
le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes)),
|
|
||||||
ucode->ucode_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(ucode->kaddr, ucode_addr, ucode->ucode_size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ struct amdgpu_umc_ras_funcs {
|
|||||||
void *ras_error_status);
|
void *ras_error_status);
|
||||||
void (*query_ras_error_address)(struct amdgpu_device *adev,
|
void (*query_ras_error_address)(struct amdgpu_device *adev,
|
||||||
void *ras_error_status);
|
void *ras_error_status);
|
||||||
|
bool (*query_ras_poison_mode)(struct amdgpu_device *adev);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amdgpu_umc_funcs {
|
struct amdgpu_umc_funcs {
|
||||||
|
51
drivers/gpu/drm/amd/amdgpu/amdgpu_umr.h
Normal file
51
drivers/gpu/drm/amd/amdgpu/amdgpu_umr.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <linux/ioctl.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MMIO debugfs IOCTL structure
|
||||||
|
*/
|
||||||
|
struct amdgpu_debugfs_regs2_iocdata {
|
||||||
|
__u32 use_srbm, use_grbm, pg_lock;
|
||||||
|
struct {
|
||||||
|
__u32 se, sh, instance;
|
||||||
|
} grbm;
|
||||||
|
struct {
|
||||||
|
__u32 me, pipe, queue, vmid;
|
||||||
|
} srbm;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MMIO debugfs state data (per file* handle)
|
||||||
|
*/
|
||||||
|
struct amdgpu_debugfs_regs2_data {
|
||||||
|
struct amdgpu_device *adev;
|
||||||
|
struct mutex lock;
|
||||||
|
struct amdgpu_debugfs_regs2_iocdata id;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AMDGPU_DEBUGFS_REGS2_CMDS {
|
||||||
|
AMDGPU_DEBUGFS_REGS2_CMD_SET_STATE=0,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define AMDGPU_DEBUGFS_REGS2_IOC_SET_STATE _IOWR(0x20, AMDGPU_DEBUGFS_REGS2_CMD_SET_STATE, struct amdgpu_debugfs_regs2_iocdata)
|
@ -134,6 +134,51 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12);
|
|||||||
MODULE_FIRMWARE(FIRMWARE_VEGA20);
|
MODULE_FIRMWARE(FIRMWARE_VEGA20);
|
||||||
|
|
||||||
static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
|
static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
|
||||||
|
static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo);
|
||||||
|
|
||||||
|
static int amdgpu_uvd_create_msg_bo_helper(struct amdgpu_device *adev,
|
||||||
|
uint32_t size,
|
||||||
|
struct amdgpu_bo **bo_ptr)
|
||||||
|
{
|
||||||
|
struct ttm_operation_ctx ctx = { true, false };
|
||||||
|
struct amdgpu_bo *bo = NULL;
|
||||||
|
void *addr;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = amdgpu_bo_create_reserved(adev, size, PAGE_SIZE,
|
||||||
|
AMDGPU_GEM_DOMAIN_GTT,
|
||||||
|
&bo, NULL, &addr);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (adev->uvd.address_64_bit)
|
||||||
|
goto succ;
|
||||||
|
|
||||||
|
amdgpu_bo_kunmap(bo);
|
||||||
|
amdgpu_bo_unpin(bo);
|
||||||
|
amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);
|
||||||
|
amdgpu_uvd_force_into_uvd_segment(bo);
|
||||||
|
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||||
|
if (r)
|
||||||
|
goto err;
|
||||||
|
r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_VRAM);
|
||||||
|
if (r)
|
||||||
|
goto err_pin;
|
||||||
|
r = amdgpu_bo_kmap(bo, &addr);
|
||||||
|
if (r)
|
||||||
|
goto err_kmap;
|
||||||
|
succ:
|
||||||
|
amdgpu_bo_unreserve(bo);
|
||||||
|
*bo_ptr = bo;
|
||||||
|
return 0;
|
||||||
|
err_kmap:
|
||||||
|
amdgpu_bo_unpin(bo);
|
||||||
|
err_pin:
|
||||||
|
err:
|
||||||
|
amdgpu_bo_unreserve(bo);
|
||||||
|
amdgpu_bo_unref(&bo);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
|
int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
@ -302,6 +347,10 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
|
|||||||
if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0))
|
if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0))
|
||||||
adev->uvd.address_64_bit = true;
|
adev->uvd.address_64_bit = true;
|
||||||
|
|
||||||
|
r = amdgpu_uvd_create_msg_bo_helper(adev, 128 << 10, &adev->uvd.ib_bo);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
switch (adev->asic_type) {
|
switch (adev->asic_type) {
|
||||||
case CHIP_TONGA:
|
case CHIP_TONGA:
|
||||||
adev->uvd.use_ctx_buf = adev->uvd.fw_version >= FW_1_65_10;
|
adev->uvd.use_ctx_buf = adev->uvd.fw_version >= FW_1_65_10;
|
||||||
@ -324,6 +373,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
|
int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
|
void *addr = amdgpu_bo_kptr(adev->uvd.ib_bo);
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
drm_sched_entity_destroy(&adev->uvd.entity);
|
drm_sched_entity_destroy(&adev->uvd.entity);
|
||||||
@ -342,6 +392,7 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
|
|||||||
for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i)
|
for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i)
|
||||||
amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]);
|
amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]);
|
||||||
}
|
}
|
||||||
|
amdgpu_bo_free_kernel(&adev->uvd.ib_bo, NULL, &addr);
|
||||||
release_firmware(adev->uvd.fw);
|
release_firmware(adev->uvd.fw);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -403,7 +454,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
|
|||||||
if (!adev->uvd.inst[j].saved_bo)
|
if (!adev->uvd.inst[j].saved_bo)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
/* re-write 0 since err_event_athub will corrupt VCPU buffer */
|
/* re-write 0 since err_event_athub will corrupt VCPU buffer */
|
||||||
if (in_ras_intr)
|
if (in_ras_intr)
|
||||||
memset(adev->uvd.inst[j].saved_bo, 0, size);
|
memset(adev->uvd.inst[j].saved_bo, 0, size);
|
||||||
@ -436,7 +487,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
|
|||||||
ptr = adev->uvd.inst[i].cpu_addr;
|
ptr = adev->uvd.inst[i].cpu_addr;
|
||||||
|
|
||||||
if (adev->uvd.inst[i].saved_bo != NULL) {
|
if (adev->uvd.inst[i].saved_bo != NULL) {
|
||||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size);
|
memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size);
|
||||||
drm_dev_exit(idx);
|
drm_dev_exit(idx);
|
||||||
}
|
}
|
||||||
@ -449,7 +500,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
|
|||||||
hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
|
hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
|
||||||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
|
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
|
||||||
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
|
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
|
||||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset,
|
memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset,
|
||||||
le32_to_cpu(hdr->ucode_size_bytes));
|
le32_to_cpu(hdr->ucode_size_bytes));
|
||||||
drm_dev_exit(idx);
|
drm_dev_exit(idx);
|
||||||
@ -1080,23 +1131,10 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||||||
unsigned offset_idx = 0;
|
unsigned offset_idx = 0;
|
||||||
unsigned offset[3] = { UVD_BASE_SI, 0, 0 };
|
unsigned offset[3] = { UVD_BASE_SI, 0, 0 };
|
||||||
|
|
||||||
amdgpu_bo_kunmap(bo);
|
|
||||||
amdgpu_bo_unpin(bo);
|
|
||||||
|
|
||||||
if (!ring->adev->uvd.address_64_bit) {
|
|
||||||
struct ttm_operation_ctx ctx = { true, false };
|
|
||||||
|
|
||||||
amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);
|
|
||||||
amdgpu_uvd_force_into_uvd_segment(bo);
|
|
||||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
|
||||||
if (r)
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = amdgpu_job_alloc_with_ib(adev, 64, direct ? AMDGPU_IB_POOL_DIRECT :
|
r = amdgpu_job_alloc_with_ib(adev, 64, direct ? AMDGPU_IB_POOL_DIRECT :
|
||||||
AMDGPU_IB_POOL_DELAYED, &job);
|
AMDGPU_IB_POOL_DELAYED, &job);
|
||||||
if (r)
|
if (r)
|
||||||
goto err;
|
return r;
|
||||||
|
|
||||||
if (adev->asic_type >= CHIP_VEGA10) {
|
if (adev->asic_type >= CHIP_VEGA10) {
|
||||||
offset_idx = 1 + ring->me;
|
offset_idx = 1 + ring->me;
|
||||||
@ -1147,9 +1185,9 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
amdgpu_bo_reserve(bo, true);
|
||||||
amdgpu_bo_fence(bo, f, false);
|
amdgpu_bo_fence(bo, f, false);
|
||||||
amdgpu_bo_unreserve(bo);
|
amdgpu_bo_unreserve(bo);
|
||||||
amdgpu_bo_unref(&bo);
|
|
||||||
|
|
||||||
if (fence)
|
if (fence)
|
||||||
*fence = dma_fence_get(f);
|
*fence = dma_fence_get(f);
|
||||||
@ -1159,10 +1197,6 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
amdgpu_job_free(job);
|
amdgpu_job_free(job);
|
||||||
|
|
||||||
err:
|
|
||||||
amdgpu_bo_unreserve(bo);
|
|
||||||
amdgpu_bo_unref(&bo);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1173,16 +1207,11 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||||||
struct dma_fence **fence)
|
struct dma_fence **fence)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = ring->adev;
|
struct amdgpu_device *adev = ring->adev;
|
||||||
struct amdgpu_bo *bo = NULL;
|
struct amdgpu_bo *bo = adev->uvd.ib_bo;
|
||||||
uint32_t *msg;
|
uint32_t *msg;
|
||||||
int r, i;
|
int i;
|
||||||
|
|
||||||
r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
|
|
||||||
AMDGPU_GEM_DOMAIN_GTT,
|
|
||||||
&bo, NULL, (void **)&msg);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
|
msg = amdgpu_bo_kptr(bo);
|
||||||
/* stitch together an UVD create msg */
|
/* stitch together an UVD create msg */
|
||||||
msg[0] = cpu_to_le32(0x00000de4);
|
msg[0] = cpu_to_le32(0x00000de4);
|
||||||
msg[1] = cpu_to_le32(0x00000000);
|
msg[1] = cpu_to_le32(0x00000000);
|
||||||
@ -1199,6 +1228,7 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||||||
msg[i] = cpu_to_le32(0x0);
|
msg[i] = cpu_to_le32(0x0);
|
||||||
|
|
||||||
return amdgpu_uvd_send_msg(ring, bo, true, fence);
|
return amdgpu_uvd_send_msg(ring, bo, true, fence);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||||
@ -1209,12 +1239,15 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||||||
uint32_t *msg;
|
uint32_t *msg;
|
||||||
int r, i;
|
int r, i;
|
||||||
|
|
||||||
r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
|
if (direct) {
|
||||||
AMDGPU_GEM_DOMAIN_GTT,
|
bo = adev->uvd.ib_bo;
|
||||||
&bo, NULL, (void **)&msg);
|
} else {
|
||||||
if (r)
|
r = amdgpu_uvd_create_msg_bo_helper(adev, 4096, &bo);
|
||||||
return r;
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = amdgpu_bo_kptr(bo);
|
||||||
/* stitch together an UVD destroy msg */
|
/* stitch together an UVD destroy msg */
|
||||||
msg[0] = cpu_to_le32(0x00000de4);
|
msg[0] = cpu_to_le32(0x00000de4);
|
||||||
msg[1] = cpu_to_le32(0x00000002);
|
msg[1] = cpu_to_le32(0x00000002);
|
||||||
@ -1223,7 +1256,12 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||||||
for (i = 4; i < 1024; ++i)
|
for (i = 4; i < 1024; ++i)
|
||||||
msg[i] = cpu_to_le32(0x0);
|
msg[i] = cpu_to_le32(0x0);
|
||||||
|
|
||||||
return amdgpu_uvd_send_msg(ring, bo, direct, fence);
|
r = amdgpu_uvd_send_msg(ring, bo, direct, fence);
|
||||||
|
|
||||||
|
if (!direct)
|
||||||
|
amdgpu_bo_free_kernel(&bo, NULL, (void **)&msg);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amdgpu_uvd_idle_work_handler(struct work_struct *work)
|
static void amdgpu_uvd_idle_work_handler(struct work_struct *work)
|
||||||
@ -1298,10 +1336,17 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||||||
struct dma_fence *fence;
|
struct dma_fence *fence;
|
||||||
long r;
|
long r;
|
||||||
|
|
||||||
r = amdgpu_uvd_get_create_msg(ring, 1, NULL);
|
r = amdgpu_uvd_get_create_msg(ring, 1, &fence);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
r = dma_fence_wait_timeout(fence, false, timeout);
|
||||||
|
dma_fence_put(fence);
|
||||||
|
if (r == 0)
|
||||||
|
r = -ETIMEDOUT;
|
||||||
|
if (r < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence);
|
r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -68,6 +68,7 @@ struct amdgpu_uvd {
|
|||||||
/* store image width to adjust nb memory state */
|
/* store image width to adjust nb memory state */
|
||||||
unsigned decode_image_width;
|
unsigned decode_image_width;
|
||||||
uint32_t keyselect;
|
uint32_t keyselect;
|
||||||
|
struct amdgpu_bo *ib_bo;
|
||||||
};
|
};
|
||||||
|
|
||||||
int amdgpu_uvd_sw_init(struct amdgpu_device *adev);
|
int amdgpu_uvd_sw_init(struct amdgpu_device *adev);
|
||||||
|
@ -82,7 +82,6 @@ MODULE_FIRMWARE(FIRMWARE_VEGA20);
|
|||||||
|
|
||||||
static void amdgpu_vce_idle_work_handler(struct work_struct *work);
|
static void amdgpu_vce_idle_work_handler(struct work_struct *work);
|
||||||
static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||||
struct amdgpu_bo *bo,
|
|
||||||
struct dma_fence **fence);
|
struct dma_fence **fence);
|
||||||
static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||||
bool direct, struct dma_fence **fence);
|
bool direct, struct dma_fence **fence);
|
||||||
@ -314,7 +313,7 @@ int amdgpu_vce_resume(struct amdgpu_device *adev)
|
|||||||
hdr = (const struct common_firmware_header *)adev->vce.fw->data;
|
hdr = (const struct common_firmware_header *)adev->vce.fw->data;
|
||||||
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
|
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
|
||||||
|
|
||||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
memcpy_toio(cpu_addr, adev->vce.fw->data + offset,
|
memcpy_toio(cpu_addr, adev->vce.fw->data + offset,
|
||||||
adev->vce.fw->size - offset);
|
adev->vce.fw->size - offset);
|
||||||
drm_dev_exit(idx);
|
drm_dev_exit(idx);
|
||||||
@ -441,12 +440,12 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
|
|||||||
* Open up a stream for HW test
|
* Open up a stream for HW test
|
||||||
*/
|
*/
|
||||||
static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||||
struct amdgpu_bo *bo,
|
|
||||||
struct dma_fence **fence)
|
struct dma_fence **fence)
|
||||||
{
|
{
|
||||||
const unsigned ib_size_dw = 1024;
|
const unsigned ib_size_dw = 1024;
|
||||||
struct amdgpu_job *job;
|
struct amdgpu_job *job;
|
||||||
struct amdgpu_ib *ib;
|
struct amdgpu_ib *ib;
|
||||||
|
struct amdgpu_ib ib_msg;
|
||||||
struct dma_fence *f = NULL;
|
struct dma_fence *f = NULL;
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
int i, r;
|
int i, r;
|
||||||
@ -456,9 +455,17 @@ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
ib = &job->ibs[0];
|
memset(&ib_msg, 0, sizeof(ib_msg));
|
||||||
|
/* only one gpu page is needed, alloc +1 page to make addr aligned. */
|
||||||
|
r = amdgpu_ib_get(ring->adev, NULL, AMDGPU_GPU_PAGE_SIZE * 2,
|
||||||
|
AMDGPU_IB_POOL_DIRECT,
|
||||||
|
&ib_msg);
|
||||||
|
if (r)
|
||||||
|
goto err;
|
||||||
|
|
||||||
addr = amdgpu_bo_gpu_offset(bo);
|
ib = &job->ibs[0];
|
||||||
|
/* let addr point to page boundary */
|
||||||
|
addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg.gpu_addr);
|
||||||
|
|
||||||
/* stitch together an VCE create msg */
|
/* stitch together an VCE create msg */
|
||||||
ib->length_dw = 0;
|
ib->length_dw = 0;
|
||||||
@ -498,6 +505,7 @@ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||||||
ib->ptr[i] = 0x0;
|
ib->ptr[i] = 0x0;
|
||||||
|
|
||||||
r = amdgpu_job_submit_direct(job, ring, &f);
|
r = amdgpu_job_submit_direct(job, ring, &f);
|
||||||
|
amdgpu_ib_free(ring->adev, &ib_msg, f);
|
||||||
if (r)
|
if (r)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -1134,20 +1142,13 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring)
|
|||||||
int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
||||||
{
|
{
|
||||||
struct dma_fence *fence = NULL;
|
struct dma_fence *fence = NULL;
|
||||||
struct amdgpu_bo *bo = NULL;
|
|
||||||
long r;
|
long r;
|
||||||
|
|
||||||
/* skip vce ring1/2 ib test for now, since it's not reliable */
|
/* skip vce ring1/2 ib test for now, since it's not reliable */
|
||||||
if (ring != &ring->adev->vce.ring[0])
|
if (ring != &ring->adev->vce.ring[0])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = amdgpu_bo_create_reserved(ring->adev, 512, PAGE_SIZE,
|
r = amdgpu_vce_get_create_msg(ring, 1, NULL);
|
||||||
AMDGPU_GEM_DOMAIN_VRAM,
|
|
||||||
&bo, NULL, NULL);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = amdgpu_vce_get_create_msg(ring, 1, bo, NULL);
|
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -1163,7 +1164,19 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
dma_fence_put(fence);
|
dma_fence_put(fence);
|
||||||
amdgpu_bo_unreserve(bo);
|
|
||||||
amdgpu_bo_free_kernel(&bo, NULL, NULL);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum amdgpu_ring_priority_level amdgpu_vce_get_ring_prio(int ring)
|
||||||
|
{
|
||||||
|
switch(ring) {
|
||||||
|
case 0:
|
||||||
|
return AMDGPU_RING_PRIO_0;
|
||||||
|
case 1:
|
||||||
|
return AMDGPU_RING_PRIO_1;
|
||||||
|
case 2:
|
||||||
|
return AMDGPU_RING_PRIO_2;
|
||||||
|
default:
|
||||||
|
return AMDGPU_RING_PRIO_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -71,5 +71,6 @@ void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring);
|
|||||||
void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring);
|
void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring);
|
||||||
unsigned amdgpu_vce_ring_get_emit_ib_size(struct amdgpu_ring *ring);
|
unsigned amdgpu_vce_ring_get_emit_ib_size(struct amdgpu_ring *ring);
|
||||||
unsigned amdgpu_vce_ring_get_dma_frame_size(struct amdgpu_ring *ring);
|
unsigned amdgpu_vce_ring_get_dma_frame_size(struct amdgpu_ring *ring);
|
||||||
|
enum amdgpu_ring_priority_level amdgpu_vce_get_ring_prio(int ring);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -86,8 +86,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++)
|
for (i = 0; i < adev->vcn.num_vcn_inst; i++)
|
||||||
atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0);
|
atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0);
|
||||||
|
|
||||||
switch (adev->asic_type) {
|
switch (adev->ip_versions[UVD_HWIP][0]) {
|
||||||
case CHIP_RAVEN:
|
case IP_VERSION(1, 0, 0):
|
||||||
|
case IP_VERSION(1, 0, 1):
|
||||||
if (adev->apu_flags & AMD_APU_IS_RAVEN2)
|
if (adev->apu_flags & AMD_APU_IS_RAVEN2)
|
||||||
fw_name = FIRMWARE_RAVEN2;
|
fw_name = FIRMWARE_RAVEN2;
|
||||||
else if (adev->apu_flags & AMD_APU_IS_PICASSO)
|
else if (adev->apu_flags & AMD_APU_IS_PICASSO)
|
||||||
@ -95,13 +96,13 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||||||
else
|
else
|
||||||
fw_name = FIRMWARE_RAVEN;
|
fw_name = FIRMWARE_RAVEN;
|
||||||
break;
|
break;
|
||||||
case CHIP_ARCTURUS:
|
case IP_VERSION(2, 5, 0):
|
||||||
fw_name = FIRMWARE_ARCTURUS;
|
fw_name = FIRMWARE_ARCTURUS;
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
adev->vcn.indirect_sram = true;
|
adev->vcn.indirect_sram = true;
|
||||||
break;
|
break;
|
||||||
case CHIP_RENOIR:
|
case IP_VERSION(2, 2, 0):
|
||||||
if (adev->apu_flags & AMD_APU_IS_RENOIR)
|
if (adev->apu_flags & AMD_APU_IS_RENOIR)
|
||||||
fw_name = FIRMWARE_RENOIR;
|
fw_name = FIRMWARE_RENOIR;
|
||||||
else
|
else
|
||||||
@ -111,58 +112,52 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
adev->vcn.indirect_sram = true;
|
adev->vcn.indirect_sram = true;
|
||||||
break;
|
break;
|
||||||
case CHIP_ALDEBARAN:
|
case IP_VERSION(2, 6, 0):
|
||||||
fw_name = FIRMWARE_ALDEBARAN;
|
fw_name = FIRMWARE_ALDEBARAN;
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
adev->vcn.indirect_sram = true;
|
adev->vcn.indirect_sram = true;
|
||||||
break;
|
break;
|
||||||
case CHIP_NAVI10:
|
case IP_VERSION(2, 0, 0):
|
||||||
fw_name = FIRMWARE_NAVI10;
|
fw_name = FIRMWARE_NAVI10;
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
adev->vcn.indirect_sram = true;
|
adev->vcn.indirect_sram = true;
|
||||||
break;
|
break;
|
||||||
case CHIP_NAVI14:
|
case IP_VERSION(2, 0, 2):
|
||||||
fw_name = FIRMWARE_NAVI14;
|
if (adev->asic_type == CHIP_NAVI12)
|
||||||
|
fw_name = FIRMWARE_NAVI12;
|
||||||
|
else
|
||||||
|
fw_name = FIRMWARE_NAVI14;
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
adev->vcn.indirect_sram = true;
|
adev->vcn.indirect_sram = true;
|
||||||
break;
|
break;
|
||||||
case CHIP_NAVI12:
|
case IP_VERSION(3, 0, 0):
|
||||||
fw_name = FIRMWARE_NAVI12;
|
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0))
|
||||||
|
fw_name = FIRMWARE_SIENNA_CICHLID;
|
||||||
|
else
|
||||||
|
fw_name = FIRMWARE_NAVY_FLOUNDER;
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
adev->vcn.indirect_sram = true;
|
adev->vcn.indirect_sram = true;
|
||||||
break;
|
break;
|
||||||
case CHIP_SIENNA_CICHLID:
|
case IP_VERSION(3, 0, 2):
|
||||||
fw_name = FIRMWARE_SIENNA_CICHLID;
|
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
|
||||||
adev->vcn.indirect_sram = true;
|
|
||||||
break;
|
|
||||||
case CHIP_NAVY_FLOUNDER:
|
|
||||||
fw_name = FIRMWARE_NAVY_FLOUNDER;
|
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
|
||||||
adev->vcn.indirect_sram = true;
|
|
||||||
break;
|
|
||||||
case CHIP_VANGOGH:
|
|
||||||
fw_name = FIRMWARE_VANGOGH;
|
fw_name = FIRMWARE_VANGOGH;
|
||||||
break;
|
break;
|
||||||
case CHIP_DIMGREY_CAVEFISH:
|
case IP_VERSION(3, 0, 16):
|
||||||
fw_name = FIRMWARE_DIMGREY_CAVEFISH;
|
fw_name = FIRMWARE_DIMGREY_CAVEFISH;
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
adev->vcn.indirect_sram = true;
|
adev->vcn.indirect_sram = true;
|
||||||
break;
|
break;
|
||||||
case CHIP_BEIGE_GOBY:
|
case IP_VERSION(3, 0, 33):
|
||||||
fw_name = FIRMWARE_BEIGE_GOBY;
|
fw_name = FIRMWARE_BEIGE_GOBY;
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
adev->vcn.indirect_sram = true;
|
adev->vcn.indirect_sram = true;
|
||||||
break;
|
break;
|
||||||
case CHIP_YELLOW_CARP:
|
case IP_VERSION(3, 1, 1):
|
||||||
fw_name = FIRMWARE_YELLOW_CARP;
|
fw_name = FIRMWARE_YELLOW_CARP;
|
||||||
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
|
||||||
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
|
||||||
@ -330,7 +325,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
|
|||||||
if (!adev->vcn.inst[i].saved_bo)
|
if (!adev->vcn.inst[i].saved_bo)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
|
memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
|
||||||
drm_dev_exit(idx);
|
drm_dev_exit(idx);
|
||||||
}
|
}
|
||||||
@ -354,7 +349,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
|
|||||||
ptr = adev->vcn.inst[i].cpu_addr;
|
ptr = adev->vcn.inst[i].cpu_addr;
|
||||||
|
|
||||||
if (adev->vcn.inst[i].saved_bo != NULL) {
|
if (adev->vcn.inst[i].saved_bo != NULL) {
|
||||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
|
memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
|
||||||
drm_dev_exit(idx);
|
drm_dev_exit(idx);
|
||||||
}
|
}
|
||||||
@ -367,7 +362,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
|
|||||||
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||||
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
|
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
|
||||||
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
|
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
|
||||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
if (drm_dev_enter(adev_to_drm(adev), &idx)) {
|
||||||
memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
|
memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
|
||||||
le32_to_cpu(hdr->ucode_size_bytes));
|
le32_to_cpu(hdr->ucode_size_bytes));
|
||||||
drm_dev_exit(idx);
|
drm_dev_exit(idx);
|
||||||
@ -541,15 +536,14 @@ int amdgpu_vcn_dec_sw_ring_test_ring(struct amdgpu_ring *ring)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
|
static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
|
||||||
struct amdgpu_bo *bo,
|
struct amdgpu_ib *ib_msg,
|
||||||
struct dma_fence **fence)
|
struct dma_fence **fence)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = ring->adev;
|
struct amdgpu_device *adev = ring->adev;
|
||||||
struct dma_fence *f = NULL;
|
struct dma_fence *f = NULL;
|
||||||
struct amdgpu_job *job;
|
struct amdgpu_job *job;
|
||||||
struct amdgpu_ib *ib;
|
struct amdgpu_ib *ib;
|
||||||
uint64_t addr;
|
uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
|
||||||
void *msg = NULL;
|
|
||||||
int i, r;
|
int i, r;
|
||||||
|
|
||||||
r = amdgpu_job_alloc_with_ib(adev, 64,
|
r = amdgpu_job_alloc_with_ib(adev, 64,
|
||||||
@ -558,8 +552,6 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ib = &job->ibs[0];
|
ib = &job->ibs[0];
|
||||||
addr = amdgpu_bo_gpu_offset(bo);
|
|
||||||
msg = amdgpu_bo_kptr(bo);
|
|
||||||
ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);
|
ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);
|
||||||
ib->ptr[1] = addr;
|
ib->ptr[1] = addr;
|
||||||
ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0);
|
ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0);
|
||||||
@ -576,9 +568,7 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
|
|||||||
if (r)
|
if (r)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
amdgpu_bo_fence(bo, f, false);
|
amdgpu_ib_free(adev, ib_msg, f);
|
||||||
amdgpu_bo_unreserve(bo);
|
|
||||||
amdgpu_bo_free_kernel(&bo, NULL, (void **)&msg);
|
|
||||||
|
|
||||||
if (fence)
|
if (fence)
|
||||||
*fence = dma_fence_get(f);
|
*fence = dma_fence_get(f);
|
||||||
@ -588,27 +578,26 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
|
|||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
amdgpu_job_free(job);
|
amdgpu_job_free(job);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
amdgpu_bo_unreserve(bo);
|
amdgpu_ib_free(adev, ib_msg, f);
|
||||||
amdgpu_bo_free_kernel(&bo, NULL, (void **)&msg);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||||
struct amdgpu_bo **bo)
|
struct amdgpu_ib *ib)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = ring->adev;
|
struct amdgpu_device *adev = ring->adev;
|
||||||
uint32_t *msg;
|
uint32_t *msg;
|
||||||
int r, i;
|
int r, i;
|
||||||
|
|
||||||
*bo = NULL;
|
memset(ib, 0, sizeof(*ib));
|
||||||
r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
|
r = amdgpu_ib_get(adev, NULL, AMDGPU_GPU_PAGE_SIZE * 2,
|
||||||
AMDGPU_GEM_DOMAIN_VRAM,
|
AMDGPU_IB_POOL_DIRECT,
|
||||||
bo, NULL, (void **)&msg);
|
ib);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
msg = (uint32_t *)AMDGPU_GPU_PAGE_ALIGN((unsigned long)ib->ptr);
|
||||||
msg[0] = cpu_to_le32(0x00000028);
|
msg[0] = cpu_to_le32(0x00000028);
|
||||||
msg[1] = cpu_to_le32(0x00000038);
|
msg[1] = cpu_to_le32(0x00000038);
|
||||||
msg[2] = cpu_to_le32(0x00000001);
|
msg[2] = cpu_to_le32(0x00000001);
|
||||||
@ -630,19 +619,20 @@ static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||||
struct amdgpu_bo **bo)
|
struct amdgpu_ib *ib)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = ring->adev;
|
struct amdgpu_device *adev = ring->adev;
|
||||||
uint32_t *msg;
|
uint32_t *msg;
|
||||||
int r, i;
|
int r, i;
|
||||||
|
|
||||||
*bo = NULL;
|
memset(ib, 0, sizeof(*ib));
|
||||||
r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
|
r = amdgpu_ib_get(adev, NULL, AMDGPU_GPU_PAGE_SIZE * 2,
|
||||||
AMDGPU_GEM_DOMAIN_VRAM,
|
AMDGPU_IB_POOL_DIRECT,
|
||||||
bo, NULL, (void **)&msg);
|
ib);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
msg = (uint32_t *)AMDGPU_GPU_PAGE_ALIGN((unsigned long)ib->ptr);
|
||||||
msg[0] = cpu_to_le32(0x00000028);
|
msg[0] = cpu_to_le32(0x00000028);
|
||||||
msg[1] = cpu_to_le32(0x00000018);
|
msg[1] = cpu_to_le32(0x00000018);
|
||||||
msg[2] = cpu_to_le32(0x00000000);
|
msg[2] = cpu_to_le32(0x00000000);
|
||||||
@ -658,21 +648,21 @@ static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
|
|||||||
int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
||||||
{
|
{
|
||||||
struct dma_fence *fence = NULL;
|
struct dma_fence *fence = NULL;
|
||||||
struct amdgpu_bo *bo;
|
struct amdgpu_ib ib;
|
||||||
long r;
|
long r;
|
||||||
|
|
||||||
r = amdgpu_vcn_dec_get_create_msg(ring, 1, &bo);
|
r = amdgpu_vcn_dec_get_create_msg(ring, 1, &ib);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
r = amdgpu_vcn_dec_send_msg(ring, bo, NULL);
|
r = amdgpu_vcn_dec_send_msg(ring, &ib, NULL);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &bo);
|
r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &ib);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
r = amdgpu_vcn_dec_send_msg(ring, bo, &fence);
|
r = amdgpu_vcn_dec_send_msg(ring, &ib, &fence);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -688,8 +678,8 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
||||||
struct amdgpu_bo *bo,
|
struct amdgpu_ib *ib_msg,
|
||||||
struct dma_fence **fence)
|
struct dma_fence **fence)
|
||||||
{
|
{
|
||||||
struct amdgpu_vcn_decode_buffer *decode_buffer = NULL;
|
struct amdgpu_vcn_decode_buffer *decode_buffer = NULL;
|
||||||
const unsigned int ib_size_dw = 64;
|
const unsigned int ib_size_dw = 64;
|
||||||
@ -697,7 +687,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
|||||||
struct dma_fence *f = NULL;
|
struct dma_fence *f = NULL;
|
||||||
struct amdgpu_job *job;
|
struct amdgpu_job *job;
|
||||||
struct amdgpu_ib *ib;
|
struct amdgpu_ib *ib;
|
||||||
uint64_t addr;
|
uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
|
||||||
int i, r;
|
int i, r;
|
||||||
|
|
||||||
r = amdgpu_job_alloc_with_ib(adev, ib_size_dw * 4,
|
r = amdgpu_job_alloc_with_ib(adev, ib_size_dw * 4,
|
||||||
@ -706,7 +696,6 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ib = &job->ibs[0];
|
ib = &job->ibs[0];
|
||||||
addr = amdgpu_bo_gpu_offset(bo);
|
|
||||||
ib->length_dw = 0;
|
ib->length_dw = 0;
|
||||||
|
|
||||||
ib->ptr[ib->length_dw++] = sizeof(struct amdgpu_vcn_decode_buffer) + 8;
|
ib->ptr[ib->length_dw++] = sizeof(struct amdgpu_vcn_decode_buffer) + 8;
|
||||||
@ -726,9 +715,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
|||||||
if (r)
|
if (r)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
amdgpu_bo_fence(bo, f, false);
|
amdgpu_ib_free(adev, ib_msg, f);
|
||||||
amdgpu_bo_unreserve(bo);
|
|
||||||
amdgpu_bo_unref(&bo);
|
|
||||||
|
|
||||||
if (fence)
|
if (fence)
|
||||||
*fence = dma_fence_get(f);
|
*fence = dma_fence_get(f);
|
||||||
@ -738,31 +725,29 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring,
|
|||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
amdgpu_job_free(job);
|
amdgpu_job_free(job);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
amdgpu_bo_unreserve(bo);
|
amdgpu_ib_free(adev, ib_msg, f);
|
||||||
amdgpu_bo_unref(&bo);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int amdgpu_vcn_dec_sw_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
int amdgpu_vcn_dec_sw_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
||||||
{
|
{
|
||||||
struct dma_fence *fence = NULL;
|
struct dma_fence *fence = NULL;
|
||||||
struct amdgpu_bo *bo;
|
struct amdgpu_ib ib;
|
||||||
long r;
|
long r;
|
||||||
|
|
||||||
r = amdgpu_vcn_dec_get_create_msg(ring, 1, &bo);
|
r = amdgpu_vcn_dec_get_create_msg(ring, 1, &ib);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
r = amdgpu_vcn_dec_sw_send_msg(ring, bo, NULL);
|
r = amdgpu_vcn_dec_sw_send_msg(ring, &ib, NULL);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &bo);
|
r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &ib);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
r = amdgpu_vcn_dec_sw_send_msg(ring, bo, &fence);
|
r = amdgpu_vcn_dec_sw_send_msg(ring, &ib, &fence);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -809,7 +794,7 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||||
struct amdgpu_bo *bo,
|
struct amdgpu_ib *ib_msg,
|
||||||
struct dma_fence **fence)
|
struct dma_fence **fence)
|
||||||
{
|
{
|
||||||
const unsigned ib_size_dw = 16;
|
const unsigned ib_size_dw = 16;
|
||||||
@ -825,7 +810,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
ib = &job->ibs[0];
|
ib = &job->ibs[0];
|
||||||
addr = amdgpu_bo_gpu_offset(bo);
|
addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
|
||||||
|
|
||||||
ib->length_dw = 0;
|
ib->length_dw = 0;
|
||||||
ib->ptr[ib->length_dw++] = 0x00000018;
|
ib->ptr[ib->length_dw++] = 0x00000018;
|
||||||
@ -863,7 +848,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
||||||
struct amdgpu_bo *bo,
|
struct amdgpu_ib *ib_msg,
|
||||||
struct dma_fence **fence)
|
struct dma_fence **fence)
|
||||||
{
|
{
|
||||||
const unsigned ib_size_dw = 16;
|
const unsigned ib_size_dw = 16;
|
||||||
@ -879,7 +864,7 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
ib = &job->ibs[0];
|
ib = &job->ibs[0];
|
||||||
addr = amdgpu_bo_gpu_offset(bo);
|
addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
|
||||||
|
|
||||||
ib->length_dw = 0;
|
ib->length_dw = 0;
|
||||||
ib->ptr[ib->length_dw++] = 0x00000018;
|
ib->ptr[ib->length_dw++] = 0x00000018;
|
||||||
@ -918,21 +903,23 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
|
|||||||
|
|
||||||
int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
||||||
{
|
{
|
||||||
|
struct amdgpu_device *adev = ring->adev;
|
||||||
struct dma_fence *fence = NULL;
|
struct dma_fence *fence = NULL;
|
||||||
struct amdgpu_bo *bo = NULL;
|
struct amdgpu_ib ib;
|
||||||
long r;
|
long r;
|
||||||
|
|
||||||
r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,
|
memset(&ib, 0, sizeof(ib));
|
||||||
AMDGPU_GEM_DOMAIN_VRAM,
|
r = amdgpu_ib_get(adev, NULL, (128 << 10) + AMDGPU_GPU_PAGE_SIZE,
|
||||||
&bo, NULL, NULL);
|
AMDGPU_IB_POOL_DIRECT,
|
||||||
|
&ib);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL);
|
r = amdgpu_vcn_enc_get_create_msg(ring, 1, &ib, NULL);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence);
|
r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &ib, &fence);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -943,9 +930,49 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
amdgpu_ib_free(adev, &ib, fence);
|
||||||
dma_fence_put(fence);
|
dma_fence_put(fence);
|
||||||
amdgpu_bo_unreserve(bo);
|
|
||||||
amdgpu_bo_free_kernel(&bo, NULL, NULL);
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring)
|
||||||
|
{
|
||||||
|
switch(ring) {
|
||||||
|
case 0:
|
||||||
|
return AMDGPU_RING_PRIO_0;
|
||||||
|
case 1:
|
||||||
|
return AMDGPU_RING_PRIO_1;
|
||||||
|
case 2:
|
||||||
|
return AMDGPU_RING_PRIO_2;
|
||||||
|
default:
|
||||||
|
return AMDGPU_RING_PRIO_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned int idx;
|
||||||
|
|
||||||
|
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||||
|
const struct common_firmware_header *hdr;
|
||||||
|
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
|
||||||
|
|
||||||
|
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||||
|
if (adev->vcn.harvest_config & (1 << i))
|
||||||
|
continue;
|
||||||
|
/* currently only support 2 FW instances */
|
||||||
|
if (i >= 2) {
|
||||||
|
dev_info(adev->dev, "More then 2 VCN FW instances!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idx = AMDGPU_UCODE_ID_VCN + i;
|
||||||
|
adev->firmware.ucode[idx].ucode_id = idx;
|
||||||
|
adev->firmware.ucode[idx].fw = adev->vcn.fw;
|
||||||
|
adev->firmware.fw_size +=
|
||||||
|
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||||
|
}
|
||||||
|
dev_info(adev->dev, "Will use PSP to load VCN firmware\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -308,4 +308,8 @@ int amdgpu_vcn_dec_sw_ring_test_ib(struct amdgpu_ring *ring, long timeout);
|
|||||||
int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring);
|
int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring);
|
||||||
int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout);
|
int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout);
|
||||||
|
|
||||||
|
enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring);
|
||||||
|
|
||||||
|
void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -532,9 +532,12 @@ static void amdgpu_virt_populate_vf2pf_ucode_info(struct amdgpu_device *adev)
|
|||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC, adev->gfx.mec_fw_version);
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC, adev->gfx.mec_fw_version);
|
||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC2, adev->gfx.mec2_fw_version);
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC2, adev->gfx.mec2_fw_version);
|
||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SOS, adev->psp.sos.fw_version);
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SOS, adev->psp.sos.fw_version);
|
||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_ASD, adev->psp.asd.fw_version);
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_ASD,
|
||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_RAS, adev->psp.ras.feature_version);
|
adev->psp.asd_context.bin_desc.fw_version);
|
||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_XGMI, adev->psp.xgmi.feature_version);
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_RAS,
|
||||||
|
adev->psp.ras_context.context.bin_desc.fw_version);
|
||||||
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_XGMI,
|
||||||
|
adev->psp.xgmi_context.context.bin_desc.fw_version);
|
||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SMC, adev->pm.fw_version);
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SMC, adev->pm.fw_version);
|
||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SDMA, adev->sdma.instance[0].fw_version);
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SDMA, adev->sdma.instance[0].fw_version);
|
||||||
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SDMA2, adev->sdma.instance[1].fw_version);
|
POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SDMA2, adev->sdma.instance[1].fw_version);
|
||||||
@ -581,6 +584,7 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev)
|
|||||||
vf2pf_info->encode_usage = 0;
|
vf2pf_info->encode_usage = 0;
|
||||||
vf2pf_info->decode_usage = 0;
|
vf2pf_info->decode_usage = 0;
|
||||||
|
|
||||||
|
vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr;
|
||||||
vf2pf_info->checksum =
|
vf2pf_info->checksum =
|
||||||
amd_sriov_msg_checksum(
|
amd_sriov_msg_checksum(
|
||||||
vf2pf_info, vf2pf_info->header.size, 0, 0);
|
vf2pf_info, vf2pf_info->header.size, 0, 0);
|
||||||
|
@ -800,7 +800,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
|||||||
struct amdgpu_bo *bo = &vmbo->bo;
|
struct amdgpu_bo *bo = &vmbo->bo;
|
||||||
unsigned entries, ats_entries;
|
unsigned entries, ats_entries;
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
int r;
|
int r, idx;
|
||||||
|
|
||||||
/* Figure out our place in the hierarchy */
|
/* Figure out our place in the hierarchy */
|
||||||
if (ancestor->parent) {
|
if (ancestor->parent) {
|
||||||
@ -845,9 +845,12 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
r = vm->update_funcs->map_table(vmbo);
|
r = vm->update_funcs->map_table(vmbo);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
goto exit;
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.adev = adev;
|
params.adev = adev;
|
||||||
@ -856,7 +859,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
|||||||
|
|
||||||
r = vm->update_funcs->prepare(¶ms, NULL, AMDGPU_SYNC_EXPLICIT);
|
r = vm->update_funcs->prepare(¶ms, NULL, AMDGPU_SYNC_EXPLICIT);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
goto exit;
|
||||||
|
|
||||||
addr = 0;
|
addr = 0;
|
||||||
if (ats_entries) {
|
if (ats_entries) {
|
||||||
@ -872,7 +875,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
|||||||
r = vm->update_funcs->update(¶ms, vmbo, addr, 0, ats_entries,
|
r = vm->update_funcs->update(¶ms, vmbo, addr, 0, ats_entries,
|
||||||
value, flags);
|
value, flags);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
goto exit;
|
||||||
|
|
||||||
addr += ats_entries * 8;
|
addr += ats_entries * 8;
|
||||||
}
|
}
|
||||||
@ -895,10 +898,13 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
|
|||||||
r = vm->update_funcs->update(¶ms, vmbo, addr, 0, entries,
|
r = vm->update_funcs->update(¶ms, vmbo, addr, 0, entries,
|
||||||
value, flags);
|
value, flags);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vm->update_funcs->commit(¶ms, NULL);
|
r = vm->update_funcs->commit(¶ms, NULL);
|
||||||
|
exit:
|
||||||
|
drm_dev_exit(idx);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1384,11 +1390,14 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
|||||||
struct amdgpu_vm *vm, bool immediate)
|
struct amdgpu_vm *vm, bool immediate)
|
||||||
{
|
{
|
||||||
struct amdgpu_vm_update_params params;
|
struct amdgpu_vm_update_params params;
|
||||||
int r;
|
int r, idx;
|
||||||
|
|
||||||
if (list_empty(&vm->relocated))
|
if (list_empty(&vm->relocated))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
params.adev = adev;
|
params.adev = adev;
|
||||||
params.vm = vm;
|
params.vm = vm;
|
||||||
@ -1396,7 +1405,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
|||||||
|
|
||||||
r = vm->update_funcs->prepare(¶ms, NULL, AMDGPU_SYNC_EXPLICIT);
|
r = vm->update_funcs->prepare(¶ms, NULL, AMDGPU_SYNC_EXPLICIT);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
goto exit;
|
||||||
|
|
||||||
while (!list_empty(&vm->relocated)) {
|
while (!list_empty(&vm->relocated)) {
|
||||||
struct amdgpu_vm_bo_base *entry;
|
struct amdgpu_vm_bo_base *entry;
|
||||||
@ -1414,10 +1423,13 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
|
|||||||
r = vm->update_funcs->commit(¶ms, &vm->last_update);
|
r = vm->update_funcs->commit(¶ms, &vm->last_update);
|
||||||
if (r)
|
if (r)
|
||||||
goto error;
|
goto error;
|
||||||
|
drm_dev_exit(idx);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
amdgpu_vm_invalidate_pds(adev, vm);
|
amdgpu_vm_invalidate_pds(adev, vm);
|
||||||
|
exit:
|
||||||
|
drm_dev_exit(idx);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1706,7 +1718,7 @@ int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||||||
enum amdgpu_sync_mode sync_mode;
|
enum amdgpu_sync_mode sync_mode;
|
||||||
int r, idx;
|
int r, idx;
|
||||||
|
|
||||||
if (!drm_dev_enter(&adev->ddev, &idx))
|
if (!drm_dev_enter(adev_to_drm(adev), &idx))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
|
@ -204,8 +204,10 @@ struct amd_sriov_msg_pf2vf_info {
|
|||||||
} mm_bw_management[AMD_SRIOV_MSG_RESERVE_VCN_INST];
|
} mm_bw_management[AMD_SRIOV_MSG_RESERVE_VCN_INST];
|
||||||
/* UUID info */
|
/* UUID info */
|
||||||
struct amd_sriov_msg_uuid_info uuid_info;
|
struct amd_sriov_msg_uuid_info uuid_info;
|
||||||
|
/* pcie atomic Ops info */
|
||||||
|
uint32_t pcie_atomic_ops_enabled_flags;
|
||||||
/* reserved */
|
/* reserved */
|
||||||
uint32_t reserved[256 - 47];
|
uint32_t reserved[256 - 48];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amd_sriov_msg_vf2pf_info_header {
|
struct amd_sriov_msg_vf2pf_info_header {
|
||||||
@ -259,9 +261,10 @@ struct amd_sriov_msg_vf2pf_info {
|
|||||||
uint8_t id;
|
uint8_t id;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
} ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE];
|
} ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE];
|
||||||
|
uint64_t dummy_page_addr;
|
||||||
|
|
||||||
/* reserved */
|
/* reserved */
|
||||||
uint32_t reserved[256-68];
|
uint32_t reserved[256-70];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* mailbox message send from guest to host */
|
/* mailbox message send from guest to host */
|
||||||
|
@ -77,10 +77,9 @@ int athub_v2_0_set_clockgating(struct amdgpu_device *adev,
|
|||||||
if (amdgpu_sriov_vf(adev))
|
if (amdgpu_sriov_vf(adev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (adev->asic_type) {
|
switch (adev->ip_versions[ATHUB_HWIP][0]) {
|
||||||
case CHIP_NAVI10:
|
case IP_VERSION(2, 0, 0):
|
||||||
case CHIP_NAVI14:
|
case IP_VERSION(2, 0, 2):
|
||||||
case CHIP_NAVI12:
|
|
||||||
athub_v2_0_update_medium_grain_clock_gating(adev,
|
athub_v2_0_update_medium_grain_clock_gating(adev,
|
||||||
state == AMD_CG_STATE_GATE);
|
state == AMD_CG_STATE_GATE);
|
||||||
athub_v2_0_update_medium_grain_light_sleep(adev,
|
athub_v2_0_update_medium_grain_light_sleep(adev,
|
||||||
|
@ -70,11 +70,10 @@ int athub_v2_1_set_clockgating(struct amdgpu_device *adev,
|
|||||||
if (amdgpu_sriov_vf(adev))
|
if (amdgpu_sriov_vf(adev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (adev->asic_type) {
|
switch (adev->ip_versions[ATHUB_HWIP][0]) {
|
||||||
case CHIP_SIENNA_CICHLID:
|
case IP_VERSION(2, 1, 0):
|
||||||
case CHIP_NAVY_FLOUNDER:
|
case IP_VERSION(2, 1, 1):
|
||||||
case CHIP_DIMGREY_CAVEFISH:
|
case IP_VERSION(2, 1, 2):
|
||||||
case CHIP_BEIGE_GOBY:
|
|
||||||
athub_v2_1_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE);
|
athub_v2_1_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE);
|
||||||
athub_v2_1_update_medium_grain_light_sleep(adev, state == AMD_CG_STATE_GATE);
|
athub_v2_1_update_medium_grain_light_sleep(adev, state == AMD_CG_STATE_GATE);
|
||||||
break;
|
break;
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020 Advanced Micro Devices, Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "amdgpu.h"
|
|
||||||
#include "nv.h"
|
|
||||||
|
|
||||||
#include "soc15_common.h"
|
|
||||||
#include "soc15_hw_ip.h"
|
|
||||||
#include "beige_goby_ip_offset.h"
|
|
||||||
|
|
||||||
int beige_goby_reg_base_init(struct amdgpu_device *adev)
|
|
||||||
{
|
|
||||||
/* HW has more IP blocks, only initialize the block needed by driver */
|
|
||||||
uint32_t i;
|
|
||||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
|
||||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
|
||||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
|
||||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
|
||||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
|
||||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
|
||||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
|
||||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
|
||||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(VCN0_BASE.instance[i]));
|
|
||||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
|
||||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DCN_BASE.instance[i]));
|
|
||||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
|
||||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
|
||||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
|
||||||
adev->reg_offset[SDMA2_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
|
||||||
adev->reg_offset[SDMA3_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
|
||||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
|
||||||
adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include "amdgpu.h"
|
|
||||||
#include "nv.h"
|
|
||||||
|
|
||||||
#include "soc15_common.h"
|
|
||||||
#include "soc15_hw_ip.h"
|
|
||||||
#include "cyan_skillfish_ip_offset.h"
|
|
||||||
|
|
||||||
int cyan_skillfish_reg_base_init(struct amdgpu_device *adev)
|
|
||||||
{
|
|
||||||
/* HW has more IP blocks, only initialized the blocke needed by driver */
|
|
||||||
uint32_t i;
|
|
||||||
for (i = 0 ; i < MAX_INSTANCE ; ++i) {
|
|
||||||
adev->reg_offset[GC_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
|
||||||
adev->reg_offset[HDP_HWIP][i] = (uint32_t *)(&(HDP_BASE.instance[i]));
|
|
||||||
adev->reg_offset[MMHUB_HWIP][i] = (uint32_t *)(&(MMHUB_BASE.instance[i]));
|
|
||||||
adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
|
|
||||||
adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
|
|
||||||
adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
|
|
||||||
adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
|
|
||||||
adev->reg_offset[VCN_HWIP][i] = (uint32_t *)(&(UVD0_BASE.instance[i]));
|
|
||||||
adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
|
|
||||||
adev->reg_offset[DCE_HWIP][i] = (uint32_t *)(&(DMU_BASE.instance[i]));
|
|
||||||
adev->reg_offset[OSSSYS_HWIP][i] = (uint32_t *)(&(OSSSYS_BASE.instance[i]));
|
|
||||||
adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
|
||||||
adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(GC_BASE.instance[i]));
|
|
||||||
adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user