mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
drm for 6.16-rc1
new drivers: - bring in the asahi uapi header standalone - nova-drm: stub driver rust dependencies (for nova-core): - auxiliary - bus abstractions - driver registration - sample driver - devres changes from driver-core - revocable changes core: - add Apple fourcc modifiers - add virtio capset definitions - extend EXPORT_SYNC_FILE for timeline syncobjs - convert to devm_platform_ioremap_resource - refactor shmem helper page pinning - DP powerup/down link helpers - remove disgusting turds - extended %p4cc in vsprintf.c to support fourcc prints - change vsprintf %p4cn to %p4chR, remove %p4cn - Add drm_file_err function - IN_FORMATS_ASYNC property - move sitronix from tiny to their own subdir rust: - add drm core infrastructure rust abstractions (device/driver, ioctl, file, gem) dma-buf: - adjust sg handling to not cache map on attach - allow setting dma-device for import - Add a helper to sort and deduplicate dma_fence arrays docs: - updated drm scheduler docs - fbdev todo update - fb rendering - actual brightness ttm: - fix delayed destroy resv object bridge: - add kunit tests - convert tc358775 to atomic - convert drivers to devm_drm_bridge_alloc - convert rk3066_hdmi to bridge driver scheduler: - add kunit tests panel: - refcount panels to improve lifetime handling - Powertip PH128800T004-ZZA01 - NLT NL13676BC25-03F, Tianma TM070JDHG34-00 - Himax HX8279/HX8279-D DDIC - Visionox G2647FB105 - Sitronix ST7571 - ZOTAC rotation quirk vkms: - allow attaching more displays i915: - xe3lpd display updates - vrr refactor - intel_display struct conversions - xe2hpd memory type identification - add link rate/count to i915_display_info - cleanup VGA plane handling - refactor HDCP GSC - fix SLPC wait boosting reference counting - add 20ms delay to engine reset - fix fence release on early probe errors xe: - SRIOV updates - BMG PCI ID update - support separate firmware for each GT - SVM fix, prelim SVM multi-device work - export fan speed - temp disable d3cold on BMG - backup VRAM in PM notifier instead of suspend/freeze - update xe_ttm_access_memory to use GPU for non-visible access - fix guc_info debugfs for VFs - use copy_from_user instead of __copy_from_user - append PCIe gen5 limitations to xe_firmware document amdgpu: - DSC cleanup - DC Scaling updates - Fused I2C-over-AUX updates - DMUB updates - Use drm_file_err in amdgpu - Enforce isolation updates - Use new dma_fence helpers - USERQ fixes - Documentation updates - SR-IOV updates - RAS updates - PSP 12 cleanups - GC 9.5 updates - SMU 13.x updates - VCN / JPEG SR-IOV updates amdkfd: - Update error messages for SDMA - Userptr updates - XNACK fixes radeon: - CIK doorbell cleanup nouveau: - add support for NVIDIA r570 GSP firmware - enable Hopper/Blackwell support nova-core: - fix task list - register definition infrastructure - move firmware into own rust module - register auxiliary device for nova-drm nova-drm: - initial driver skeleton msm: - GPU: - ACD (adaptive clock distribution) for X1-85 - drop fictional address_space_size - improve GMU HFI response time out robustness - fix crash when throttling during boot - DPU: - use single CTL path for flushing on DPU 5.x+ - improve SSPP allocation code for better sharing - Enabled SmartDMA on SM8150, SC8180X, SC8280XP, SM8550 - Added SAR2130P support - Disabled DSC support on MSM8937, MSM8917, MSM8953, SDM660 - DP: - switch to new audio helpers - better LTTPR handling - DSI: - Added support for SA8775P - Added SAR2130P support - HDMI: - Switched to use new helpers for ACR data - Fixed old standing issue of HPD not working in some cases amdxdna: - add dma-buf support - allow empty command submits renesas: - add dma-buf support - add zpos, alpha, blend support panthor: - fail properly for NO_MMAP bos - add SET_LABEL ioctl - debugfs BO dumping support imagination: - update DT bindings - support TI AM68 GPU hibmc: - improve interrupt handling and HPD support virtio: - add panic handler support rockchip: - add RK3588 support - add DP AUX bus panel support ivpu: - add heartbeat based hangcheck mediatek: - prepares support for MT8195/99 HDMIv2/DDCv2 anx7625: - improve HPD tegra: - speed up firmware loading -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmg2aVAACgkQDHTzWXnE hr6DjhAApr2fZjugU3EmpsARdcIWgEd+X65R97ef7RlUGqBKm2joSwZGOhH0oBsG 9WyO92Qzu6XMe8OibKqY4D2hir9UPz5v+uEWe3q9CzZGbNyAwyVRjVkaKpnI9upv 1dmHFI7HgPu6qbz6RfPIfgALBLXvVXMaQ4+ZgN/cLtZFa+OLAV5ByqWsRPPXZFb0 F/pQGQ4ursglfA+LH3SVPfnTN53lu93IlM5/Os9OQQGj+44w94zQ6DCm7CY1AugH n+RM/0Yv7WaoF1ByeOtq4FcrmLRrd+ozsvITbRZqhOx7zS/mhP8LRzAwgKWOYzSh puKunyQiSdHR7FSqSi8uyY3YumcLWNa/17LMKoTf+KqweJbKGE7RVBuFBn6WUdPb AYHZrSB4USAeyahdrrsU+q7ltu5urs5ckpbXsRurMiaUz/BLim1PIm3N5FDLPY7B PD1n1FcMUv3CmJT5Y+aNIQgmf1/dETESRTSAgSoOo3gNp6jdRCYqSuWIBsppibWT 26+tyz0/FGhE50QviHzg0Sv+jd/g93fN6snNlV8wNFMviq3bC69Toa+y3qJ5e7UC /42R7nCWdkCZJfr6E67rOaahe9TDV/LXLqPErwptOkdK8sMchaIgF+deybgTtTi/ zGRBfjLvb5ocYBmPbeGX4mtXNRpyZ3o9I0QUyGUO4zMwFXmFwn0= =jpVr -----END PGP SIGNATURE----- Merge tag 'drm-next-2025-05-28' of https://gitlab.freedesktop.org/drm/kernel Pull drm updates from Dave Airlie: "As part of building up nova-core/nova-drm pieces we've brought in some rust abstractions through this tree, aux bus being the main one, with devres changes also in the driver-core tree. Along with the drm core abstractions and enough nova-core/nova-drm to use them. This is still all stub work under construction, to build the nova driver upstream. The other big NVIDIA related one is nouveau adds support for Hopper/Blackwell GPUs, this required a new GSP firmware update to 570.144, and a bunch of rework in order to support multiple fw interfaces. There is also the introduction of an asahi uapi header file as a precursor to getting the real driver in later, but to unblock userspace mesa packages while the driver is trapped behind rust enablement. Otherwise it's the usual mixture of stuff all over, amdgpu, i915/xe, and msm being the main ones, and some changes to vsprintf. new drivers: - bring in the asahi uapi header standalone - nova-drm: stub driver rust dependencies (for nova-core): - auxiliary - bus abstractions - driver registration - sample driver - devres changes from driver-core - revocable changes core: - add Apple fourcc modifiers - add virtio capset definitions - extend EXPORT_SYNC_FILE for timeline syncobjs - convert to devm_platform_ioremap_resource - refactor shmem helper page pinning - DP powerup/down link helpers - extended %p4cc in vsprintf.c to support fourcc prints - change vsprintf %p4cn to %p4chR, remove %p4cn - Add drm_file_err function - IN_FORMATS_ASYNC property - move sitronix from tiny to their own subdir rust: - add drm core infrastructure rust abstractions (device/driver, ioctl, file, gem) dma-buf: - adjust sg handling to not cache map on attach - allow setting dma-device for import - Add a helper to sort and deduplicate dma_fence arrays docs: - updated drm scheduler docs - fbdev todo update - fb rendering - actual brightness ttm: - fix delayed destroy resv object bridge: - add kunit tests - convert tc358775 to atomic - convert drivers to devm_drm_bridge_alloc - convert rk3066_hdmi to bridge driver scheduler: - add kunit tests panel: - refcount panels to improve lifetime handling - Powertip PH128800T004-ZZA01 - NLT NL13676BC25-03F, Tianma TM070JDHG34-00 - Himax HX8279/HX8279-D DDIC - Visionox G2647FB105 - Sitronix ST7571 - ZOTAC rotation quirk vkms: - allow attaching more displays i915: - xe3lpd display updates - vrr refactor - intel_display struct conversions - xe2hpd memory type identification - add link rate/count to i915_display_info - cleanup VGA plane handling - refactor HDCP GSC - fix SLPC wait boosting reference counting - add 20ms delay to engine reset - fix fence release on early probe errors xe: - SRIOV updates - BMG PCI ID update - support separate firmware for each GT - SVM fix, prelim SVM multi-device work - export fan speed - temp disable d3cold on BMG - backup VRAM in PM notifier instead of suspend/freeze - update xe_ttm_access_memory to use GPU for non-visible access - fix guc_info debugfs for VFs - use copy_from_user instead of __copy_from_user - append PCIe gen5 limitations to xe_firmware document amdgpu: - DSC cleanup - DC Scaling updates - Fused I2C-over-AUX updates - DMUB updates - Use drm_file_err in amdgpu - Enforce isolation updates - Use new dma_fence helpers - USERQ fixes - Documentation updates - SR-IOV updates - RAS updates - PSP 12 cleanups - GC 9.5 updates - SMU 13.x updates - VCN / JPEG SR-IOV updates amdkfd: - Update error messages for SDMA - Userptr updates - XNACK fixes radeon: - CIK doorbell cleanup nouveau: - add support for NVIDIA r570 GSP firmware - enable Hopper/Blackwell support nova-core: - fix task list - register definition infrastructure - move firmware into own rust module - register auxiliary device for nova-drm nova-drm: - initial driver skeleton msm: - GPU: - ACD (adaptive clock distribution) for X1-85 - drop fictional address_space_size - improve GMU HFI response time out robustness - fix crash when throttling during boot - DPU: - use single CTL path for flushing on DPU 5.x+ - improve SSPP allocation code for better sharing - Enabled SmartDMA on SM8150, SC8180X, SC8280XP, SM8550 - Added SAR2130P support - Disabled DSC support on MSM8937, MSM8917, MSM8953, SDM660 - DP: - switch to new audio helpers - better LTTPR handling - DSI: - Added support for SA8775P - Added SAR2130P support - HDMI: - Switched to use new helpers for ACR data - Fixed old standing issue of HPD not working in some cases amdxdna: - add dma-buf support - allow empty command submits renesas: - add dma-buf support - add zpos, alpha, blend support panthor: - fail properly for NO_MMAP bos - add SET_LABEL ioctl - debugfs BO dumping support imagination: - update DT bindings - support TI AM68 GPU hibmc: - improve interrupt handling and HPD support virtio: - add panic handler support rockchip: - add RK3588 support - add DP AUX bus panel support ivpu: - add heartbeat based hangcheck mediatek: - prepares support for MT8195/99 HDMIv2/DDCv2 anx7625: - improve HPD tegra: - speed up firmware loading * tag 'drm-next-2025-05-28' of https://gitlab.freedesktop.org/drm/kernel: (1627 commits) drm/nouveau/tegra: Fix error pointer vs NULL return in nvkm_device_tegra_resource_addr() drm/xe: Default auto_link_downgrade status to false drm/xe/guc: Make creation of SLPC debugfs files conditional drm/i915/display: Add check for alloc_ordered_workqueue() and alloc_workqueue() drm/i915/dp_mst: Work around Thunderbolt sink disconnect after SINK_COUNT_ESI read drm/i915/ptl: Use everywhere the correct DDI port clock select mask drm/nouveau/kms: add support for GB20x drm/dp: add option to disable zero sized address only transactions. drm/nouveau: add support for GB20x drm/nouveau/gsp: add hal for fifo.chan.doorbell_handle drm/nouveau: add support for GB10x drm/nouveau/gf100-: track chan progress with non-WFI semaphore release drm/nouveau/nv50-: separate CHANNEL_GPFIFO handling out from CHANNEL_DMA drm/nouveau: add helper functions for allocating pinned/cpu-mapped bos drm/nouveau: add support for GH100 drm/nouveau: improve handling of 64-bit BARs drm/nouveau/gv100-: switch to volta semaphore methods drm/nouveau/gsp: support deeper page tables in COPY_SERVER_RESERVED_PDES drm/nouveau/gsp: init client VMMs with NV0080_CTRL_DMA_SET_PAGE_DIRECTORY drm/nouveau/gsp: fetch level shift and PDE from BAR2 VMM ...
This commit is contained in:
commit
b08494a8f7
1726 changed files with 71517 additions and 36307 deletions
|
@ -722,6 +722,13 @@ ForEachMacros:
|
|||
- 'v4l2_m2m_for_each_src_buf'
|
||||
- 'v4l2_m2m_for_each_src_buf_safe'
|
||||
- 'virtio_device_for_each_vq'
|
||||
- 'vkms_config_for_each_connector'
|
||||
- 'vkms_config_for_each_crtc'
|
||||
- 'vkms_config_for_each_encoder'
|
||||
- 'vkms_config_for_each_plane'
|
||||
- 'vkms_config_connector_for_each_possible_encoder'
|
||||
- 'vkms_config_encoder_for_each_possible_crtc'
|
||||
- 'vkms_config_plane_for_each_possible_crtc'
|
||||
- 'while_for_each_ftrace_op'
|
||||
- 'workloads__for_each'
|
||||
- 'xa_for_each'
|
||||
|
|
|
@ -26,7 +26,12 @@ Date: March 2006
|
|||
KernelVersion: 2.6.17
|
||||
Contact: Richard Purdie <rpurdie@rpsys.net>
|
||||
Description:
|
||||
Show the actual brightness by querying the hardware.
|
||||
Show the actual brightness by querying the hardware. Due
|
||||
to implementation differences in hardware this may not
|
||||
match the value in 'brightness'. For example some hardware
|
||||
may treat blanking differently or have custom power saving
|
||||
features. Userspace should generally use the values in
|
||||
'brightness' to make decisions.
|
||||
Users: HAL
|
||||
|
||||
What: /sys/class/backlight/<backlight>/max_brightness
|
||||
|
|
|
@ -124,3 +124,27 @@ Contact: intel-xe@lists.freedesktop.org
|
|||
Description: RO. VRAM temperature in millidegree Celsius.
|
||||
|
||||
Only supported for particular Intel Xe graphics platforms.
|
||||
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/fan1_input
|
||||
Date: March 2025
|
||||
KernelVersion: 6.16
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
Description: RO. Fan 1 speed in RPM.
|
||||
|
||||
Only supported for particular Intel Xe graphics platforms.
|
||||
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/fan2_input
|
||||
Date: March 2025
|
||||
KernelVersion: 6.16
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
Description: RO. Fan 2 speed in RPM.
|
||||
|
||||
Only supported for particular Intel Xe graphics platforms.
|
||||
|
||||
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/fan3_input
|
||||
Date: March 2025
|
||||
KernelVersion: 6.16
|
||||
Contact: intel-xe@lists.freedesktop.org
|
||||
Description: RO. Fan 3 speed in RPM.
|
||||
|
||||
Only supported for particular Intel Xe graphics platforms.
|
||||
|
|
|
@ -647,6 +647,38 @@ Examples::
|
|||
%p4cc Y10 little-endian (0x20303159)
|
||||
%p4cc NV12 big-endian (0xb231564e)
|
||||
|
||||
Generic FourCC code
|
||||
-------------------
|
||||
|
||||
::
|
||||
%p4c[h[R]lb] gP00 (0x67503030)
|
||||
|
||||
Print a generic FourCC code, as both ASCII characters and its numerical
|
||||
value as hexadecimal.
|
||||
|
||||
The generic FourCC code is always printed in the big-endian format,
|
||||
the most significant byte first. This is the opposite of V4L/DRM FourCCs.
|
||||
|
||||
The additional ``h``, ``hR``, ``l``, and ``b`` specifiers define what
|
||||
endianness is used to load the stored bytes. The data might be interpreted
|
||||
using the host, reversed host byte order, little-endian, or big-endian.
|
||||
|
||||
Passed by reference.
|
||||
|
||||
Examples for a little-endian machine, given &(u32)0x67503030::
|
||||
|
||||
%p4ch gP00 (0x67503030)
|
||||
%p4chR 00Pg (0x30305067)
|
||||
%p4cl gP00 (0x67503030)
|
||||
%p4cb 00Pg (0x30305067)
|
||||
|
||||
Examples for a big-endian machine, given &(u32)0x67503030::
|
||||
|
||||
%p4ch gP00 (0x67503030)
|
||||
%p4chR 00Pg (0x30305067)
|
||||
%p4cl 00Pg (0x30305067)
|
||||
%p4cb gP00 (0x67503030)
|
||||
|
||||
Rust
|
||||
----
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek HDMI MT8195 series HDMI Display Data Channel (DDC)
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
- CK Hu <ck.hu@mediatek.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: mediatek,mt8195-hdmi-ddc
|
||||
- items:
|
||||
- const: mediatek,mt8188-hdmi-ddc
|
||||
- const: mediatek,mt8195-hdmi-ddc
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
hdmi {
|
||||
hdmi_ddc: i2c {
|
||||
compatible = "mediatek,mt8195-hdmi-ddc";
|
||||
clocks = <&clk26m>;
|
||||
};
|
||||
};
|
||||
...
|
|
@ -0,0 +1,151 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/mediatek/mediatek,mt8195-hdmi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek MT8195 series HDMI-TX Encoder
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
- CK Hu <ck.hu@mediatek.com>
|
||||
|
||||
description:
|
||||
The MediaTek HDMI-TX v2 encoder can generate HDMI format data based on
|
||||
the HDMI Specification 2.0b.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt8188-hdmi-tx
|
||||
- mediatek,mt8195-hdmi-tx
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: HDMI Peripheral Bus (APB) clock
|
||||
- description: HDCP and HDMI_TOP clock
|
||||
- description: HDCP, HDMI_TOP and HDMI Audio reference clock
|
||||
- description: VPP HDMI Split clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: hdcp
|
||||
- const: hdcp24m
|
||||
- const: hdmi-split
|
||||
|
||||
i2c:
|
||||
type: object
|
||||
$ref: /schemas/display/mediatek/mediatek,mt8195-hdmi-ddc.yaml
|
||||
unevaluatedProperties: false
|
||||
description: HDMI DDC I2C controller
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
description: PHY providing clocking TMDS and pixel to controller
|
||||
|
||||
phy-names:
|
||||
items:
|
||||
- const: hdmi
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description:
|
||||
Input port, usually connected to the output port of a DPI
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description:
|
||||
Output port that must be connected either to the input port of
|
||||
a HDMI connector node containing a ddc-i2c-bus, or to the input
|
||||
port of an attached bridge chip, such as a SlimPort transmitter.
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- phys
|
||||
- phy-names
|
||||
- ports
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/sound/dai-common.yaml#
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mt8195-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/mt8195-power.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
hdmi@1c300000 {
|
||||
compatible = "mediatek,mt8195-hdmi-tx";
|
||||
reg = <0 0x1c300000 0 0x1000>;
|
||||
clocks = <&topckgen CLK_TOP_HDMI_APB>,
|
||||
<&topckgen CLK_TOP_HDCP>,
|
||||
<&topckgen CLK_TOP_HDCP_24M>,
|
||||
<&vppsys1 CLK_VPP1_VPP_SPLIT_HDMI>;
|
||||
clock-names = "bus", "hdcp", "hdcp24m", "hdmi-split";
|
||||
interrupts = <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
phys = <&hdmi_phy>;
|
||||
phy-names = "hdmi";
|
||||
power-domains = <&spm MT8195_POWER_DOMAIN_HDMI_TX>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hdmi_pins>;
|
||||
#sound-dai-cells = <1>;
|
||||
|
||||
hdmitx_ddc: i2c {
|
||||
compatible = "mediatek,mt8195-hdmi-ddc";
|
||||
clocks = <&clk26m>;
|
||||
};
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
hdmi_in: endpoint {
|
||||
remote-endpoint = <&dpi1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
hdmi_out: endpoint {
|
||||
remote-endpoint = <&hdmi_connector_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -31,6 +31,7 @@ properties:
|
|||
- qcom,sm8650-dp
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sar2130p-dp
|
||||
- qcom,sm6350-dp
|
||||
- qcom,sm8150-dp
|
||||
- qcom,sm8250-dp
|
||||
|
|
|
@ -23,6 +23,8 @@ properties:
|
|||
- qcom,msm8996-dsi-ctrl
|
||||
- qcom,msm8998-dsi-ctrl
|
||||
- qcom,qcm2290-dsi-ctrl
|
||||
- qcom,sa8775p-dsi-ctrl
|
||||
- qcom,sar2130p-dsi-ctrl
|
||||
- qcom,sc7180-dsi-ctrl
|
||||
- qcom,sc7280-dsi-ctrl
|
||||
- qcom,sdm660-dsi-ctrl
|
||||
|
@ -314,6 +316,8 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- qcom,msm8998-dsi-ctrl
|
||||
- qcom,sa8775p-dsi-ctrl
|
||||
- qcom,sar2130p-dsi-ctrl
|
||||
- qcom,sc7180-dsi-ctrl
|
||||
- qcom,sc7280-dsi-ctrl
|
||||
- qcom,sdm845-dsi-ctrl
|
||||
|
|
|
@ -17,6 +17,8 @@ properties:
|
|||
enum:
|
||||
- qcom,dsi-phy-7nm
|
||||
- qcom,dsi-phy-7nm-8150
|
||||
- qcom,sa8775p-dsi-phy-5nm
|
||||
- qcom,sar2130p-dsi-phy-5nm
|
||||
- qcom,sc7280-dsi-phy-7nm
|
||||
- qcom,sm6375-dsi-phy-7nm
|
||||
- qcom,sm8350-dsi-phy-5nm
|
||||
|
|
|
@ -66,21 +66,6 @@ properties:
|
|||
maxItems: 1
|
||||
description: hpd pin
|
||||
|
||||
qcom,hdmi-tx-mux-en-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
description: HDMI mux enable pin
|
||||
|
||||
qcom,hdmi-tx-mux-sel-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
description: HDMI mux select pin
|
||||
|
||||
qcom,hdmi-tx-mux-lpm-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
description: HDMI mux lpm pin
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
|
@ -89,12 +74,12 @@ properties:
|
|||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
|
|
|
@ -18,9 +18,10 @@ properties:
|
|||
|
||||
clocks:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
maxItems: 8
|
||||
|
||||
clock-names:
|
||||
minItems: 6
|
||||
items:
|
||||
- const: core_clk
|
||||
- const: iface_clk
|
||||
|
@ -28,6 +29,12 @@ properties:
|
|||
- const: lut_clk
|
||||
- const: hdmi_clk
|
||||
- const: tv_clk
|
||||
- const: lcdc_clk
|
||||
- const: pxo
|
||||
description: XO used to drive the internal LVDS PLL
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
@ -84,6 +84,18 @@ properties:
|
|||
items:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
interconnects:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Interconnect path from mdp0 (or a single mdp) port to the data bus
|
||||
- description: Interconnect path from CPU to the reg bus
|
||||
|
||||
interconnect-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: mdp0-mem
|
||||
- const: cpu-cfg
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
@ -52,12 +52,23 @@ patternProperties:
|
|||
items:
|
||||
- const: qcom,sa8775p-dp
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,sa8775p-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sa8775p-edp-phy
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sa8775p-dsi-phy-5nm
|
||||
- qcom,sa8775p-edp-phy
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -139,6 +150,20 @@ examples:
|
|||
remote-endpoint = <&mdss0_dp0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&mdss0_dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&mdss0_dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss0_mdp_opp_table: opp-table {
|
||||
|
@ -186,6 +211,160 @@ examples:
|
|||
vdda-pll-supply = <&vreg_l4a>;
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,sa8775p-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispc_byte_clk>,
|
||||
<&dispcc_intf_clk>,
|
||||
<&dispcc_pclk>,
|
||||
<&dispcc_esc_clk>,
|
||||
<&dispcc_ahb_clk>,
|
||||
<&gcc_bus_clk>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&dispcc_byte_clk>,
|
||||
<&dispcc_pclk>;
|
||||
assigned-clock-parents = <&mdss0_dsi0_phy 0>, <&mdss0_dsi0_phy 1>;
|
||||
phys = <&mdss0_dsi0_phy>;
|
||||
|
||||
operating-points-v2 = <&dsi0_opp_table>;
|
||||
power-domains = <&rpmhpd SA8775P_MMCX>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
mdss0_dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
mdss0_dsi0_out: endpoint { };
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss0_dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,sa8775p-dsi-phy-5nm";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94900 0x27c>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc_iface_clk>,
|
||||
<&rpmhcc_ref_clk>;
|
||||
clock-names = "iface", "ref";
|
||||
|
||||
vdds-supply = <&vreg_dsi_supply>;
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,sa8775p-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispc_byte_clk>,
|
||||
<&dispcc_intf_clk>,
|
||||
<&dispcc_pclk>,
|
||||
<&dispcc_esc_clk>,
|
||||
<&dispcc_ahb_clk>,
|
||||
<&gcc_bus_clk>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&dispcc_byte_clk>,
|
||||
<&dispcc_pclk>;
|
||||
assigned-clock-parents = <&mdss0_dsi1_phy 0>, <&mdss0_dsi1_phy 1>;
|
||||
phys = <&mdss0_dsi1_phy>;
|
||||
|
||||
operating-points-v2 = <&dsi1_opp_table>;
|
||||
power-domains = <&rpmhpd SA8775P_MMCX>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
mdss0_dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
mdss0_dsi1_out: endpoint { };
|
||||
};
|
||||
};
|
||||
|
||||
dsi1_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss0_dsi1_phy: phy@ae96400 {
|
||||
compatible = "qcom,sa8775p-dsi-phy-5nm";
|
||||
reg = <0x0ae96400 0x200>,
|
||||
<0x0ae96600 0x280>,
|
||||
<0x0ae96900 0x27c>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc_iface_clk>,
|
||||
<&rpmhcc_ref_clk>;
|
||||
clock-names = "iface", "ref";
|
||||
|
||||
vdds-supply = <&vreg_dsi_supply>;
|
||||
};
|
||||
|
||||
displayport-controller@af54000 {
|
||||
compatible = "qcom,sa8775p-dp";
|
||||
|
||||
|
|
|
@ -0,0 +1,439 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sar2130p-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SAR2130P Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <lumag@kernel.org>
|
||||
|
||||
description:
|
||||
SAR2310P MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like
|
||||
DPU display controller, DSI and DP interfaces etc.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sar2130p-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display MDSS AHB
|
||||
- description: Display AHB
|
||||
- description: Display hf AXI
|
||||
- description: Display core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
items:
|
||||
- description: Interconnect path from mdp0 port to the data bus
|
||||
- description: Interconnect path from CPU to the reg bus
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: mdp0-mem
|
||||
- const: cpu-cfg
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sar2130p-dpu
|
||||
|
||||
"^displayport-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,sar2130p-dp
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,sar2130p-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sar2130p-dsi-phy-5nm
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom,rpmhpd.h>
|
||||
#include <dt-bindings/phy/phy-qcom-qmp.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
compatible = "qcom,sar2130p-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
interconnects = <&mmss_noc_master_mdp &mc_virt_slave_ebi1>,
|
||||
<&gem_noc_master_appss_proc &config_noc_slave_display_cfg>;
|
||||
interconnect-names = "mdp0-mem", "cpu-cfg";
|
||||
|
||||
resets = <&dispcc_disp_cc_mdss_core_bcr>;
|
||||
|
||||
power-domains = <&dispcc_mdss_gdsc>;
|
||||
|
||||
clocks = <&dispcc_disp_cc_mdss_ahb_clk>,
|
||||
<&gcc_gcc_disp_ahb_clk>,
|
||||
<&gcc_gcc_disp_hf_axi_clk>,
|
||||
<&dispcc_disp_cc_mdss_mdp_clk>;
|
||||
clock-names = "iface", "bus", "nrt_bus", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x1c00 0x2>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sar2130p-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc_gcc_disp_ahb_clk>,
|
||||
<&gcc_gcc_disp_hf_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";
|
||||
|
||||
assigned-clocks = <&dispcc_disp_cc_mdss_vsync_clk>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd RPMHPD_MMCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
dpu_intf0_out: endpoint {
|
||||
remote-endpoint = <&mdss_dp0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&mdss_dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&mdss_dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-200000000 {
|
||||
opp-hz = /bits/ 64 <200000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-325000000 {
|
||||
opp-hz = /bits/ 64 <325000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-375000000 {
|
||||
opp-hz = /bits/ 64 <375000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-514000000 {
|
||||
opp-hz = /bits/ 64 <514000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
displayport-controller@ae90000 {
|
||||
compatible = "qcom,sar2130p-dp",
|
||||
"qcom,sm8350-dp";
|
||||
reg = <0xae90000 0x200>,
|
||||
<0xae90200 0x200>,
|
||||
<0xae90400 0xc00>,
|
||||
<0xae91000 0x400>,
|
||||
<0xae91400 0x400>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <12>;
|
||||
clocks = <&dispcc_disp_cc_mdss_ahb_clk>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_aux_clk>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_link_clk>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_link_intf_clk>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_pixel0_clk>;
|
||||
clock-names = "core_iface",
|
||||
"core_aux",
|
||||
"ctrl_link",
|
||||
"ctrl_link_iface",
|
||||
"stream_pixel";
|
||||
|
||||
assigned-clocks = <&dispcc_disp_cc_mdss_dptx0_link_clk_src>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_pixel0_clk_src>;
|
||||
assigned-clock-parents = <&usb_dp_qmpphy_QMP_USB43DP_DP_LINK_CLK>,
|
||||
<&usb_dp_qmpphy_QMP_USB43DP_DP_VCO_DIV_CLK>;
|
||||
|
||||
phys = <&usb_dp_qmpphy QMP_USB43DP_DP_PHY>;
|
||||
phy-names = "dp";
|
||||
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
operating-points-v2 = <&dp_opp_table>;
|
||||
power-domains = <&rpmhpd RPMHPD_MMCX>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
mdss_dp0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
mdss_dp0_out: endpoint {
|
||||
remote-endpoint = <&usb_dp_qmpphy_dp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-162000000 {
|
||||
opp-hz = /bits/ 64 <162000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs_d1>;
|
||||
};
|
||||
|
||||
opp-270000000 {
|
||||
opp-hz = /bits/ 64 <270000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-540000000 {
|
||||
opp-hz = /bits/ 64 <540000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-810000000 {
|
||||
opp-hz = /bits/ 64 <810000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,sar2130p-dsi-ctrl",
|
||||
"qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc_disp_cc_mdss_byte0_clk>,
|
||||
<&dispcc_disp_cc_mdss_byte0_intf_clk>,
|
||||
<&dispcc_disp_cc_mdss_pclk0_clk>,
|
||||
<&dispcc_disp_cc_mdss_esc0_clk>,
|
||||
<&dispcc_disp_cc_mdss_ahb_clk>,
|
||||
<&gcc_gcc_disp_hf_axi_clk>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc_disp_cc_mdss_byte0_clk_src>,
|
||||
<&dispcc_disp_cc_mdss_pclk0_clk_src>;
|
||||
assigned-clock-parents = <&mdss_dsi0_phy 0>, <&mdss_dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd RPMHPD_MMCX>;
|
||||
|
||||
phys = <&mdss_dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mdss_dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
mdss_dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-187500000 {
|
||||
opp-hz = /bits/ 64 <187500000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss_dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,sar2130p-dsi-phy-5nm";
|
||||
reg = <0x0ae95000 0x200>,
|
||||
<0x0ae95200 0x280>,
|
||||
<0x0ae95500 0x400>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc_disp_cc_mdss_ahb_clk>,
|
||||
<&rpmhcc_rpmh_cxo_clk>;
|
||||
clock-names = "iface", "ref";
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,sar2130p-dsi-ctrl",
|
||||
"qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <5>;
|
||||
|
||||
clocks = <&dispcc_disp_cc_mdss_byte1_clk>,
|
||||
<&dispcc_disp_cc_mdss_byte1_intf_clk>,
|
||||
<&dispcc_disp_cc_mdss_pclk1_clk>,
|
||||
<&dispcc_disp_cc_mdss_esc1_clk>,
|
||||
<&dispcc_disp_cc_mdss_ahb_clk>,
|
||||
<&gcc_gcc_disp_hf_axi_clk>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc_disp_cc_mdss_byte1_clk_src>,
|
||||
<&dispcc_disp_cc_mdss_pclk1_clk_src>;
|
||||
assigned-clock-parents = <&mdss_dsi1_phy 0>, <&mdss_dsi1_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd RPMHPD_MMCX>;
|
||||
|
||||
phys = <&mdss_dsi1_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mdss_dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
mdss_dsi1_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss_dsi1_phy: phy@ae97000 {
|
||||
compatible = "qcom,sar2130p-dsi-phy-5nm";
|
||||
reg = <0x0ae97000 0x200>,
|
||||
<0x0ae97200 0x280>,
|
||||
<0x0ae97500 0x400>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc_disp_cc_mdss_ahb_clk>,
|
||||
<&rpmhcc_rpmh_cxo_clk>;
|
||||
clock-names = "iface", "ref";
|
||||
};
|
||||
};
|
||||
...
|
|
@ -17,6 +17,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sar2130p-dpu
|
||||
- qcom,sc7280-dpu
|
||||
- qcom,sc8280xp-dpu
|
||||
- qcom,sm8350-dpu
|
||||
|
|
|
@ -38,12 +38,16 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: Interconnect path from the MDP0 port to the data bus
|
||||
- description: Interconnect path from the MDP1 port to the data bus
|
||||
- description: Interconnect path from the CPU to the reg bus
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: mdp0-mem
|
||||
- const: mdp1-mem
|
||||
- const: cpu-cfg
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
|
@ -88,6 +92,7 @@ examples:
|
|||
#include <dt-bindings/clock/qcom,gcc-sm8350.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,icc.h>
|
||||
#include <dt-bindings/interconnect/qcom,sm8350.h>
|
||||
#include <dt-bindings/power/qcom,rpmhpd.h>
|
||||
|
||||
|
@ -97,8 +102,10 @@ examples:
|
|||
reg-names = "mdss";
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>,
|
||||
<&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>;
|
||||
interconnect-names = "mdp0-mem", "mdp1-mem";
|
||||
<&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>,
|
||||
<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
|
||||
&config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
|
||||
interconnect-names = "mdp0-mem", "mdp1-mem", "cpu-cfg";
|
||||
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/boe,td4320.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: BOE TD4320 MIPI-DSI panels
|
||||
|
||||
maintainers:
|
||||
- Barnabas Czeman <barnabas.czeman@mainlining.org>
|
||||
|
||||
description:
|
||||
BOE TD4320 6.3" 1080x2340 panel found in Xiaomi Redmi Note 7 smartphone.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: boe,td4320
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
iovcc-supply:
|
||||
description: I/O voltage rail
|
||||
|
||||
vsn-supply:
|
||||
description: Negative source voltage rail
|
||||
|
||||
vsp-supply:
|
||||
description: Positive source voltage rail
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reset-gpios
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "boe,td4320";
|
||||
reg = <0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&tlmm 45 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
panel_in: endpoint {
|
||||
remote-endpoint = <&dsi_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,75 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/himax,hx8279.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Himax HX8279/HX8279-D based MIPI-DSI panels
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
|
||||
description:
|
||||
The Himax HX8279 is a 1803 channel outputs source driver with MIPI
|
||||
TCON, which generates the horizontal and vertical control timing to
|
||||
the source and gate drivers.
|
||||
This DriverIC is most suitable for 1200x1920, 1080x1920, 1200x1600,
|
||||
and 600x1024 panels and outputs full RGB888 over two or four lanes,
|
||||
single or dual, MIPI-DSI video interface.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common-dual.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- aoly,sl101pm1794fog-v15
|
||||
- startek,kd070fhfid078
|
||||
- const: himax,hx8279
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
iovcc-supply:
|
||||
description: I/O voltage supply
|
||||
|
||||
vdd-supply:
|
||||
description: Panel power supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- backlight
|
||||
- reset-gpios
|
||||
- iovcc-supply
|
||||
- vdd-supply
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "startek,kd070fhfid078", "himax,hx8279";
|
||||
reg = <0>;
|
||||
backlight = <&backlight>;
|
||||
enable-gpios = <&pio 25 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&pio 45 GPIO_ACTIVE_HIGH>;
|
||||
iovcc-supply = <&vreg_lcm_vio>;
|
||||
vdd-supply = <&vreg_lcm_vdd>;
|
||||
|
||||
port {
|
||||
panel_in: endpoint {
|
||||
remote-endpoint = <&dsi_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -23,6 +23,7 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
backlight: true
|
||||
port: true
|
||||
reset-gpios: true
|
||||
iovcc-supply:
|
||||
description: regulator that supplies the iovcc voltage
|
||||
|
|
|
@ -22,6 +22,7 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
backlight: true
|
||||
port: true
|
||||
reset-gpios: true
|
||||
iovcc-supply:
|
||||
description: regulator that supplies the iovcc voltage
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/novatek,nt37801.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Novatek NT37801 AMOLED DSI Panel
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
||||
description:
|
||||
Naming is inconclusive and different sources claim this is either Novatek
|
||||
NT37801 or NT37810 AMOLED DSI Panel.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: novatek,nt37801
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: DSI virtual channel
|
||||
|
||||
vci-supply: true
|
||||
vdd-supply: true
|
||||
vddio-supply: true
|
||||
port: true
|
||||
reset-gpios: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vci-supply
|
||||
- vdd-supply
|
||||
- vddio-supply
|
||||
- port
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "novatek,nt37801";
|
||||
reg = <0>;
|
||||
|
||||
vci-supply = <&vreg_l13b_3p0>;
|
||||
vdd-supply = <&vreg_l11b_1p2>;
|
||||
vddio-supply = <&vreg_l12b_1p8>;
|
||||
|
||||
reset-gpios = <&tlmm 98 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -226,6 +226,8 @@ properties:
|
|||
- netron-dy,e231732
|
||||
# Newhaven Display International 480 x 272 TFT LCD panel
|
||||
- newhaven,nhd-4.3-480272ef-atxl
|
||||
# NLT Technologies, Ltd. 15.6" WXGA (1366×768) LVDS TFT LCD panel
|
||||
- nlt,nl13676bc25-03f
|
||||
# New Vision Display 7.0" 800 RGB x 480 TFT LCD panel
|
||||
- nvd,9128
|
||||
# OKAYA Electric America, Inc. RS800480T-7X0GP 7" WVGA LCD panel
|
||||
|
@ -246,6 +248,8 @@ properties:
|
|||
- osddisplays,osd070t1718-19ts
|
||||
# One Stop Displays OSD101T2045-53TS 10.1" 1920x1200 panel
|
||||
- osddisplays,osd101t2045-53ts
|
||||
# POWERTIP PH128800T004-ZZA01 10.1" WXGA TFT LCD panel
|
||||
- powertip,ph128800t004-zza01
|
||||
# POWERTIP PH128800T006-ZHC01 10.1" WXGA TFT LCD panel
|
||||
- powertip,ph128800t006-zhc01
|
||||
# POWERTIP PH800480T013-IDF2 7.0" WVGA TFT LCD panel
|
||||
|
@ -284,6 +288,8 @@ properties:
|
|||
- startek,kd070wvfpa
|
||||
# Team Source Display Technology TST043015CMHX 4.3" WQVGA TFT LCD panel
|
||||
- team-source-display,tst043015cmhx
|
||||
# Tianma Micro-electronics P0700WXF1MBAA 7.0" WXGA (1280x800) LVDS TFT LCD panel
|
||||
- tianma,p0700wxf1mbaa
|
||||
# Tianma Micro-electronics TM070JDHG30 7.0" WXGA TFT LCD panel
|
||||
- tianma,tm070jdhg30
|
||||
# Tianma Micro-electronics TM070JDHG34-00 7.0" WXGA (1280x800) LVDS TFT LCD panel
|
||||
|
|
|
@ -19,6 +19,8 @@ properties:
|
|||
- const: samsung,atna33xc20
|
||||
- items:
|
||||
- enum:
|
||||
# Samsung 14" WQXGA+ (2880×1800 pixels) eDP AMOLED panel
|
||||
- samsung,atna40yk20
|
||||
# Samsung 14.5" WQXGA+ (2880x1800 pixels) eDP AMOLED panel
|
||||
- samsung,atna45af01
|
||||
# Samsung 14.5" 3K (2944x1840 pixels) eDP AMOLED panel
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/truly,nt35597-2K-display.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Truly NT35597 DSI 2K display
|
||||
|
||||
maintainers:
|
||||
- Neil Armstrong <neil.armstrong@linaro.org>
|
||||
|
||||
description: |
|
||||
Truly NT35597 DSI 2K display is used on the Qualcomm SDM845 MTP board.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common-dual.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: truly,nt35597-2K-display
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
vdda-supply:
|
||||
description: regulator that provides the supply voltage Power IC supply
|
||||
|
||||
vdispp-supply:
|
||||
description: regulator that provides the supply voltage for positive LCD bias
|
||||
|
||||
vdispn-supply:
|
||||
description: regulator that provides the supply voltage for negative LCD bias
|
||||
|
||||
reset-gpios: true
|
||||
|
||||
mode-gpios:
|
||||
description:
|
||||
Gpio for choosing the mode of the display for single DSI or Dual DSI.
|
||||
This should be low for dual DSI and high for single DSI mode.
|
||||
|
||||
ports:
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdda-supply
|
||||
- reset-gpios
|
||||
- mode-gpios
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "truly,nt35597-2K-display";
|
||||
reg = <0>;
|
||||
|
||||
vdda-supply = <&pm8998_l14>;
|
||||
vdispp-supply = <&lab_regulator>;
|
||||
vdispn-supply = <&ibb_regulator>;
|
||||
|
||||
reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>;
|
||||
mode-gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
panel0_in: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
panel1_in: endpoint {
|
||||
remote-endpoint = <&dsi1_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -0,0 +1,79 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/visionox,g2647fb105.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Visionox G2647FB105 6.47" 1080x2340 MIPI-DSI Panel
|
||||
|
||||
maintainers:
|
||||
- Alexander Baransky <sanyapilot496@gmail.com>
|
||||
|
||||
description:
|
||||
The Visionox G2647FB105 is a 6.47 inch 1080x2340 MIPI-DSI CMD mode OLED panel.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: visionox,g2647fb105
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
vdd3p3-supply:
|
||||
description: 3.3V source voltage rail
|
||||
|
||||
vddio-supply:
|
||||
description: I/O source voltage rail
|
||||
|
||||
vsn-supply:
|
||||
description: Negative source voltage rail
|
||||
|
||||
vsp-supply:
|
||||
description: Positive source voltage rail
|
||||
|
||||
reset-gpios: true
|
||||
port: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd3p3-supply
|
||||
- vddio-supply
|
||||
- vsn-supply
|
||||
- vsp-supply
|
||||
- reset-gpios
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "visionox,g2647fb105";
|
||||
reg = <0>;
|
||||
|
||||
vdd3p3-supply = <&vreg_l7c_3p0>;
|
||||
vddio-supply = <&vreg_l13a_1p8>;
|
||||
vsn-supply = <&vreg_ibb>;
|
||||
vsp-supply = <&vreg_lab>;
|
||||
|
||||
reset-gpios = <&pm6150l_gpios 9 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
panel_in: endpoint {
|
||||
remote-endpoint = <&mdss_dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -15,6 +15,7 @@ properties:
|
|||
enum:
|
||||
- rockchip,rk3288-dp
|
||||
- rockchip,rk3399-edp
|
||||
- rockchip,rk3588-edp
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
|
@ -31,16 +32,23 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
const: dp
|
||||
minItems: 1
|
||||
items:
|
||||
- const: dp
|
||||
- const: apb
|
||||
|
||||
rockchip,grf:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
This SoC makes use of GRF regs.
|
||||
|
||||
aux-bus:
|
||||
$ref: /schemas/display/dp-aux-bus.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
|
@ -52,6 +60,19 @@ required:
|
|||
allOf:
|
||||
- $ref: /schemas/display/bridge/analogix,dp.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,rk3588-edp
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
minItems: 2
|
||||
reset-names:
|
||||
minItems: 2
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
|
@ -23,13 +23,11 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: The HDMI controller main clock
|
||||
- description: The HDMI PHY reference clock
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: pclk
|
||||
- const: ref
|
||||
|
@ -58,6 +56,12 @@ properties:
|
|||
- port@0
|
||||
- port@1
|
||||
|
||||
rockchip,grf:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to GRF used for control the polarity of hsync/vsync of rk3036
|
||||
HDMI.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -77,6 +81,8 @@ allOf:
|
|||
const: rockchip,rk3036-inno-hdmi
|
||||
|
||||
then:
|
||||
required:
|
||||
- rockchip,grf
|
||||
properties:
|
||||
power-domains: false
|
||||
|
||||
|
@ -87,11 +93,6 @@ allOf:
|
|||
const: rockchip,rk3128-inno-hdmi
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
clock-names:
|
||||
minItems: 2
|
||||
required:
|
||||
- power-domains
|
||||
|
||||
|
@ -106,10 +107,11 @@ examples:
|
|||
compatible = "rockchip,rk3036-inno-hdmi";
|
||||
reg = <0x20034000 0x4000>;
|
||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru PCLK_HDMI>;
|
||||
clock-names = "pclk";
|
||||
clocks = <&cru PCLK_HDMI>, <&cru SCLK_LCDC>;
|
||||
clock-names = "pclk", "ref";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hdmi_ctl>;
|
||||
rockchip,grf = <&grf>;
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
ports {
|
||||
|
|
|
@ -73,12 +73,6 @@ properties:
|
|||
port:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
assigned-clocks:
|
||||
maxItems: 2
|
||||
|
||||
assigned-clock-rates:
|
||||
maxItems: 2
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/sitronix,st7571.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sitronix ST7571 Display Controller
|
||||
|
||||
maintainers:
|
||||
- Marcus Folkesson <marcus.folkesson@gmail.com>
|
||||
|
||||
description:
|
||||
Sitronix ST7571 is a driver and controller for 4-level gray
|
||||
scale and monochrome dot matrix LCD panels.
|
||||
|
||||
allOf:
|
||||
- $ref: panel/panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sitronix,st7571
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
sitronix,grayscale:
|
||||
type: boolean
|
||||
description:
|
||||
Display supports 4-level grayscale.
|
||||
|
||||
reset-gpios: true
|
||||
width-mm: true
|
||||
height-mm: true
|
||||
panel-timing: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reset-gpios
|
||||
- width-mm
|
||||
- height-mm
|
||||
- panel-timing
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
display@3f {
|
||||
compatible = "sitronix,st7571";
|
||||
reg = <0x3f>;
|
||||
reset-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
|
||||
width-mm = <37>;
|
||||
height-mm = <27>;
|
||||
|
||||
panel-timing {
|
||||
hactive = <128>;
|
||||
vactive = <96>;
|
||||
hback-porch = <0>;
|
||||
vback-porch = <0>;
|
||||
clock-frequency = <0>;
|
||||
hfront-porch = <0>;
|
||||
hsync-len = <0>;
|
||||
vfront-porch = <0>;
|
||||
vsync-len = <0>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,59 +0,0 @@
|
|||
Truly model NT35597 DSI display driver
|
||||
|
||||
The Truly NT35597 is a generic display driver, currently only configured
|
||||
for use in the 2K display on the Qualcomm SDM845 MTP board.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "truly,nt35597-2K-display"
|
||||
- vdda-supply: phandle of the regulator that provides the supply voltage
|
||||
Power IC supply
|
||||
- vdispp-supply: phandle of the regulator that provides the supply voltage
|
||||
for positive LCD bias
|
||||
- vdispn-supply: phandle of the regulator that provides the supply voltage
|
||||
for negative LCD bias
|
||||
- reset-gpios: phandle of gpio for reset line
|
||||
This should be 8mA, gpio can be configured using mux, pinctrl, pinctrl-names
|
||||
(active low)
|
||||
- mode-gpios: phandle of the gpio for choosing the mode of the display
|
||||
for single DSI or Dual DSI
|
||||
This should be low for dual DSI and high for single DSI mode
|
||||
- ports: This device has two video ports driven by two DSIs. Their connections
|
||||
are modeled using the OF graph bindings specified in
|
||||
Documentation/devicetree/bindings/graph.txt.
|
||||
- port@0: DSI input port driven by master DSI
|
||||
- port@1: DSI input port driven by secondary DSI
|
||||
|
||||
Example:
|
||||
|
||||
dsi@ae94000 {
|
||||
panel@0 {
|
||||
compatible = "truly,nt35597-2K-display";
|
||||
reg = <0>;
|
||||
vdda-supply = <&pm8998_l14>;
|
||||
vdispp-supply = <&lab_regulator>;
|
||||
vdispn-supply = <&ibb_regulator>;
|
||||
pinctrl-names = "default", "suspend";
|
||||
pinctrl-0 = <&dpu_dsi_active>;
|
||||
pinctrl-1 = <&dpu_dsi_suspend>;
|
||||
|
||||
reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>;
|
||||
mode-gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>;
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
panel0_in: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
panel1_in: endpoint {
|
||||
remote-endpoint = <&dsi1_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Broadcom V3D GPU
|
||||
|
||||
maintainers:
|
||||
- Eric Anholt <eric@anholt.net>
|
||||
- Maíra Canal <mcanal@igalia.com>
|
||||
- Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
|
||||
|
||||
properties:
|
||||
|
@ -22,20 +22,12 @@ properties:
|
|||
- brcm,7278-v3d
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: hub register (required)
|
||||
- description: core0 register (required)
|
||||
- description: GCA cache controller register (if GCA controller present)
|
||||
- description: bridge register (if no external reset controller)
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: hub
|
||||
- const: core0
|
||||
- enum: [ bridge, gca ]
|
||||
- enum: [ bridge, gca ]
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
|
@ -58,6 +50,76 @@ required:
|
|||
- reg-names
|
||||
- interrupts
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: brcm,2711-v3d
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: hub register
|
||||
- description: core0 register
|
||||
reg-names:
|
||||
items:
|
||||
- const: hub
|
||||
- const: core0
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: brcm,2712-v3d
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: hub register
|
||||
- description: core0 register
|
||||
- description: SMS state manager register
|
||||
reg-names:
|
||||
items:
|
||||
- const: hub
|
||||
- const: core0
|
||||
- const: sms
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: brcm,7268-v3d
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: hub register
|
||||
- description: core0 register
|
||||
- description: GCA cache controller register
|
||||
- description: bridge register
|
||||
reg-names:
|
||||
items:
|
||||
- const: hub
|
||||
- const: core0
|
||||
- const: gca
|
||||
- const: bridge
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: brcm,7278-v3d
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: hub register
|
||||
- description: core0 register
|
||||
- description: bridge register
|
||||
reg-names:
|
||||
items:
|
||||
- const: hub
|
||||
- const: core0
|
||||
- const: bridge
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -66,9 +128,9 @@ examples:
|
|||
compatible = "brcm,7268-v3d";
|
||||
reg = <0xf1200000 0x4000>,
|
||||
<0xf1208000 0x4000>,
|
||||
<0xf1204000 0x100>,
|
||||
<0xf1204100 0x100>;
|
||||
reg-names = "hub", "core0", "bridge", "gca";
|
||||
<0xf1204100 0x100>,
|
||||
<0xf1204000 0x100>;
|
||||
reg-names = "hub", "core0", "gca", "bridge";
|
||||
interrupts = <0 78 4>,
|
||||
<0 77 4>;
|
||||
};
|
||||
|
|
|
@ -12,10 +12,28 @@ maintainers:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- ti,am62-gpu
|
||||
- const: img,img-axe # IMG AXE GPU model/revision is fully discoverable
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- ti,am62-gpu
|
||||
- const: img,img-axe-1-16m
|
||||
# This deprecated element must be kept around to allow old kernels to
|
||||
# work with newer dts.
|
||||
- const: img,img-axe
|
||||
- const: img,img-rogue
|
||||
- items:
|
||||
- enum:
|
||||
- ti,j721s2-gpu
|
||||
- const: img,img-bxs-4-64
|
||||
- const: img,img-rogue
|
||||
|
||||
# This legacy combination of compatible strings was introduced early on
|
||||
# before the more specific GPU identifiers were used.
|
||||
- items:
|
||||
- enum:
|
||||
- ti,am62-gpu
|
||||
- const: img,img-axe
|
||||
deprecated: true
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -35,6 +53,18 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: a
|
||||
- const: b
|
||||
minItems: 1
|
||||
|
||||
dma-coherent: true
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
|
@ -47,11 +77,49 @@ required:
|
|||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
# Constraints added alongside the new compatible strings that would otherwise
|
||||
# create an ABI break.
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ti,am62-gpu
|
||||
const: img,img-rogue
|
||||
then:
|
||||
required:
|
||||
- power-domains
|
||||
- power-domain-names
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: img,img-axe-1-16m
|
||||
then:
|
||||
properties:
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
power-domain-names:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: img,img-bxs-4-64
|
||||
then:
|
||||
properties:
|
||||
power-domains:
|
||||
minItems: 2
|
||||
power-domain-names:
|
||||
minItems: 2
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,am62-gpu
|
||||
- ti,j721s2-gpu
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
@ -64,10 +132,12 @@ examples:
|
|||
#include <dt-bindings/soc/ti,sci_pm_domain.h>
|
||||
|
||||
gpu@fd00000 {
|
||||
compatible = "ti,am62-gpu", "img,img-axe";
|
||||
compatible = "ti,am62-gpu", "img,img-axe-1-16m", "img,img-axe",
|
||||
"img,img-rogue";
|
||||
reg = <0x0fd00000 0x20000>;
|
||||
clocks = <&k3_clks 187 0>;
|
||||
clock-names = "core";
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
|
||||
power-domains = <&k3_pds 187 TI_SCI_PD_EXCLUSIVE>;
|
||||
power-domain-names = "a";
|
||||
};
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/opp/opp-v2-qcom-adreno.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Adreno compatible OPP supply
|
||||
|
||||
description:
|
||||
Adreno GPUs present in Qualcomm's Snapdragon chipsets uses an OPP specific
|
||||
ACD related information tailored for the specific chipset. This binding
|
||||
provides the information needed to describe such a hardware value.
|
||||
|
||||
maintainers:
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: opp-v2-base.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: operating-points-v2-adreno
|
||||
|
||||
patternProperties:
|
||||
'^opp-[0-9]+$':
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
opp-hz: true
|
||||
|
||||
opp-level: true
|
||||
|
||||
opp-peak-kBps: true
|
||||
|
||||
opp-supported-hw: true
|
||||
|
||||
qcom,opp-acd-level:
|
||||
description: |
|
||||
A positive value representing the ACD (Adaptive Clock Distribution,
|
||||
a fancy name for clk throttling during voltage droop) level associated
|
||||
with this OPP node. This value is shared to a co-processor inside GPU
|
||||
(called Graphics Management Unit a.k.a GMU) during wake up. It may not
|
||||
be present for some OPPs and GMU will disable ACD while transitioning
|
||||
to that OPP. This value encodes a voltage threshold, delay cycles &
|
||||
calibration margins which are identified by characterization of the
|
||||
SoC. So, it doesn't have any unit. This data is passed to GMU firmware
|
||||
via 'HFI_H2F_MSG_ACD' packet.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
- opp-hz
|
||||
- opp-level
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
gpu_opp_table: opp-table {
|
||||
compatible = "operating-points-v2-adreno", "operating-points-v2";
|
||||
|
||||
opp-687000000 {
|
||||
opp-hz = /bits/ 64 <687000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
|
||||
opp-peak-kBps = <8171875>;
|
||||
qcom,opp-acd-level = <0x882e5ffd>;
|
||||
};
|
||||
|
||||
opp-550000000 {
|
||||
opp-hz = /bits/ 64 <550000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
|
||||
opp-peak-kBps = <6074219>;
|
||||
qcom,opp-acd-level = <0xc0285ffd>;
|
||||
};
|
||||
|
||||
opp-390000000 {
|
||||
opp-hz = /bits/ 64 <390000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
|
||||
opp-peak-kBps = <3000000>;
|
||||
qcom,opp-acd-level = <0xc0285ffd>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
|
||||
opp-peak-kBps = <2136719>;
|
||||
/* Intentionally left out qcom,opp-acd-level property here */
|
||||
};
|
||||
|
||||
};
|
|
@ -129,6 +129,8 @@ patternProperties:
|
|||
description: Andes Technology Corporation
|
||||
"^anvo,.*":
|
||||
description: Anvo-Systems Dresden GmbH
|
||||
"^aoly,.*":
|
||||
description: Shenzhen Aoly Technology Co., Ltd.
|
||||
"^aosong,.*":
|
||||
description: Guangzhou Aosong Electronic Co., Ltd.
|
||||
"^apm,.*":
|
||||
|
|
23
Documentation/gpu/amdgpu/amd-hardware-list-info.rst
Normal file
23
Documentation/gpu/amdgpu/amd-hardware-list-info.rst
Normal file
|
@ -0,0 +1,23 @@
|
|||
=================================================
|
||||
AMD Hardware Components Information per Product
|
||||
=================================================
|
||||
|
||||
On this page, you can find the AMD product name and which component version is
|
||||
part of it.
|
||||
|
||||
Accelerated Processing Units (APU) Info
|
||||
---------------------------------------
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:widths: 3, 2, 2, 1, 1, 1, 1
|
||||
:file: ./apu-asic-info-table.csv
|
||||
|
||||
Discrete GPU Info
|
||||
-----------------
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:widths: 3, 2, 2, 1, 1, 1
|
||||
:file: ./dgpu-asic-info-table.csv
|
||||
|
|
@ -12,18 +12,39 @@ we have a dedicated glossary for Display Core at
|
|||
The number of CUs that are active on the system. The number of active
|
||||
CUs may be less than SE * SH * CU depending on the board configuration.
|
||||
|
||||
BACO
|
||||
Bus Alive, Chip Off
|
||||
|
||||
BOCO
|
||||
Bus Off, Chip Off
|
||||
|
||||
CE
|
||||
Constant Engine
|
||||
|
||||
CIK
|
||||
Sea Islands
|
||||
|
||||
CB
|
||||
Color Buffer
|
||||
|
||||
CP
|
||||
Command Processor
|
||||
|
||||
CPLIB
|
||||
Content Protection Library
|
||||
|
||||
CS
|
||||
Command Submission
|
||||
|
||||
CSB
|
||||
Clear State Indirect Buffer
|
||||
|
||||
CU
|
||||
Compute Unit
|
||||
|
||||
DB
|
||||
Depth Buffer
|
||||
|
||||
DFS
|
||||
Digital Frequency Synthesizer
|
||||
|
||||
|
@ -33,6 +54,9 @@ we have a dedicated glossary for Display Core at
|
|||
EOP
|
||||
End Of Pipe/Pipeline
|
||||
|
||||
FLR
|
||||
Function Level Reset
|
||||
|
||||
GART
|
||||
Graphics Address Remapping Table. This is the name we use for the GPUVM
|
||||
page table used by the GPU kernel driver. It remaps system resources
|
||||
|
@ -45,6 +69,12 @@ we have a dedicated glossary for Display Core at
|
|||
GC
|
||||
Graphics and Compute
|
||||
|
||||
GDS
|
||||
Global Data Share
|
||||
|
||||
GE
|
||||
Geometry Engine
|
||||
|
||||
GMC
|
||||
Graphic Memory Controller
|
||||
|
||||
|
@ -80,6 +110,9 @@ we have a dedicated glossary for Display Core at
|
|||
KCQ
|
||||
Kernel Compute Queue
|
||||
|
||||
KFD
|
||||
Kernel Fusion Driver
|
||||
|
||||
KGQ
|
||||
Kernel Graphics Queue
|
||||
|
||||
|
@ -89,6 +122,9 @@ we have a dedicated glossary for Display Core at
|
|||
MC
|
||||
Memory Controller
|
||||
|
||||
MCBP
|
||||
Mid Command Buffer Preemption
|
||||
|
||||
ME
|
||||
MicroEngine (Graphics)
|
||||
|
||||
|
@ -104,6 +140,9 @@ we have a dedicated glossary for Display Core at
|
|||
MQD
|
||||
Memory Queue Descriptor
|
||||
|
||||
PA
|
||||
Primitive Assembler / Physical Address
|
||||
|
||||
PFP
|
||||
Pre-Fetch Parser (Graphics)
|
||||
|
||||
|
@ -113,24 +152,39 @@ we have a dedicated glossary for Display Core at
|
|||
PSP
|
||||
Platform Security Processor
|
||||
|
||||
RB
|
||||
Render Backends. Some people called it ROPs.
|
||||
|
||||
RLC
|
||||
RunList Controller. This name is a remnant of past ages and doesn't have
|
||||
much meaning today. It's a group of general-purpose helper engines for
|
||||
the GFX block. It's involved in GFX power management and SR-IOV, among
|
||||
other things.
|
||||
|
||||
SC
|
||||
Scan Converter
|
||||
|
||||
SDMA
|
||||
System DMA
|
||||
|
||||
SE
|
||||
Shader Engine
|
||||
|
||||
SGPR
|
||||
Scalar General-Purpose Registers
|
||||
|
||||
SH
|
||||
SHader array
|
||||
|
||||
SI
|
||||
Southern Islands
|
||||
|
||||
SMU/SMC
|
||||
System Management Unit / System Management Controller
|
||||
|
||||
SPI (AMDGPU)
|
||||
Shader Processor Input
|
||||
|
||||
SRLC
|
||||
Save/Restore List Control
|
||||
|
||||
|
@ -143,12 +197,21 @@ we have a dedicated glossary for Display Core at
|
|||
SS
|
||||
Spread Spectrum
|
||||
|
||||
SX
|
||||
Shader Export
|
||||
|
||||
TA
|
||||
Trusted Application
|
||||
|
||||
TC
|
||||
Texture Cache
|
||||
|
||||
TOC
|
||||
Table of Contents
|
||||
|
||||
UMSCH
|
||||
User Mode Scheduler
|
||||
|
||||
UVD
|
||||
Unified Video Decoder
|
||||
|
||||
|
@ -158,5 +221,17 @@ we have a dedicated glossary for Display Core at
|
|||
VCN
|
||||
Video Codec Next
|
||||
|
||||
VGPR
|
||||
Vector General-Purpose Registers
|
||||
|
||||
VMID
|
||||
Virtual Memory ID
|
||||
|
||||
VPE
|
||||
Video Processing Engine
|
||||
|
||||
XCC
|
||||
Accelerator Core Complex
|
||||
|
||||
XCP
|
||||
Accelerator Core Partition
|
||||
|
|
|
@ -13,3 +13,5 @@ Ryzen 7x20 series, Mendocino, 3.1.6, 10.3.7, 3.1.1, 5.2.7, 13.0.8
|
|||
Ryzen 7x40 series, Phoenix, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11
|
||||
Ryzen 8x40 series, Hawk Point, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11
|
||||
Ryzen AI 300 series, Strix Point, 3.5.0, 11.5.0, 4.0.5, 6.1.0, 14.0.0
|
||||
Ryzen AI 350 series, Krackan Point, 3.5.0, 11.5.2, 4.0.5, 6.1.2, 14.0.4
|
||||
Ryzen AI Max 300 series, Strix Halo, 3.5.1, 11.5.1, 4.0.6, 6.1.1, 14.0.1
|
||||
|
|
|
210
Documentation/gpu/amdgpu/debugfs.rst
Normal file
210
Documentation/gpu/amdgpu/debugfs.rst
Normal file
|
@ -0,0 +1,210 @@
|
|||
==============
|
||||
AMDGPU DebugFS
|
||||
==============
|
||||
|
||||
The amdgpu driver provides a number of debugfs files to aid in debugging
|
||||
issues in the driver. These are usually found in
|
||||
/sys/kernel/debug/dri/<num>.
|
||||
|
||||
DebugFS Files
|
||||
=============
|
||||
|
||||
amdgpu_benchmark
|
||||
----------------
|
||||
|
||||
Run benchmarks using the DMA engine the driver uses for GPU memory paging.
|
||||
Write a number to the file to run the test. The results are written to the
|
||||
kernel log. VRAM is on device memory (dGPUs) or carve out (APUs) and GTT
|
||||
(Graphics Translation Tables) is system memory that is accessible by the GPU.
|
||||
The following tests are available:
|
||||
|
||||
- 1: simple test, VRAM to GTT and GTT to VRAM
|
||||
- 2: simple test, VRAM to VRAM
|
||||
- 3: GTT to VRAM, buffer size sweep, powers of 2
|
||||
- 4: VRAM to GTT, buffer size sweep, powers of 2
|
||||
- 5: VRAM to VRAM, buffer size sweep, powers of 2
|
||||
- 6: GTT to VRAM, buffer size sweep, common display sizes
|
||||
- 7: VRAM to GTT, buffer size sweep, common display sizes
|
||||
- 8: VRAM to VRAM, buffer size sweep, common display sizes
|
||||
|
||||
amdgpu_test_ib
|
||||
--------------
|
||||
|
||||
Read this file to run simple IB (Indirect Buffer) tests on all kernel managed
|
||||
rings. IBs are command buffers usually generated by userspace applications
|
||||
which are submitted to the kernel for execution on an particular GPU engine.
|
||||
This just runs the simple IB tests included in the kernel. These tests
|
||||
are engine specific and verify that IB submission works.
|
||||
|
||||
amdgpu_discovery
|
||||
----------------
|
||||
|
||||
Provides raw access to the IP discovery binary provided by the GPU. Read this
|
||||
file to access the raw binary. This is useful for verifying the contents of
|
||||
the IP discovery table. It is chip specific.
|
||||
|
||||
amdgpu_vbios
|
||||
------------
|
||||
|
||||
Provides raw access to the ROM binary image from the GPU. Read this file to
|
||||
access the raw binary. This is useful for verifying the contents of the
|
||||
video BIOS ROM. It is board specific.
|
||||
|
||||
amdgpu_evict_gtt
|
||||
----------------
|
||||
|
||||
Evict all buffers from the GTT memory pool. Read this file to evict all
|
||||
buffers from this pool.
|
||||
|
||||
amdgpu_evict_vram
|
||||
-----------------
|
||||
|
||||
Evict all buffers from the VRAM memory pool. Read this file to evict all
|
||||
buffers from this pool.
|
||||
|
||||
amdgpu_gpu_recover
|
||||
------------------
|
||||
|
||||
Trigger a GPU reset. Read this file to trigger reset the entire GPU.
|
||||
All work currently running on the GPU will be lost.
|
||||
|
||||
amdgpu_ring_<name>
|
||||
------------------
|
||||
|
||||
Provides read access to the kernel managed ring buffers for each ring <name>.
|
||||
These are useful for debugging problems on a particular ring. The ring buffer
|
||||
is how the CPU sends commands to the GPU. The CPU writes commands into the
|
||||
buffer and then asks the GPU engine to process it. This is the raw binary
|
||||
contents of the ring buffer. Use a tool like UMR to decode the rings into human
|
||||
readable form.
|
||||
|
||||
amdgpu_mqd_<name>
|
||||
-----------------
|
||||
|
||||
Provides read access to the kernel managed MQD (Memory Queue Descriptor) for
|
||||
ring <name> managed by the kernel driver. MQDs define the features of the ring
|
||||
and are used to store the ring's state when it is not connected to hardware.
|
||||
The driver writes the requested ring features and metadata (GPU addresses of
|
||||
the ring itself and associated buffers) to the MQD and the firmware uses the MQD
|
||||
to populate the hardware when the ring is mapped to a hardware slot. Only
|
||||
available on engines which use MQDs. This provides access to the raw MQD
|
||||
binary.
|
||||
|
||||
amdgpu_error_<name>
|
||||
-------------------
|
||||
|
||||
Provides an interface to set an error code on the dma fences associated with
|
||||
ring <name>. The error code specified is propogated to all fences associated
|
||||
with the ring. Use this to inject a fence error into a ring.
|
||||
|
||||
amdgpu_pm_info
|
||||
--------------
|
||||
|
||||
Provides human readable information about the power management features
|
||||
and state of the GPU. This includes current GFX clock, Memory clock,
|
||||
voltages, average SoC power, temperature, GFX load, Memory load, SMU
|
||||
feature mask, VCN power state, clock and power gating features.
|
||||
|
||||
amdgpu_firmware_info
|
||||
--------------------
|
||||
|
||||
Lists the firmware versions for all firmwares used by the GPU. Only
|
||||
entries with a non-0 version are valid. If the version is 0, the firmware
|
||||
is not valid for the GPU.
|
||||
|
||||
amdgpu_fence_info
|
||||
-----------------
|
||||
|
||||
Shows the last signalled and emitted fence sequence numbers for each
|
||||
kernel driver managed ring. Fences are associated with submissions
|
||||
to the engine. Emitted fences have been submitted to the ring
|
||||
and signalled fences have been signalled by the GPU. Rings with a
|
||||
larger emitted fence value have outstanding work that is still being
|
||||
processed by the engine that owns that ring. When the emitted and
|
||||
signalled fence values are equal, the ring is idle.
|
||||
|
||||
amdgpu_gem_info
|
||||
---------------
|
||||
|
||||
Lists all of the PIDs using the GPU and the GPU buffers that they have
|
||||
allocated. This lists the buffer size, pool (VRAM, GTT, etc.), and buffer
|
||||
attributes (CPU access required, CPU cache attributes, etc.).
|
||||
|
||||
amdgpu_vm_info
|
||||
--------------
|
||||
|
||||
Lists all of the PIDs using the GPU and the GPU buffers that they have
|
||||
allocated as well as the status of those buffers relative to that process'
|
||||
GPU virtual address space (e.g., evicted, idle, invalidated, etc.).
|
||||
|
||||
amdgpu_sa_info
|
||||
--------------
|
||||
|
||||
Prints out all of the suballocations (sa) by the suballocation manager in the
|
||||
kernel driver. Prints the GPU address, size, and fence info associated
|
||||
with each suballocation. The suballocations are used internally within
|
||||
the kernel driver for various things.
|
||||
|
||||
amdgpu_<pool>_mm
|
||||
----------------
|
||||
|
||||
Prints TTM information about the memory pool <pool>.
|
||||
|
||||
amdgpu_vram
|
||||
-----------
|
||||
|
||||
Provides direct access to VRAM. Used by tools like UMR to inspect
|
||||
objects in VRAM.
|
||||
|
||||
amdgpu_iomem
|
||||
------------
|
||||
|
||||
Provides direct access to GTT memory. Used by tools like UMR to inspect
|
||||
GTT memory.
|
||||
|
||||
amdgpu_regs_*
|
||||
-------------
|
||||
|
||||
Provides direct access to various register aperatures on the GPU. Used
|
||||
by tools like UMR to access GPU registers.
|
||||
|
||||
amdgpu_regs2
|
||||
------------
|
||||
|
||||
Provides an IOCTL interface used by UMR for interacting with GPU registers.
|
||||
|
||||
|
||||
amdgpu_sensors
|
||||
--------------
|
||||
|
||||
Provides an interface to query GPU power metrics (temperature, average
|
||||
power, etc.). Used by tools like UMR to query GPU power metrics.
|
||||
|
||||
|
||||
amdgpu_gca_config
|
||||
-----------------
|
||||
|
||||
Provides an interface to query GPU details (Graphics/Compute Array config,
|
||||
PCI config, GPU family, etc.). Used by tools like UMR to query GPU details.
|
||||
|
||||
amdgpu_wave
|
||||
-----------
|
||||
|
||||
Used to query GFX/compute wave information from the hardware. Used by tools
|
||||
like UMR to query GFX/compute wave information.
|
||||
|
||||
amdgpu_gpr
|
||||
----------
|
||||
|
||||
Used to query GFX/compute GPR (General Purpose Register) information from the
|
||||
hardware. Used by tools like UMR to query GPRs when debugging shaders.
|
||||
|
||||
amdgpu_gprwave
|
||||
--------------
|
||||
|
||||
Provides an IOCTL interface used by UMR for interacting with shader waves.
|
||||
|
||||
amdgpu_fw_attestation
|
||||
---------------------
|
||||
|
||||
Provides an interface for reading back firmware attestation records.
|
|
@ -2,6 +2,13 @@
|
|||
GPU Debugging
|
||||
===============
|
||||
|
||||
General Debugging Options
|
||||
=========================
|
||||
|
||||
The DebugFS section provides documentation on a number files to aid in debugging
|
||||
issues on the GPU.
|
||||
|
||||
|
||||
GPUVM Debugging
|
||||
===============
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ of the display parameters, but the userspace might also cause this issue. One
|
|||
way to identify the source of the problem is to take a screenshot or make a
|
||||
desktop video capture when the problem happens; after checking the
|
||||
screenshot/video recording, if you don't see any of the artifacts, it means
|
||||
that the issue is likely on the the driver side. If you can still see the
|
||||
that the issue is likely on the driver side. If you can still see the
|
||||
problem in the data collected, it is an issue that probably happened during
|
||||
rendering, and the display code just got the framebuffer already corrupted.
|
||||
|
||||
|
|
|
@ -67,36 +67,66 @@ GC (Graphics and Compute)
|
|||
This is the graphics and compute engine, i.e., the block that
|
||||
encompasses the 3D pipeline and and shader blocks. This is by far the
|
||||
largest block on the GPU. The 3D pipeline has tons of sub-blocks. In
|
||||
addition to that, it also contains the CP microcontrollers (ME, PFP,
|
||||
CE, MEC) and the RLC microcontroller. It's exposed to userspace for
|
||||
user mode drivers (OpenGL, Vulkan, OpenCL, etc.)
|
||||
addition to that, it also contains the CP microcontrollers (ME, PFP, CE,
|
||||
MEC) and the RLC microcontroller. It's exposed to userspace for user mode
|
||||
drivers (OpenGL, Vulkan, OpenCL, etc.). More details in :ref:`Graphics (GFX)
|
||||
and Compute <amdgpu-gc>`.
|
||||
|
||||
VCN (Video Core Next)
|
||||
This is the multi-media engine. It handles video and image encode and
|
||||
decode. It's exposed to userspace for user mode drivers (VA-API,
|
||||
OpenMAX, etc.)
|
||||
|
||||
Graphics and Compute Microcontrollers
|
||||
-------------------------------------
|
||||
.. _pipes-and-queues-description:
|
||||
|
||||
CP (Command Processor)
|
||||
The name for the hardware block that encompasses the front end of the
|
||||
GFX/Compute pipeline. Consists mainly of a bunch of microcontrollers
|
||||
(PFP, ME, CE, MEC). The firmware that runs on these microcontrollers
|
||||
provides the driver interface to interact with the GFX/Compute engine.
|
||||
GFX, Compute, and SDMA Overall Behavior
|
||||
=======================================
|
||||
|
||||
MEC (MicroEngine Compute)
|
||||
This is the microcontroller that controls the compute queues on the
|
||||
GFX/compute engine.
|
||||
.. note:: For simplicity, whenever the term block is used in this section, it
|
||||
means GFX, Compute, and SDMA.
|
||||
|
||||
MES (MicroEngine Scheduler)
|
||||
This is a new engine for managing queues. This is currently unused.
|
||||
GFX, Compute and SDMA share a similar form of operation that can be abstracted
|
||||
to facilitate understanding of the behavior of these blocks. See the figure
|
||||
below illustrating the common components of these blocks:
|
||||
|
||||
RLC (RunList Controller)
|
||||
This is another microcontroller in the GFX/Compute engine. It handles
|
||||
power management related functionality within the GFX/Compute engine.
|
||||
The name is a vestige of old hardware where it was originally added
|
||||
and doesn't really have much relation to what the engine does now.
|
||||
.. kernel-figure:: pipe_and_queue_abstraction.svg
|
||||
|
||||
In the central part of this figure, you can see two hardware elements, one called
|
||||
**Pipes** and another called **Queues**; it is important to highlight that Queues
|
||||
must be associated with a Pipe and vice-versa. Every specific hardware IP may have
|
||||
a different number of Pipes and, in turn, a different number of Queues; for
|
||||
example, GFX 11 has two Pipes and two Queues per Pipe for the GFX front end.
|
||||
|
||||
Pipe is the hardware that processes the instructions available in the Queues;
|
||||
in other words, it is a thread executing the operations inserted in the Queue.
|
||||
One crucial characteristic of Pipes is that they can only execute one Queue at
|
||||
a time; no matter if the hardware has multiple Queues in the Pipe, it only runs
|
||||
one Queue per Pipe.
|
||||
|
||||
Pipes have the mechanics of swapping between queues at the hardware level.
|
||||
Nonetheless, they only make use of Queues that are considered mapped. Pipes can
|
||||
switch between queues based on any of the following inputs:
|
||||
|
||||
1. Command Stream;
|
||||
2. Packet by Packet;
|
||||
3. Other hardware requests the change (e.g., MES).
|
||||
|
||||
Queues within Pipes are defined by the Hardware Queue Descriptors (HQD).
|
||||
Associated with the HQD concept, we have the Memory Queue Descriptor (MQD),
|
||||
which is responsible for storing information about the state of each of the
|
||||
available Queues in the memory. The state of a Queue contains information such
|
||||
as the GPU virtual address of the queue itself, save areas, doorbell, etc. The
|
||||
MQD also stores the HQD registers, which are vital for activating or
|
||||
deactivating a given Queue. The scheduling firmware (e.g., MES) is responsible
|
||||
for loading HQDs from MQDs and vice versa.
|
||||
|
||||
The Queue-switching process can also happen with the firmware requesting the
|
||||
preemption or unmapping of a Queue. The firmware waits for the HQD_ACTIVE bit
|
||||
to change to low before saving the state into the MQD. To make a different
|
||||
Queue become active, the firmware copies the MQD state into the HQD registers
|
||||
and loads any additional state. Finally, it sets the HQD_ACTIVE bit to high to
|
||||
indicate that the queue is active. The Pipe will then execute work from active
|
||||
Queues.
|
||||
|
||||
Driver Structure
|
||||
================
|
||||
|
@ -110,7 +140,8 @@ Some useful constructs:
|
|||
KIQ (Kernel Interface Queue)
|
||||
This is a control queue used by the kernel driver to manage other gfx
|
||||
and compute queues on the GFX/compute engine. You can use it to
|
||||
map/unmap additional queues, etc.
|
||||
map/unmap additional queues, etc. This is replaced by MES on
|
||||
GFX 11 and newer hardware.
|
||||
|
||||
IB (Indirect Buffer)
|
||||
A command buffer for a particular engine. Rather than writing
|
||||
|
|
|
@ -50,23 +50,6 @@ board_info
|
|||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
||||
:doc: board_info
|
||||
|
||||
Accelerated Processing Units (APU) Info
|
||||
---------------------------------------
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:widths: 3, 2, 2, 1, 1, 1, 1
|
||||
:file: ./apu-asic-info-table.csv
|
||||
|
||||
Discrete GPU Info
|
||||
-----------------
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:widths: 3, 2, 2, 1, 1, 1
|
||||
:file: ./dgpu-asic-info-table.csv
|
||||
|
||||
|
||||
GPU Memory Usage Information
|
||||
============================
|
||||
|
||||
|
|
52
Documentation/gpu/amdgpu/gc/index.rst
Normal file
52
Documentation/gpu/amdgpu/gc/index.rst
Normal file
|
@ -0,0 +1,52 @@
|
|||
.. _amdgpu-gc:
|
||||
|
||||
========================================
|
||||
drm/amdgpu - Graphics and Compute (GC)
|
||||
========================================
|
||||
|
||||
The relationship between the CPU and GPU can be described as the
|
||||
producer-consumer problem, where the CPU fills out a buffer with operations
|
||||
(producer) to be executed by the GPU (consumer). The requested operations in
|
||||
the buffer are called Command Packets, which can be summarized as a compressed
|
||||
way of transmitting command information to the graphics controller.
|
||||
|
||||
The component that acts as the front end between the CPU and the GPU is called
|
||||
the Command Processor (CP). This component is responsible for providing greater
|
||||
flexibility to the GC since CP makes it possible to program various aspects of
|
||||
the GPU pipeline. CP also coordinates the communication between the CPU and GPU
|
||||
via a mechanism named **Ring Buffers**, where the CPU appends information to
|
||||
the buffer while the GPU removes operations. It is relevant to highlight that a
|
||||
CPU can add a pointer to the Ring Buffer that points to another region of
|
||||
memory outside the Ring Buffer, and CP can handle it; this mechanism is called
|
||||
**Indirect Buffer (IB)**. CP receives and parses the Command Streams (CS), and
|
||||
writes the operations to the correct hardware blocks.
|
||||
|
||||
Graphics (GFX) and Compute Microcontrollers
|
||||
-------------------------------------------
|
||||
|
||||
GC is a large block, and as a result, it has multiple firmware associated with
|
||||
it. Some of them are:
|
||||
|
||||
CP (Command Processor)
|
||||
The name for the hardware block that encompasses the front end of the
|
||||
GFX/Compute pipeline. Consists mainly of a bunch of microcontrollers
|
||||
(PFP, ME, CE, MEC). The firmware that runs on these microcontrollers
|
||||
provides the driver interface to interact with the GFX/Compute engine.
|
||||
|
||||
MEC (MicroEngine Compute)
|
||||
This is the microcontroller that controls the compute queues on the
|
||||
GFX/compute engine.
|
||||
|
||||
MES (MicroEngine Scheduler)
|
||||
This is the engine for managing queues. For more details check
|
||||
:ref:`MicroEngine Scheduler (MES) <amdgpu-mes>`.
|
||||
|
||||
RLC (RunList Controller)
|
||||
This is another microcontroller in the GFX/Compute engine. It handles
|
||||
power management related functionality within the GFX/Compute engine.
|
||||
The name is a vestige of old hardware where it was originally added
|
||||
and doesn't really have much relation to what the engine does now.
|
||||
|
||||
.. toctree::
|
||||
|
||||
mes.rst
|
38
Documentation/gpu/amdgpu/gc/mes.rst
Normal file
38
Documentation/gpu/amdgpu/gc/mes.rst
Normal file
|
@ -0,0 +1,38 @@
|
|||
.. _amdgpu-mes:
|
||||
|
||||
=============================
|
||||
MicroEngine Scheduler (MES)
|
||||
=============================
|
||||
|
||||
.. note::
|
||||
Queue and ring buffer are used as a synonymous.
|
||||
|
||||
.. note::
|
||||
This section assumes that you are familiar with the concept of Pipes, Queues, and GC.
|
||||
If not, check :ref:`GFX, Compute, and SDMA Overall Behavior<pipes-and-queues-description>`
|
||||
and :ref:`drm/amdgpu - Graphics and Compute (GC) <amdgpu-gc>`.
|
||||
|
||||
Every GFX has a pipe component with one or more hardware queues. Pipes can
|
||||
switch between queues depending on certain conditions, and one of the
|
||||
components that can request a queue switch to a pipe is the MicroEngine
|
||||
Scheduler (MES). Whenever the driver is initialized, it creates one MQD per
|
||||
hardware queue, and then the MQDs are handed to the MES firmware for mapping
|
||||
to:
|
||||
|
||||
1. Kernel Queues (legacy): This queue is statically mapped to HQDs and never
|
||||
preempted. Even though this is a legacy feature, it is the current default, and
|
||||
most existing hardware supports it. When an application submits work to the
|
||||
kernel driver, it submits all of the application command buffers to the kernel
|
||||
queues. The CS IOCTL takes the command buffer from the applications and
|
||||
schedules them on the kernel queue.
|
||||
|
||||
2. User Queues: These queues are dynamically mapped to the HQDs. Regarding the
|
||||
utilization of User Queues, the userspace application will create its user
|
||||
queues and submit work directly to its user queues with no need to IOCTL for
|
||||
each submission and no need to share a single kernel queue.
|
||||
|
||||
In terms of User Queues, MES can dynamically map them to the HQD. If there are
|
||||
more MQDs than HQDs, the MES firmware will preempt other user queues to make
|
||||
sure each queues get a time slice; in other words, MES is a microcontroller
|
||||
that handles the mapping and unmapping of MQDs into HQDs, as well as the
|
||||
priorities and oversubscription of MQDs.
|
|
@ -7,8 +7,10 @@ Next (GCN), Radeon DNA (RDNA), and Compute DNA (CDNA) architectures.
|
|||
|
||||
.. toctree::
|
||||
|
||||
module-parameters
|
||||
driver-core
|
||||
amd-hardware-list-info
|
||||
module-parameters
|
||||
gc/index
|
||||
display/index
|
||||
flashing
|
||||
xgmi
|
||||
|
@ -16,5 +18,6 @@ Next (GCN), Radeon DNA (RDNA), and Compute DNA (CDNA) architectures.
|
|||
thermal
|
||||
driver-misc
|
||||
debugging
|
||||
debugfs
|
||||
process-isolation
|
||||
amdgpu-glossary
|
||||
|
|
1279
Documentation/gpu/amdgpu/pipe_and_queue_abstraction.svg
Normal file
1279
Documentation/gpu/amdgpu/pipe_and_queue_abstraction.svg
Normal file
File diff suppressed because it is too large
Load diff
After Width: | Height: | Size: 61 KiB |
|
@ -115,6 +115,10 @@ created (eg. https://gitlab.freedesktop.org/janedoe/linux/-/pipelines)
|
|||
5. The various jobs will be run and when the pipeline is finished, all jobs
|
||||
should be green unless a regression has been found.
|
||||
|
||||
6. Warnings in the pipeline indicate that lockdep
|
||||
(see Documentation/locking/lockdep-design.rst) issues have been detected
|
||||
during the tests.
|
||||
|
||||
|
||||
How to update test expectations
|
||||
===============================
|
||||
|
|
|
@ -27,3 +27,8 @@ drm/xe uAPI
|
|||
===========
|
||||
|
||||
.. kernel-doc:: include/uapi/drm/xe_drm.h
|
||||
|
||||
drm/asahi uAPI
|
||||
================
|
||||
|
||||
.. kernel-doc:: include/uapi/drm/asahi_drm.h
|
||||
|
|
|
@ -233,6 +233,21 @@ Panel Self Refresh Helper Reference
|
|||
.. kernel-doc:: drivers/gpu/drm/drm_self_refresh_helper.c
|
||||
:export:
|
||||
|
||||
HDMI Atomic State Helpers
|
||||
=========================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/display/drm_hdmi_state_helper.c
|
||||
:doc: hdmi helpers
|
||||
|
||||
Functions Reference
|
||||
-------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/display/drm_hdmi_state_helper.c
|
||||
:export:
|
||||
|
||||
HDCP Helper Functions Reference
|
||||
===============================
|
||||
|
||||
|
|
|
@ -27,3 +27,6 @@ GSP Support
|
|||
|
||||
.. kernel-doc:: drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
|
||||
:doc: GSP message queue element
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
|
||||
:doc: GSP message handling policy
|
||||
|
|
|
@ -102,7 +102,13 @@ Usage:
|
|||
let boot0 = Boot0::read(&bar);
|
||||
pr_info!("Revision: {}\n", boot0.revision());
|
||||
|
||||
Note: a work-in-progress implementation currently resides in
|
||||
`drivers/gpu/nova-core/regs/macros.rs` and is used in nova-core. It would be
|
||||
nice to improve it (possibly using proc macros) and move it to the `kernel`
|
||||
crate so it can be used by other components as well.
|
||||
|
||||
| Complexity: Advanced
|
||||
| Contact: Alexandre Courbot
|
||||
|
||||
Delay / Sleep abstractions
|
||||
--------------------------
|
||||
|
@ -190,16 +196,6 @@ Rust abstraction for debugfs APIs.
|
|||
| Reference: Export GSP log buffers
|
||||
| Complexity: Intermediate
|
||||
|
||||
Vec extensions
|
||||
--------------
|
||||
|
||||
Implement ``Vec::truncate`` and ``Vec::resize``.
|
||||
|
||||
Currently this is used for some experimental code to parse the vBIOS.
|
||||
|
||||
| Reference vBIOS support
|
||||
| Complexity: Beginner
|
||||
|
||||
GPU (general)
|
||||
=============
|
||||
|
||||
|
|
|
@ -441,14 +441,15 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de>
|
|||
|
||||
Level: Intermediate
|
||||
|
||||
Request memory regions in all drivers
|
||||
-------------------------------------
|
||||
Request memory regions in all fbdev drivers
|
||||
--------------------------------------------
|
||||
|
||||
Go through all drivers and add code to request the memory regions that the
|
||||
driver uses. This requires adding calls to request_mem_region(),
|
||||
Old/ancient fbdev drivers do not request their memory properly.
|
||||
Go through these drivers and add code to request the memory regions
|
||||
that the driver uses. This requires adding calls to request_mem_region(),
|
||||
pci_request_region() or similar functions. Use helpers for managed cleanup
|
||||
where possible.
|
||||
|
||||
where possible. Problematic areas include hardware that has exclusive ranges
|
||||
like VGA. VGA16fb does not request the range as it is expected.
|
||||
Drivers are pretty bad at doing this and there used to be conflicts among
|
||||
DRM and fbdev drivers. Still, it's the correct thing to do.
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ Section 7, Legacy Devices.
|
|||
|
||||
The Resource Access Control (RAC) module inside the X server [0] existed for
|
||||
the legacy VGA arbitration task (besides other bus management tasks) when more
|
||||
than one legacy device co-exists on the same machine. But the problem happens
|
||||
than one legacy device co-exist on the same machine. But the problem happens
|
||||
when these devices are trying to be accessed by different userspace clients
|
||||
(e.g. two server in parallel). Their address assignments conflict. Moreover,
|
||||
(e.g. two servers in parallel). Their address assignments conflict. Moreover,
|
||||
ideally, being a userspace application, it is not the role of the X server to
|
||||
control bus resources. Therefore an arbitration scheme outside of the X server
|
||||
is needed to control the sharing of these resources. This document introduces
|
||||
|
@ -106,7 +106,7 @@ In-kernel interface
|
|||
libpciaccess
|
||||
------------
|
||||
|
||||
To use the vga arbiter char device it was implemented an API inside the
|
||||
To use the vga arbiter char device, an API was implemented inside the
|
||||
libpciaccess library. One field was added to struct pci_device (each device
|
||||
on the system)::
|
||||
|
||||
|
|
|
@ -25,3 +25,4 @@ DG2, etc is provided to prototype the driver.
|
|||
xe_debugging
|
||||
xe_devcoredump
|
||||
xe-drm-usage-stats.rst
|
||||
xe_configfs
|
||||
|
|
10
Documentation/gpu/xe/xe_configfs.rst
Normal file
10
Documentation/gpu/xe/xe_configfs.rst
Normal file
|
@ -0,0 +1,10 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
.. _xe_configfs:
|
||||
|
||||
============
|
||||
Xe Configfs
|
||||
============
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/xe/xe_configfs.c
|
||||
:doc: Xe Configfs
|
|
@ -31,6 +31,12 @@ GuC Power Conservation (PC)
|
|||
.. kernel-doc:: drivers/gpu/drm/xe/xe_guc_pc.c
|
||||
:doc: GuC Power Conservation (PC)
|
||||
|
||||
PCIe Gen5 Limitations
|
||||
=====================
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/xe/xe_device_sysfs.c
|
||||
:doc: PCIe Gen5 Limitations
|
||||
|
||||
Internal API
|
||||
============
|
||||
|
||||
|
|
|
@ -12,3 +12,10 @@ Internal API
|
|||
|
||||
.. kernel-doc:: drivers/gpu/drm/xe/xe_pcode.c
|
||||
:internal:
|
||||
|
||||
==================
|
||||
Boot Survivability
|
||||
==================
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/xe/xe_survivability_mode.c
|
||||
:doc: Xe Boot Survivability
|
||||
|
|
55
MAINTAINERS
55
MAINTAINERS
|
@ -2341,6 +2341,7 @@ F: drivers/watchdog/apple_wdt.c
|
|||
F: include/dt-bindings/interrupt-controller/apple-aic.h
|
||||
F: include/dt-bindings/pinctrl/apple.h
|
||||
F: include/linux/soc/apple/*
|
||||
F: include/uapi/drm/asahi_drm.h
|
||||
|
||||
ARM/ARTPEC MACHINE SUPPORT
|
||||
M: Jesper Nilsson <jesper.nilsson@axis.com>
|
||||
|
@ -3916,6 +3917,9 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
|
|||
F: Documentation/driver-api/auxiliary_bus.rst
|
||||
F: drivers/base/auxiliary.c
|
||||
F: include/linux/auxiliary_bus.h
|
||||
F: rust/helpers/auxiliary.c
|
||||
F: rust/kernel/auxiliary.rs
|
||||
F: samples/rust/rust_driver_auxiliary.rs
|
||||
|
||||
AUXILIARY DISPLAY DRIVERS
|
||||
M: Andy Shevchenko <andy@kernel.org>
|
||||
|
@ -7432,8 +7436,7 @@ M: Javier Martinez Canillas <javierm@redhat.com>
|
|||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: drivers/gpu/drm/tiny/ofdrm.c
|
||||
F: drivers/gpu/drm/tiny/simpledrm.c
|
||||
F: drivers/gpu/drm/sysfb/
|
||||
F: drivers/video/aperture.c
|
||||
F: drivers/video/nomodeset.c
|
||||
F: include/linux/aperture.h
|
||||
|
@ -7574,6 +7577,7 @@ S: Maintained
|
|||
B: https://gitlab.freedesktop.org/drm/msm/-/issues
|
||||
T: git https://gitlab.freedesktop.org/drm/msm.git
|
||||
F: Documentation/devicetree/bindings/display/msm/gpu.yaml
|
||||
F: Documentation/devicetree/bindings/opp/opp-v2-qcom-adreno.yaml
|
||||
F: drivers/gpu/drm/msm/adreno/
|
||||
F: drivers/gpu/drm/msm/msm_gpu.*
|
||||
F: drivers/gpu/drm/msm/msm_gpu_devfreq.*
|
||||
|
@ -7627,6 +7631,12 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
|||
F: Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
|
||||
F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c
|
||||
|
||||
DRM DRIVER FOR NOVATEK NT37801 PANELS
|
||||
M: Krzysztof Kozlowski <krzk@kernel.org>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/display/panel/novatek,nt37801.yaml
|
||||
F: drivers/gpu/drm/panel/panel-novatek-nt37801.c
|
||||
|
||||
DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
|
||||
M: Lyude Paul <lyude@redhat.com>
|
||||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
|
@ -7653,6 +7663,18 @@ T: git https://gitlab.freedesktop.org/drm/nova.git nova-next
|
|||
F: Documentation/gpu/nova/
|
||||
F: drivers/gpu/nova-core/
|
||||
|
||||
DRM DRIVER FOR NVIDIA GPUS [RUST]
|
||||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
L: nouveau@lists.freedesktop.org
|
||||
S: Supported
|
||||
Q: https://patchwork.freedesktop.org/project/nouveau/
|
||||
B: https://gitlab.freedesktop.org/drm/nova/-/issues
|
||||
C: irc://irc.oftc.net/nouveau
|
||||
T: git https://gitlab.freedesktop.org/drm/nova.git nova-next
|
||||
F: Documentation/gpu/nova/
|
||||
F: drivers/gpu/drm/nova/
|
||||
F: include/uapi/drm/nova_drm.h
|
||||
|
||||
DRM DRIVER FOR OLIMEX LCD-OLINUXINO PANELS
|
||||
M: Stefan Mavrodiev <stefan@olimex.com>
|
||||
S: Maintained
|
||||
|
@ -7742,7 +7764,13 @@ M: David Lechner <david@lechnology.com>
|
|||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: Documentation/devicetree/bindings/display/sitronix,st7586.txt
|
||||
F: drivers/gpu/drm/tiny/st7586.c
|
||||
F: drivers/gpu/drm/sitronix/st7586.c
|
||||
|
||||
DRM DRIVER FOR SITRONIX ST7571 PANELS
|
||||
M: Marcus Folkesson <marcus.folkesson@gmail.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/display/sitronix,st7571.yaml
|
||||
F: drivers/gpu/drm/sitronix/st7571-i2c.c
|
||||
|
||||
DRM DRIVER FOR SITRONIX ST7701 PANELS
|
||||
M: Jagan Teki <jagan@amarulasolutions.com>
|
||||
|
@ -7763,7 +7791,7 @@ M: David Lechner <david@lechnology.com>
|
|||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: Documentation/devicetree/bindings/display/sitronix,st7735r.yaml
|
||||
F: drivers/gpu/drm/tiny/st7735r.c
|
||||
F: drivers/gpu/drm/sitronix/st7735r.c
|
||||
|
||||
DRM DRIVER FOR SOLOMON SSD130X OLED DISPLAYS
|
||||
M: Javier Martinez Canillas <javierm@redhat.com>
|
||||
|
@ -7860,6 +7888,7 @@ F: Documentation/devicetree/bindings/display/
|
|||
F: Documentation/devicetree/bindings/gpu/
|
||||
F: Documentation/gpu/
|
||||
F: drivers/gpu/
|
||||
F: rust/kernel/drm/
|
||||
F: include/drm/
|
||||
F: include/linux/vga*
|
||||
F: include/uapi/drm/
|
||||
|
@ -7876,6 +7905,7 @@ F: Documentation/devicetree/bindings/gpu/
|
|||
F: Documentation/gpu/
|
||||
F: drivers/gpu/drm/
|
||||
F: drivers/gpu/vga/
|
||||
F: rust/kernel/drm/
|
||||
F: include/drm/drm
|
||||
F: include/linux/vga*
|
||||
F: include/uapi/drm/
|
||||
|
@ -7915,8 +7945,8 @@ F: drivers/gpu/drm/ci/xfails/meson*
|
|||
F: drivers/gpu/drm/meson/
|
||||
|
||||
DRM DRIVERS FOR ATMEL HLCDC
|
||||
M: Sam Ravnborg <sam@ravnborg.org>
|
||||
M: Boris Brezillon <bbrezillon@kernel.org>
|
||||
M: Manikandan Muralidharan <manikandan.m@microchip.com>
|
||||
M: Dharma Balasubiramani <dharma.b@microchip.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
|
@ -8244,7 +8274,8 @@ F: drivers/gpu/drm/ttm/
|
|||
F: include/drm/ttm/
|
||||
|
||||
DRM AUTOMATED TESTING
|
||||
M: Helen Koike <helen.koike@collabora.com>
|
||||
M: Helen Koike <helen.fornazier@gmail.com>
|
||||
M: Vignesh Raman <vignesh.raman@collabora.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
|
@ -12004,13 +12035,10 @@ F: drivers/gpio/gpio-tangier.c
|
|||
F: drivers/gpio/gpio-tangier.h
|
||||
|
||||
INTEL GVT-g DRIVERS (Intel GPU Virtualization)
|
||||
M: Zhenyu Wang <zhenyuw.linux@gmail.com>
|
||||
M: Zhi Wang <zhi.wang.linux@gmail.com>
|
||||
L: intel-gvt-dev@lists.freedesktop.org
|
||||
L: intel-gfx@lists.freedesktop.org
|
||||
S: Supported
|
||||
R: Zhenyu Wang <zhenyuw.linux@gmail.com>
|
||||
R: Zhi Wang <zhi.wang.linux@gmail.com>
|
||||
S: Odd Fixes
|
||||
W: https://github.com/intel/gvt-linux/wiki
|
||||
T: git https://github.com/intel/gvt-linux.git
|
||||
F: drivers/gpu/drm/i915/gvt/
|
||||
|
||||
INTEL HID EVENT DRIVER
|
||||
|
@ -25940,6 +25968,7 @@ F: include/uapi/linux/virtio_gpio.h
|
|||
VIRTIO GPU DRIVER
|
||||
M: David Airlie <airlied@redhat.com>
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
M: Dmitry Osipenko <dmitry.osipenko@collabora.com>
|
||||
R: Gurchetan Singh <gurchetansingh@chromium.org>
|
||||
R: Chia-I Wu <olvaffe@gmail.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
|
|
|
@ -3752,60 +3752,83 @@
|
|||
};
|
||||
|
||||
gpu_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
compatible = "operating-points-v2-adreno", "operating-points-v2";
|
||||
|
||||
opp-1250000000 {
|
||||
opp-hz = /bits/ 64 <1250000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>;
|
||||
opp-peak-kBps = <16500000>;
|
||||
qcom,opp-acd-level = <0xa82a5ffd>;
|
||||
};
|
||||
|
||||
opp-1175000000 {
|
||||
opp-hz = /bits/ 64 <1175000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L2>;
|
||||
opp-peak-kBps = <14398438>;
|
||||
qcom,opp-acd-level = <0xa82a5ffd>;
|
||||
};
|
||||
|
||||
opp-1100000000 {
|
||||
opp-hz = /bits/ 64 <1100000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
|
||||
opp-peak-kBps = <16500000>;
|
||||
opp-peak-kBps = <14398438>;
|
||||
qcom,opp-acd-level = <0xa82a5ffd>;
|
||||
};
|
||||
|
||||
opp-1000000000 {
|
||||
opp-hz = /bits/ 64 <1000000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
|
||||
opp-peak-kBps = <14398438>;
|
||||
qcom,opp-acd-level = <0xa82b5ffd>;
|
||||
};
|
||||
|
||||
opp-925000000 {
|
||||
opp-hz = /bits/ 64 <925000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
|
||||
opp-peak-kBps = <14398438>;
|
||||
qcom,opp-acd-level = <0xa82b5ffd>;
|
||||
};
|
||||
|
||||
opp-800000000 {
|
||||
opp-hz = /bits/ 64 <800000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
|
||||
opp-peak-kBps = <12449219>;
|
||||
qcom,opp-acd-level = <0xa82c5ffd>;
|
||||
};
|
||||
|
||||
opp-744000000 {
|
||||
opp-hz = /bits/ 64 <744000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
|
||||
opp-peak-kBps = <10687500>;
|
||||
qcom,opp-acd-level = <0x882e5ffd>;
|
||||
};
|
||||
|
||||
opp-687000000 {
|
||||
opp-hz = /bits/ 64 <687000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
|
||||
opp-peak-kBps = <8171875>;
|
||||
qcom,opp-acd-level = <0x882e5ffd>;
|
||||
};
|
||||
|
||||
opp-550000000 {
|
||||
opp-hz = /bits/ 64 <550000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
|
||||
opp-peak-kBps = <6074219>;
|
||||
qcom,opp-acd-level = <0xc0285ffd>;
|
||||
};
|
||||
|
||||
opp-390000000 {
|
||||
opp-hz = /bits/ 64 <390000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
|
||||
opp-peak-kBps = <3000000>;
|
||||
qcom,opp-acd-level = <0xc0285ffd>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
|
||||
opp-peak-kBps = <2136719>;
|
||||
qcom,opp-acd-level = <0xc02b5ffd>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
- Add import and export BO support
|
||||
- Add debugfs support
|
||||
- Add debug BO support
|
||||
|
|
|
@ -758,27 +758,42 @@ int aie2_hwctx_config(struct amdxdna_hwctx *hwctx, u32 type, u64 value, void *bu
|
|||
static int aie2_populate_range(struct amdxdna_gem_obj *abo)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
struct mm_struct *mm = abo->mem.notifier.mm;
|
||||
struct hmm_range range = { 0 };
|
||||
struct amdxdna_umap *mapp;
|
||||
unsigned long timeout;
|
||||
struct mm_struct *mm;
|
||||
bool found;
|
||||
int ret;
|
||||
|
||||
XDNA_INFO_ONCE(xdna, "populate memory range %llx size %lx",
|
||||
abo->mem.userptr, abo->mem.size);
|
||||
range.notifier = &abo->mem.notifier;
|
||||
range.start = abo->mem.userptr;
|
||||
range.end = abo->mem.userptr + abo->mem.size;
|
||||
range.hmm_pfns = abo->mem.pfns;
|
||||
range.default_flags = HMM_PFN_REQ_FAULT;
|
||||
|
||||
if (!mmget_not_zero(mm))
|
||||
return -EFAULT;
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
|
||||
again:
|
||||
range.notifier_seq = mmu_interval_read_begin(&abo->mem.notifier);
|
||||
found = false;
|
||||
down_write(&xdna->notifier_lock);
|
||||
list_for_each_entry(mapp, &abo->mem.umap_list, node) {
|
||||
if (mapp->invalid) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
abo->mem.map_invalid = false;
|
||||
up_write(&xdna->notifier_lock);
|
||||
return 0;
|
||||
}
|
||||
kref_get(&mapp->refcnt);
|
||||
up_write(&xdna->notifier_lock);
|
||||
|
||||
XDNA_DBG(xdna, "populate memory range %lx %lx",
|
||||
mapp->vma->vm_start, mapp->vma->vm_end);
|
||||
mm = mapp->notifier.mm;
|
||||
if (!mmget_not_zero(mm)) {
|
||||
amdxdna_umap_put(mapp);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
mapp->range.notifier_seq = mmu_interval_read_begin(&mapp->notifier);
|
||||
mmap_read_lock(mm);
|
||||
ret = hmm_range_fault(&range);
|
||||
ret = hmm_range_fault(&mapp->range);
|
||||
mmap_read_unlock(mm);
|
||||
if (ret) {
|
||||
if (time_after(jiffies, timeout)) {
|
||||
|
@ -786,21 +801,27 @@ again:
|
|||
goto put_mm;
|
||||
}
|
||||
|
||||
if (ret == -EBUSY)
|
||||
if (ret == -EBUSY) {
|
||||
amdxdna_umap_put(mapp);
|
||||
goto again;
|
||||
}
|
||||
|
||||
goto put_mm;
|
||||
}
|
||||
|
||||
down_read(&xdna->notifier_lock);
|
||||
if (mmu_interval_read_retry(&abo->mem.notifier, range.notifier_seq)) {
|
||||
up_read(&xdna->notifier_lock);
|
||||
down_write(&xdna->notifier_lock);
|
||||
if (mmu_interval_read_retry(&mapp->notifier, mapp->range.notifier_seq)) {
|
||||
up_write(&xdna->notifier_lock);
|
||||
amdxdna_umap_put(mapp);
|
||||
goto again;
|
||||
}
|
||||
abo->mem.map_invalid = false;
|
||||
up_read(&xdna->notifier_lock);
|
||||
mapp->invalid = false;
|
||||
up_write(&xdna->notifier_lock);
|
||||
amdxdna_umap_put(mapp);
|
||||
goto again;
|
||||
|
||||
put_mm:
|
||||
amdxdna_umap_put(mapp);
|
||||
mmput(mm);
|
||||
return ret;
|
||||
}
|
||||
|
@ -908,10 +929,6 @@ void aie2_hmm_invalidate(struct amdxdna_gem_obj *abo,
|
|||
struct drm_gem_object *gobj = to_gobj(abo);
|
||||
long ret;
|
||||
|
||||
down_write(&xdna->notifier_lock);
|
||||
abo->mem.map_invalid = true;
|
||||
mmu_interval_set_seq(&abo->mem.notifier, cur_seq);
|
||||
up_write(&xdna->notifier_lock);
|
||||
ret = dma_resv_wait_timeout(gobj->resv, DMA_RESV_USAGE_BOOKKEEP,
|
||||
true, MAX_SCHEDULE_TIMEOUT);
|
||||
if (!ret || ret == -ERESTARTSYS)
|
||||
|
|
|
@ -525,7 +525,7 @@ aie2_cmdlist_fill_one_slot_cf(void *cmd_buf, u32 offset,
|
|||
if (!payload)
|
||||
return -EINVAL;
|
||||
|
||||
if (!slot_cf_has_space(offset, payload_len))
|
||||
if (!slot_has_space(*buf, offset, payload_len))
|
||||
return -ENOSPC;
|
||||
|
||||
buf->cu_idx = cu_idx;
|
||||
|
@ -558,7 +558,7 @@ aie2_cmdlist_fill_one_slot_dpu(void *cmd_buf, u32 offset,
|
|||
if (payload_len < sizeof(*sn) || arg_sz > MAX_DPU_ARGS_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (!slot_dpu_has_space(offset, arg_sz))
|
||||
if (!slot_has_space(*buf, offset, arg_sz))
|
||||
return -ENOSPC;
|
||||
|
||||
buf->inst_buf_addr = sn->buffer;
|
||||
|
@ -569,7 +569,7 @@ aie2_cmdlist_fill_one_slot_dpu(void *cmd_buf, u32 offset,
|
|||
memcpy(buf->args, sn->prop_args, arg_sz);
|
||||
|
||||
/* Accurate buf size to hint firmware to do necessary copy */
|
||||
*size += sizeof(*buf) + arg_sz;
|
||||
*size = sizeof(*buf) + arg_sz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -319,18 +319,16 @@ struct async_event_msg_resp {
|
|||
} __packed;
|
||||
|
||||
#define MAX_CHAIN_CMDBUF_SIZE SZ_4K
|
||||
#define slot_cf_has_space(offset, payload_size) \
|
||||
(MAX_CHAIN_CMDBUF_SIZE - ((offset) + (payload_size)) > \
|
||||
offsetof(struct cmd_chain_slot_execbuf_cf, args[0]))
|
||||
#define slot_has_space(slot, offset, payload_size) \
|
||||
(MAX_CHAIN_CMDBUF_SIZE >= (offset) + (payload_size) + \
|
||||
sizeof(typeof(slot)))
|
||||
|
||||
struct cmd_chain_slot_execbuf_cf {
|
||||
__u32 cu_idx;
|
||||
__u32 arg_cnt;
|
||||
__u32 args[] __counted_by(arg_cnt);
|
||||
};
|
||||
|
||||
#define slot_dpu_has_space(offset, payload_size) \
|
||||
(MAX_CHAIN_CMDBUF_SIZE - ((offset) + (payload_size)) > \
|
||||
offsetof(struct cmd_chain_slot_dpu, args[0]))
|
||||
struct cmd_chain_slot_dpu {
|
||||
__u64 inst_buf_addr;
|
||||
__u32 inst_size;
|
||||
|
|
|
@ -496,11 +496,11 @@ static int amdxdna_drm_submit_execbuf(struct amdxdna_client *client,
|
|||
struct amdxdna_drm_exec_cmd *args)
|
||||
{
|
||||
struct amdxdna_dev *xdna = client->xdna;
|
||||
u32 *arg_bo_hdls;
|
||||
u32 *arg_bo_hdls = NULL;
|
||||
u32 cmd_bo_hdl;
|
||||
int ret;
|
||||
|
||||
if (!args->arg_count || args->arg_count > MAX_ARG_COUNT) {
|
||||
if (args->arg_count > MAX_ARG_COUNT) {
|
||||
XDNA_ERR(xdna, "Invalid arg bo count %d", args->arg_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -512,14 +512,16 @@ static int amdxdna_drm_submit_execbuf(struct amdxdna_client *client,
|
|||
}
|
||||
|
||||
cmd_bo_hdl = (u32)args->cmd_handles;
|
||||
arg_bo_hdls = kcalloc(args->arg_count, sizeof(u32), GFP_KERNEL);
|
||||
if (!arg_bo_hdls)
|
||||
return -ENOMEM;
|
||||
ret = copy_from_user(arg_bo_hdls, u64_to_user_ptr(args->args),
|
||||
args->arg_count * sizeof(u32));
|
||||
if (ret) {
|
||||
ret = -EFAULT;
|
||||
goto free_cmd_bo_hdls;
|
||||
if (args->arg_count) {
|
||||
arg_bo_hdls = kcalloc(args->arg_count, sizeof(u32), GFP_KERNEL);
|
||||
if (!arg_bo_hdls)
|
||||
return -ENOMEM;
|
||||
ret = copy_from_user(arg_bo_hdls, u64_to_user_ptr(args->args),
|
||||
args->arg_count * sizeof(u32));
|
||||
if (ret) {
|
||||
ret = -EFAULT;
|
||||
goto free_cmd_bo_hdls;
|
||||
}
|
||||
}
|
||||
|
||||
ret = amdxdna_cmd_submit(client, cmd_bo_hdl, arg_bo_hdls,
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
#include <drm/drm_gem.h>
|
||||
#include <drm/drm_gem_shmem_helper.h>
|
||||
#include <drm/gpu_scheduler.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-direct.h>
|
||||
#include <linux/iosys-map.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "amdxdna_ctx.h"
|
||||
|
@ -18,6 +21,8 @@
|
|||
|
||||
#define XDNA_MAX_CMD_BO_SIZE SZ_32K
|
||||
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
|
||||
static int
|
||||
amdxdna_gem_insert_node_locked(struct amdxdna_gem_obj *abo, bool use_vmap)
|
||||
{
|
||||
|
@ -55,6 +60,306 @@ amdxdna_gem_insert_node_locked(struct amdxdna_gem_obj *abo, bool use_vmap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool amdxdna_hmm_invalidate(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
{
|
||||
struct amdxdna_umap *mapp = container_of(mni, struct amdxdna_umap, notifier);
|
||||
struct amdxdna_gem_obj *abo = mapp->abo;
|
||||
struct amdxdna_dev *xdna;
|
||||
|
||||
xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
XDNA_DBG(xdna, "Invalidating range 0x%lx, 0x%lx, type %d",
|
||||
mapp->vma->vm_start, mapp->vma->vm_end, abo->type);
|
||||
|
||||
if (!mmu_notifier_range_blockable(range))
|
||||
return false;
|
||||
|
||||
down_write(&xdna->notifier_lock);
|
||||
abo->mem.map_invalid = true;
|
||||
mapp->invalid = true;
|
||||
mmu_interval_set_seq(&mapp->notifier, cur_seq);
|
||||
up_write(&xdna->notifier_lock);
|
||||
|
||||
xdna->dev_info->ops->hmm_invalidate(abo, cur_seq);
|
||||
|
||||
if (range->event == MMU_NOTIFY_UNMAP) {
|
||||
down_write(&xdna->notifier_lock);
|
||||
if (!mapp->unmapped) {
|
||||
queue_work(xdna->notifier_wq, &mapp->hmm_unreg_work);
|
||||
mapp->unmapped = true;
|
||||
}
|
||||
up_write(&xdna->notifier_lock);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct mmu_interval_notifier_ops amdxdna_hmm_ops = {
|
||||
.invalidate = amdxdna_hmm_invalidate,
|
||||
};
|
||||
|
||||
static void amdxdna_hmm_unregister(struct amdxdna_gem_obj *abo,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
struct amdxdna_umap *mapp;
|
||||
|
||||
down_read(&xdna->notifier_lock);
|
||||
list_for_each_entry(mapp, &abo->mem.umap_list, node) {
|
||||
if (!vma || mapp->vma == vma) {
|
||||
if (!mapp->unmapped) {
|
||||
queue_work(xdna->notifier_wq, &mapp->hmm_unreg_work);
|
||||
mapp->unmapped = true;
|
||||
}
|
||||
if (vma)
|
||||
break;
|
||||
}
|
||||
}
|
||||
up_read(&xdna->notifier_lock);
|
||||
}
|
||||
|
||||
static void amdxdna_umap_release(struct kref *ref)
|
||||
{
|
||||
struct amdxdna_umap *mapp = container_of(ref, struct amdxdna_umap, refcnt);
|
||||
struct vm_area_struct *vma = mapp->vma;
|
||||
struct amdxdna_dev *xdna;
|
||||
|
||||
mmu_interval_notifier_remove(&mapp->notifier);
|
||||
if (is_import_bo(mapp->abo) && vma->vm_file && vma->vm_file->f_mapping)
|
||||
mapping_clear_unevictable(vma->vm_file->f_mapping);
|
||||
|
||||
xdna = to_xdna_dev(to_gobj(mapp->abo)->dev);
|
||||
down_write(&xdna->notifier_lock);
|
||||
list_del(&mapp->node);
|
||||
up_write(&xdna->notifier_lock);
|
||||
|
||||
kvfree(mapp->range.hmm_pfns);
|
||||
kfree(mapp);
|
||||
}
|
||||
|
||||
void amdxdna_umap_put(struct amdxdna_umap *mapp)
|
||||
{
|
||||
kref_put(&mapp->refcnt, amdxdna_umap_release);
|
||||
}
|
||||
|
||||
static void amdxdna_hmm_unreg_work(struct work_struct *work)
|
||||
{
|
||||
struct amdxdna_umap *mapp = container_of(work, struct amdxdna_umap,
|
||||
hmm_unreg_work);
|
||||
|
||||
amdxdna_umap_put(mapp);
|
||||
}
|
||||
|
||||
static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
unsigned long len = vma->vm_end - vma->vm_start;
|
||||
unsigned long addr = vma->vm_start;
|
||||
struct amdxdna_umap *mapp;
|
||||
u32 nr_pages;
|
||||
int ret;
|
||||
|
||||
if (!xdna->dev_info->ops->hmm_invalidate)
|
||||
return 0;
|
||||
|
||||
mapp = kzalloc(sizeof(*mapp), GFP_KERNEL);
|
||||
if (!mapp)
|
||||
return -ENOMEM;
|
||||
|
||||
nr_pages = (PAGE_ALIGN(addr + len) - (addr & PAGE_MASK)) >> PAGE_SHIFT;
|
||||
mapp->range.hmm_pfns = kvcalloc(nr_pages, sizeof(*mapp->range.hmm_pfns),
|
||||
GFP_KERNEL);
|
||||
if (!mapp->range.hmm_pfns) {
|
||||
ret = -ENOMEM;
|
||||
goto free_map;
|
||||
}
|
||||
|
||||
ret = mmu_interval_notifier_insert_locked(&mapp->notifier,
|
||||
current->mm,
|
||||
addr,
|
||||
len,
|
||||
&amdxdna_hmm_ops);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Insert mmu notifier failed, ret %d", ret);
|
||||
goto free_pfns;
|
||||
}
|
||||
|
||||
mapp->range.notifier = &mapp->notifier;
|
||||
mapp->range.start = vma->vm_start;
|
||||
mapp->range.end = vma->vm_end;
|
||||
mapp->range.default_flags = HMM_PFN_REQ_FAULT;
|
||||
mapp->vma = vma;
|
||||
mapp->abo = abo;
|
||||
kref_init(&mapp->refcnt);
|
||||
|
||||
if (abo->mem.userptr == AMDXDNA_INVALID_ADDR)
|
||||
abo->mem.userptr = addr;
|
||||
INIT_WORK(&mapp->hmm_unreg_work, amdxdna_hmm_unreg_work);
|
||||
if (is_import_bo(abo) && vma->vm_file && vma->vm_file->f_mapping)
|
||||
mapping_set_unevictable(vma->vm_file->f_mapping);
|
||||
|
||||
down_write(&xdna->notifier_lock);
|
||||
list_add_tail(&mapp->node, &abo->mem.umap_list);
|
||||
up_write(&xdna->notifier_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
free_pfns:
|
||||
kvfree(mapp->range.hmm_pfns);
|
||||
free_map:
|
||||
kfree(mapp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdxdna_insert_pages(struct amdxdna_gem_obj *abo,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
unsigned long num_pages = vma_pages(vma);
|
||||
unsigned long offset = 0;
|
||||
int ret;
|
||||
|
||||
if (!is_import_bo(abo)) {
|
||||
ret = drm_gem_shmem_mmap(&abo->base, vma);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Failed shmem mmap %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The buffer is based on memory pages. Fix the flag. */
|
||||
vm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP);
|
||||
ret = vm_insert_pages(vma, vma->vm_start, abo->base.pages,
|
||||
&num_pages);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Failed insert pages %d", ret);
|
||||
vma->vm_ops->close(vma);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
vma->vm_private_data = NULL;
|
||||
vma->vm_ops = NULL;
|
||||
ret = dma_buf_mmap(to_gobj(abo)->dma_buf, vma, 0);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Failed to mmap dma buf %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
do {
|
||||
vm_fault_t fault_ret;
|
||||
|
||||
fault_ret = handle_mm_fault(vma, vma->vm_start + offset,
|
||||
FAULT_FLAG_WRITE, NULL);
|
||||
if (fault_ret & VM_FAULT_ERROR) {
|
||||
vma->vm_ops->close(vma);
|
||||
XDNA_ERR(xdna, "Fault in page failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
offset += PAGE_SIZE;
|
||||
} while (--num_pages);
|
||||
|
||||
/* Drop the reference drm_gem_mmap_obj() acquired.*/
|
||||
drm_gem_object_put(to_gobj(abo));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdxdna_gem_obj_mmap(struct drm_gem_object *gobj,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev);
|
||||
struct amdxdna_gem_obj *abo = to_xdna_obj(gobj);
|
||||
int ret;
|
||||
|
||||
ret = amdxdna_hmm_register(abo, vma);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = amdxdna_insert_pages(abo, vma);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Failed insert pages, ret %d", ret);
|
||||
goto hmm_unreg;
|
||||
}
|
||||
|
||||
XDNA_DBG(xdna, "BO map_offset 0x%llx type %d userptr 0x%lx size 0x%lx",
|
||||
drm_vma_node_offset_addr(&gobj->vma_node), abo->type,
|
||||
vma->vm_start, gobj->size);
|
||||
return 0;
|
||||
|
||||
hmm_unreg:
|
||||
amdxdna_hmm_unregister(abo, vma);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdxdna_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
|
||||
{
|
||||
struct drm_gem_object *gobj = dma_buf->priv;
|
||||
struct amdxdna_gem_obj *abo = to_xdna_obj(gobj);
|
||||
unsigned long num_pages = vma_pages(vma);
|
||||
int ret;
|
||||
|
||||
vma->vm_ops = &drm_gem_shmem_vm_ops;
|
||||
vma->vm_private_data = gobj;
|
||||
|
||||
drm_gem_object_get(gobj);
|
||||
ret = drm_gem_shmem_mmap(&abo->base, vma);
|
||||
if (ret)
|
||||
goto put_obj;
|
||||
|
||||
/* The buffer is based on memory pages. Fix the flag. */
|
||||
vm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP);
|
||||
ret = vm_insert_pages(vma, vma->vm_start, abo->base.pages,
|
||||
&num_pages);
|
||||
if (ret)
|
||||
goto close_vma;
|
||||
|
||||
return 0;
|
||||
|
||||
close_vma:
|
||||
vma->vm_ops->close(vma);
|
||||
put_obj:
|
||||
drm_gem_object_put(gobj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dma_buf_ops amdxdna_dmabuf_ops = {
|
||||
.attach = drm_gem_map_attach,
|
||||
.detach = drm_gem_map_detach,
|
||||
.map_dma_buf = drm_gem_map_dma_buf,
|
||||
.unmap_dma_buf = drm_gem_unmap_dma_buf,
|
||||
.release = drm_gem_dmabuf_release,
|
||||
.mmap = amdxdna_gem_dmabuf_mmap,
|
||||
.vmap = drm_gem_dmabuf_vmap,
|
||||
.vunmap = drm_gem_dmabuf_vunmap,
|
||||
};
|
||||
|
||||
static struct dma_buf *amdxdna_gem_prime_export(struct drm_gem_object *gobj, int flags)
|
||||
{
|
||||
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
||||
|
||||
exp_info.ops = &amdxdna_dmabuf_ops;
|
||||
exp_info.size = gobj->size;
|
||||
exp_info.flags = flags;
|
||||
exp_info.priv = gobj;
|
||||
exp_info.resv = gobj->resv;
|
||||
|
||||
return drm_gem_dmabuf_export(gobj->dev, &exp_info);
|
||||
}
|
||||
|
||||
static void amdxdna_imported_obj_free(struct amdxdna_gem_obj *abo)
|
||||
{
|
||||
dma_buf_unmap_attachment_unlocked(abo->attach, abo->base.sgt, DMA_BIDIRECTIONAL);
|
||||
dma_buf_detach(abo->dma_buf, abo->attach);
|
||||
dma_buf_put(abo->dma_buf);
|
||||
drm_gem_object_release(to_gobj(abo));
|
||||
kfree(abo);
|
||||
}
|
||||
|
||||
static void amdxdna_gem_obj_free(struct drm_gem_object *gobj)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev);
|
||||
|
@ -62,6 +367,10 @@ static void amdxdna_gem_obj_free(struct drm_gem_object *gobj)
|
|||
struct iosys_map map = IOSYS_MAP_INIT_VADDR(abo->mem.kva);
|
||||
|
||||
XDNA_DBG(xdna, "BO type %d xdna_addr 0x%llx", abo->type, abo->mem.dev_addr);
|
||||
|
||||
amdxdna_hmm_unregister(abo, NULL);
|
||||
flush_workqueue(xdna->notifier_wq);
|
||||
|
||||
if (abo->pinned)
|
||||
amdxdna_gem_unpin(abo);
|
||||
|
||||
|
@ -81,8 +390,14 @@ static void amdxdna_gem_obj_free(struct drm_gem_object *gobj)
|
|||
if (abo->type == AMDXDNA_BO_DEV_HEAP)
|
||||
drm_mm_takedown(&abo->mm);
|
||||
|
||||
drm_gem_vunmap_unlocked(gobj, &map);
|
||||
drm_gem_vunmap(gobj, &map);
|
||||
mutex_destroy(&abo->lock);
|
||||
|
||||
if (is_import_bo(abo)) {
|
||||
amdxdna_imported_obj_free(abo);
|
||||
return;
|
||||
}
|
||||
|
||||
drm_gem_shmem_free(&abo->base);
|
||||
}
|
||||
|
||||
|
@ -90,127 +405,6 @@ static const struct drm_gem_object_funcs amdxdna_gem_dev_obj_funcs = {
|
|||
.free = amdxdna_gem_obj_free,
|
||||
};
|
||||
|
||||
static bool amdxdna_hmm_invalidate(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
{
|
||||
struct amdxdna_gem_obj *abo = container_of(mni, struct amdxdna_gem_obj,
|
||||
mem.notifier);
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
|
||||
XDNA_DBG(xdna, "Invalid range 0x%llx, 0x%lx, type %d",
|
||||
abo->mem.userptr, abo->mem.size, abo->type);
|
||||
|
||||
if (!mmu_notifier_range_blockable(range))
|
||||
return false;
|
||||
|
||||
xdna->dev_info->ops->hmm_invalidate(abo, cur_seq);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct mmu_interval_notifier_ops amdxdna_hmm_ops = {
|
||||
.invalidate = amdxdna_hmm_invalidate,
|
||||
};
|
||||
|
||||
static void amdxdna_hmm_unregister(struct amdxdna_gem_obj *abo)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
|
||||
if (!xdna->dev_info->ops->hmm_invalidate)
|
||||
return;
|
||||
|
||||
mmu_interval_notifier_remove(&abo->mem.notifier);
|
||||
kvfree(abo->mem.pfns);
|
||||
abo->mem.pfns = NULL;
|
||||
}
|
||||
|
||||
static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo, unsigned long addr,
|
||||
size_t len)
|
||||
{
|
||||
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
u32 nr_pages;
|
||||
int ret;
|
||||
|
||||
if (!xdna->dev_info->ops->hmm_invalidate)
|
||||
return 0;
|
||||
|
||||
if (abo->mem.pfns)
|
||||
return -EEXIST;
|
||||
|
||||
nr_pages = (PAGE_ALIGN(addr + len) - (addr & PAGE_MASK)) >> PAGE_SHIFT;
|
||||
abo->mem.pfns = kvcalloc(nr_pages, sizeof(*abo->mem.pfns),
|
||||
GFP_KERNEL);
|
||||
if (!abo->mem.pfns)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mmu_interval_notifier_insert_locked(&abo->mem.notifier,
|
||||
current->mm,
|
||||
addr,
|
||||
len,
|
||||
&amdxdna_hmm_ops);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Insert mmu notifier failed, ret %d", ret);
|
||||
kvfree(abo->mem.pfns);
|
||||
}
|
||||
abo->mem.userptr = addr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdxdna_gem_obj_mmap(struct drm_gem_object *gobj,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct amdxdna_gem_obj *abo = to_xdna_obj(gobj);
|
||||
unsigned long num_pages;
|
||||
int ret;
|
||||
|
||||
ret = amdxdna_hmm_register(abo, vma->vm_start, gobj->size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_gem_shmem_mmap(&abo->base, vma);
|
||||
if (ret)
|
||||
goto hmm_unreg;
|
||||
|
||||
num_pages = gobj->size >> PAGE_SHIFT;
|
||||
/* Try to insert the pages */
|
||||
vm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP);
|
||||
ret = vm_insert_pages(vma, vma->vm_start, abo->base.pages, &num_pages);
|
||||
if (ret)
|
||||
XDNA_ERR(abo->client->xdna, "Failed insert pages, ret %d", ret);
|
||||
|
||||
return 0;
|
||||
|
||||
hmm_unreg:
|
||||
amdxdna_hmm_unregister(abo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static vm_fault_t amdxdna_gem_vm_fault(struct vm_fault *vmf)
|
||||
{
|
||||
return drm_gem_shmem_vm_ops.fault(vmf);
|
||||
}
|
||||
|
||||
static void amdxdna_gem_vm_open(struct vm_area_struct *vma)
|
||||
{
|
||||
drm_gem_shmem_vm_ops.open(vma);
|
||||
}
|
||||
|
||||
static void amdxdna_gem_vm_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct drm_gem_object *gobj = vma->vm_private_data;
|
||||
|
||||
amdxdna_hmm_unregister(to_xdna_obj(gobj));
|
||||
drm_gem_shmem_vm_ops.close(vma);
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct amdxdna_gem_vm_ops = {
|
||||
.fault = amdxdna_gem_vm_fault,
|
||||
.open = amdxdna_gem_vm_open,
|
||||
.close = amdxdna_gem_vm_close,
|
||||
};
|
||||
|
||||
static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = {
|
||||
.free = amdxdna_gem_obj_free,
|
||||
.print_info = drm_gem_shmem_object_print_info,
|
||||
|
@ -220,7 +414,8 @@ static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = {
|
|||
.vmap = drm_gem_shmem_object_vmap,
|
||||
.vunmap = drm_gem_shmem_object_vunmap,
|
||||
.mmap = amdxdna_gem_obj_mmap,
|
||||
.vm_ops = &amdxdna_gem_vm_ops,
|
||||
.vm_ops = &drm_gem_shmem_vm_ops,
|
||||
.export = amdxdna_gem_prime_export,
|
||||
};
|
||||
|
||||
static struct amdxdna_gem_obj *
|
||||
|
@ -239,6 +434,7 @@ amdxdna_gem_create_obj(struct drm_device *dev, size_t size)
|
|||
abo->mem.userptr = AMDXDNA_INVALID_ADDR;
|
||||
abo->mem.dev_addr = AMDXDNA_INVALID_ADDR;
|
||||
abo->mem.size = size;
|
||||
INIT_LIST_HEAD(&abo->mem.umap_list);
|
||||
|
||||
return abo;
|
||||
}
|
||||
|
@ -258,6 +454,51 @@ amdxdna_gem_create_object_cb(struct drm_device *dev, size_t size)
|
|||
return to_gobj(abo);
|
||||
}
|
||||
|
||||
struct drm_gem_object *
|
||||
amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf)
|
||||
{
|
||||
struct dma_buf_attachment *attach;
|
||||
struct amdxdna_gem_obj *abo;
|
||||
struct drm_gem_object *gobj;
|
||||
struct sg_table *sgt;
|
||||
int ret;
|
||||
|
||||
get_dma_buf(dma_buf);
|
||||
|
||||
attach = dma_buf_attach(dma_buf, dev->dev);
|
||||
if (IS_ERR(attach)) {
|
||||
ret = PTR_ERR(attach);
|
||||
goto put_buf;
|
||||
}
|
||||
|
||||
sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
|
||||
if (IS_ERR(sgt)) {
|
||||
ret = PTR_ERR(sgt);
|
||||
goto fail_detach;
|
||||
}
|
||||
|
||||
gobj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt);
|
||||
if (IS_ERR(gobj)) {
|
||||
ret = PTR_ERR(gobj);
|
||||
goto fail_unmap;
|
||||
}
|
||||
|
||||
abo = to_xdna_obj(gobj);
|
||||
abo->attach = attach;
|
||||
abo->dma_buf = dma_buf;
|
||||
|
||||
return gobj;
|
||||
|
||||
fail_unmap:
|
||||
dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
|
||||
fail_detach:
|
||||
dma_buf_detach(dma_buf, attach);
|
||||
put_buf:
|
||||
dma_buf_put(dma_buf);
|
||||
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static struct amdxdna_gem_obj *
|
||||
amdxdna_drm_alloc_shmem(struct drm_device *dev,
|
||||
struct amdxdna_drm_create_bo *args,
|
||||
|
@ -417,7 +658,7 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev,
|
|||
abo->type = AMDXDNA_BO_CMD;
|
||||
abo->client = filp->driver_priv;
|
||||
|
||||
ret = drm_gem_vmap_unlocked(to_gobj(abo), &map);
|
||||
ret = drm_gem_vmap(to_gobj(abo), &map);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret);
|
||||
goto release_obj;
|
||||
|
@ -483,6 +724,9 @@ int amdxdna_gem_pin_nolock(struct amdxdna_gem_obj *abo)
|
|||
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
|
||||
int ret;
|
||||
|
||||
if (is_import_bo(abo))
|
||||
return 0;
|
||||
|
||||
switch (abo->type) {
|
||||
case AMDXDNA_BO_SHMEM:
|
||||
case AMDXDNA_BO_DEV_HEAP:
|
||||
|
@ -515,6 +759,9 @@ int amdxdna_gem_pin(struct amdxdna_gem_obj *abo)
|
|||
|
||||
void amdxdna_gem_unpin(struct amdxdna_gem_obj *abo)
|
||||
{
|
||||
if (is_import_bo(abo))
|
||||
return;
|
||||
|
||||
if (abo->type == AMDXDNA_BO_DEV)
|
||||
abo = abo->dev_heap;
|
||||
|
||||
|
@ -606,7 +853,9 @@ int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev,
|
|||
goto put_obj;
|
||||
}
|
||||
|
||||
if (abo->type == AMDXDNA_BO_DEV)
|
||||
if (is_import_bo(abo))
|
||||
drm_clflush_sg(abo->base.sgt);
|
||||
else if (abo->type == AMDXDNA_BO_DEV)
|
||||
drm_clflush_pages(abo->mem.pages, abo->mem.nr_pages);
|
||||
else
|
||||
drm_clflush_pages(abo->base.pages, gobj->size >> PAGE_SHIFT);
|
||||
|
|
|
@ -6,6 +6,20 @@
|
|||
#ifndef _AMDXDNA_GEM_H_
|
||||
#define _AMDXDNA_GEM_H_
|
||||
|
||||
#include <linux/hmm.h>
|
||||
|
||||
struct amdxdna_umap {
|
||||
struct vm_area_struct *vma;
|
||||
struct mmu_interval_notifier notifier;
|
||||
struct hmm_range range;
|
||||
struct work_struct hmm_unreg_work;
|
||||
struct amdxdna_gem_obj *abo;
|
||||
struct list_head node;
|
||||
struct kref refcnt;
|
||||
bool invalid;
|
||||
bool unmapped;
|
||||
};
|
||||
|
||||
struct amdxdna_mem {
|
||||
u64 userptr;
|
||||
void *kva;
|
||||
|
@ -13,8 +27,7 @@ struct amdxdna_mem {
|
|||
size_t size;
|
||||
struct page **pages;
|
||||
u32 nr_pages;
|
||||
struct mmu_interval_notifier notifier;
|
||||
unsigned long *pfns;
|
||||
struct list_head umap_list;
|
||||
bool map_invalid;
|
||||
};
|
||||
|
||||
|
@ -31,9 +44,12 @@ struct amdxdna_gem_obj {
|
|||
struct amdxdna_gem_obj *dev_heap; /* For AMDXDNA_BO_DEV */
|
||||
struct drm_mm_node mm_node; /* For AMDXDNA_BO_DEV */
|
||||
u32 assigned_hwctx;
|
||||
struct dma_buf *dma_buf;
|
||||
struct dma_buf_attachment *attach;
|
||||
};
|
||||
|
||||
#define to_gobj(obj) (&(obj)->base.base)
|
||||
#define is_import_bo(obj) ((obj)->attach)
|
||||
|
||||
static inline struct amdxdna_gem_obj *to_xdna_obj(struct drm_gem_object *gobj)
|
||||
{
|
||||
|
@ -47,8 +63,12 @@ static inline void amdxdna_gem_put_obj(struct amdxdna_gem_obj *abo)
|
|||
drm_gem_object_put(to_gobj(abo));
|
||||
}
|
||||
|
||||
void amdxdna_umap_put(struct amdxdna_umap *mapp);
|
||||
|
||||
struct drm_gem_object *
|
||||
amdxdna_gem_create_object_cb(struct drm_device *dev, size_t size);
|
||||
struct drm_gem_object *
|
||||
amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf);
|
||||
struct amdxdna_gem_obj *
|
||||
amdxdna_drm_alloc_dev_bo(struct drm_device *dev,
|
||||
struct amdxdna_drm_create_bo *args,
|
||||
|
|
|
@ -226,6 +226,7 @@ const struct drm_driver amdxdna_drm_drv = {
|
|||
.num_ioctls = ARRAY_SIZE(amdxdna_drm_ioctls),
|
||||
|
||||
.gem_create_object = amdxdna_gem_create_object_cb,
|
||||
.gem_prime_import = amdxdna_gem_prime_import,
|
||||
};
|
||||
|
||||
static const struct amdxdna_dev_info *
|
||||
|
@ -266,12 +267,16 @@ static int amdxdna_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
fs_reclaim_release(GFP_KERNEL);
|
||||
}
|
||||
|
||||
xdna->notifier_wq = alloc_ordered_workqueue("notifier_wq", 0);
|
||||
if (!xdna->notifier_wq)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&xdna->dev_lock);
|
||||
ret = xdna->dev_info->ops->init(xdna);
|
||||
mutex_unlock(&xdna->dev_lock);
|
||||
if (ret) {
|
||||
XDNA_ERR(xdna, "Hardware init failed, ret %d", ret);
|
||||
return ret;
|
||||
goto destroy_notifier_wq;
|
||||
}
|
||||
|
||||
ret = amdxdna_sysfs_init(xdna);
|
||||
|
@ -301,6 +306,8 @@ failed_dev_fini:
|
|||
mutex_lock(&xdna->dev_lock);
|
||||
xdna->dev_info->ops->fini(xdna);
|
||||
mutex_unlock(&xdna->dev_lock);
|
||||
destroy_notifier_wq:
|
||||
destroy_workqueue(xdna->notifier_wq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -310,6 +317,8 @@ static void amdxdna_remove(struct pci_dev *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct amdxdna_client *client;
|
||||
|
||||
destroy_workqueue(xdna->notifier_wq);
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_forbid(dev);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef _AMDXDNA_PCI_DRV_H_
|
||||
#define _AMDXDNA_PCI_DRV_H_
|
||||
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/xarray.h>
|
||||
|
||||
#define XDNA_INFO(xdna, fmt, args...) drm_info(&(xdna)->ddev, fmt, ##args)
|
||||
|
@ -98,6 +99,7 @@ struct amdxdna_dev {
|
|||
struct list_head client_list;
|
||||
struct amdxdna_fw_ver fw_ver;
|
||||
struct rw_semaphore notifier_lock; /* for mmu notifier*/
|
||||
struct workqueue_struct *notifier_wq;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -374,6 +374,9 @@ int ivpu_boot(struct ivpu_device *vdev)
|
|||
{
|
||||
int ret;
|
||||
|
||||
drm_WARN_ON(&vdev->drm, atomic_read(&vdev->job_timeout_counter));
|
||||
drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa));
|
||||
|
||||
/* Update boot params located at first 4KB of FW memory */
|
||||
ivpu_fw_boot_params_setup(vdev, ivpu_bo_vaddr(vdev->fw->mem));
|
||||
|
||||
|
@ -573,6 +576,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
|
|||
vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID;
|
||||
vdev->context_xa_limit.max = IVPU_USER_CONTEXT_MAX_SSID;
|
||||
atomic64_set(&vdev->unique_id_counter, 0);
|
||||
atomic_set(&vdev->job_timeout_counter, 0);
|
||||
xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
|
||||
xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1);
|
||||
xa_init_flags(&vdev->db_xa, XA_FLAGS_ALLOC1);
|
||||
|
|
|
@ -154,6 +154,7 @@ struct ivpu_device {
|
|||
struct mutex submitted_jobs_lock; /* Protects submitted_jobs */
|
||||
struct xarray submitted_jobs_xa;
|
||||
struct ivpu_ipc_consumer job_done_consumer;
|
||||
atomic_t job_timeout_counter;
|
||||
|
||||
atomic64_t unique_id_counter;
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ struct ivpu_fw_info {
|
|||
u64 read_only_addr;
|
||||
u32 read_only_size;
|
||||
u32 sched_mode;
|
||||
u64 last_heartbeat;
|
||||
};
|
||||
|
||||
int ivpu_fw_init(struct ivpu_device *vdev);
|
||||
|
|
|
@ -30,7 +30,7 @@ static inline void ivpu_dbg_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, con
|
|||
"%6s: bo %8p vpu_addr %9llx size %8zu ctx %d has_pages %d dma_mapped %d mmu_mapped %d wc %d imported %d\n",
|
||||
action, bo, bo->vpu_addr, ivpu_bo_size(bo), bo->ctx ? bo->ctx->id : 0,
|
||||
(bool)bo->base.pages, (bool)bo->base.sgt, bo->mmu_mapped, bo->base.map_wc,
|
||||
(bool)bo->base.base.import_attach);
|
||||
(bool)drm_gem_is_imported(&bo->base.base));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -122,7 +122,7 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo)
|
|||
bo->ctx = NULL;
|
||||
}
|
||||
|
||||
if (bo->base.base.import_attach)
|
||||
if (drm_gem_is_imported(&bo->base.base))
|
||||
return;
|
||||
|
||||
dma_resv_lock(bo->base.base.resv, NULL);
|
||||
|
@ -282,7 +282,7 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj)
|
|||
ivpu_bo_unbind_locked(bo);
|
||||
mutex_destroy(&bo->lock);
|
||||
|
||||
drm_WARN_ON(obj->dev, bo->base.pages_use_count > 1);
|
||||
drm_WARN_ON(obj->dev, refcount_read(&bo->base.pages_use_count) > 1);
|
||||
drm_gem_shmem_free(&bo->base);
|
||||
}
|
||||
|
||||
|
@ -362,7 +362,7 @@ ivpu_bo_create(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
|
|||
|
||||
if (flags & DRM_IVPU_BO_MAPPABLE) {
|
||||
dma_resv_lock(bo->base.base.resv, NULL);
|
||||
ret = drm_gem_shmem_vmap(&bo->base, &map);
|
||||
ret = drm_gem_shmem_vmap_locked(&bo->base, &map);
|
||||
dma_resv_unlock(bo->base.base.resv);
|
||||
|
||||
if (ret)
|
||||
|
@ -387,7 +387,7 @@ void ivpu_bo_free(struct ivpu_bo *bo)
|
|||
|
||||
if (bo->flags & DRM_IVPU_BO_MAPPABLE) {
|
||||
dma_resv_lock(bo->base.base.resv, NULL);
|
||||
drm_gem_shmem_vunmap(&bo->base, &map);
|
||||
drm_gem_shmem_vunmap_locked(&bo->base, &map);
|
||||
dma_resv_unlock(bo->base.base.resv);
|
||||
}
|
||||
|
||||
|
@ -461,7 +461,7 @@ static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p)
|
|||
if (bo->mmu_mapped)
|
||||
drm_printf(p, " mmu_mapped");
|
||||
|
||||
if (bo->base.base.import_attach)
|
||||
if (drm_gem_is_imported(&bo->base.base))
|
||||
drm_printf(p, " imported");
|
||||
|
||||
drm_printf(p, "\n");
|
||||
|
|
|
@ -34,6 +34,7 @@ module_param_named(tdr_timeout_ms, ivpu_tdr_timeout_ms, ulong, 0644);
|
|||
MODULE_PARM_DESC(tdr_timeout_ms, "Timeout for device hang detection, in milliseconds, 0 - default");
|
||||
|
||||
#define PM_RESCHEDULE_LIMIT 5
|
||||
#define PM_TDR_HEARTBEAT_LIMIT 30
|
||||
|
||||
static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev)
|
||||
{
|
||||
|
@ -44,6 +45,7 @@ static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev)
|
|||
ivpu_fw_log_reset(vdev);
|
||||
ivpu_fw_load(vdev);
|
||||
fw->entry_point = fw->cold_boot_entry_point;
|
||||
fw->last_heartbeat = 0;
|
||||
}
|
||||
|
||||
static void ivpu_pm_prepare_warm_boot(struct ivpu_device *vdev)
|
||||
|
@ -189,7 +191,24 @@ static void ivpu_job_timeout_work(struct work_struct *work)
|
|||
{
|
||||
struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, job_timeout_work.work);
|
||||
struct ivpu_device *vdev = pm->vdev;
|
||||
u64 heartbeat;
|
||||
|
||||
if (ivpu_jsm_get_heartbeat(vdev, 0, &heartbeat) || heartbeat <= vdev->fw->last_heartbeat) {
|
||||
ivpu_err(vdev, "Job timeout detected, heartbeat not progressed\n");
|
||||
goto recovery;
|
||||
}
|
||||
|
||||
if (atomic_fetch_inc(&vdev->job_timeout_counter) > PM_TDR_HEARTBEAT_LIMIT) {
|
||||
ivpu_err(vdev, "Job timeout detected, heartbeat limit exceeded\n");
|
||||
goto recovery;
|
||||
}
|
||||
|
||||
vdev->fw->last_heartbeat = heartbeat;
|
||||
ivpu_start_job_timeout_detection(vdev);
|
||||
return;
|
||||
|
||||
recovery:
|
||||
atomic_set(&vdev->job_timeout_counter, 0);
|
||||
ivpu_pm_trigger_recovery(vdev, "TDR");
|
||||
}
|
||||
|
||||
|
@ -204,6 +223,7 @@ void ivpu_start_job_timeout_detection(struct ivpu_device *vdev)
|
|||
void ivpu_stop_job_timeout_detection(struct ivpu_device *vdev)
|
||||
{
|
||||
cancel_delayed_work_sync(&vdev->pm->job_timeout_work);
|
||||
atomic_set(&vdev->job_timeout_counter, 0);
|
||||
}
|
||||
|
||||
int ivpu_pm_suspend_cb(struct device *dev)
|
||||
|
|
|
@ -609,7 +609,7 @@ static int qaic_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struc
|
|||
struct scatterlist *sg;
|
||||
int ret = 0;
|
||||
|
||||
if (obj->import_attach)
|
||||
if (drm_gem_is_imported(obj))
|
||||
return -EINVAL;
|
||||
|
||||
for (sg = bo->sgt->sgl; sg; sg = sg_next(sg)) {
|
||||
|
@ -630,7 +630,7 @@ static void qaic_free_object(struct drm_gem_object *obj)
|
|||
{
|
||||
struct qaic_bo *bo = to_qaic_bo(obj);
|
||||
|
||||
if (obj->import_attach) {
|
||||
if (drm_gem_is_imported(obj)) {
|
||||
/* DMABUF/PRIME Path */
|
||||
drm_prime_gem_destroy(obj, NULL);
|
||||
} else {
|
||||
|
@ -870,7 +870,7 @@ static int qaic_prepare_bo(struct qaic_device *qdev, struct qaic_bo *bo,
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (bo->base.import_attach)
|
||||
if (drm_gem_is_imported(&bo->base))
|
||||
ret = qaic_prepare_import_bo(bo, hdr);
|
||||
else
|
||||
ret = qaic_prepare_export_bo(qdev, bo, hdr);
|
||||
|
@ -894,7 +894,7 @@ static void qaic_unprepare_export_bo(struct qaic_device *qdev, struct qaic_bo *b
|
|||
|
||||
static void qaic_unprepare_bo(struct qaic_device *qdev, struct qaic_bo *bo)
|
||||
{
|
||||
if (bo->base.import_attach)
|
||||
if (drm_gem_is_imported(&bo->base))
|
||||
qaic_unprepare_import_bo(bo);
|
||||
else
|
||||
qaic_unprepare_export_bo(qdev, bo);
|
||||
|
|
|
@ -240,7 +240,6 @@ static int qaic_bootlog_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_d
|
|||
mhi_unprepare:
|
||||
mhi_unprepare_from_transfer(mhi_dev);
|
||||
destroy_workqueue:
|
||||
flush_workqueue(qdev->bootlog_wq);
|
||||
destroy_workqueue(qdev->bootlog_wq);
|
||||
out:
|
||||
return ret;
|
||||
|
@ -253,7 +252,6 @@ static void qaic_bootlog_mhi_remove(struct mhi_device *mhi_dev)
|
|||
qdev = dev_get_drvdata(&mhi_dev->dev);
|
||||
|
||||
mhi_unprepare_from_transfer(qdev->bootlog_ch);
|
||||
flush_workqueue(qdev->bootlog_wq);
|
||||
destroy_workqueue(qdev->bootlog_wq);
|
||||
qdev->bootlog_ch = NULL;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ struct intel_gtt_driver {
|
|||
* of the mmio register file, that's done in the generic code. */
|
||||
void (*cleanup)(void);
|
||||
void (*write_entry)(dma_addr_t addr, unsigned int entry, unsigned int flags);
|
||||
dma_addr_t (*read_entry)(unsigned int entry, bool *is_present, bool *is_local);
|
||||
/* Flags is a more or less chipset specific opaque value.
|
||||
* For chipsets that need to support old ums (non-gem) code, this
|
||||
* needs to be identical to the various supported agp memory types! */
|
||||
|
@ -336,6 +337,19 @@ static void i810_write_entry(dma_addr_t addr, unsigned int entry,
|
|||
writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
|
||||
}
|
||||
|
||||
static dma_addr_t i810_read_entry(unsigned int entry,
|
||||
bool *is_present, bool *is_local)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(intel_private.gtt + entry);
|
||||
|
||||
*is_present = val & I810_PTE_VALID;
|
||||
*is_local = val & I810_PTE_LOCAL;
|
||||
|
||||
return val & ~0xfff;
|
||||
}
|
||||
|
||||
static resource_size_t intel_gtt_stolen_size(void)
|
||||
{
|
||||
u16 gmch_ctrl;
|
||||
|
@ -741,6 +755,19 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry,
|
|||
writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
|
||||
}
|
||||
|
||||
static dma_addr_t i830_read_entry(unsigned int entry,
|
||||
bool *is_present, bool *is_local)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(intel_private.gtt + entry);
|
||||
|
||||
*is_present = val & I810_PTE_VALID;
|
||||
*is_local = false;
|
||||
|
||||
return val & ~0xfff;
|
||||
}
|
||||
|
||||
bool intel_gmch_enable_gtt(void)
|
||||
{
|
||||
u8 __iomem *reg;
|
||||
|
@ -878,6 +905,13 @@ void intel_gmch_gtt_insert_sg_entries(struct sg_table *st,
|
|||
}
|
||||
EXPORT_SYMBOL(intel_gmch_gtt_insert_sg_entries);
|
||||
|
||||
dma_addr_t intel_gmch_gtt_read_entry(unsigned int pg,
|
||||
bool *is_present, bool *is_local)
|
||||
{
|
||||
return intel_private.driver->read_entry(pg, is_present, is_local);
|
||||
}
|
||||
EXPORT_SYMBOL(intel_gmch_gtt_read_entry);
|
||||
|
||||
#if IS_ENABLED(CONFIG_AGP_INTEL)
|
||||
static void intel_gmch_gtt_insert_pages(unsigned int first_entry,
|
||||
unsigned int num_entries,
|
||||
|
@ -1126,6 +1160,19 @@ static void i965_write_entry(dma_addr_t addr,
|
|||
writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
|
||||
}
|
||||
|
||||
static dma_addr_t i965_read_entry(unsigned int entry,
|
||||
bool *is_present, bool *is_local)
|
||||
{
|
||||
u64 val;
|
||||
|
||||
val = readl(intel_private.gtt + entry);
|
||||
|
||||
*is_present = val & I810_PTE_VALID;
|
||||
*is_local = false;
|
||||
|
||||
return ((val & 0xf0) << 28) | (val & ~0xfff);
|
||||
}
|
||||
|
||||
static int i9xx_setup(void)
|
||||
{
|
||||
phys_addr_t reg_addr;
|
||||
|
@ -1187,6 +1234,7 @@ static const struct intel_gtt_driver i81x_gtt_driver = {
|
|||
.cleanup = i810_cleanup,
|
||||
.check_flags = i830_check_flags,
|
||||
.write_entry = i810_write_entry,
|
||||
.read_entry = i810_read_entry,
|
||||
};
|
||||
static const struct intel_gtt_driver i8xx_gtt_driver = {
|
||||
.gen = 2,
|
||||
|
@ -1194,6 +1242,7 @@ static const struct intel_gtt_driver i8xx_gtt_driver = {
|
|||
.setup = i830_setup,
|
||||
.cleanup = i830_cleanup,
|
||||
.write_entry = i830_write_entry,
|
||||
.read_entry = i830_read_entry,
|
||||
.dma_mask_size = 32,
|
||||
.check_flags = i830_check_flags,
|
||||
.chipset_flush = i830_chipset_flush,
|
||||
|
@ -1205,6 +1254,7 @@ static const struct intel_gtt_driver i915_gtt_driver = {
|
|||
.cleanup = i9xx_cleanup,
|
||||
/* i945 is the last gpu to need phys mem (for overlay and cursors). */
|
||||
.write_entry = i830_write_entry,
|
||||
.read_entry = i830_read_entry,
|
||||
.dma_mask_size = 32,
|
||||
.check_flags = i830_check_flags,
|
||||
.chipset_flush = i9xx_chipset_flush,
|
||||
|
@ -1215,6 +1265,7 @@ static const struct intel_gtt_driver g33_gtt_driver = {
|
|||
.setup = i9xx_setup,
|
||||
.cleanup = i9xx_cleanup,
|
||||
.write_entry = i965_write_entry,
|
||||
.read_entry = i965_read_entry,
|
||||
.dma_mask_size = 36,
|
||||
.check_flags = i830_check_flags,
|
||||
.chipset_flush = i9xx_chipset_flush,
|
||||
|
@ -1225,6 +1276,7 @@ static const struct intel_gtt_driver pineview_gtt_driver = {
|
|||
.setup = i9xx_setup,
|
||||
.cleanup = i9xx_cleanup,
|
||||
.write_entry = i965_write_entry,
|
||||
.read_entry = i965_read_entry,
|
||||
.dma_mask_size = 36,
|
||||
.check_flags = i830_check_flags,
|
||||
.chipset_flush = i9xx_chipset_flush,
|
||||
|
@ -1235,6 +1287,7 @@ static const struct intel_gtt_driver i965_gtt_driver = {
|
|||
.setup = i9xx_setup,
|
||||
.cleanup = i9xx_cleanup,
|
||||
.write_entry = i965_write_entry,
|
||||
.read_entry = i965_read_entry,
|
||||
.dma_mask_size = 36,
|
||||
.check_flags = i830_check_flags,
|
||||
.chipset_flush = i9xx_chipset_flush,
|
||||
|
@ -1244,6 +1297,7 @@ static const struct intel_gtt_driver g4x_gtt_driver = {
|
|||
.setup = i9xx_setup,
|
||||
.cleanup = i9xx_cleanup,
|
||||
.write_entry = i965_write_entry,
|
||||
.read_entry = i965_read_entry,
|
||||
.dma_mask_size = 36,
|
||||
.check_flags = i830_check_flags,
|
||||
.chipset_flush = i9xx_chipset_flush,
|
||||
|
@ -1254,6 +1308,7 @@ static const struct intel_gtt_driver ironlake_gtt_driver = {
|
|||
.setup = i9xx_setup,
|
||||
.cleanup = i9xx_cleanup,
|
||||
.write_entry = i965_write_entry,
|
||||
.read_entry = i965_read_entry,
|
||||
.dma_mask_size = 36,
|
||||
.check_flags = i830_check_flags,
|
||||
.chipset_flush = i9xx_chipset_flush,
|
||||
|
|
|
@ -636,10 +636,6 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
|||
|| !exp_info->ops->release))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (WARN_ON(exp_info->ops->cache_sgt_mapping &&
|
||||
(exp_info->ops->pin || exp_info->ops->unpin)))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (WARN_ON(!exp_info->ops->pin != !exp_info->ops->unpin))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
|
@ -782,7 +778,7 @@ static void mangle_sg_table(struct sg_table *sg_table)
|
|||
|
||||
/* To catch abuse of the underlying struct page by importers mix
|
||||
* up the bits, but take care to preserve the low SG_ bits to
|
||||
* not corrupt the sgt. The mixing is undone in __unmap_dma_buf
|
||||
* not corrupt the sgt. The mixing is undone on unmap
|
||||
* before passing the sgt back to the exporter.
|
||||
*/
|
||||
for_each_sgtable_sg(sg_table, sg, i)
|
||||
|
@ -790,29 +786,19 @@ static void mangle_sg_table(struct sg_table *sg_table)
|
|||
#endif
|
||||
|
||||
}
|
||||
static struct sg_table *__map_dma_buf(struct dma_buf_attachment *attach,
|
||||
enum dma_data_direction direction)
|
||||
|
||||
static inline bool
|
||||
dma_buf_attachment_is_dynamic(struct dma_buf_attachment *attach)
|
||||
{
|
||||
struct sg_table *sg_table;
|
||||
signed long ret;
|
||||
return !!attach->importer_ops;
|
||||
}
|
||||
|
||||
sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
|
||||
if (IS_ERR_OR_NULL(sg_table))
|
||||
return sg_table;
|
||||
|
||||
if (!dma_buf_attachment_is_dynamic(attach)) {
|
||||
ret = dma_resv_wait_timeout(attach->dmabuf->resv,
|
||||
DMA_RESV_USAGE_KERNEL, true,
|
||||
MAX_SCHEDULE_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
attach->dmabuf->ops->unmap_dma_buf(attach, sg_table,
|
||||
direction);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
}
|
||||
|
||||
mangle_sg_table(sg_table);
|
||||
return sg_table;
|
||||
static bool
|
||||
dma_buf_pin_on_map(struct dma_buf_attachment *attach)
|
||||
{
|
||||
return attach->dmabuf->ops->pin &&
|
||||
(!dma_buf_attachment_is_dynamic(attach) ||
|
||||
!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -935,48 +921,11 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
|
|||
list_add(&attach->node, &dmabuf->attachments);
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
|
||||
/* When either the importer or the exporter can't handle dynamic
|
||||
* mappings we cache the mapping here to avoid issues with the
|
||||
* reservation object lock.
|
||||
*/
|
||||
if (dma_buf_attachment_is_dynamic(attach) !=
|
||||
dma_buf_is_dynamic(dmabuf)) {
|
||||
struct sg_table *sgt;
|
||||
|
||||
dma_resv_lock(attach->dmabuf->resv, NULL);
|
||||
if (dma_buf_is_dynamic(attach->dmabuf)) {
|
||||
ret = dmabuf->ops->pin(attach);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
sgt = __map_dma_buf(attach, DMA_BIDIRECTIONAL);
|
||||
if (!sgt)
|
||||
sgt = ERR_PTR(-ENOMEM);
|
||||
if (IS_ERR(sgt)) {
|
||||
ret = PTR_ERR(sgt);
|
||||
goto err_unpin;
|
||||
}
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
attach->sgt = sgt;
|
||||
attach->dir = DMA_BIDIRECTIONAL;
|
||||
}
|
||||
|
||||
return attach;
|
||||
|
||||
err_attach:
|
||||
kfree(attach);
|
||||
return ERR_PTR(ret);
|
||||
|
||||
err_unpin:
|
||||
if (dma_buf_is_dynamic(attach->dmabuf))
|
||||
dmabuf->ops->unpin(attach);
|
||||
|
||||
err_unlock:
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
|
||||
dma_buf_detach(dmabuf, attach);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF");
|
||||
|
||||
|
@ -995,16 +944,6 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
|
|||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_attach, "DMA_BUF");
|
||||
|
||||
static void __unmap_dma_buf(struct dma_buf_attachment *attach,
|
||||
struct sg_table *sg_table,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
/* uses XOR, hence this unmangles */
|
||||
mangle_sg_table(sg_table);
|
||||
|
||||
attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_buf_detach - Remove the given attachment from dmabuf's attachments list
|
||||
* @dmabuf: [in] buffer to detach from.
|
||||
|
@ -1020,16 +959,7 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
|
|||
return;
|
||||
|
||||
dma_resv_lock(dmabuf->resv, NULL);
|
||||
|
||||
if (attach->sgt) {
|
||||
|
||||
__unmap_dma_buf(attach, attach->sgt, attach->dir);
|
||||
|
||||
if (dma_buf_is_dynamic(attach->dmabuf))
|
||||
dmabuf->ops->unpin(attach);
|
||||
}
|
||||
list_del(&attach->node);
|
||||
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
|
||||
if (dmabuf->ops->detach)
|
||||
|
@ -1058,7 +988,7 @@ int dma_buf_pin(struct dma_buf_attachment *attach)
|
|||
struct dma_buf *dmabuf = attach->dmabuf;
|
||||
int ret = 0;
|
||||
|
||||
WARN_ON(!dma_buf_attachment_is_dynamic(attach));
|
||||
WARN_ON(!attach->importer_ops);
|
||||
|
||||
dma_resv_assert_held(dmabuf->resv);
|
||||
|
||||
|
@ -1081,7 +1011,7 @@ void dma_buf_unpin(struct dma_buf_attachment *attach)
|
|||
{
|
||||
struct dma_buf *dmabuf = attach->dmabuf;
|
||||
|
||||
WARN_ON(!dma_buf_attachment_is_dynamic(attach));
|
||||
WARN_ON(!attach->importer_ops);
|
||||
|
||||
dma_resv_assert_held(dmabuf->resv);
|
||||
|
||||
|
@ -1115,7 +1045,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
|||
enum dma_data_direction direction)
|
||||
{
|
||||
struct sg_table *sg_table;
|
||||
int r;
|
||||
signed long ret;
|
||||
|
||||
might_sleep();
|
||||
|
||||
|
@ -1124,41 +1054,37 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
|||
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
|
||||
if (attach->sgt) {
|
||||
if (dma_buf_pin_on_map(attach)) {
|
||||
ret = attach->dmabuf->ops->pin(attach);
|
||||
/*
|
||||
* Two mappings with different directions for the same
|
||||
* attachment are not allowed.
|
||||
* Catch exporters making buffers inaccessible even when
|
||||
* attachments preventing that exist.
|
||||
*/
|
||||
if (attach->dir != direction &&
|
||||
attach->dir != DMA_BIDIRECTIONAL)
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
return attach->sgt;
|
||||
WARN_ON_ONCE(ret == EBUSY);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
if (dma_buf_is_dynamic(attach->dmabuf)) {
|
||||
if (!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) {
|
||||
r = attach->dmabuf->ops->pin(attach);
|
||||
if (r)
|
||||
return ERR_PTR(r);
|
||||
}
|
||||
}
|
||||
|
||||
sg_table = __map_dma_buf(attach, direction);
|
||||
sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
|
||||
if (!sg_table)
|
||||
sg_table = ERR_PTR(-ENOMEM);
|
||||
if (IS_ERR(sg_table))
|
||||
goto error_unpin;
|
||||
|
||||
if (IS_ERR(sg_table) && dma_buf_is_dynamic(attach->dmabuf) &&
|
||||
!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY))
|
||||
attach->dmabuf->ops->unpin(attach);
|
||||
|
||||
if (!IS_ERR(sg_table) && attach->dmabuf->ops->cache_sgt_mapping) {
|
||||
attach->sgt = sg_table;
|
||||
attach->dir = direction;
|
||||
/*
|
||||
* Importers with static attachments don't wait for fences.
|
||||
*/
|
||||
if (!dma_buf_attachment_is_dynamic(attach)) {
|
||||
ret = dma_resv_wait_timeout(attach->dmabuf->resv,
|
||||
DMA_RESV_USAGE_KERNEL, true,
|
||||
MAX_SCHEDULE_TIMEOUT);
|
||||
if (ret < 0)
|
||||
goto error_unmap;
|
||||
}
|
||||
mangle_sg_table(sg_table);
|
||||
|
||||
#ifdef CONFIG_DMA_API_DEBUG
|
||||
if (!IS_ERR(sg_table)) {
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
u64 addr;
|
||||
int len;
|
||||
|
@ -1175,6 +1101,16 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
|||
}
|
||||
#endif /* CONFIG_DMA_API_DEBUG */
|
||||
return sg_table;
|
||||
|
||||
error_unmap:
|
||||
attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
|
||||
sg_table = ERR_PTR(ret);
|
||||
|
||||
error_unpin:
|
||||
if (dma_buf_pin_on_map(attach))
|
||||
attach->dmabuf->ops->unpin(attach);
|
||||
|
||||
return sg_table;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, "DMA_BUF");
|
||||
|
||||
|
@ -1227,14 +1163,11 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
|
|||
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
|
||||
if (attach->sgt == sg_table)
|
||||
return;
|
||||
mangle_sg_table(sg_table);
|
||||
attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
|
||||
|
||||
__unmap_dma_buf(attach, sg_table, direction);
|
||||
|
||||
if (dma_buf_is_dynamic(attach->dmabuf) &&
|
||||
!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY))
|
||||
dma_buf_unpin(attach);
|
||||
if (dma_buf_pin_on_map(attach))
|
||||
attach->dmabuf->ops->unpin(attach);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, "DMA_BUF");
|
||||
|
||||
|
|
|
@ -79,6 +79,41 @@ static int fence_cmp(const void *_a, const void *_b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_fence_dedup_array - Sort and deduplicate an array of dma_fence pointers
|
||||
* @fences: Array of dma_fence pointers to be deduplicated
|
||||
* @num_fences: Number of entries in the @fences array
|
||||
*
|
||||
* Sorts the input array by context, then removes duplicate
|
||||
* fences with the same context, keeping only the most recent one.
|
||||
*
|
||||
* The array is modified in-place and unreferenced duplicate fences are released
|
||||
* via dma_fence_put(). The function returns the new number of fences after
|
||||
* deduplication.
|
||||
*
|
||||
* Return: Number of unique fences remaining in the array.
|
||||
*/
|
||||
int dma_fence_dedup_array(struct dma_fence **fences, int num_fences)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
sort(fences, num_fences, sizeof(*fences), fence_cmp, NULL);
|
||||
|
||||
/*
|
||||
* Only keep the most recent fence for each context.
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 1; i < num_fences; i++) {
|
||||
if (fences[i]->context == fences[j]->context)
|
||||
dma_fence_put(fences[i]);
|
||||
else
|
||||
fences[++j] = fences[i];
|
||||
}
|
||||
|
||||
return ++j;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_fence_dedup_array);
|
||||
|
||||
/* Implementation for the dma_fence_merge() marco, don't use directly */
|
||||
struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
|
||||
struct dma_fence **fences,
|
||||
|
@ -87,7 +122,7 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
|
|||
struct dma_fence *tmp, *unsignaled = NULL, **array;
|
||||
struct dma_fence_array *result;
|
||||
ktime_t timestamp;
|
||||
int i, j, count;
|
||||
int i, count;
|
||||
|
||||
count = 0;
|
||||
timestamp = ns_to_ktime(0);
|
||||
|
@ -141,19 +176,7 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
|
|||
if (count == 0 || count == 1)
|
||||
goto return_fastpath;
|
||||
|
||||
sort(array, count, sizeof(*array), fence_cmp, NULL);
|
||||
|
||||
/*
|
||||
* Only keep the most recent fence for each context.
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 1; i < count; i++) {
|
||||
if (array[i]->context == array[j]->context)
|
||||
dma_fence_put(array[i]);
|
||||
else
|
||||
array[++j] = array[i];
|
||||
}
|
||||
count = ++j;
|
||||
count = dma_fence_dedup_array(array, count);
|
||||
|
||||
if (count > 1) {
|
||||
result = dma_fence_array_create(count, array,
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
static struct dma_heap *sys_heap;
|
||||
|
||||
struct system_heap_buffer {
|
||||
struct dma_heap *heap;
|
||||
struct list_head attachments;
|
||||
|
@ -424,6 +422,7 @@ static const struct dma_heap_ops system_heap_ops = {
|
|||
static int __init system_heap_create(void)
|
||||
{
|
||||
struct dma_heap_export_info exp_info;
|
||||
struct dma_heap *sys_heap;
|
||||
|
||||
exp_info.name = "system";
|
||||
exp_info.ops = &system_heap_ops;
|
||||
|
|
|
@ -173,20 +173,6 @@ static bool timeline_fence_signaled(struct dma_fence *fence)
|
|||
return !__dma_fence_is_later(fence->seqno, parent->value, fence->ops);
|
||||
}
|
||||
|
||||
static void timeline_fence_value_str(struct dma_fence *fence,
|
||||
char *str, int size)
|
||||
{
|
||||
snprintf(str, size, "%lld", fence->seqno);
|
||||
}
|
||||
|
||||
static void timeline_fence_timeline_value_str(struct dma_fence *fence,
|
||||
char *str, int size)
|
||||
{
|
||||
struct sync_timeline *parent = dma_fence_parent(fence);
|
||||
|
||||
snprintf(str, size, "%d", parent->value);
|
||||
}
|
||||
|
||||
static void timeline_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)
|
||||
{
|
||||
struct sync_pt *pt = dma_fence_to_sync_pt(fence);
|
||||
|
@ -208,8 +194,6 @@ static const struct dma_fence_ops timeline_fence_ops = {
|
|||
.get_timeline_name = timeline_fence_get_timeline_name,
|
||||
.signaled = timeline_fence_signaled,
|
||||
.release = timeline_fence_release,
|
||||
.fence_value_str = timeline_fence_value_str,
|
||||
.timeline_value_str = timeline_fence_timeline_value_str,
|
||||
.set_deadline = timeline_fence_set_deadline,
|
||||
};
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ static struct dentry *dbgfs;
|
|||
|
||||
static LIST_HEAD(sync_timeline_list_head);
|
||||
static DEFINE_SPINLOCK(sync_timeline_list_lock);
|
||||
static LIST_HEAD(sync_file_list_head);
|
||||
static DEFINE_SPINLOCK(sync_file_list_lock);
|
||||
|
||||
void sync_timeline_debug_add(struct sync_timeline *obj)
|
||||
{
|
||||
|
@ -33,24 +31,6 @@ void sync_timeline_debug_remove(struct sync_timeline *obj)
|
|||
spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
|
||||
}
|
||||
|
||||
void sync_file_debug_add(struct sync_file *sync_file)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&sync_file_list_lock, flags);
|
||||
list_add_tail(&sync_file->sync_file_list, &sync_file_list_head);
|
||||
spin_unlock_irqrestore(&sync_file_list_lock, flags);
|
||||
}
|
||||
|
||||
void sync_file_debug_remove(struct sync_file *sync_file)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&sync_file_list_lock, flags);
|
||||
list_del(&sync_file->sync_file_list);
|
||||
spin_unlock_irqrestore(&sync_file_list_lock, flags);
|
||||
}
|
||||
|
||||
static const char *sync_status_str(int status)
|
||||
{
|
||||
if (status < 0)
|
||||
|
@ -82,25 +62,8 @@ static void sync_print_fence(struct seq_file *s,
|
|||
seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec);
|
||||
}
|
||||
|
||||
if (fence->ops->timeline_value_str &&
|
||||
fence->ops->fence_value_str) {
|
||||
char value[64];
|
||||
bool success;
|
||||
|
||||
fence->ops->fence_value_str(fence, value, sizeof(value));
|
||||
success = strlen(value);
|
||||
|
||||
if (success) {
|
||||
seq_printf(s, ": %s", value);
|
||||
|
||||
fence->ops->timeline_value_str(fence, value,
|
||||
sizeof(value));
|
||||
|
||||
if (strlen(value))
|
||||
seq_printf(s, " / %s", value);
|
||||
}
|
||||
}
|
||||
|
||||
seq_printf(s, ": %lld", fence->seqno);
|
||||
seq_printf(s, " / %d", parent->value);
|
||||
seq_putc(s, '\n');
|
||||
}
|
||||
|
||||
|
@ -118,26 +81,6 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
|
|||
spin_unlock(&obj->lock);
|
||||
}
|
||||
|
||||
static void sync_print_sync_file(struct seq_file *s,
|
||||
struct sync_file *sync_file)
|
||||
{
|
||||
char buf[128];
|
||||
int i;
|
||||
|
||||
seq_printf(s, "[%p] %s: %s\n", sync_file,
|
||||
sync_file_get_name(sync_file, buf, sizeof(buf)),
|
||||
sync_status_str(dma_fence_get_status(sync_file->fence)));
|
||||
|
||||
if (dma_fence_is_array(sync_file->fence)) {
|
||||
struct dma_fence_array *array = to_dma_fence_array(sync_file->fence);
|
||||
|
||||
for (i = 0; i < array->num_fences; ++i)
|
||||
sync_print_fence(s, array->fences[i], true);
|
||||
} else {
|
||||
sync_print_fence(s, sync_file->fence, true);
|
||||
}
|
||||
}
|
||||
|
||||
static int sync_info_debugfs_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct list_head *pos;
|
||||
|
@ -157,15 +100,6 @@ static int sync_info_debugfs_show(struct seq_file *s, void *unused)
|
|||
|
||||
seq_puts(s, "fences:\n--------------\n");
|
||||
|
||||
spin_lock_irq(&sync_file_list_lock);
|
||||
list_for_each(pos, &sync_file_list_head) {
|
||||
struct sync_file *sync_file =
|
||||
container_of(pos, struct sync_file, sync_file_list);
|
||||
|
||||
sync_print_sync_file(s, sync_file);
|
||||
seq_putc(s, '\n');
|
||||
}
|
||||
spin_unlock_irq(&sync_file_list_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,5 @@ extern const struct file_operations sw_sync_debugfs_fops;
|
|||
|
||||
void sync_timeline_debug_add(struct sync_timeline *obj);
|
||||
void sync_timeline_debug_remove(struct sync_timeline *obj);
|
||||
void sync_file_debug_add(struct sync_file *fence);
|
||||
void sync_file_debug_remove(struct sync_file *fence);
|
||||
|
||||
#endif /* _LINUX_SYNC_H */
|
||||
|
|
|
@ -285,7 +285,6 @@ static int end_cpu_udmabuf(struct dma_buf *buf,
|
|||
}
|
||||
|
||||
static const struct dma_buf_ops udmabuf_ops = {
|
||||
.cache_sgt_mapping = true,
|
||||
.map_dma_buf = map_udmabuf,
|
||||
.unmap_dma_buf = unmap_udmabuf,
|
||||
.release = release_udmabuf,
|
||||
|
|
|
@ -558,6 +558,7 @@ int __efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
|
|||
|
||||
extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
|
||||
__weak __alias(__efi_mem_desc_lookup);
|
||||
EXPORT_SYMBOL_GPL(efi_mem_desc_lookup);
|
||||
|
||||
/*
|
||||
* Calculate the highest address of an efi memory descriptor.
|
||||
|
|
|
@ -35,36 +35,7 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
|
|||
if (type != VIDEO_TYPE_VLFB && type != VIDEO_TYPE_EFI)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* The meaning of depth and bpp for direct-color formats is
|
||||
* inconsistent:
|
||||
*
|
||||
* - DRM format info specifies depth as the number of color
|
||||
* bits; including alpha, but not including filler bits.
|
||||
* - Linux' EFI platform code computes lfb_depth from the
|
||||
* individual color channels, including the reserved bits.
|
||||
* - VBE 1.1 defines lfb_depth for XRGB1555 as 16, but later
|
||||
* versions use 15.
|
||||
* - On the kernel command line, 'bpp' of 32 is usually
|
||||
* XRGB8888 including the filler bits, but 15 is XRGB1555
|
||||
* not including the filler bit.
|
||||
*
|
||||
* It's not easily possible to fix this in struct screen_info,
|
||||
* as this could break UAPI. The best solution is to compute
|
||||
* bits_per_pixel from the color bits, reserved bits and
|
||||
* reported lfb_depth, whichever is highest. In the loop below,
|
||||
* ignore simplefb formats with alpha bits, as EFI and VESA
|
||||
* don't specify alpha channels.
|
||||
*/
|
||||
if (si->lfb_depth > 8) {
|
||||
bits_per_pixel = max(max3(si->red_size + si->red_pos,
|
||||
si->green_size + si->green_pos,
|
||||
si->blue_size + si->blue_pos),
|
||||
si->rsvd_size + si->rsvd_pos);
|
||||
bits_per_pixel = max_t(u32, bits_per_pixel, si->lfb_depth);
|
||||
} else {
|
||||
bits_per_pixel = si->lfb_depth;
|
||||
}
|
||||
bits_per_pixel = __screen_info_lfb_bits_per_pixel(si);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(formats); ++i) {
|
||||
const struct simplefb_format *f = &formats[i];
|
||||
|
|
|
@ -26,6 +26,11 @@ menuconfig DRM
|
|||
details. You should also select and configure AGP
|
||||
(/dev/agpgart) support if it is available for your platform.
|
||||
|
||||
menu "DRM debugging options"
|
||||
depends on DRM
|
||||
source "drivers/gpu/drm/Kconfig.debug"
|
||||
endmenu
|
||||
|
||||
if DRM
|
||||
|
||||
config DRM_MIPI_DBI
|
||||
|
@ -37,65 +42,6 @@ config DRM_MIPI_DSI
|
|||
bool
|
||||
depends on DRM
|
||||
|
||||
config DRM_DEBUG_MM
|
||||
bool "Insert extra checks and debug info into the DRM range managers"
|
||||
default n
|
||||
depends on DRM
|
||||
depends on STACKTRACE_SUPPORT
|
||||
select STACKDEPOT
|
||||
help
|
||||
Enable allocation tracking of memory manager and leak detection on
|
||||
shutdown.
|
||||
|
||||
Recommended for driver developers only.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_USE_DYNAMIC_DEBUG
|
||||
bool "use dynamic debug to implement drm.debug"
|
||||
default n
|
||||
depends on BROKEN
|
||||
depends on DRM
|
||||
depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
|
||||
depends on JUMP_LABEL
|
||||
help
|
||||
Use dynamic-debug to avoid drm_debug_enabled() runtime overheads.
|
||||
Due to callsite counts in DRM drivers (~4k in amdgpu) and 56
|
||||
bytes per callsite, the .data costs can be substantial, and
|
||||
are therefore configurable.
|
||||
|
||||
config DRM_KUNIT_TEST_HELPERS
|
||||
tristate
|
||||
depends on DRM && KUNIT
|
||||
select DRM_KMS_HELPER
|
||||
help
|
||||
KUnit Helpers for KMS drivers.
|
||||
|
||||
config DRM_KUNIT_TEST
|
||||
tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
|
||||
depends on DRM && KUNIT && MMU
|
||||
select DRM_BUDDY
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_HDMI_STATE_HELPER
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_EXEC
|
||||
select DRM_EXPORT_FOR_TESTS if m
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select DRM_KUNIT_TEST_HELPERS
|
||||
select DRM_LIB_RANDOM
|
||||
select PRIME_NUMBERS
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
This builds unit tests for DRM. This option is not useful for
|
||||
distributions or general kernels, but only for kernel
|
||||
developers working on DRM and associated drivers.
|
||||
|
||||
For more information on KUnit and unit tests in general,
|
||||
please refer to the KUnit documentation in
|
||||
Documentation/dev-tools/kunit/.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_KMS_HELPER
|
||||
tristate
|
||||
depends on DRM
|
||||
|
@ -247,23 +193,6 @@ config DRM_TTM
|
|||
GPU memory types. Will be enabled automatically if a device driver
|
||||
uses it.
|
||||
|
||||
config DRM_TTM_KUNIT_TEST
|
||||
tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
|
||||
default n
|
||||
depends on DRM && KUNIT && MMU && (UML || COMPILE_TEST)
|
||||
select DRM_TTM
|
||||
select DRM_BUDDY
|
||||
select DRM_EXPORT_FOR_TESTS if m
|
||||
select DRM_KUNIT_TEST_HELPERS
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
Enables unit tests for TTM, a GPU memory manager subsystem used
|
||||
to manage memory buffers. This option is mostly useful for kernel
|
||||
developers. It depends on (UML || COMPILE_TEST) since no other driver
|
||||
which uses TTM can be loaded while running the tests.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_EXEC
|
||||
tristate
|
||||
depends on DRM
|
||||
|
@ -335,6 +264,8 @@ config DRM_SCHED
|
|||
tristate
|
||||
depends on DRM
|
||||
|
||||
source "drivers/gpu/drm/sysfb/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/arm/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/radeon/Kconfig"
|
||||
|
@ -343,6 +274,8 @@ source "drivers/gpu/drm/amd/amdgpu/Kconfig"
|
|||
|
||||
source "drivers/gpu/drm/nouveau/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/nova/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/i915/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/xe/Kconfig"
|
||||
|
@ -454,6 +387,8 @@ source "drivers/gpu/drm/xlnx/Kconfig"
|
|||
|
||||
source "drivers/gpu/drm/gud/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/sitronix/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/solomon/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/sprd/Kconfig"
|
||||
|
@ -474,9 +409,6 @@ config DRM_HYPERV
|
|||
|
||||
If M is selected the module will be called hyperv_drm.
|
||||
|
||||
config DRM_EXPORT_FOR_TESTS
|
||||
bool
|
||||
|
||||
# Separate option as not all DRM drivers use it
|
||||
config DRM_PANEL_BACKLIGHT_QUIRKS
|
||||
tristate
|
||||
|
@ -489,31 +421,6 @@ config DRM_PRIVACY_SCREEN
|
|||
bool
|
||||
default n
|
||||
|
||||
config DRM_WERROR
|
||||
bool "Compile the drm subsystem with warnings as errors"
|
||||
depends on DRM && EXPERT
|
||||
depends on !WERROR
|
||||
default n
|
||||
help
|
||||
A kernel build should not cause any compiler warnings, and this
|
||||
enables the '-Werror' flag to enforce that rule in the drm subsystem.
|
||||
|
||||
The drm subsystem enables more warnings than the kernel default, so
|
||||
this config option is disabled by default.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config DRM_HEADER_TEST
|
||||
bool "Ensure DRM headers are self-contained and pass kernel-doc"
|
||||
depends on DRM && EXPERT && BROKEN
|
||||
default n
|
||||
help
|
||||
Ensure the DRM subsystem headers both under drivers/gpu/drm and
|
||||
include/drm compile, are self-contained, have header guards, and have
|
||||
no kernel-doc warnings.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
endif
|
||||
|
||||
# Separate option because drm_panel_orientation_quirks.c is shared with fbdev
|
||||
|
|
116
drivers/gpu/drm/Kconfig.debug
Normal file
116
drivers/gpu/drm/Kconfig.debug
Normal file
|
@ -0,0 +1,116 @@
|
|||
config DRM_USE_DYNAMIC_DEBUG
|
||||
bool "use dynamic debug to implement drm.debug"
|
||||
default n
|
||||
depends on BROKEN
|
||||
depends on DRM
|
||||
depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
|
||||
depends on JUMP_LABEL
|
||||
help
|
||||
Use dynamic-debug to avoid drm_debug_enabled() runtime overheads.
|
||||
Due to callsite counts in DRM drivers (~4k in amdgpu) and 56
|
||||
bytes per callsite, the .data costs can be substantial, and
|
||||
are therefore configurable.
|
||||
|
||||
config DRM_WERROR
|
||||
bool "Compile the drm subsystem with warnings as errors"
|
||||
depends on DRM && EXPERT
|
||||
depends on !WERROR
|
||||
default n
|
||||
help
|
||||
A kernel build should not cause any compiler warnings, and this
|
||||
enables the '-Werror' flag to enforce that rule in the drm subsystem.
|
||||
|
||||
The drm subsystem enables more warnings than the kernel default, so
|
||||
this config option is disabled by default.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config DRM_HEADER_TEST
|
||||
bool "Ensure DRM headers are self-contained and pass kernel-doc"
|
||||
depends on DRM && EXPERT && BROKEN
|
||||
default n
|
||||
help
|
||||
Ensure the DRM subsystem headers both under drivers/gpu/drm and
|
||||
include/drm compile, are self-contained, have header guards, and have
|
||||
no kernel-doc warnings.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config DRM_DEBUG_MM
|
||||
bool "Insert extra checks and debug info into the DRM range managers"
|
||||
default n
|
||||
depends on DRM
|
||||
depends on STACKTRACE_SUPPORT
|
||||
select STACKDEPOT
|
||||
help
|
||||
Enable allocation tracking of memory manager and leak detection on
|
||||
shutdown.
|
||||
|
||||
Recommended for driver developers only.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_KUNIT_TEST_HELPERS
|
||||
tristate
|
||||
depends on DRM && KUNIT
|
||||
select DRM_KMS_HELPER
|
||||
help
|
||||
KUnit Helpers for KMS drivers.
|
||||
|
||||
config DRM_KUNIT_TEST
|
||||
tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
|
||||
depends on DRM && KUNIT && MMU
|
||||
select DRM_BRIDGE_CONNECTOR
|
||||
select DRM_BUDDY
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_HDMI_STATE_HELPER
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_EXEC
|
||||
select DRM_EXPORT_FOR_TESTS if m
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select DRM_KUNIT_TEST_HELPERS
|
||||
select DRM_LIB_RANDOM
|
||||
select PRIME_NUMBERS
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
This builds unit tests for DRM. This option is not useful for
|
||||
distributions or general kernels, but only for kernel
|
||||
developers working on DRM and associated drivers.
|
||||
|
||||
For more information on KUnit and unit tests in general,
|
||||
please refer to the KUnit documentation in
|
||||
Documentation/dev-tools/kunit/.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_TTM_KUNIT_TEST
|
||||
tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
|
||||
default n
|
||||
depends on DRM && KUNIT && MMU && (UML || COMPILE_TEST)
|
||||
select DRM_TTM
|
||||
select DRM_BUDDY
|
||||
select DRM_EXPORT_FOR_TESTS if m
|
||||
select DRM_KUNIT_TEST_HELPERS
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
Enables unit tests for TTM, a GPU memory manager subsystem used
|
||||
to manage memory buffers. This option is mostly useful for kernel
|
||||
developers. It depends on (UML || COMPILE_TEST) since no other driver
|
||||
which uses TTM can be loaded while running the tests.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_SCHED_KUNIT_TEST
|
||||
tristate "KUnit tests for the DRM scheduler" if !KUNIT_ALL_TESTS
|
||||
select DRM_SCHED
|
||||
depends on DRM && KUNIT
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
Choose this option to build unit tests for the DRM scheduler.
|
||||
|
||||
Recommended for driver developers only.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_EXPORT_FOR_TESTS
|
||||
bool
|
|
@ -134,6 +134,7 @@ obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
|
|||
drm_kms_helper-y := \
|
||||
drm_atomic_helper.o \
|
||||
drm_atomic_state_helper.o \
|
||||
drm_bridge_helper.o \
|
||||
drm_crtc_helper.o \
|
||||
drm_damage_helper.o \
|
||||
drm_flip_work.o \
|
||||
|
@ -176,6 +177,7 @@ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
|
|||
obj-$(CONFIG_DRM_VGEM) += vgem/
|
||||
obj-$(CONFIG_DRM_VKMS) += vkms/
|
||||
obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
|
||||
obj-$(CONFIG_DRM_NOVA) += nova/
|
||||
obj-$(CONFIG_DRM_EXYNOS) +=exynos/
|
||||
obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/
|
||||
obj-$(CONFIG_DRM_GMA500) += gma500/
|
||||
|
@ -204,6 +206,7 @@ obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
|
|||
obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
|
||||
obj-y += hisilicon/
|
||||
obj-y += mxsfb/
|
||||
obj-y += sysfb/
|
||||
obj-y += tiny/
|
||||
obj-$(CONFIG_DRM_PL111) += pl111/
|
||||
obj-$(CONFIG_DRM_TVE200) += tve200/
|
||||
|
@ -219,6 +222,7 @@ obj-$(CONFIG_DRM_TIDSS) += tidss/
|
|||
obj-y += xlnx/
|
||||
obj-y += gud/
|
||||
obj-$(CONFIG_DRM_HYPERV) += hyperv/
|
||||
obj-y += sitronix/
|
||||
obj-y += solomon/
|
||||
obj-$(CONFIG_DRM_SPRD) += sprd/
|
||||
obj-$(CONFIG_DRM_LOONGSON) += loongson/
|
||||
|
|
|
@ -212,12 +212,13 @@ static const struct mipi_dsi_host_ops adp_dsi_host_ops = {
|
|||
};
|
||||
|
||||
static int adp_dsi_bridge_attach(struct drm_bridge *bridge,
|
||||
struct drm_encoder *encoder,
|
||||
enum drm_bridge_attach_flags flags)
|
||||
{
|
||||
struct adp_mipi_drv_private *adp =
|
||||
container_of(bridge, struct adp_mipi_drv_private, bridge);
|
||||
|
||||
return drm_bridge_attach(bridge->encoder, adp->next_bridge, bridge, flags);
|
||||
return drm_bridge_attach(encoder, adp->next_bridge, bridge, flags);
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs adp_dsi_bridge_funcs = {
|
||||
|
|
|
@ -66,7 +66,7 @@ amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
|
|||
amdgpu_fw_attestation.o amdgpu_securedisplay.o \
|
||||
amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \
|
||||
amdgpu_ring_mux.o amdgpu_xcp.o amdgpu_seq64.o amdgpu_aca.o amdgpu_dev_coredump.o \
|
||||
amdgpu_cper.o
|
||||
amdgpu_cper.o amdgpu_userq_fence.o amdgpu_eviction_fence.o
|
||||
|
||||
amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o
|
||||
|
||||
|
@ -174,7 +174,10 @@ amdgpu-y += \
|
|||
amdgpu-y += \
|
||||
amdgpu_mes.o \
|
||||
mes_v11_0.o \
|
||||
mes_v12_0.o
|
||||
mes_v12_0.o \
|
||||
|
||||
# add GFX userqueue support
|
||||
amdgpu-y += mes_userqueue.o
|
||||
|
||||
# add UVD block
|
||||
amdgpu-y += \
|
||||
|
@ -253,6 +256,8 @@ amdgpu-y += \
|
|||
# add amdkfd interfaces
|
||||
amdgpu-y += amdgpu_amdkfd.o
|
||||
|
||||
# add gfx usermode queue
|
||||
amdgpu-y += amdgpu_userq.o
|
||||
|
||||
ifneq ($(CONFIG_HSA_AMD),)
|
||||
AMDKFD_PATH := ../amdkfd
|
||||
|
|
|
@ -113,6 +113,8 @@
|
|||
#include "amdgpu_xcp.h"
|
||||
#include "amdgpu_seq64.h"
|
||||
#include "amdgpu_reg_state.h"
|
||||
#include "amdgpu_userq.h"
|
||||
#include "amdgpu_eviction_fence.h"
|
||||
#if defined(CONFIG_DRM_AMD_ISP)
|
||||
#include "amdgpu_isp.h"
|
||||
#endif
|
||||
|
@ -228,7 +230,7 @@ extern int amdgpu_force_asic_type;
|
|||
extern int amdgpu_smartshift_bias;
|
||||
extern int amdgpu_use_xgmi_p2p;
|
||||
extern int amdgpu_mtype_local;
|
||||
extern bool enforce_isolation;
|
||||
extern int amdgpu_enforce_isolation;
|
||||
#ifdef CONFIG_HSA_AMD
|
||||
extern int sched_policy;
|
||||
extern bool debug_evictions;
|
||||
|
@ -266,8 +268,10 @@ extern int amdgpu_umsch_mm_fwlog;
|
|||
|
||||
extern int amdgpu_user_partt_mode;
|
||||
extern int amdgpu_agp;
|
||||
extern int amdgpu_rebar;
|
||||
|
||||
extern int amdgpu_wbrf;
|
||||
extern int amdgpu_user_queue;
|
||||
|
||||
#define AMDGPU_VM_MAX_NUM_CTX 4096
|
||||
#define AMDGPU_SG_THRESHOLD (256*1024*1024)
|
||||
|
@ -488,7 +492,6 @@ struct amdgpu_flip_work {
|
|||
bool async;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* file private structure
|
||||
*/
|
||||
|
@ -501,6 +504,11 @@ struct amdgpu_fpriv {
|
|||
struct mutex bo_list_lock;
|
||||
struct idr bo_list_handles;
|
||||
struct amdgpu_ctx_mgr ctx_mgr;
|
||||
struct amdgpu_userq_mgr userq_mgr;
|
||||
|
||||
/* Eviction fence infra */
|
||||
struct amdgpu_eviction_fence_mgr evf_mgr;
|
||||
|
||||
/** GPU partition selection */
|
||||
uint32_t xcp_id;
|
||||
};
|
||||
|
@ -512,12 +520,62 @@ int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
|
|||
*/
|
||||
#define AMDGPU_MAX_WB 1024 /* Reserve at most 1024 WB slots for amdgpu-owned rings. */
|
||||
|
||||
/**
|
||||
* amdgpu_wb - This struct is used for small GPU memory allocation.
|
||||
*
|
||||
* This struct is used to allocate a small amount of GPU memory that can be
|
||||
* used to shadow certain states into the memory. This is especially useful for
|
||||
* providing easy CPU access to some states without requiring register access
|
||||
* (e.g., if some block is power gated, reading register may be problematic).
|
||||
*
|
||||
* Note: the term writeback was initially used because many of the amdgpu
|
||||
* components had some level of writeback memory, and this struct initially
|
||||
* described those components.
|
||||
*/
|
||||
struct amdgpu_wb {
|
||||
|
||||
/**
|
||||
* @wb_obj:
|
||||
*
|
||||
* Buffer Object used for the writeback memory.
|
||||
*/
|
||||
struct amdgpu_bo *wb_obj;
|
||||
|
||||
/**
|
||||
* @wb:
|
||||
*
|
||||
* Pointer to the first writeback slot. In terms of CPU address
|
||||
* this value can be accessed directly by using the offset as an index.
|
||||
* For the GPU address, it is necessary to use gpu_addr and the offset.
|
||||
*/
|
||||
volatile uint32_t *wb;
|
||||
|
||||
/**
|
||||
* @gpu_addr:
|
||||
*
|
||||
* Writeback base address in the GPU.
|
||||
*/
|
||||
uint64_t gpu_addr;
|
||||
u32 num_wb; /* Number of wb slots actually reserved for amdgpu. */
|
||||
|
||||
/**
|
||||
* @num_wb:
|
||||
*
|
||||
* Number of writeback slots reserved for amdgpu.
|
||||
*/
|
||||
u32 num_wb;
|
||||
|
||||
/**
|
||||
* @used:
|
||||
*
|
||||
* Track the writeback slot already used.
|
||||
*/
|
||||
unsigned long used[DIV_ROUND_UP(AMDGPU_MAX_WB, BITS_PER_LONG)];
|
||||
|
||||
/**
|
||||
* @lock:
|
||||
*
|
||||
* Protects read and write of the used field array.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
|
@ -551,6 +609,7 @@ struct amdgpu_allowed_register_entry {
|
|||
* are reset depends on the ASIC. Notably doesn't reset IPs
|
||||
* shared with the CPU on APUs or the memory controllers (so
|
||||
* VRAM is not lost). Not available on all ASICs.
|
||||
* @AMD_RESET_LINK: Triggers SW-UP link reset on other GPUs
|
||||
* @AMD_RESET_BACO: BACO (Bus Alive, Chip Off) method powers off and on the card
|
||||
* but without powering off the PCI bus. Suitable only for
|
||||
* discrete GPUs.
|
||||
|
@ -568,6 +627,7 @@ enum amd_reset_method {
|
|||
AMD_RESET_METHOD_MODE0,
|
||||
AMD_RESET_METHOD_MODE1,
|
||||
AMD_RESET_METHOD_MODE2,
|
||||
AMD_RESET_METHOD_LINK,
|
||||
AMD_RESET_METHOD_BACO,
|
||||
AMD_RESET_METHOD_PCI,
|
||||
AMD_RESET_METHOD_ON_INIT,
|
||||
|
@ -821,6 +881,11 @@ struct amdgpu_mqd_prop {
|
|||
uint32_t hqd_queue_priority;
|
||||
bool allow_tunneling;
|
||||
bool hqd_active;
|
||||
uint64_t shadow_addr;
|
||||
uint64_t gds_bkup_addr;
|
||||
uint64_t csa_addr;
|
||||
uint64_t fence_address;
|
||||
bool tmz_queue;
|
||||
};
|
||||
|
||||
struct amdgpu_mqd {
|
||||
|
@ -829,6 +894,12 @@ struct amdgpu_mqd {
|
|||
struct amdgpu_mqd_prop *p);
|
||||
};
|
||||
|
||||
struct amdgpu_pcie_reset_ctx {
|
||||
bool in_link_reset;
|
||||
bool occurs_dpc;
|
||||
bool audio_suspended;
|
||||
};
|
||||
|
||||
/*
|
||||
* Custom Init levels could be defined for different situations where a full
|
||||
* initialization of all hardware blocks are not expected. Sample cases are
|
||||
|
@ -853,6 +924,14 @@ struct amdgpu_init_level {
|
|||
struct amdgpu_reset_domain;
|
||||
struct amdgpu_fru_info;
|
||||
|
||||
enum amdgpu_enforce_isolation_mode {
|
||||
AMDGPU_ENFORCE_ISOLATION_DISABLE = 0,
|
||||
AMDGPU_ENFORCE_ISOLATION_ENABLE = 1,
|
||||
AMDGPU_ENFORCE_ISOLATION_ENABLE_LEGACY = 2,
|
||||
AMDGPU_ENFORCE_ISOLATION_NO_CLEANER_SHADER = 3,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Non-zero (true) if the GPU has VRAM. Zero (false) otherwise.
|
||||
*/
|
||||
|
@ -1081,6 +1160,13 @@ struct amdgpu_device {
|
|||
bool enable_uni_mes;
|
||||
struct amdgpu_mes mes;
|
||||
struct amdgpu_mqd mqds[AMDGPU_HW_IP_NUM];
|
||||
const struct amdgpu_userq_funcs *userq_funcs[AMDGPU_HW_IP_NUM];
|
||||
|
||||
/* xarray used to retrieve the user queue fence driver reference
|
||||
* in the EOP interrupt handler to signal the particular user
|
||||
* queue fence.
|
||||
*/
|
||||
struct xarray userq_xa;
|
||||
|
||||
/* df */
|
||||
struct amdgpu_df df;
|
||||
|
@ -1160,6 +1246,8 @@ struct amdgpu_device {
|
|||
struct pci_saved_state *pci_state;
|
||||
pci_channel_state_t pci_channel_state;
|
||||
|
||||
struct amdgpu_pcie_reset_ctx pcie_reset_ctx;
|
||||
|
||||
/* Track auto wait count on s_barrier settings */
|
||||
bool barrier_has_auto_waitcnt;
|
||||
|
||||
|
@ -1193,10 +1281,11 @@ struct amdgpu_device {
|
|||
bool debug_enable_ras_aca;
|
||||
bool debug_exp_resets;
|
||||
bool debug_disable_gpu_ring_reset;
|
||||
bool debug_vm_userptr;
|
||||
|
||||
/* Protection for the following isolation structure */
|
||||
struct mutex enforce_isolation_mutex;
|
||||
bool enforce_isolation[MAX_XCP];
|
||||
enum amdgpu_enforce_isolation_mode enforce_isolation[MAX_XCP];
|
||||
struct amdgpu_isolation {
|
||||
void *owner;
|
||||
struct dma_fence *spearhead;
|
||||
|
@ -1210,6 +1299,10 @@ struct amdgpu_device {
|
|||
* in KFD: VRAM or GTT.
|
||||
*/
|
||||
bool apu_prefer_gtt;
|
||||
|
||||
struct list_head userq_mgr_list;
|
||||
struct mutex userq_mutex;
|
||||
bool userq_halt_for_enforce_isolation;
|
||||
};
|
||||
|
||||
static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
|
||||
|
@ -1464,6 +1557,7 @@ void amdgpu_device_program_register_sequence(struct amdgpu_device *adev,
|
|||
const u32 array_size);
|
||||
|
||||
int amdgpu_device_mode1_reset(struct amdgpu_device *adev);
|
||||
int amdgpu_device_link_reset(struct amdgpu_device *adev);
|
||||
bool amdgpu_device_supports_atpx(struct drm_device *dev);
|
||||
bool amdgpu_device_supports_px(struct drm_device *dev);
|
||||
bool amdgpu_device_supports_boco(struct drm_device *dev);
|
||||
|
|
|
@ -120,6 +120,9 @@ static void aca_smu_bank_dump(struct amdgpu_device *adev, int idx, int total, st
|
|||
for (i = 0; i < ARRAY_SIZE(aca_regs); i++)
|
||||
RAS_EVENT_LOG(adev, event_id, HW_ERR "ACA[%02d/%02d].%s=0x%016llx\n",
|
||||
idx + 1, total, aca_regs[i].name, bank->regs[aca_regs[i].reg_idx]);
|
||||
|
||||
if (ACA_REG__STATUS__SCRUB(bank->regs[ACA_REG_IDX_STATUS]))
|
||||
RAS_EVENT_LOG(adev, event_id, HW_ERR "hardware error logged by the scrubber\n");
|
||||
}
|
||||
|
||||
static int aca_smu_get_valid_aca_banks(struct amdgpu_device *adev, enum aca_smu_type type,
|
||||
|
|
|
@ -2559,6 +2559,18 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
|
|||
if (ret != -EFAULT)
|
||||
return ret;
|
||||
|
||||
/* If applications unmap memory before destroying the userptr
|
||||
* from the KFD, trigger a segmentation fault in VM debug mode.
|
||||
*/
|
||||
if (amdgpu_ttm_adev(bo->tbo.bdev)->debug_vm_userptr) {
|
||||
pr_err("Pid %d unmapped memory before destroying userptr at GPU addr 0x%llx\n",
|
||||
pid_nr(process_info->pid), mem->va);
|
||||
|
||||
// Send GPU VM fault to user space
|
||||
kfd_signal_vm_fault_event_with_userptr(kfd_lookup_process_by_pid(process_info->pid),
|
||||
mem->va);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -281,6 +281,9 @@ static int convert_atom_mem_type_to_vram_type(struct amdgpu_device *adev,
|
|||
case ATOM_DGPU_VRAM_TYPE_GDDR6:
|
||||
vram_type = AMDGPU_VRAM_TYPE_GDDR6;
|
||||
break;
|
||||
case ATOM_DGPU_VRAM_TYPE_HBM3E:
|
||||
vram_type = AMDGPU_VRAM_TYPE_HBM3E;
|
||||
break;
|
||||
default:
|
||||
vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
break;
|
||||
|
|
|
@ -252,83 +252,22 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
|||
|
||||
if (!adev->pm.fw) {
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_TAHITI:
|
||||
strcpy(fw_name, "radeon/tahiti_smc.bin");
|
||||
break;
|
||||
case CHIP_PITCAIRN:
|
||||
if ((adev->pdev->revision == 0x81) &&
|
||||
((adev->pdev->device == 0x6810) ||
|
||||
(adev->pdev->device == 0x6811))) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "radeon/pitcairn_k_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "radeon/pitcairn_smc.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_VERDE:
|
||||
if (((adev->pdev->device == 0x6820) &&
|
||||
((adev->pdev->revision == 0x81) ||
|
||||
(adev->pdev->revision == 0x83))) ||
|
||||
((adev->pdev->device == 0x6821) &&
|
||||
((adev->pdev->revision == 0x83) ||
|
||||
(adev->pdev->revision == 0x87))) ||
|
||||
((adev->pdev->revision == 0x87) &&
|
||||
((adev->pdev->device == 0x6823) ||
|
||||
(adev->pdev->device == 0x682b)))) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "radeon/verde_k_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "radeon/verde_smc.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_OLAND:
|
||||
if (((adev->pdev->revision == 0x81) &&
|
||||
((adev->pdev->device == 0x6600) ||
|
||||
(adev->pdev->device == 0x6604) ||
|
||||
(adev->pdev->device == 0x6605) ||
|
||||
(adev->pdev->device == 0x6610))) ||
|
||||
((adev->pdev->revision == 0x83) &&
|
||||
(adev->pdev->device == 0x6610))) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "radeon/oland_k_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "radeon/oland_smc.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_HAINAN:
|
||||
if (((adev->pdev->revision == 0x81) &&
|
||||
(adev->pdev->device == 0x6660)) ||
|
||||
((adev->pdev->revision == 0x83) &&
|
||||
((adev->pdev->device == 0x6660) ||
|
||||
(adev->pdev->device == 0x6663) ||
|
||||
(adev->pdev->device == 0x6665) ||
|
||||
(adev->pdev->device == 0x6667)))) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "radeon/hainan_k_smc.bin");
|
||||
} else if ((adev->pdev->revision == 0xc3) &&
|
||||
(adev->pdev->device == 0x6665)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "radeon/banks_k_2_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "radeon/hainan_smc.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_BONAIRE:
|
||||
if ((adev->pdev->revision == 0x80) ||
|
||||
(adev->pdev->revision == 0x81) ||
|
||||
(adev->pdev->device == 0x665f)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/bonaire_k_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/bonaire_k_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "amdgpu/bonaire_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/bonaire_smc.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_HAWAII:
|
||||
if (adev->pdev->revision == 0x80) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/hawaii_k_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/hawaii_k_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "amdgpu/hawaii_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/hawaii_smc.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_TOPAZ:
|
||||
|
@ -338,76 +277,76 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
|||
((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) ||
|
||||
((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/topaz_k_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/topaz_k_smc.bin");
|
||||
} else
|
||||
strcpy(fw_name, "amdgpu/topaz_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/topaz_smc.bin");
|
||||
break;
|
||||
case CHIP_TONGA:
|
||||
if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) ||
|
||||
((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/tonga_k_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/tonga_k_smc.bin");
|
||||
} else
|
||||
strcpy(fw_name, "amdgpu/tonga_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/tonga_smc.bin");
|
||||
break;
|
||||
case CHIP_FIJI:
|
||||
strcpy(fw_name, "amdgpu/fiji_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/fiji_smc.bin");
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
if (type == CGS_UCODE_ID_SMU) {
|
||||
if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris11_k_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris11_k_smc.bin");
|
||||
} else if (ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris11_k2_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "amdgpu/polaris11_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris11_smc.bin");
|
||||
}
|
||||
} else if (type == CGS_UCODE_ID_SMU_SK) {
|
||||
strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris11_smc_sk.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
if (type == CGS_UCODE_ID_SMU) {
|
||||
if (ASICID_IS_P20(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris10_k_smc.bin");
|
||||
} else if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris10_k2_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "amdgpu/polaris10_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris10_smc.bin");
|
||||
}
|
||||
} else if (type == CGS_UCODE_ID_SMU_SK) {
|
||||
strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_POLARIS12:
|
||||
if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) {
|
||||
info->is_kicker = true;
|
||||
strcpy(fw_name, "amdgpu/polaris12_k_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris12_k_smc.bin");
|
||||
} else {
|
||||
strcpy(fw_name, "amdgpu/polaris12_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/polaris12_smc.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_VEGAM:
|
||||
strcpy(fw_name, "amdgpu/vegam_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/vegam_smc.bin");
|
||||
break;
|
||||
case CHIP_VEGA10:
|
||||
if ((adev->pdev->device == 0x687f) &&
|
||||
((adev->pdev->revision == 0xc0) ||
|
||||
(adev->pdev->revision == 0xc1) ||
|
||||
(adev->pdev->revision == 0xc3)))
|
||||
strcpy(fw_name, "amdgpu/vega10_acg_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/vega10_acg_smc.bin");
|
||||
else
|
||||
strcpy(fw_name, "amdgpu/vega10_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/vega10_smc.bin");
|
||||
break;
|
||||
case CHIP_VEGA12:
|
||||
strcpy(fw_name, "amdgpu/vega12_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/vega12_smc.bin");
|
||||
break;
|
||||
case CHIP_VEGA20:
|
||||
strcpy(fw_name, "amdgpu/vega20_smc.bin");
|
||||
strscpy(fw_name, "amdgpu/vega20_smc.bin");
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("SMC firmware not supported\n");
|
||||
|
|
|
@ -549,7 +549,7 @@ int amdgpu_cper_init(struct amdgpu_device *adev)
|
|||
{
|
||||
int r;
|
||||
|
||||
if (!amdgpu_aca_is_enabled(adev))
|
||||
if (!amdgpu_aca_is_enabled(adev) && !amdgpu_sriov_ras_cper_en(adev))
|
||||
return 0;
|
||||
|
||||
r = amdgpu_cper_ring_init(adev);
|
||||
|
@ -568,7 +568,7 @@ int amdgpu_cper_init(struct amdgpu_device *adev)
|
|||
|
||||
int amdgpu_cper_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!amdgpu_aca_is_enabled(adev))
|
||||
if (!amdgpu_aca_is_enabled(adev) && !amdgpu_sriov_ras_cper_en(adev))
|
||||
return 0;
|
||||
|
||||
adev->cper.enabled = false;
|
||||
|
|
|
@ -296,7 +296,25 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
|
|||
num_ibs[i], &p->jobs[i]);
|
||||
if (ret)
|
||||
goto free_all_kdata;
|
||||
p->jobs[i]->enforce_isolation = p->adev->enforce_isolation[fpriv->xcp_id];
|
||||
switch (p->adev->enforce_isolation[fpriv->xcp_id]) {
|
||||
case AMDGPU_ENFORCE_ISOLATION_DISABLE:
|
||||
default:
|
||||
p->jobs[i]->enforce_isolation = false;
|
||||
p->jobs[i]->run_cleaner_shader = false;
|
||||
break;
|
||||
case AMDGPU_ENFORCE_ISOLATION_ENABLE:
|
||||
p->jobs[i]->enforce_isolation = true;
|
||||
p->jobs[i]->run_cleaner_shader = true;
|
||||
break;
|
||||
case AMDGPU_ENFORCE_ISOLATION_ENABLE_LEGACY:
|
||||
p->jobs[i]->enforce_isolation = true;
|
||||
p->jobs[i]->run_cleaner_shader = false;
|
||||
break;
|
||||
case AMDGPU_ENFORCE_ISOLATION_NO_CLEANER_SHADER:
|
||||
p->jobs[i]->enforce_isolation = true;
|
||||
p->jobs[i]->run_cleaner_shader = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p->gang_leader = p->jobs[p->gang_leader_idx];
|
||||
|
||||
|
@ -349,6 +367,10 @@ static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p,
|
|||
ring = amdgpu_job_ring(job);
|
||||
ib = &job->ibs[job->num_ibs++];
|
||||
|
||||
/* submissions to kernel queues are disabled */
|
||||
if (ring->no_user_submission)
|
||||
return -EINVAL;
|
||||
|
||||
/* MM engine doesn't support user fences */
|
||||
if (p->uf_bo && ring->funcs->no_user_fence)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -2105,6 +2105,7 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
|||
amdgpu_rap_debugfs_init(adev);
|
||||
amdgpu_securedisplay_debugfs_init(adev);
|
||||
amdgpu_fw_attestation_debugfs_init(adev);
|
||||
amdgpu_psp_debugfs_init(adev);
|
||||
|
||||
debugfs_create_file("amdgpu_evict_vram", 0400, root, adev,
|
||||
&amdgpu_evict_vram_fops);
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
|
||||
#if IS_ENABLED(CONFIG_X86)
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
#endif
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
|
||||
|
@ -1680,6 +1681,9 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev)
|
|||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
if (!amdgpu_rebar)
|
||||
return 0;
|
||||
|
||||
/* resizing on Dell G5 SE platforms causes problems with runtime pm */
|
||||
if ((amdgpu_runtime_pm != 0) &&
|
||||
adev->pdev->vendor == PCI_VENDOR_ID_ATI &&
|
||||
|
@ -1870,6 +1874,35 @@ static bool amdgpu_device_pcie_dynamic_switching_supported(struct amdgpu_device
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool amdgpu_device_aspm_support_quirk(struct amdgpu_device *adev)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_X86)
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
if (!(amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(12, 0, 0) ||
|
||||
amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(12, 0, 1)))
|
||||
return false;
|
||||
|
||||
if (c->x86 == 6 &&
|
||||
adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN5) {
|
||||
switch (c->x86_model) {
|
||||
case VFM_MODEL(INTEL_ALDERLAKE):
|
||||
case VFM_MODEL(INTEL_ALDERLAKE_L):
|
||||
case VFM_MODEL(INTEL_RAPTORLAKE):
|
||||
case VFM_MODEL(INTEL_RAPTORLAKE_P):
|
||||
case VFM_MODEL(INTEL_RAPTORLAKE_S):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_should_use_aspm - check if the device should program ASPM
|
||||
*
|
||||
|
@ -1894,7 +1927,7 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
|
|||
}
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return false;
|
||||
if (!(adev->pm.pp_feature & PP_PCIE_DPM_MASK))
|
||||
if (amdgpu_device_aspm_support_quirk(adev))
|
||||
return false;
|
||||
return pcie_aspm_enabled(adev->pdev);
|
||||
}
|
||||
|
@ -2112,8 +2145,31 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev)
|
|||
|
||||
adev->firmware.load_type = amdgpu_ucode_get_load_type(adev, amdgpu_fw_load_type);
|
||||
|
||||
for (i = 0; i < MAX_XCP; i++)
|
||||
adev->enforce_isolation[i] = !!enforce_isolation;
|
||||
for (i = 0; i < MAX_XCP; i++) {
|
||||
switch (amdgpu_enforce_isolation) {
|
||||
case -1:
|
||||
case 0:
|
||||
default:
|
||||
/* disable */
|
||||
adev->enforce_isolation[i] = AMDGPU_ENFORCE_ISOLATION_DISABLE;
|
||||
break;
|
||||
case 1:
|
||||
/* enable */
|
||||
adev->enforce_isolation[i] =
|
||||
AMDGPU_ENFORCE_ISOLATION_ENABLE;
|
||||
break;
|
||||
case 2:
|
||||
/* enable legacy mode */
|
||||
adev->enforce_isolation[i] =
|
||||
AMDGPU_ENFORCE_ISOLATION_ENABLE_LEGACY;
|
||||
break;
|
||||
case 3:
|
||||
/* enable only process isolation without submitting cleaner shader */
|
||||
adev->enforce_isolation[i] =
|
||||
AMDGPU_ENFORCE_ISOLATION_NO_CLEANER_SHADER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2689,6 +2745,13 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Check for IP version 9.4.3 with A0 hardware */
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) &&
|
||||
!amdgpu_device_get_rev_id(adev)) {
|
||||
dev_err(adev->dev, "Unsupported A0 hardware\n");
|
||||
return -ENODEV; /* device unsupported - no device error */
|
||||
}
|
||||
|
||||
if (amdgpu_has_atpx() &&
|
||||
(amdgpu_is_atpx_hybrid() ||
|
||||
amdgpu_has_atpx_dgpu_power_cntl()) &&
|
||||
|
@ -2701,7 +2764,6 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
|
|||
adev->has_pr3 = parent ? pci_pr3_present(parent) : false;
|
||||
}
|
||||
|
||||
|
||||
adev->pm.pp_feature = amdgpu_pp_feature_mask;
|
||||
if (amdgpu_sriov_vf(adev) || sched_policy == KFD_SCHED_POLICY_NO_HWS)
|
||||
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
|
||||
|
@ -3172,6 +3234,7 @@ static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev)
|
|||
* always assumed to be lost.
|
||||
*/
|
||||
switch (amdgpu_asic_reset_method(adev)) {
|
||||
case AMD_RESET_METHOD_LINK:
|
||||
case AMD_RESET_METHOD_BACO:
|
||||
case AMD_RESET_METHOD_MODE1:
|
||||
return true;
|
||||
|
@ -3455,6 +3518,7 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
|
|||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
|
||||
|
||||
amdgpu_amdkfd_suspend(adev, false);
|
||||
amdgpu_userq_suspend(adev);
|
||||
|
||||
/* Workaround for ASICs need to disable SMC first */
|
||||
amdgpu_device_smu_fini_early(adev);
|
||||
|
@ -4307,9 +4371,10 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
amdgpu_sync_create(&adev->isolation[i].active);
|
||||
amdgpu_sync_create(&adev->isolation[i].prev);
|
||||
}
|
||||
mutex_init(&adev->gfx.kfd_sch_mutex);
|
||||
mutex_init(&adev->gfx.userq_sch_mutex);
|
||||
mutex_init(&adev->gfx.workload_profile_mutex);
|
||||
mutex_init(&adev->vcn.workload_profile_mutex);
|
||||
mutex_init(&adev->userq_mutex);
|
||||
|
||||
amdgpu_device_init_apu_flags(adev);
|
||||
|
||||
|
@ -4329,12 +4394,16 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
spin_lock_init(&adev->virt.rlcg_reg_lock);
|
||||
spin_lock_init(&adev->wb.lock);
|
||||
|
||||
xa_init_flags(&adev->userq_xa, XA_FLAGS_LOCK_IRQ);
|
||||
|
||||
INIT_LIST_HEAD(&adev->reset_list);
|
||||
|
||||
INIT_LIST_HEAD(&adev->ras_list);
|
||||
|
||||
INIT_LIST_HEAD(&adev->pm.od_kobj_list);
|
||||
|
||||
INIT_LIST_HEAD(&adev->userq_mgr_list);
|
||||
|
||||
INIT_DELAYED_WORK(&adev->delayed_init_work,
|
||||
amdgpu_device_delayed_init_work_handler);
|
||||
INIT_DELAYED_WORK(&adev->gfx.gfx_off_delay_work,
|
||||
|
@ -5003,8 +5072,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
|
|||
|
||||
amdgpu_device_ip_suspend_phase1(adev);
|
||||
|
||||
if (!adev->in_s0ix)
|
||||
if (!adev->in_s0ix) {
|
||||
amdgpu_amdkfd_suspend(adev, adev->in_runpm);
|
||||
amdgpu_userq_suspend(adev);
|
||||
}
|
||||
|
||||
r = amdgpu_device_evict_resources(adev);
|
||||
if (r)
|
||||
|
@ -5071,6 +5142,10 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients)
|
|||
r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
|
||||
if (r)
|
||||
goto exit;
|
||||
|
||||
r = amdgpu_userq_resume(adev);
|
||||
if (r)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
r = amdgpu_device_ip_late_init(adev);
|
||||
|
@ -5119,9 +5194,6 @@ exit:
|
|||
}
|
||||
adev->in_suspend = false;
|
||||
|
||||
if (adev->enable_mes)
|
||||
amdgpu_mes_self_test(adev);
|
||||
|
||||
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0))
|
||||
DRM_WARN("smart shift update failed\n");
|
||||
|
||||
|
@ -5502,6 +5574,29 @@ mode1_reset_failed:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_device_link_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
dev_info(adev->dev, "GPU link reset\n");
|
||||
|
||||
if (!adev->pcie_reset_ctx.occurs_dpc)
|
||||
ret = amdgpu_dpm_link_reset(adev);
|
||||
|
||||
if (ret)
|
||||
goto link_reset_failed;
|
||||
|
||||
ret = amdgpu_psp_wait_for_bootloader(adev);
|
||||
if (ret)
|
||||
goto link_reset_failed;
|
||||
|
||||
return 0;
|
||||
|
||||
link_reset_failed:
|
||||
dev_err(adev->dev, "GPU link reset failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
|
@ -5806,6 +5901,7 @@ static void amdgpu_device_set_mp1_state(struct amdgpu_device *adev)
|
|||
|
||||
switch (amdgpu_asic_reset_method(adev)) {
|
||||
case AMD_RESET_METHOD_MODE1:
|
||||
case AMD_RESET_METHOD_LINK:
|
||||
adev->mp1_state = PP_MP1_STATE_SHUTDOWN;
|
||||
break;
|
||||
case AMD_RESET_METHOD_MODE2:
|
||||
|
@ -5922,94 +6018,42 @@ static int amdgpu_device_health_check(struct list_head *device_list_handle)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_gpu_recover - reset the asic and recover scheduler
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @job: which job trigger hang
|
||||
* @reset_context: amdgpu reset context pointer
|
||||
*
|
||||
* Attempt to reset the GPU if it has hung (all asics).
|
||||
* Attempt to do soft-reset or full-reset and reinitialize Asic
|
||||
* Returns 0 for success or an error on failure.
|
||||
*/
|
||||
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
static int amdgpu_device_halt_activities(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
struct amdgpu_reset_context *reset_context,
|
||||
struct list_head *device_list,
|
||||
struct amdgpu_hive_info *hive,
|
||||
bool need_emergency_restart)
|
||||
{
|
||||
struct list_head device_list, *device_list_handle = NULL;
|
||||
bool job_signaled = false;
|
||||
struct amdgpu_hive_info *hive = NULL;
|
||||
struct list_head *device_list_handle = NULL;
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
int i, r = 0;
|
||||
bool need_emergency_restart = false;
|
||||
bool audio_suspended = false;
|
||||
int retry_limit = AMDGPU_MAX_RETRY_LIMIT;
|
||||
|
||||
/*
|
||||
* If it reaches here because of hang/timeout and a RAS error is
|
||||
* detected at the same time, let RAS recovery take care of it.
|
||||
*/
|
||||
if (amdgpu_ras_is_err_state(adev, AMDGPU_RAS_BLOCK__ANY) &&
|
||||
!amdgpu_sriov_vf(adev) &&
|
||||
reset_context->src != AMDGPU_RESET_SRC_RAS) {
|
||||
dev_dbg(adev->dev,
|
||||
"Gpu recovery from source: %d yielding to RAS error recovery handling",
|
||||
reset_context->src);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Special case: RAS triggered and full reset isn't supported
|
||||
*/
|
||||
need_emergency_restart = amdgpu_ras_need_emergency_restart(adev);
|
||||
|
||||
/*
|
||||
* Flush RAM to disk so that after reboot
|
||||
* the user can read log and see why the system rebooted.
|
||||
*/
|
||||
if (need_emergency_restart && amdgpu_ras_get_context(adev) &&
|
||||
amdgpu_ras_get_context(adev)->reboot) {
|
||||
DRM_WARN("Emergency reboot.");
|
||||
|
||||
ksys_sync_helper();
|
||||
emergency_restart();
|
||||
}
|
||||
|
||||
dev_info(adev->dev, "GPU %s begin!\n",
|
||||
need_emergency_restart ? "jobs stop":"reset");
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive)
|
||||
mutex_lock(&hive->hive_lock);
|
||||
|
||||
reset_context->job = job;
|
||||
reset_context->hive = hive;
|
||||
/*
|
||||
* Build list of devices to reset.
|
||||
* In case we are in XGMI hive mode, resort the device list
|
||||
* to put adev in the 1st position.
|
||||
*/
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1) && hive) {
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
list_add_tail(&tmp_adev->reset_list, device_list);
|
||||
if (adev->shutdown)
|
||||
tmp_adev->shutdown = true;
|
||||
if (adev->pcie_reset_ctx.occurs_dpc)
|
||||
tmp_adev->pcie_reset_ctx.in_link_reset = true;
|
||||
}
|
||||
if (!list_is_first(&adev->reset_list, &device_list))
|
||||
list_rotate_to_front(&adev->reset_list, &device_list);
|
||||
device_list_handle = &device_list;
|
||||
if (!list_is_first(&adev->reset_list, device_list))
|
||||
list_rotate_to_front(&adev->reset_list, device_list);
|
||||
device_list_handle = device_list;
|
||||
} else {
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
device_list_handle = &device_list;
|
||||
list_add_tail(&adev->reset_list, device_list);
|
||||
device_list_handle = device_list;
|
||||
}
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
if (!amdgpu_sriov_vf(adev) && (!adev->pcie_reset_ctx.occurs_dpc)) {
|
||||
r = amdgpu_device_health_check(device_list_handle);
|
||||
if (r)
|
||||
goto end_reset;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* We need to lock reset domain only once both for XGMI and single device */
|
||||
|
@ -6033,7 +6077,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
* some audio codec errors.
|
||||
*/
|
||||
if (!amdgpu_device_suspend_display_audio(tmp_adev))
|
||||
audio_suspended = true;
|
||||
tmp_adev->pcie_reset_ctx.audio_suspended = true;
|
||||
|
||||
amdgpu_ras_set_error_query_ready(tmp_adev, false);
|
||||
|
||||
|
@ -6051,6 +6095,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
|
||||
/* disable ras on ALL IPs */
|
||||
if (!need_emergency_restart &&
|
||||
(!adev->pcie_reset_ctx.occurs_dpc) &&
|
||||
amdgpu_device_ip_need_full_reset(tmp_adev))
|
||||
amdgpu_ras_suspend(tmp_adev);
|
||||
|
||||
|
@ -6068,24 +6113,24 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
|||
atomic_inc(&tmp_adev->gpu_reset_counter);
|
||||
}
|
||||
|
||||
if (need_emergency_restart)
|
||||
goto skip_sched_resume;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must check guilty signal here since after this point all old
|
||||
* HW fences are force signaled.
|
||||
*
|
||||
* job->base holds a reference to parent fence
|
||||
*/
|
||||
if (job && dma_fence_is_signaled(&job->hw_fence)) {
|
||||
job_signaled = true;
|
||||
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
|
||||
goto skip_hw_reset;
|
||||
}
|
||||
static int amdgpu_device_asic_reset(struct amdgpu_device *adev,
|
||||
struct list_head *device_list,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
int retry_limit = AMDGPU_MAX_RETRY_LIMIT;
|
||||
int r = 0;
|
||||
|
||||
retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
list_for_each_entry(tmp_adev, device_list, reset_list) {
|
||||
if (adev->pcie_reset_ctx.occurs_dpc)
|
||||
tmp_adev->no_hw_access = true;
|
||||
r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context);
|
||||
if (adev->pcie_reset_ctx.occurs_dpc)
|
||||
tmp_adev->no_hw_access = false;
|
||||
/*TODO Should we stop ?*/
|
||||
if (r) {
|
||||
dev_err(tmp_adev->dev, "GPU pre asic reset failed with err, %d for drm dev, %s ",
|
||||
|
@ -6097,6 +6142,11 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
|||
/* Actual ASIC resets if needed.*/
|
||||
/* Host driver will handle XGMI hive reset for SRIOV */
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
|
||||
/* Bail out of reset early */
|
||||
if (amdgpu_ras_is_rma(adev))
|
||||
return -ENODEV;
|
||||
|
||||
if (amdgpu_ras_get_fed_status(adev) || amdgpu_virt_rcvd_ras_interrupt(adev)) {
|
||||
dev_dbg(adev->dev, "Detected RAS error, wait for FLR completion\n");
|
||||
amdgpu_ras_set_fed(adev, true);
|
||||
|
@ -6111,12 +6161,12 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
|||
if (r)
|
||||
adev->asic_reset_res = r;
|
||||
} else {
|
||||
r = amdgpu_do_asic_reset(device_list_handle, reset_context);
|
||||
r = amdgpu_do_asic_reset(device_list, reset_context);
|
||||
if (r && r == -EAGAIN)
|
||||
goto retry;
|
||||
}
|
||||
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
list_for_each_entry(tmp_adev, device_list, reset_list) {
|
||||
/*
|
||||
* Drop any pending non scheduler resets queued before reset is done.
|
||||
* Any reset scheduled after this point would be valid. Scheduler resets
|
||||
|
@ -6126,10 +6176,18 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
|||
amdgpu_device_stop_pending_resets(tmp_adev);
|
||||
}
|
||||
|
||||
skip_hw_reset:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_device_sched_resume(struct list_head *device_list,
|
||||
struct amdgpu_reset_context *reset_context,
|
||||
bool job_signaled)
|
||||
{
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
int i, r = 0;
|
||||
|
||||
/* Post ASIC reset for all devs .*/
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
list_for_each_entry(tmp_adev, device_list, reset_list) {
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = tmp_adev->rings[i];
|
||||
|
@ -6165,8 +6223,16 @@ skip_hw_reset:
|
|||
}
|
||||
}
|
||||
|
||||
skip_sched_resume:
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static void amdgpu_device_gpu_resume(struct amdgpu_device *adev,
|
||||
struct list_head *device_list,
|
||||
bool need_emergency_restart)
|
||||
{
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
|
||||
list_for_each_entry(tmp_adev, device_list, reset_list) {
|
||||
/* unlock kfd: SRIOV would do it separately */
|
||||
if (!need_emergency_restart && !amdgpu_sriov_vf(tmp_adev))
|
||||
amdgpu_amdkfd_post_reset(tmp_adev);
|
||||
|
@ -6177,18 +6243,114 @@ skip_sched_resume:
|
|||
if (!adev->kfd.init_complete)
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
|
||||
if (audio_suspended)
|
||||
if (tmp_adev->pcie_reset_ctx.audio_suspended)
|
||||
amdgpu_device_resume_display_audio(tmp_adev);
|
||||
|
||||
amdgpu_device_unset_mp1_state(tmp_adev);
|
||||
|
||||
amdgpu_ras_set_error_query_ready(tmp_adev, true);
|
||||
|
||||
}
|
||||
|
||||
tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
|
||||
tmp_adev = list_first_entry(device_list, struct amdgpu_device,
|
||||
reset_list);
|
||||
amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* amdgpu_device_gpu_recover - reset the asic and recover scheduler
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @job: which job trigger hang
|
||||
* @reset_context: amdgpu reset context pointer
|
||||
*
|
||||
* Attempt to reset the GPU if it has hung (all asics).
|
||||
* Attempt to do soft-reset or full-reset and reinitialize Asic
|
||||
* Returns 0 for success or an error on failure.
|
||||
*/
|
||||
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
struct list_head device_list;
|
||||
bool job_signaled = false;
|
||||
struct amdgpu_hive_info *hive = NULL;
|
||||
int r = 0;
|
||||
bool need_emergency_restart = false;
|
||||
|
||||
/*
|
||||
* If it reaches here because of hang/timeout and a RAS error is
|
||||
* detected at the same time, let RAS recovery take care of it.
|
||||
*/
|
||||
if (amdgpu_ras_is_err_state(adev, AMDGPU_RAS_BLOCK__ANY) &&
|
||||
!amdgpu_sriov_vf(adev) &&
|
||||
reset_context->src != AMDGPU_RESET_SRC_RAS) {
|
||||
dev_dbg(adev->dev,
|
||||
"Gpu recovery from source: %d yielding to RAS error recovery handling",
|
||||
reset_context->src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case: RAS triggered and full reset isn't supported
|
||||
*/
|
||||
need_emergency_restart = amdgpu_ras_need_emergency_restart(adev);
|
||||
|
||||
/*
|
||||
* Flush RAM to disk so that after reboot
|
||||
* the user can read log and see why the system rebooted.
|
||||
*/
|
||||
if (need_emergency_restart && amdgpu_ras_get_context(adev) &&
|
||||
amdgpu_ras_get_context(adev)->reboot) {
|
||||
DRM_WARN("Emergency reboot.");
|
||||
|
||||
ksys_sync_helper();
|
||||
emergency_restart();
|
||||
}
|
||||
|
||||
dev_info(adev->dev, "GPU %s begin!\n",
|
||||
need_emergency_restart ? "jobs stop":"reset");
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive)
|
||||
mutex_lock(&hive->hive_lock);
|
||||
|
||||
reset_context->job = job;
|
||||
reset_context->hive = hive;
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
|
||||
r = amdgpu_device_halt_activities(adev, job, reset_context, &device_list,
|
||||
hive, need_emergency_restart);
|
||||
if (r)
|
||||
goto end_reset;
|
||||
|
||||
if (need_emergency_restart)
|
||||
goto skip_sched_resume;
|
||||
/*
|
||||
* Must check guilty signal here since after this point all old
|
||||
* HW fences are force signaled.
|
||||
*
|
||||
* job->base holds a reference to parent fence
|
||||
*/
|
||||
if (job && dma_fence_is_signaled(&job->hw_fence)) {
|
||||
job_signaled = true;
|
||||
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
|
||||
goto skip_hw_reset;
|
||||
}
|
||||
|
||||
r = amdgpu_device_asic_reset(adev, &device_list, reset_context);
|
||||
if (r)
|
||||
goto end_reset;
|
||||
skip_hw_reset:
|
||||
r = amdgpu_device_sched_resume(&device_list, reset_context, job_signaled);
|
||||
if (r)
|
||||
goto end_reset;
|
||||
skip_sched_resume:
|
||||
amdgpu_device_gpu_resume(adev, &device_list, need_emergency_restart);
|
||||
end_reset:
|
||||
if (hive) {
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
|
@ -6572,12 +6734,15 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
|
|||
{
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
int i;
|
||||
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
|
||||
struct amdgpu_reset_context reset_context;
|
||||
struct list_head device_list;
|
||||
int r = 0;
|
||||
|
||||
DRM_INFO("PCI error: detected callback, state(%d)!!\n", state);
|
||||
dev_info(adev->dev, "PCI error: detected callback!!\n");
|
||||
|
||||
if (adev->gmc.xgmi.num_physical_nodes > 1) {
|
||||
DRM_WARN("No support for XGMI hive yet...");
|
||||
if (!amdgpu_dpm_is_link_reset_supported(adev)) {
|
||||
dev_warn(adev->dev, "No support for XGMI hive yet...\n");
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
}
|
||||
|
||||
|
@ -6585,32 +6750,30 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
|
|||
|
||||
switch (state) {
|
||||
case pci_channel_io_normal:
|
||||
dev_info(adev->dev, "pci_channel_io_normal: state(%d)!!\n", state);
|
||||
return PCI_ERS_RESULT_CAN_RECOVER;
|
||||
/* Fatal error, prepare for slot reset */
|
||||
case pci_channel_io_frozen:
|
||||
/*
|
||||
* Locking adev->reset_domain->sem will prevent any external access
|
||||
* to GPU during PCI error recovery
|
||||
*/
|
||||
amdgpu_device_lock_reset_domain(adev->reset_domain);
|
||||
amdgpu_device_set_mp1_state(adev);
|
||||
/* Fatal error, prepare for slot reset */
|
||||
dev_info(adev->dev, "pci_channel_io_frozen: state(%d)!!\n", state);
|
||||
|
||||
/*
|
||||
* Block any work scheduling as we do for regular GPU reset
|
||||
* for the duration of the recovery
|
||||
*/
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
if (hive)
|
||||
mutex_lock(&hive->hive_lock);
|
||||
adev->pcie_reset_ctx.occurs_dpc = true;
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
|
||||
drm_sched_stop(&ring->sched, NULL);
|
||||
r = amdgpu_device_halt_activities(adev, NULL, &reset_context, &device_list,
|
||||
hive, false);
|
||||
if (hive) {
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
}
|
||||
atomic_inc(&adev->gpu_reset_counter);
|
||||
if (r)
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
return PCI_ERS_RESULT_NEED_RESET;
|
||||
case pci_channel_io_perm_failure:
|
||||
/* Permanent error, prepare for device removal */
|
||||
dev_info(adev->dev, "pci_channel_io_perm_failure: state(%d)!!\n", state);
|
||||
return PCI_ERS_RESULT_DISCONNECT;
|
||||
}
|
||||
|
||||
|
@ -6623,8 +6786,10 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
|
|||
*/
|
||||
pci_ers_result_t amdgpu_pci_mmio_enabled(struct pci_dev *pdev)
|
||||
{
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
|
||||
DRM_INFO("PCI error: mmio enabled callback!!\n");
|
||||
dev_info(adev->dev, "PCI error: mmio enabled callback!!\n");
|
||||
|
||||
/* TODO - dump whatever for debugging purposes */
|
||||
|
||||
|
@ -6648,10 +6813,12 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
|
|||
{
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
int r, i;
|
||||
struct amdgpu_reset_context reset_context;
|
||||
u32 memsize;
|
||||
struct amdgpu_device *tmp_adev;
|
||||
struct amdgpu_hive_info *hive;
|
||||
struct list_head device_list;
|
||||
int r = 0, i;
|
||||
u32 memsize;
|
||||
|
||||
/* PCI error slot reset should be skipped During RAS recovery */
|
||||
if ((amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) ||
|
||||
|
@ -6659,15 +6826,12 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
|
|||
amdgpu_ras_in_recovery(adev))
|
||||
return PCI_ERS_RESULT_RECOVERED;
|
||||
|
||||
DRM_INFO("PCI error: slot reset callback!!\n");
|
||||
dev_info(adev->dev, "PCI error: slot reset callback!!\n");
|
||||
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
|
||||
/* wait for asic to come out of reset */
|
||||
msleep(500);
|
||||
msleep(700);
|
||||
|
||||
/* Restore PCI confspace */
|
||||
amdgpu_device_load_pci_state(pdev);
|
||||
|
@ -6688,26 +6852,40 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
|
|||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
|
||||
set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags);
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
|
||||
adev->no_hw_access = true;
|
||||
r = amdgpu_device_pre_asic_reset(adev, &reset_context);
|
||||
adev->no_hw_access = false;
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = amdgpu_do_asic_reset(&device_list, &reset_context);
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive) {
|
||||
mutex_lock(&hive->hive_lock);
|
||||
reset_context.hive = hive;
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
tmp_adev->pcie_reset_ctx.in_link_reset = true;
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
}
|
||||
} else {
|
||||
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
}
|
||||
|
||||
r = amdgpu_device_asic_reset(adev, &device_list, &reset_context);
|
||||
out:
|
||||
if (!r) {
|
||||
if (amdgpu_device_cache_pci_state(adev->pdev))
|
||||
pci_restore_state(adev->pdev);
|
||||
|
||||
DRM_INFO("PCIe error recovery succeeded\n");
|
||||
dev_info(adev->dev, "PCIe error recovery succeeded\n");
|
||||
} else {
|
||||
DRM_ERROR("PCIe error recovery failed, err:%d", r);
|
||||
amdgpu_device_unset_mp1_state(adev);
|
||||
amdgpu_device_unlock_reset_domain(adev->reset_domain);
|
||||
dev_err(adev->dev, "PCIe error recovery failed, err:%d\n", r);
|
||||
if (hive) {
|
||||
list_for_each_entry(tmp_adev, &device_list, reset_list)
|
||||
amdgpu_device_unset_mp1_state(tmp_adev);
|
||||
amdgpu_device_unlock_reset_domain(adev->reset_domain);
|
||||
}
|
||||
}
|
||||
|
||||
if (hive) {
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
}
|
||||
|
||||
return r ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
|
||||
|
@ -6724,26 +6902,36 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
|
|||
{
|
||||
struct drm_device *dev = pci_get_drvdata(pdev);
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
int i;
|
||||
struct list_head device_list;
|
||||
struct amdgpu_hive_info *hive = NULL;
|
||||
struct amdgpu_device *tmp_adev = NULL;
|
||||
|
||||
|
||||
DRM_INFO("PCI error: resume callback!!\n");
|
||||
dev_info(adev->dev, "PCI error: resume callback!!\n");
|
||||
|
||||
/* Only continue execution for the case of pci_channel_io_frozen */
|
||||
if (adev->pci_channel_state != pci_channel_io_frozen)
|
||||
return;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
INIT_LIST_HEAD(&device_list);
|
||||
|
||||
if (!amdgpu_ring_sched_ready(ring))
|
||||
continue;
|
||||
hive = amdgpu_get_xgmi_hive(adev);
|
||||
if (hive) {
|
||||
mutex_lock(&hive->hive_lock);
|
||||
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
|
||||
tmp_adev->pcie_reset_ctx.in_link_reset = false;
|
||||
list_add_tail(&tmp_adev->reset_list, &device_list);
|
||||
}
|
||||
} else
|
||||
list_add_tail(&adev->reset_list, &device_list);
|
||||
|
||||
drm_sched_start(&ring->sched, 0);
|
||||
amdgpu_device_sched_resume(&device_list, NULL, NULL);
|
||||
amdgpu_device_gpu_resume(adev, &device_list, false);
|
||||
adev->pcie_reset_ctx.occurs_dpc = false;
|
||||
|
||||
if (hive) {
|
||||
mutex_unlock(&hive->hive_lock);
|
||||
amdgpu_put_xgmi_hive(hive);
|
||||
}
|
||||
|
||||
amdgpu_device_unset_mp1_state(adev);
|
||||
amdgpu_device_unlock_reset_domain(adev->reset_domain);
|
||||
}
|
||||
|
||||
bool amdgpu_device_cache_pci_state(struct pci_dev *pdev)
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#include "amdgpu_reset.h"
|
||||
#include "amdgpu_sched.h"
|
||||
#include "amdgpu_xgmi.h"
|
||||
#include "amdgpu_userq.h"
|
||||
#include "amdgpu_userq_fence.h"
|
||||
#include "../amdxcp/amdgpu_xcp_drv.h"
|
||||
|
||||
/*
|
||||
|
@ -123,9 +125,10 @@
|
|||
* - 3.61.0 - Contains fix for RV/PCO compute queues
|
||||
* - 3.62.0 - Add AMDGPU_IDS_FLAGS_MODE_PF, AMDGPU_IDS_FLAGS_MODE_VF & AMDGPU_IDS_FLAGS_MODE_PT
|
||||
* - 3.63.0 - GFX12 display DCC supports 256B max compressed block size
|
||||
* - 3.64.0 - Userq IP support query
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 63
|
||||
#define KMS_DRIVER_MINOR 64
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
/*
|
||||
|
@ -140,6 +143,7 @@ enum AMDGPU_DEBUG_MASK {
|
|||
AMDGPU_DEBUG_ENABLE_EXP_RESETS = BIT(5),
|
||||
AMDGPU_DEBUG_DISABLE_GPU_RING_RESET = BIT(6),
|
||||
AMDGPU_DEBUG_SMU_POOL = BIT(7),
|
||||
AMDGPU_DEBUG_VM_USERPTR = BIT(8),
|
||||
};
|
||||
|
||||
unsigned int amdgpu_vram_limit = UINT_MAX;
|
||||
|
@ -176,7 +180,7 @@ uint amdgpu_pg_mask = 0xffffffff;
|
|||
uint amdgpu_sdma_phase_quantum = 32;
|
||||
char *amdgpu_disable_cu;
|
||||
char *amdgpu_virtual_display;
|
||||
bool enforce_isolation;
|
||||
int amdgpu_enforce_isolation = -1;
|
||||
int amdgpu_modeset = -1;
|
||||
|
||||
/* Specifies the default granularity for SVM, used in buffer
|
||||
|
@ -238,6 +242,8 @@ int amdgpu_agp = -1; /* auto */
|
|||
int amdgpu_wbrf = -1;
|
||||
int amdgpu_damage_clips = -1; /* auto */
|
||||
int amdgpu_umsch_mm_fwlog;
|
||||
int amdgpu_rebar = -1; /* auto */
|
||||
int amdgpu_user_queue = -1;
|
||||
|
||||
DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0,
|
||||
"DRM_UT_CORE",
|
||||
|
@ -1033,11 +1039,13 @@ module_param_named(user_partt_mode, amdgpu_user_partt_mode, uint, 0444);
|
|||
|
||||
|
||||
/**
|
||||
* DOC: enforce_isolation (bool)
|
||||
* enforce process isolation between graphics and compute via using the same reserved vmid.
|
||||
* DOC: enforce_isolation (int)
|
||||
* enforce process isolation between graphics and compute.
|
||||
* (-1 = auto, 0 = disable, 1 = enable, 2 = enable legacy mode, 3 = enable without cleaner shader)
|
||||
*/
|
||||
module_param(enforce_isolation, bool, 0444);
|
||||
MODULE_PARM_DESC(enforce_isolation, "enforce process isolation between graphics and compute . enforce_isolation = on");
|
||||
module_param_named(enforce_isolation, amdgpu_enforce_isolation, int, 0444);
|
||||
MODULE_PARM_DESC(enforce_isolation,
|
||||
"enforce process isolation between graphics and compute. (-1 = auto, 0 = disable, 1 = enable, 2 = enable legacy mode, 3 = enable without cleaner shader)");
|
||||
|
||||
/**
|
||||
* DOC: modeset (int)
|
||||
|
@ -1096,6 +1104,28 @@ MODULE_PARM_DESC(wbrf,
|
|||
"Enable Wifi RFI interference mitigation (0 = disabled, 1 = enabled, -1 = auto(default)");
|
||||
module_param_named(wbrf, amdgpu_wbrf, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: rebar (int)
|
||||
* Allow BAR resizing. Disable this to prevent the driver from attempting
|
||||
* to resize the BAR if the GPU supports it and there is available MMIO space.
|
||||
* Note that this just prevents the driver from resizing the BAR. The BIOS
|
||||
* may have already resized the BAR at boot time.
|
||||
*/
|
||||
MODULE_PARM_DESC(rebar, "Resizable BAR (-1 = auto (default), 0 = disable, 1 = enable)");
|
||||
module_param_named(rebar, amdgpu_rebar, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: user_queue (int)
|
||||
* Enable user queues on systems that support user queues. Possible values:
|
||||
*
|
||||
* - -1 = auto (ASIC specific default)
|
||||
* - 0 = user queues disabled
|
||||
* - 1 = user queues enabled and kernel queues enabled (if supported)
|
||||
* - 2 = user queues enabled and kernel queues disabled
|
||||
*/
|
||||
MODULE_PARM_DESC(user_queue, "Enable user queues (-1 = auto (default), 0 = disable, 1 = enable, 2 = enable UQs and disable KQs)");
|
||||
module_param_named(user_queue, amdgpu_user_queue, int, 0444);
|
||||
|
||||
/* These devices are not supported by amdgpu.
|
||||
* They are supported by the mach64, r128, radeon drivers
|
||||
*/
|
||||
|
@ -2244,6 +2274,10 @@ static void amdgpu_init_debug_options(struct amdgpu_device *adev)
|
|||
pr_info("debug: use vram for smu pool\n");
|
||||
adev->pm.smu_debug_mask |= SMU_DEBUG_POOL_USE_VRAM;
|
||||
}
|
||||
if (amdgpu_debug_mask & AMDGPU_DEBUG_VM_USERPTR) {
|
||||
pr_info("debug: VM mode debug for userptr is enabled\n");
|
||||
adev->debug_vm_userptr = true;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev, unsigned long flags)
|
||||
|
@ -2700,6 +2734,29 @@ static int amdgpu_runtime_idle_check_display(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_runtime_idle_check_userq(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct drm_device *drm_dev = pci_get_drvdata(pdev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
struct amdgpu_usermode_queue *queue;
|
||||
struct amdgpu_userq_mgr *uqm, *tmp;
|
||||
int queue_id;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&adev->userq_mutex);
|
||||
list_for_each_entry_safe(uqm, tmp, &adev->userq_mgr_list, list) {
|
||||
idr_for_each_entry(&uqm->userq_idr, queue, queue_id) {
|
||||
ret = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
mutex_unlock(&adev->userq_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdgpu_pmops_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
@ -2713,6 +2770,9 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
|
|||
}
|
||||
|
||||
ret = amdgpu_runtime_idle_check_display(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = amdgpu_runtime_idle_check_userq(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -2836,12 +2896,30 @@ static int amdgpu_pmops_runtime_idle(struct device *dev)
|
|||
}
|
||||
|
||||
ret = amdgpu_runtime_idle_check_display(dev);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
ret = amdgpu_runtime_idle_check_userq(dev);
|
||||
done:
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_autosuspend(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int amdgpu_drm_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct drm_file *file_priv = filp->private_data;
|
||||
struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
|
||||
|
||||
if (fpriv) {
|
||||
fpriv->evf_mgr.fd_closing = true;
|
||||
amdgpu_userq_mgr_fini(&fpriv->userq_mgr);
|
||||
amdgpu_eviction_fence_destroy(&fpriv->evf_mgr);
|
||||
}
|
||||
|
||||
return drm_release(inode, filp);
|
||||
}
|
||||
|
||||
long amdgpu_drm_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
|
@ -2893,7 +2971,7 @@ static const struct file_operations amdgpu_driver_kms_fops = {
|
|||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.flush = amdgpu_flush,
|
||||
.release = drm_release,
|
||||
.release = amdgpu_drm_release,
|
||||
.unlocked_ioctl = amdgpu_drm_ioctl,
|
||||
.mmap = drm_gem_mmap,
|
||||
.poll = drm_poll,
|
||||
|
@ -2940,6 +3018,9 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
|
|||
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(AMDGPU_USERQ, amdgpu_userq_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_SIGNAL, amdgpu_userq_signal_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_WAIT, amdgpu_userq_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
|
||||
};
|
||||
|
||||
static const struct drm_driver amdgpu_kms_driver = {
|
||||
|
@ -3030,6 +3111,10 @@ static int __init amdgpu_init(void)
|
|||
if (r)
|
||||
goto error_fence;
|
||||
|
||||
r = amdgpu_userq_fence_slab_init();
|
||||
if (r)
|
||||
goto error_fence;
|
||||
|
||||
DRM_INFO("amdgpu kernel modesetting enabled.\n");
|
||||
amdgpu_register_atpx_handler();
|
||||
amdgpu_acpi_detect();
|
||||
|
@ -3061,6 +3146,7 @@ static void __exit amdgpu_exit(void)
|
|||
amdgpu_acpi_release();
|
||||
amdgpu_sync_fini();
|
||||
amdgpu_fence_slab_fini();
|
||||
amdgpu_userq_fence_slab_fini();
|
||||
mmu_notifier_synchronize();
|
||||
amdgpu_xcp_drv_release();
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue