mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
drm for 5.20/6.0
New driver: - logicvc vfio: - use aperture API core: - of: Add data-lane helpers and convert drivers - connector: Remove deprecated ida_simple_get() media: - Add various RGB666 and RGB888 format constants panel: - Add HannStar HSD101PWW - Add ETML0700Y5DHA dma-buf: - add sync-file API - set dma mask for udmabuf devices fbcon: - Improve scrolling performance - Sanitize input fbdev: - device unregistering fixes - vesa: Support COMPILE_TEST - Disable firmware-device registration when first native driver loads aperture: - fix segfault during hot-unplug - export for use with other subsystems client: - use driver validated modes dp: - aux: make probing more reliable - mst: Read extended DPCD capabilities during system resume - Support waiting for HDP signal - Port-validation fixes edid: - CEA data-block iterators - struct drm_edid introduction - implement HF-EEODB extension gem: - don't use fb format non-existing planes probe-helper: - use 640x480 as displayport fallback scheduler: - don't kill jobs in interrupt context bridge: - Add support for i.MX8qxp and i.MX8qm - lots of fixes/cleanups - Add TI-DLPC3433 - fy07024di26a30d: Optional GPIO reset - ldb: Add reg and reg-name properties to bindings, Kconfig fixes - lt9611: Fix display sensing; - tc358767: DSI/DPI refactoring and DSI-to-eDP support, DSI lane handling - tc358775: Fix clock settings - ti-sn65dsi83: Allow GPIO to sleep - adv7511: I2C fixes - anx7625: Fix error handling; DPI fixes; Implement HDP timeout via callback - fsl-ldb: Drop DE flip - ti-sn65dsi86: Convert to atomic modesetting amdgpu: - use atomic fence helpers in DM - fix VRAM address calculations - export CRTC bpc via debugfs - Initial devcoredump support - Enable high priority gfx queue on asics which support it - Adjust GART size on newer APUs for S/G display - Soft reset for GFX 11 / SDMA 6 - Add gfxoff status query for vangogh - Fix timestamps for cursor only commits - Adjust GART size on newer APUs for S/G display - fix buddy memory corruption amdkfd: - MMU notifier fixes - P2P DMA support using dma-buf - Add available memory IOCTL - HMM profiler support - Simplify GPUVM validation - Unified memory for CWSR save/restore area i915: - General driver clean-up - DG2 enabling (still under force probe) - DG2 small BAR memory support - HuC loading support - DG2 workarounds - DG2/ATS-M device IDs added - Ponte Vecchio prep work and new blitter engines - add Meteorlake support - Fix sparse warnings - DMC MMIO range checks - Audio related fixes - Runtime PM fixes - PSR fixes - Media freq factor and per-gt enhancements - DSI fixes for ICL+ - Disable DMC flip queue handlers - ADL_P voltage swing updates - Use more the VBT for panel information - Fix on Type-C ports with TBT mode - Improve fastset and allow seamless M/N changes - Accept more fixed modes with VRR/DMRRS panels - Disable connector polling for a headless SKU - ADL-S display PLL w/a - Enable THP on Icelake and beyond - Fix i915_gem_object_ggtt_pin_ww regression on old platforms - Expose per tile media freq factor in sysfs - Fix dma_resv fence handling in multi-batch execbuf - Improve on suspend / resume time with VT-d enabled - export CRTC bpc settings via debugfs msm: - gpu: a619 support - gpu: Fix for unclocked GMU register access - gpu: Devcore dump enhancements - client utilization via fdinfo support - fix fence rollover issue - gem: Lockdep false-positive warning fix - gem: Switch to pfn mappings - WB support on sc7180 - dp: dropped custom bulk clock implementation - fix link retraining on resolution change - hdmi: dropped obsolete GPIO support tegra: - context isolation for host1x engines - tegra234 soc support mediatek: - add vdosys0/1 for mt8195 - add MT8195 dp_intf driver exynos: - Fix resume function issue of exynos decon driver by calling clk_disable_unprepare() properly if clk_prepare_enable() failed. nouveau: - set of misc fixes/cleanups - display cleanups gma500: - Cleanup connector I2C handling hyperv: - Unify VRAM allocation of Gen1 and Gen2 meson: - Support YUV422 output; Refcount fixes mgag200: - Support damage clipping - Support gamma handling - Protect concurrent HW access - Fixes to connector - Store model-specific limits in device-info structure - fix PCI register init panfrost: - Valhall support r128: - Fix bit-shift overflow rockchip: - Locking fixes in error path ssd130x: - Fix built-in linkage udl: - Always advertize VGA connector ast: - Support multiple outputs - fix black screen on resume sun4i: - HDMI PHY cleanups vc4: - Add support for BCM2711 vkms: - Allocate output buffer with vmalloc() mcde: - Fix ref-count leak mxsfb/lcdif: - Support i.MX8MP LCD controller stm/ltdc: - Support dynamic Z order - Support mirroring ingenic: - Fix display at maximum resolution -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmLp/7YACgkQDHTzWXnE hr7NjhAAnefa+72EG42OAqajbwTQMENOtFfqyL3k6ueK2ciYbsj/wklw/xc4Ok3o DM5kG54t+nA9L1M7UyE7eaO36/XcuvS8Ea0uKKkamWt+3Ux4g1Vo1J37nP5sK5jI GT/wceKA5sk3nuYly2lBby6mVTGuhAX+3edTAFeOwmd0WvQzzpy4vV+nCAgfshUs ql4gfQPdQdP+wiovUzCIEu6exCSCAI/Oc944fd3AJi5bZbOPFXRS4rMMOLSrdoXV 9P44EZExPbYrDuVUCx/UaZtN8D9myyyBfZe62CtdgNyTYUHXnHCBYue+7D/s5O+y GaLWcP128MsqZNmJNhmcWFIlgqowO24YkKUH68JH0UtBLSWich8rfdEsrxIidYED 0ma1jodRapjyZOjrHEJ3N5deKpoflMmqvCMpvIk1Ev6pT8KX9a6u34kLgsOVCV41 2bDEYD+DbRW2FexGR79yB2huXHGSnguco6069ca1oy9RF4q8cX6Pb1w2u42oS7zX lIgLIashilVR2AYg/qi6IPHavmOQ9ItSXPC+4YasYiMGp/mwePqpmL63b/wkhg0D nXn6/F8Bm6wle2FFbkLGwo1fF1Hn7RzTHSlqRWDKSEaMLhCus6M09VsobFCB19i0 lO4FNVTL8ZtryR94bgVmgi616w9hOhDhM9A+C0kJ9KBkDnDYUJU= =HQ9U -----END PGP SIGNATURE----- Merge tag 'drm-next-2022-08-03' of git://anongit.freedesktop.org/drm/drm Pull drm updates from Dave Airlie: "Highlights: - New driver for logicvc - which is a display IP core. - EDID parser rework to add new extensions - fbcon scrolling improvements - i915 has some more DG2 work but not enabled by default, but should have enough features for userspace to work now. Otherwise it's lots of work all over the place. Detailed summary: New driver: - logicvc vfio: - use aperture API core: - of: Add data-lane helpers and convert drivers - connector: Remove deprecated ida_simple_get() media: - Add various RGB666 and RGB888 format constants panel: - Add HannStar HSD101PWW - Add ETML0700Y5DHA dma-buf: - add sync-file API - set dma mask for udmabuf devices fbcon: - Improve scrolling performance - Sanitize input fbdev: - device unregistering fixes - vesa: Support COMPILE_TEST - Disable firmware-device registration when first native driver loads aperture: - fix segfault during hot-unplug - export for use with other subsystems client: - use driver validated modes dp: - aux: make probing more reliable - mst: Read extended DPCD capabilities during system resume - Support waiting for HDP signal - Port-validation fixes edid: - CEA data-block iterators - struct drm_edid introduction - implement HF-EEODB extension gem: - don't use fb format non-existing planes probe-helper: - use 640x480 as displayport fallback scheduler: - don't kill jobs in interrupt context bridge: - Add support for i.MX8qxp and i.MX8qm - lots of fixes/cleanups - Add TI-DLPC3433 - fy07024di26a30d: Optional GPIO reset - ldb: Add reg and reg-name properties to bindings, Kconfig fixes - lt9611: Fix display sensing; - tc358767: DSI/DPI refactoring and DSI-to-eDP support, DSI lane handling - tc358775: Fix clock settings - ti-sn65dsi83: Allow GPIO to sleep - adv7511: I2C fixes - anx7625: Fix error handling; DPI fixes; Implement HDP timeout via callback - fsl-ldb: Drop DE flip - ti-sn65dsi86: Convert to atomic modesetting amdgpu: - use atomic fence helpers in DM - fix VRAM address calculations - export CRTC bpc via debugfs - Initial devcoredump support - Enable high priority gfx queue on asics which support it - Adjust GART size on newer APUs for S/G display - Soft reset for GFX 11 / SDMA 6 - Add gfxoff status query for vangogh - Fix timestamps for cursor only commits - Adjust GART size on newer APUs for S/G display - fix buddy memory corruption amdkfd: - MMU notifier fixes - P2P DMA support using dma-buf - Add available memory IOCTL - HMM profiler support - Simplify GPUVM validation - Unified memory for CWSR save/restore area i915: - General driver clean-up - DG2 enabling (still under force probe) - DG2 small BAR memory support - HuC loading support - DG2 workarounds - DG2/ATS-M device IDs added - Ponte Vecchio prep work and new blitter engines - add Meteorlake support - Fix sparse warnings - DMC MMIO range checks - Audio related fixes - Runtime PM fixes - PSR fixes - Media freq factor and per-gt enhancements - DSI fixes for ICL+ - Disable DMC flip queue handlers - ADL_P voltage swing updates - Use more the VBT for panel information - Fix on Type-C ports with TBT mode - Improve fastset and allow seamless M/N changes - Accept more fixed modes with VRR/DMRRS panels - Disable connector polling for a headless SKU - ADL-S display PLL w/a - Enable THP on Icelake and beyond - Fix i915_gem_object_ggtt_pin_ww regression on old platforms - Expose per tile media freq factor in sysfs - Fix dma_resv fence handling in multi-batch execbuf - Improve on suspend / resume time with VT-d enabled - export CRTC bpc settings via debugfs msm: - gpu: a619 support - gpu: Fix for unclocked GMU register access - gpu: Devcore dump enhancements - client utilization via fdinfo support - fix fence rollover issue - gem: Lockdep false-positive warning fix - gem: Switch to pfn mappings - WB support on sc7180 - dp: dropped custom bulk clock implementation - fix link retraining on resolution change - hdmi: dropped obsolete GPIO support tegra: - context isolation for host1x engines - tegra234 soc support mediatek: - add vdosys0/1 for mt8195 - add MT8195 dp_intf driver exynos: - Fix resume function issue of exynos decon driver by calling clk_disable_unprepare() properly if clk_prepare_enable() failed. nouveau: - set of misc fixes/cleanups - display cleanups gma500: - Cleanup connector I2C handling hyperv: - Unify VRAM allocation of Gen1 and Gen2 meson: - Support YUV422 output; Refcount fixes mgag200: - Support damage clipping - Support gamma handling - Protect concurrent HW access - Fixes to connector - Store model-specific limits in device-info structure - fix PCI register init panfrost: - Valhall support r128: - Fix bit-shift overflow rockchip: - Locking fixes in error path ssd130x: - Fix built-in linkage udl: - Always advertize VGA connector ast: - Support multiple outputs - fix black screen on resume sun4i: - HDMI PHY cleanups vc4: - Add support for BCM2711 vkms: - Allocate output buffer with vmalloc() mcde: - Fix ref-count leak mxsfb/lcdif: - Support i.MX8MP LCD controller stm/ltdc: - Support dynamic Z order - Support mirroring ingenic: - Fix display at maximum resolution" * tag 'drm-next-2022-08-03' of git://anongit.freedesktop.org/drm/drm: (1480 commits) drm/amd/display: Fix a compilation failure on PowerPC caused by FPU code drm/amdgpu: enable support for psp 13.0.4 block drm/amdgpu: add files for PSP 13.0.4 drm/amdgpu: add header files for MP 13.0.4 drm/amdgpu: correct RLC_RLCS_BOOTLOAD_STATUS offset and index drm/amdgpu: send msg to IMU for the front-door loading drm/amdkfd: use time_is_before_jiffies(a + b) to replace "jiffies - a > b" drm/amdgpu: fix hive reference leak when reflecting psp topology info drm/amd/pm: enable GFX ULV feature support for SMU13.0.0 drm/amd/pm: update driver if header for SMU 13.0.0 drm/amdgpu: move mes self test after drm sched re-started drm/amdgpu: drop non-necessary call trace dump drm/amdgpu: enable VCN cg and JPEG cg/pg drm/amdgpu: vcn_4_0_2 video codec query drm/amdgpu: add VCN_4_0_2 firmware support drm/amdgpu: add VCN function in NBIO v7.7 drm/amdgpu: fix a vcn4 boot poll bug in emulation mode drm/amd/amdgpu: add memory training support for PSP_V13 drm/amdkfd: remove an unnecessary amdgpu_bo_ref drm/amd/pm: Add get_gfx_off_status interface for yellow carp ...
This commit is contained in:
commit
b44f2fd879
4
CREDITS
4
CREDITS
@ -3495,6 +3495,10 @@ D: wd33c93 SCSI driver (linux-m68k)
|
||||
S: San Jose, California
|
||||
S: USA
|
||||
|
||||
N: Joonyoung Shim
|
||||
E: y0922.shim@samsung.com
|
||||
D: Samsung Exynos DRM drivers
|
||||
|
||||
N: Robert Siemer
|
||||
E: Robert.Siemer@gmx.de
|
||||
P: 2048/C99A4289 2F DC 17 2E 56 62 01 C8 3D F2 AC 09 F2 E5 DD EE
|
||||
|
@ -94,7 +94,22 @@ properties:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Video port for MIPI DSI input.
|
||||
MIPI DSI/DPI input.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
remote-endpoint: true
|
||||
|
||||
bus-type:
|
||||
enum: [7]
|
||||
default: 1
|
||||
|
||||
data-lanes: true
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
@ -143,6 +158,8 @@ examples:
|
||||
reg = <0>;
|
||||
anx7625_in: endpoint {
|
||||
remote-endpoint = <&mipi_dsi>;
|
||||
bus-type = <7>;
|
||||
data-lanes = <0 1 2 3>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,173 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/bridge/fsl,imx8qxp-ldb.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale i.MX8qm/qxp LVDS Display Bridge
|
||||
|
||||
maintainers:
|
||||
- Liu Ying <victor.liu@nxp.com>
|
||||
|
||||
description: |
|
||||
The Freescale i.MX8qm/qxp LVDS Display Bridge(LDB) has two channels.
|
||||
|
||||
The i.MX8qm/qxp LDB is controlled by Control and Status Registers(CSR) module.
|
||||
The CSR module, as a system controller, contains the LDB's configuration
|
||||
registers.
|
||||
|
||||
For i.MX8qxp LDB, each channel supports up to 24bpp parallel input color
|
||||
format and can map the input to VESA or JEIDA standards. The two channels
|
||||
cannot be used simultaneously, that is to say, the user should pick one of
|
||||
them to use. Two LDB channels from two LDB instances can work together in
|
||||
LDB split mode to support a dual link LVDS display. The channel indexes
|
||||
have to be different. Channel0 outputs odd pixels and channel1 outputs
|
||||
even pixels.
|
||||
|
||||
For i.MX8qm LDB, each channel additionally supports up to 30bpp parallel
|
||||
input color format. The two channels can be used simultaneously, either
|
||||
in dual mode or split mode. In dual mode, the two channels output identical
|
||||
data. In split mode, channel0 outputs odd pixels and channel1 outputs even
|
||||
pixels.
|
||||
|
||||
A side note is that i.MX8qm/qxp LDB is officially called pixel mapper in
|
||||
the SoC reference manuals. The pixel mapper uses logic of LDBs embedded in
|
||||
i.MX6qdl/sx SoCs, i.e., it is essentially based on them. To keep the naming
|
||||
consistency, this binding calls it LDB.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8qm-ldb
|
||||
- fsl,imx8qxp-ldb
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: pixel clock
|
||||
- description: bypass clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pixel
|
||||
- const: bypass
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
fsl,companion-ldb:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: |
|
||||
A phandle which points to companion LDB which is used in LDB split mode.
|
||||
|
||||
patternProperties:
|
||||
"^channel@[0-1]$":
|
||||
type: object
|
||||
description: Represents a channel of LDB.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
description: The channel index.
|
||||
enum: [ 0, 1 ]
|
||||
|
||||
phys:
|
||||
description: A phandle to the phy module representing the LVDS PHY.
|
||||
maxItems: 1
|
||||
|
||||
phy-names:
|
||||
const: lvds_phy
|
||||
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Input port of the channel.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Output port of the channel.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- reg
|
||||
- phys
|
||||
- phy-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- channel@0
|
||||
- channel@1
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx8qm-ldb
|
||||
then:
|
||||
properties:
|
||||
fsl,companion-ldb: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
ldb {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,imx8qxp-ldb";
|
||||
clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>,
|
||||
<&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
|
||||
clock-names = "pixel", "bypass";
|
||||
power-domains = <&pd IMX_SC_R_LVDS_0>;
|
||||
|
||||
channel@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
phys = <&mipi_lvds_0_phy>;
|
||||
phy-names = "lvds_phy";
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint {
|
||||
remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
channel@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
phys = <&mipi_lvds_0_phy>;
|
||||
phy-names = "lvds_phy";
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint {
|
||||
remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,144 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/bridge/fsl,imx8qxp-pixel-combiner.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale i.MX8qm/qxp Pixel Combiner
|
||||
|
||||
maintainers:
|
||||
- Liu Ying <victor.liu@nxp.com>
|
||||
|
||||
description: |
|
||||
The Freescale i.MX8qm/qxp Pixel Combiner takes two output streams from a
|
||||
single display controller and manipulates the two streams to support a number
|
||||
of modes(bypass, pixel combine, YUV444 to YUV422, split_RGB) configured as
|
||||
either one screen, two screens, or virtual screens. The pixel combiner is
|
||||
also responsible for generating some of the control signals for the pixel link
|
||||
output channel.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8qm-pixel-combiner
|
||||
- fsl,imx8qxp-pixel-combiner
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: apb
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^channel@[0-1]$":
|
||||
type: object
|
||||
description: Represents a display stream of pixel combiner.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
description: The display stream index.
|
||||
enum: [ 0, 1 ]
|
||||
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Input endpoint of the display stream.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Output endpoint of the display stream.
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- reg
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx8-lpcg.h>
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
pixel-combiner@56020000 {
|
||||
compatible = "fsl,imx8qxp-pixel-combiner";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x56020000 0x10000>;
|
||||
clocks = <&dc0_pixel_combiner_lpcg IMX_LPCG_CLK_4>;
|
||||
clock-names = "apb";
|
||||
power-domains = <&pd IMX_SC_R_DC_0>;
|
||||
|
||||
channel@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
dc0_pixel_combiner_ch0_dc0_dpu_disp0: endpoint {
|
||||
remote-endpoint = <&dc0_dpu_disp0_dc0_pixel_combiner_ch0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
dc0_pixel_combiner_ch0_dc0_pixel_link0: endpoint {
|
||||
remote-endpoint = <&dc0_pixel_link0_dc0_pixel_combiner_ch0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
channel@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
dc0_pixel_combiner_ch1_dc0_dpu_disp1: endpoint {
|
||||
remote-endpoint = <&dc0_dpu_disp1_dc0_pixel_combiner_ch1>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
dc0_pixel_combiner_ch1_dc0_pixel_link1: endpoint {
|
||||
remote-endpoint = <&dc0_pixel_link1_dc0_pixel_combiner_ch1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,144 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/bridge/fsl,imx8qxp-pixel-link.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale i.MX8qm/qxp Display Pixel Link
|
||||
|
||||
maintainers:
|
||||
- Liu Ying <victor.liu@nxp.com>
|
||||
|
||||
description: |
|
||||
The Freescale i.MX8qm/qxp Display Pixel Link(DPL) forms a standard
|
||||
asynchronous linkage between pixel sources(display controller or
|
||||
camera module) and pixel consumers(imaging or displays).
|
||||
It consists of two distinct functions, a pixel transfer function and a
|
||||
control interface. Multiple pixel channels can exist per one control channel.
|
||||
This binding documentation is only for pixel links whose pixel sources are
|
||||
display controllers.
|
||||
|
||||
The i.MX8qm/qxp Display Pixel Link is accessed via System Controller Unit(SCU)
|
||||
firmware.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8qm-dc-pixel-link
|
||||
- fsl,imx8qxp-dc-pixel-link
|
||||
|
||||
fsl,dc-id:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8
|
||||
description: |
|
||||
u8 value representing the display controller index that the pixel link
|
||||
connects to.
|
||||
|
||||
fsl,dc-stream-id:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8
|
||||
description: |
|
||||
u8 value representing the display controller stream index that the pixel
|
||||
link connects to.
|
||||
enum: [0, 1]
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The pixel link input port node from upstream video source.
|
||||
|
||||
patternProperties:
|
||||
"^port@[1-4]$":
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The pixel link output port node to downstream bridge.
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
- port@2
|
||||
- port@3
|
||||
- port@4
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx8qxp-dc-pixel-link
|
||||
then:
|
||||
properties:
|
||||
fsl,dc-id:
|
||||
const: 0
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx8qm-dc-pixel-link
|
||||
then:
|
||||
properties:
|
||||
fsl,dc-id:
|
||||
enum: [0, 1]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- fsl,dc-id
|
||||
- fsl,dc-stream-id
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
dc0-pixel-link0 {
|
||||
compatible = "fsl,imx8qxp-dc-pixel-link";
|
||||
fsl,dc-id = /bits/ 8 <0>;
|
||||
fsl,dc-stream-id = /bits/ 8 <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* from dc0 pixel combiner channel0 */
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
dc0_pixel_link0_dc0_pixel_combiner_ch0: endpoint {
|
||||
remote-endpoint = <&dc0_pixel_combiner_ch0_dc0_pixel_link0>;
|
||||
};
|
||||
};
|
||||
|
||||
/* to PXL2DPIs in MIPI/LVDS combo subsystems */
|
||||
port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
dc0_pixel_link0_mipi_lvds_0_pxl2dpi: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi_lvds_0_pxl2dpi_dc0_pixel_link0>;
|
||||
};
|
||||
|
||||
dc0_pixel_link0_mipi_lvds_1_pxl2dpi: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&mipi_lvds_1_pxl2dpi_dc0_pixel_link0>;
|
||||
};
|
||||
};
|
||||
|
||||
/* unused */
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
|
||||
/* unused */
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
};
|
||||
|
||||
/* to imaging subsystem */
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,108 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/bridge/fsl,imx8qxp-pxl2dpi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale i.MX8qxp Pixel Link to Display Pixel Interface
|
||||
|
||||
maintainers:
|
||||
- Liu Ying <victor.liu@nxp.com>
|
||||
|
||||
description: |
|
||||
The Freescale i.MX8qxp Pixel Link to Display Pixel Interface(PXL2DPI)
|
||||
interfaces the pixel link 36-bit data output and the DSI controller’s
|
||||
MIPI-DPI 24-bit data input, and inputs of LVDS Display Bridge(LDB) module
|
||||
used in LVDS mode, to remap the pixel color codings between those modules.
|
||||
This module is purely combinatorial.
|
||||
|
||||
The i.MX8qxp PXL2DPI is controlled by Control and Status Registers(CSR) module.
|
||||
The CSR module, as a system controller, contains the PXL2DPI's configuration
|
||||
register.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,imx8qxp-pxl2dpi
|
||||
|
||||
fsl,sc-resource:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: The SCU resource ID associated with this PXL2DPI instance.
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
fsl,companion-pxl2dpi:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: |
|
||||
A phandle which points to companion PXL2DPI which is used by downstream
|
||||
LVDS Display Bridge(LDB) in split mode.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The PXL2DPI input port node from pixel link.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The PXL2DPI output port node to downstream bridge.
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- fsl,sc-resource
|
||||
- power-domains
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
pxl2dpi {
|
||||
compatible = "fsl,imx8qxp-pxl2dpi";
|
||||
fsl,sc-resource = <IMX_SC_R_MIPI_0>;
|
||||
power-domains = <&pd IMX_SC_R_MIPI_0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
mipi_lvds_0_pxl2dpi_dc_pixel_link0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&dc_pixel_link0_mipi_lvds_0_pxl2dpi>;
|
||||
};
|
||||
|
||||
mipi_lvds_0_pxl2dpi_dc_pixel_link1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&dc_pixel_link1_mipi_lvds_0_pxl2dpi>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi>;
|
||||
};
|
||||
|
||||
mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -24,6 +24,15 @@ properties:
|
||||
clock-names:
|
||||
const: ldb
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: ldb
|
||||
- const: lvds
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
@ -56,10 +65,15 @@ examples:
|
||||
#include <dt-bindings/clock/imx8mp-clock.h>
|
||||
|
||||
blk-ctrl {
|
||||
bridge {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
bridge@5c {
|
||||
compatible = "fsl,imx8mp-ldb";
|
||||
clocks = <&clk IMX8MP_CLK_MEDIA_LDB>;
|
||||
clock-names = "ldb";
|
||||
reg = <0x5c 0x4>, <0x128 0x4>;
|
||||
reg-names = "ldb", "lvds";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
|
@ -55,7 +55,6 @@ examples:
|
||||
compatible = "ingenic,jz4780-dw-hdmi";
|
||||
reg = <0x10180000 0x8000>;
|
||||
reg-io-width = <4>;
|
||||
ddc-i2c-bus = <&i2c4>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <3>;
|
||||
clocks = <&cgu JZ4780_CLK_AHB0>, <&cgu JZ4780_CLK_HDMI>;
|
||||
|
@ -0,0 +1,117 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/bridge/ti,dlpc3433.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI DLPC3433 MIPI DSI to DMD bridge
|
||||
|
||||
maintainers:
|
||||
- Jagan Teki <jagan@amarulasolutions.com>
|
||||
- Christopher Vollo <chris@renewoutreach.org>
|
||||
|
||||
description: |
|
||||
TI DLPC3433 is a MIPI DSI based display controller bridge
|
||||
for processing high resolution DMD based projectors.
|
||||
|
||||
It has a flexible configuration of MIPI DSI and DPI signal
|
||||
input that produces a DMD output in RGB565, RGB666, RGB888
|
||||
formats.
|
||||
|
||||
It supports upto 720p resolution with 60 and 120 Hz refresh
|
||||
rates.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,dlpc3433
|
||||
|
||||
reg:
|
||||
enum:
|
||||
- 0x1b
|
||||
- 0x1d
|
||||
|
||||
enable-gpios:
|
||||
description: PROJ_ON pin, chip powers up PROJ_ON is high.
|
||||
|
||||
vcc_intf-supply:
|
||||
description: A 1.8V/3.3V supply that power the Host I/O.
|
||||
|
||||
vcc_flsh-supply:
|
||||
description: A 1.8V/3.3V supply that power the Flash I/O.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description: Video port for MIPI DSI input.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
description: array of physical DSI data lane indexes.
|
||||
minItems: 1
|
||||
items:
|
||||
- const: 1
|
||||
- const: 2
|
||||
- const: 3
|
||||
- const: 4
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Video port for DMD output.
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- enable-gpios
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
bridge@1b {
|
||||
compatible = "ti,dlpc3433";
|
||||
reg = <0x1b>;
|
||||
enable-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
bridge_in_dsi: endpoint {
|
||||
remote-endpoint = <&dsi_out_bridge>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
bridge_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_out_bridge>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -20,6 +20,7 @@ properties:
|
||||
- fsl,imx23-lcdif
|
||||
- fsl,imx28-lcdif
|
||||
- fsl,imx6sx-lcdif
|
||||
- fsl,imx8mp-lcdif
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx6sl-lcdif
|
||||
|
@ -4,16 +4,16 @@
|
||||
$id: http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: mediatek DPI Controller Device Tree Bindings
|
||||
title: MediaTek DPI and DP_INTF Controller
|
||||
|
||||
maintainers:
|
||||
- CK Hu <ck.hu@mediatek.com>
|
||||
- Jitao shi <jitao.shi@mediatek.com>
|
||||
|
||||
description: |
|
||||
The Mediatek DPI function block is a sink of the display subsystem and
|
||||
provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
|
||||
output bus.
|
||||
The MediaTek DPI and DP_INTF function blocks are a sink of the display
|
||||
subsystem and provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a
|
||||
parallel output bus.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@ -24,6 +24,7 @@ properties:
|
||||
- mediatek,mt8183-dpi
|
||||
- mediatek,mt8186-dpi
|
||||
- mediatek,mt8192-dpi
|
||||
- mediatek,mt8195-dp-intf
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -55,7 +56,7 @@ properties:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description:
|
||||
Output port node. This port should be connected to the input port of an
|
||||
attached HDMI or LVDS encoder chip.
|
||||
attached HDMI, LVDS or DisplayPort encoder chip.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -1,62 +0,0 @@
|
||||
Mediatek DSI Device
|
||||
===================
|
||||
|
||||
The Mediatek DSI function block is a sink of the display subsystem and can
|
||||
drive up to 4-lane MIPI DSI output. Two DSIs can be synchronized for dual-
|
||||
channel output.
|
||||
|
||||
Required properties:
|
||||
- compatible: "mediatek,<chip>-dsi"
|
||||
- the supported chips are mt2701, mt7623, mt8167, mt8173 and mt8183.
|
||||
- reg: Physical base address and length of the controller's registers
|
||||
- interrupts: The interrupt signal from the function block.
|
||||
- clocks: device clocks
|
||||
See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
|
||||
- clock-names: must contain "engine", "digital", and "hs"
|
||||
- phys: phandle link to the MIPI D-PHY controller.
|
||||
- phy-names: must contain "dphy"
|
||||
- port: Output port node with endpoint definitions as described in
|
||||
Documentation/devicetree/bindings/graph.txt. This port should be connected
|
||||
to the input port of an attached DSI panel or DSI-to-eDP encoder chip.
|
||||
|
||||
Optional properties:
|
||||
- resets: list of phandle + reset specifier pair, as described in [1].
|
||||
|
||||
[1] Documentation/devicetree/bindings/reset/reset.txt
|
||||
|
||||
MIPI TX Configuration Module
|
||||
============================
|
||||
|
||||
See phy/mediatek,dsi-phy.yaml
|
||||
|
||||
Example:
|
||||
|
||||
mipi_tx0: mipi-dphy@10215000 {
|
||||
compatible = "mediatek,mt8173-mipi-tx";
|
||||
reg = <0 0x10215000 0 0x1000>;
|
||||
clocks = <&clk26m>;
|
||||
clock-output-names = "mipi_tx0_pll";
|
||||
#clock-cells = <0>;
|
||||
#phy-cells = <0>;
|
||||
drive-strength-microamp = <4600>;
|
||||
nvmem-cells= <&mipi_tx_calibration>;
|
||||
nvmem-cell-names = "calibration-data";
|
||||
};
|
||||
|
||||
dsi0: dsi@1401b000 {
|
||||
compatible = "mediatek,mt8173-dsi";
|
||||
reg = <0 0x1401b000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&mmsys MM_DSI0_ENGINE>, <&mmsys MM_DSI0_DIGITAL>,
|
||||
<&mipi_tx0>;
|
||||
clock-names = "engine", "digital", "hs";
|
||||
resets = <&mmsys MT8173_MMSYS_SW0_RST_B_DISP_DSI0>;
|
||||
phys = <&mipi_tx0>;
|
||||
phy-names = "dphy";
|
||||
|
||||
port {
|
||||
dsi0_out: endpoint {
|
||||
remote-endpoint = <&panel_in>;
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,116 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek DSI Controller Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chun-Kuang Hu <chunkuang.hu@kernel.org>
|
||||
- Philipp Zabel <p.zabel@pengutronix.de>
|
||||
- Jitao Shi <jitao.shi@mediatek.com>
|
||||
- Xinlei Lee <xinlei.lee@mediatek.com>
|
||||
|
||||
description: |
|
||||
The MediaTek DSI function block is a sink of the display subsystem and can
|
||||
drive up to 4-lane MIPI DSI output. Two DSIs can be synchronized for dual-
|
||||
channel output.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/display/dsi-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt2701-dsi
|
||||
- mediatek,mt7623-dsi
|
||||
- mediatek,mt8167-dsi
|
||||
- mediatek,mt8173-dsi
|
||||
- mediatek,mt8183-dsi
|
||||
- mediatek,mt8186-dsi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Engine Clock
|
||||
- description: Digital Clock
|
||||
- description: HS Clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: engine
|
||||
- const: digital
|
||||
- const: hs
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
|
||||
phy-names:
|
||||
items:
|
||||
- const: dphy
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description:
|
||||
Output port node. This port should be connected to the input
|
||||
port of an attached DSI panel or DSI-to-eDP encoder chip.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- power-domains
|
||||
- clocks
|
||||
- clock-names
|
||||
- phys
|
||||
- phy-names
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mt8183-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/power/mt8183-power.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <dt-bindings/reset/mt8183-resets.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
dsi0: dsi@14014000 {
|
||||
compatible = "mediatek,mt8183-dsi";
|
||||
reg = <0 0x14014000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_LOW>;
|
||||
power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
|
||||
clocks = <&mmsys CLK_MM_DSI0_MM>,
|
||||
<&mmsys CLK_MM_DSI0_IF>,
|
||||
<&mipi_tx0>;
|
||||
clock-names = "engine", "digital", "hs";
|
||||
resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>;
|
||||
phys = <&mipi_tx0>;
|
||||
phy-names = "dphy";
|
||||
port {
|
||||
dsi0_out: endpoint {
|
||||
remote-endpoint = <&panel_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -0,0 +1,88 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/mediatek/mediatek,mdp-rdma.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek MDP RDMA
|
||||
|
||||
maintainers:
|
||||
- Chun-Kuang Hu <chunkuang.hu@kernel.org>
|
||||
- Philipp Zabel <p.zabel@pengutronix.de>
|
||||
|
||||
description:
|
||||
The MediaTek MDP RDMA stands for Read Direct Memory Access.
|
||||
It provides real time data to the back-end panel driver, such as DSI,
|
||||
DPI and DP_INTF.
|
||||
It contains one line buffer to store the sufficient pixel data.
|
||||
RDMA device node must be siblings to the central MMSYS_CONFIG node.
|
||||
For a description of the MMSYS_CONFIG binding, see
|
||||
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8195-vdo1-rdma
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: RDMA Clock
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
mediatek,gce-client-reg:
|
||||
description:
|
||||
The register of display function block to be set by gce. There are 4 arguments,
|
||||
such as gce node, subsys id, offset and register size. The subsys id that is
|
||||
mapping to the register of display function blocks is defined in the gce header
|
||||
include/dt-bindings/gce/<chip>-gce.h of each chips.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
items:
|
||||
- description: phandle of GCE
|
||||
- description: GCE subsys id
|
||||
- description: register offset
|
||||
- description: register size
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- power-domains
|
||||
- clocks
|
||||
- iommus
|
||||
- mediatek,gce-client-reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/mt8195-clk.h>
|
||||
#include <dt-bindings/power/mt8195-power.h>
|
||||
#include <dt-bindings/gce/mt8195-gce.h>
|
||||
#include <dt-bindings/memory/mt8195-memory-port.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
rdma@1c104000 {
|
||||
compatible = "mediatek,mt8195-vdo1-rdma";
|
||||
reg = <0 0x1c104000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
|
||||
power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
|
||||
iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
|
||||
mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x4000 0x1000>;
|
||||
};
|
||||
};
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: MSM Display Port Controller
|
||||
|
||||
maintainers:
|
||||
- Kuogee Hsieh <khsieh@codeaurora.org>
|
||||
- Kuogee Hsieh <quic_khsieh@quicinc.com>
|
||||
|
||||
description: |
|
||||
Device tree bindings for DisplayPort host controller for MSM targets
|
||||
@ -76,6 +76,9 @@ properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
vdda-0p9-supply: true
|
||||
vdda-1p2-supply: true
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
@ -137,6 +140,9 @@ examples:
|
||||
|
||||
power-domains = <&rpmhpd SC7180_CX>;
|
||||
|
||||
vdda-0p9-supply = <&vdda_usb_ss_dp_core>;
|
||||
vdda-1p2-supply = <&vdda_usb_ss_dp_1p2>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -1,99 +0,0 @@
|
||||
Qualcomm adreno/snapdragon hdmi output
|
||||
|
||||
Required properties:
|
||||
- compatible: one of the following
|
||||
* "qcom,hdmi-tx-8996"
|
||||
* "qcom,hdmi-tx-8994"
|
||||
* "qcom,hdmi-tx-8084"
|
||||
* "qcom,hdmi-tx-8974"
|
||||
* "qcom,hdmi-tx-8660"
|
||||
* "qcom,hdmi-tx-8960"
|
||||
- reg: Physical base address and length of the controller's registers
|
||||
- reg-names: "core_physical"
|
||||
- interrupts: The interrupt signal from the hdmi block.
|
||||
- power-domains: Should be <&mmcc MDSS_GDSC>.
|
||||
- clocks: device clocks
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- core-vdda-supply: phandle to supply regulator
|
||||
- hdmi-mux-supply: phandle to mux regulator
|
||||
- phys: the phandle for the HDMI PHY device
|
||||
- phy-names: the name of the corresponding PHY device
|
||||
|
||||
Optional properties:
|
||||
- hpd-gpios: hpd pin
|
||||
- qcom,hdmi-tx-mux-en-gpios: hdmi mux enable pin
|
||||
- qcom,hdmi-tx-mux-sel-gpios: hdmi mux select pin
|
||||
- qcom,hdmi-tx-mux-lpm-gpios: hdmi mux lpm pin
|
||||
- power-domains: reference to the power domain(s), if available.
|
||||
- pinctrl-names: the pin control state names; should contain "default"
|
||||
- pinctrl-0: the default pinctrl state (active)
|
||||
- pinctrl-1: the "sleep" pinctrl state
|
||||
|
||||
HDMI PHY:
|
||||
Required properties:
|
||||
- compatible: Could be the following
|
||||
* "qcom,hdmi-phy-8660"
|
||||
* "qcom,hdmi-phy-8960"
|
||||
* "qcom,hdmi-phy-8974"
|
||||
* "qcom,hdmi-phy-8084"
|
||||
* "qcom,hdmi-phy-8996"
|
||||
- #phy-cells: Number of cells in a PHY specifier; Should be 0.
|
||||
- reg: Physical base address and length of the registers of the PHY sub blocks.
|
||||
- reg-names: The names of register regions. The following regions are required:
|
||||
* "hdmi_phy"
|
||||
* "hdmi_pll"
|
||||
For HDMI PHY on msm8996, these additional register regions are required:
|
||||
* "hdmi_tx_l0"
|
||||
* "hdmi_tx_l1"
|
||||
* "hdmi_tx_l3"
|
||||
* "hdmi_tx_l4"
|
||||
- power-domains: Should be <&mmcc MDSS_GDSC>.
|
||||
- clocks: device clocks
|
||||
See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
|
||||
- core-vdda-supply: phandle to vdda regulator device node
|
||||
|
||||
Example:
|
||||
|
||||
/ {
|
||||
...
|
||||
|
||||
hdmi: hdmi@4a00000 {
|
||||
compatible = "qcom,hdmi-tx-8960";
|
||||
reg-names = "core_physical";
|
||||
reg = <0x04a00000 0x2f0>;
|
||||
interrupts = <GIC_SPI 79 0>;
|
||||
power-domains = <&mmcc MDSS_GDSC>;
|
||||
clock-names =
|
||||
"core",
|
||||
"master_iface",
|
||||
"slave_iface";
|
||||
clocks =
|
||||
<&mmcc HDMI_APP_CLK>,
|
||||
<&mmcc HDMI_M_AHB_CLK>,
|
||||
<&mmcc HDMI_S_AHB_CLK>;
|
||||
qcom,hdmi-tx-ddc-clk = <&msmgpio 70 GPIO_ACTIVE_HIGH>;
|
||||
qcom,hdmi-tx-ddc-data = <&msmgpio 71 GPIO_ACTIVE_HIGH>;
|
||||
qcom,hdmi-tx-hpd = <&msmgpio 72 GPIO_ACTIVE_HIGH>;
|
||||
core-vdda-supply = <&pm8921_hdmi_mvs>;
|
||||
hdmi-mux-supply = <&ext_3p3v>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&hpd_active &ddc_active &cec_active>;
|
||||
pinctrl-1 = <&hpd_suspend &ddc_suspend &cec_suspend>;
|
||||
|
||||
phys = <&hdmi_phy>;
|
||||
phy-names = "hdmi_phy";
|
||||
};
|
||||
|
||||
hdmi_phy: phy@4a00400 {
|
||||
compatible = "qcom,hdmi-phy-8960";
|
||||
reg-names = "hdmi_phy",
|
||||
"hdmi_pll";
|
||||
reg = <0x4a00400 0x60>,
|
||||
<0x4a00500 0x100>;
|
||||
#phy-cells = <0>;
|
||||
power-domains = <&mmcc MDSS_GDSC>;
|
||||
clock-names = "slave_iface";
|
||||
clocks = <&mmcc HDMI_S_AHB_CLK>;
|
||||
core-vdda-supply = <&pm8921_hdmi_mvs>;
|
||||
};
|
||||
};
|
232
Documentation/devicetree/bindings/display/msm/hdmi.yaml
Normal file
232
Documentation/devicetree/bindings/display/msm/hdmi.yaml
Normal file
@ -0,0 +1,232 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
|
||||
$id: http://devicetree.org/schemas/display/msm/hdmi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Adreno/Snapdragon HDMI output
|
||||
|
||||
maintainers:
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,hdmi-tx-8084
|
||||
- qcom,hdmi-tx-8660
|
||||
- qcom,hdmi-tx-8960
|
||||
- qcom,hdmi-tx-8974
|
||||
- qcom,hdmi-tx-8994
|
||||
- qcom,hdmi-tx-8996
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: core_physical
|
||||
- const: qfprom_physical
|
||||
- const: hdcp_physical
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
|
||||
phy-names:
|
||||
enum:
|
||||
- hdmi_phy
|
||||
- hdmi-phy
|
||||
deprecated: true
|
||||
|
||||
core-vdda-supply:
|
||||
description: phandle to VDDA supply regulator
|
||||
|
||||
hdmi-mux-supply:
|
||||
description: phandle to mux regulator
|
||||
deprecated: true
|
||||
|
||||
core-vcc-supply:
|
||||
description: phandle to VCC supply regulator
|
||||
|
||||
hpd-gpios:
|
||||
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
|
||||
|
||||
ports:
|
||||
type: object
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
required:
|
||||
- port@0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
- reg-names
|
||||
- interrupts
|
||||
- phys
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,hdmi-tx-8960
|
||||
- qcom,hdmi-tx-8660
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: master_iface
|
||||
- const: slave_iface
|
||||
core-vcc-supplies: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,hdmi-tx-8974
|
||||
- qcom,hdmi-tx-8084
|
||||
- qcom,hdmi-tx-8994
|
||||
- qcom,hdmi-tx-8996
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 5
|
||||
clock-names:
|
||||
items:
|
||||
- const: mdp_core
|
||||
- const: iface
|
||||
- const: core
|
||||
- const: alt_iface
|
||||
- const: extp
|
||||
hdmi-mux-supplies: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
hdmi: hdmi@4a00000 {
|
||||
compatible = "qcom,hdmi-tx-8960";
|
||||
reg-names = "core_physical";
|
||||
reg = <0x04a00000 0x2f0>;
|
||||
interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-names = "core",
|
||||
"master_iface",
|
||||
"slave_iface";
|
||||
clocks = <&clk 61>,
|
||||
<&clk 72>,
|
||||
<&clk 98>;
|
||||
hpd-gpios = <&msmgpio 72 GPIO_ACTIVE_HIGH>;
|
||||
core-vdda-supply = <&pm8921_hdmi_mvs>;
|
||||
hdmi-mux-supply = <&ext_3p3v>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&hpd_active &ddc_active &cec_active>;
|
||||
pinctrl-1 = <&hpd_suspend &ddc_suspend &cec_suspend>;
|
||||
|
||||
phys = <&hdmi_phy>;
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-msm8996.h>
|
||||
#include <dt-bindings/clock/qcom,mmcc-msm8996.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
hdmi@9a0000 {
|
||||
compatible = "qcom,hdmi-tx-8996";
|
||||
reg = <0x009a0000 0x50c>,
|
||||
<0x00070000 0x6158>,
|
||||
<0x009e0000 0xfff>;
|
||||
reg-names = "core_physical",
|
||||
"qfprom_physical",
|
||||
"hdcp_physical";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
clocks = <&mmcc MDSS_MDP_CLK>,
|
||||
<&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_HDMI_CLK>,
|
||||
<&mmcc MDSS_HDMI_AHB_CLK>,
|
||||
<&mmcc MDSS_EXTPCLK_CLK>;
|
||||
clock-names = "mdp_core",
|
||||
"iface",
|
||||
"core",
|
||||
"alt_iface",
|
||||
"extp";
|
||||
|
||||
phys = <&hdmi_phy>;
|
||||
#sound-dai-cells = <1>;
|
||||
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&hdmi_hpd_active &hdmi_ddc_active>;
|
||||
pinctrl-1 = <&hdmi_hpd_suspend &hdmi_ddc_suspend>;
|
||||
|
||||
core-vdda-supply = <&vreg_l12a_1p8>;
|
||||
core-vcc-supply = <&vreg_s4a_1p8>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&mdp5_intf3_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,74 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/ebbg,ft8719.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: EBBG FT8719 MIPI-DSI LCD panel
|
||||
|
||||
maintainers:
|
||||
- Joel Selvaraj <jo@jsfamily.in>
|
||||
|
||||
description: |
|
||||
The FT8719 panel from EBBG is a FHD+ LCD display panel with a resolution
|
||||
of 1080x2246. It is a video mode DSI panel. The backlight is managed
|
||||
through the QCOM WLED driver.
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ebbg,ft8719
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: DSI virtual channel of the peripheral
|
||||
|
||||
vddio-supply:
|
||||
description: power IC supply regulator
|
||||
|
||||
vddpos-supply:
|
||||
description: positive boost supply regulator
|
||||
|
||||
vddneg-supply:
|
||||
description: negative boost supply regulator
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vddio-supply
|
||||
- vddpos-supply
|
||||
- vddneg-supply
|
||||
- reset-gpios
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "ebbg,ft8719";
|
||||
reg = <0>;
|
||||
|
||||
vddio-supply = <&vreg_l14a_1p88>;
|
||||
vddpos-supply = <&lab>;
|
||||
vddneg-supply = <&ibb>;
|
||||
|
||||
reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>;
|
||||
|
||||
backlight = <&pmi8998_wled>;
|
||||
|
||||
port {
|
||||
ebbg_ft8719_in_0: endpoint {
|
||||
remote-endpoint = <&dsi0_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -35,7 +35,6 @@ required:
|
||||
- reg
|
||||
- avdd-supply
|
||||
- dvdd-supply
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -46,6 +46,7 @@ properties:
|
||||
|
||||
reg: true
|
||||
port: true
|
||||
backlight: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -73,6 +74,7 @@ examples:
|
||||
vddpos-supply = <&lab>;
|
||||
vddneg-supply = <&ibb>;
|
||||
|
||||
backlight = <&pmi8998_wled>;
|
||||
reset-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
port {
|
||||
|
@ -35,6 +35,8 @@ properties:
|
||||
- ampire,am-480272h3tmqw-t01h
|
||||
# Ampire AM-800480R3TMQW-A1H 7.0" WVGA TFT LCD panel
|
||||
- ampire,am800480r3tmqwa1h
|
||||
# Ampire AM-800600P5TMQW-TB8H 8.0" SVGA TFT LCD panel
|
||||
- ampire,am800600p5tmqw-tb8h
|
||||
# AU Optronics Corporation 10.1" WSVGA TFT LCD panel
|
||||
- auo,b101aw03
|
||||
# AU Optronics Corporation 10.1" WSVGA TFT LCD panel
|
||||
@ -107,6 +109,8 @@ properties:
|
||||
- chunghwa,claa101wb03
|
||||
# DataImage, Inc. 4.3" WQVGA (480x272) TFT LCD panel with 24-bit parallel interface.
|
||||
- dataimage,fg040346dsswbg04
|
||||
# DataImage, Inc. 10.1" WXGA (1280×800) TFT LCD panel
|
||||
- dataimage,fg1001l0dsswmg01
|
||||
# DataImage, Inc. 7" WVGA (800x480) TFT LCD panel with 24-bit parallel interface.
|
||||
- dataimage,scf0700c48ggu18
|
||||
# DLC Display Co. DLC1010GIG 10.1" WXGA TFT LCD Panel
|
||||
@ -137,6 +141,8 @@ properties:
|
||||
# Emerging Display Technology Corp. WVGA TFT Display with capacitive touch
|
||||
- edt,etm0700g0dh6
|
||||
- edt,etm0700g0edh6
|
||||
# Emerging Display Technology Corp. LVDS WSVGA TFT Display with capacitive touch
|
||||
- edt,etml0700y5dha
|
||||
# Emerging Display Technology Corp. 5.7" VGA TFT LCD panel with
|
||||
# capacitive touch
|
||||
- edt,etmv570g2dhu
|
||||
@ -158,6 +164,8 @@ properties:
|
||||
- hannstar,hsd070pww1
|
||||
# HannStar Display Corp. HSD100PXN1 10.1" XGA LVDS panel
|
||||
- hannstar,hsd100pxn1
|
||||
# HannStar Display Corp. HSD101PWW2 10.1" WXGA (1280x800) LVDS panel
|
||||
- hannstar,hsd101pww2
|
||||
# Hitachi Ltd. Corporation 9" WVGA (800x480) TFT LCD panel
|
||||
- hit,tx23d38vm0caa
|
||||
# InfoVision Optoelectronics M133NWF4 R0 13.3" FHD (1920x1080) TFT LCD panel
|
||||
|
@ -30,7 +30,12 @@ allOf:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sharp,lq101r1sx01
|
||||
oneOf:
|
||||
- items:
|
||||
- const: sharp,lq101r1sx03
|
||||
- const: sharp,lq101r1sx01
|
||||
- items:
|
||||
- const: sharp,lq101r1sx01
|
||||
|
||||
reg: true
|
||||
power-supply: true
|
||||
|
@ -8,7 +8,6 @@ title: Samsung Exynos SoC HDMI DDC
|
||||
|
||||
maintainers:
|
||||
- Inki Dae <inki.dae@samsung.com>
|
||||
- Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
- Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
- Kyungmin Park <kyungmin.park@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
@ -8,7 +8,6 @@ title: Samsung Exynos SoC HDMI
|
||||
|
||||
maintainers:
|
||||
- Inki Dae <inki.dae@samsung.com>
|
||||
- Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
- Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
- Kyungmin Park <kyungmin.park@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
@ -8,7 +8,6 @@ title: Samsung Exynos SoC Mixer
|
||||
|
||||
maintainers:
|
||||
- Inki Dae <inki.dae@samsung.com>
|
||||
- Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
- Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
- Kyungmin Park <kyungmin.park@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
@ -8,7 +8,6 @@ title: Samsung Exynos5433 SoC Display and Enhancement Controller (DECON)
|
||||
|
||||
maintainers:
|
||||
- Inki Dae <inki.dae@samsung.com>
|
||||
- Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
- Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
- Kyungmin Park <kyungmin.park@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
@ -8,7 +8,6 @@ title: Samsung Exynos5433 SoC Mobile Image Compressor (MIC)
|
||||
|
||||
maintainers:
|
||||
- Inki Dae <inki.dae@samsung.com>
|
||||
- Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
- Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
- Kyungmin Park <kyungmin.park@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
@ -8,7 +8,6 @@ title: Samsung Exynos7 SoC Display and Enhancement Controller (DECON)
|
||||
|
||||
maintainers:
|
||||
- Inki Dae <inki.dae@samsung.com>
|
||||
- Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
- Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
- Kyungmin Park <kyungmin.park@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
@ -8,7 +8,6 @@ title: Samsung S3C/S5P/Exynos SoC Fully Interactive Mobile Display (FIMD)
|
||||
|
||||
maintainers:
|
||||
- Inki Dae <inki.dae@samsung.com>
|
||||
- Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
- Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
- Kyungmin Park <kyungmin.park@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
@ -1,41 +0,0 @@
|
||||
NVIDIA Tegra MIPI pad calibration controller
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-mipi"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- mipi-cal
|
||||
- #nvidia,mipi-calibrate-cells: Should be 1. The cell is a bitmask of the pads
|
||||
that need to be calibrated for a given device.
|
||||
|
||||
User nodes need to contain an nvidia,mipi-calibrate property that has a
|
||||
phandle to refer to the calibration controller node and a bitmask of the pads
|
||||
that need to be calibrated.
|
||||
|
||||
Example:
|
||||
|
||||
mipi: mipi@700e3000 {
|
||||
compatible = "nvidia,tegra114-mipi";
|
||||
reg = <0x700e3000 0x100>;
|
||||
clocks = <&tegra_car TEGRA114_CLK_MIPI_CAL>;
|
||||
clock-names = "mipi-cal";
|
||||
#nvidia,mipi-calibrate-cells = <1>;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
host1x@50000000 {
|
||||
...
|
||||
|
||||
dsi@54300000 {
|
||||
...
|
||||
|
||||
nvidia,mipi-calibrate = <&mipi 0x060>;
|
||||
|
||||
...
|
||||
};
|
||||
|
||||
...
|
||||
};
|
@ -0,0 +1,74 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra114-mipi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra MIPI pad calibration controller
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^mipi@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra114-mipi
|
||||
- nvidia,tegra210-mipi
|
||||
- nvidia,tegra186-mipi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mipi-cal
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
"#nvidia,mipi-calibrate-cells":
|
||||
description: The number of cells in a MIPI calibration specifier.
|
||||
Should be 1. The single cell specifies a bitmask of the pads that
|
||||
need to be calibrated for a given device.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
const: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- "#nvidia,mipi-calibrate-cells"
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra114-car.h>
|
||||
|
||||
mipi@700e3000 {
|
||||
compatible = "nvidia,tegra114-mipi";
|
||||
reg = <0x700e3000 0x100>;
|
||||
clocks = <&tegra_car TEGRA114_CLK_MIPI_CAL>;
|
||||
clock-names = "mipi-cal";
|
||||
#nvidia,mipi-calibrate-cells = <1>;
|
||||
};
|
||||
|
||||
dsia: dsi@54300000 {
|
||||
compatible = "nvidia,tegra114-dsi";
|
||||
reg = <0x54300000 0x00040000>;
|
||||
clocks = <&tegra_car TEGRA114_CLK_DSIA>,
|
||||
<&tegra_car TEGRA114_CLK_DSIALP>,
|
||||
<&tegra_car TEGRA114_CLK_PLL_D_OUT0>;
|
||||
clock-names = "dsi", "lp", "parent";
|
||||
resets = <&tegra_car 48>;
|
||||
reset-names = "dsi";
|
||||
nvidia,mipi-calibrate = <&mipi 0x060>; /* DSIA & DSIB pads */
|
||||
};
|
@ -0,0 +1,152 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra124-dpaux.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra DisplayPort AUX Interface
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
description: |
|
||||
The Tegra Display Port Auxiliary (DPAUX) pad controller manages two
|
||||
pins which can be assigned to either the DPAUX channel or to an I2C
|
||||
controller.
|
||||
|
||||
When configured for DisplayPort AUX operation, the DPAUX controller
|
||||
can also be used to communicate with a DisplayPort device using the
|
||||
AUX channel.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^dpaux@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- nvidia,tegra124-dpaux
|
||||
- nvidia,tegra210-dpaux
|
||||
- nvidia,tegra186-dpaux
|
||||
- nvidia,tegra194-dpaux
|
||||
|
||||
- items:
|
||||
- const: nvidia,tegra132-dpaux
|
||||
- const: nvidia,tegra124-dpaux
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: clock input for the DPAUX hardware
|
||||
- description: reference clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: dpaux
|
||||
- const: parent
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: dpaux
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
i2c-bus:
|
||||
description: Subnode where I2C slave devices are listed. This
|
||||
subnode must be always present. If there are no I2C slave
|
||||
devices, an empty node should be added. See ../../i2c/i2c.yaml
|
||||
for more information.
|
||||
type: object
|
||||
|
||||
aux-bus:
|
||||
$ref: /schemas/display/dp-aux-bus.yaml#
|
||||
|
||||
vdd-supply:
|
||||
description: phandle of a supply that powers the DisplayPort
|
||||
link
|
||||
|
||||
patternProperties:
|
||||
"^pinmux-[a-z0-9]+$":
|
||||
description:
|
||||
Since only three configurations are possible, only three child
|
||||
nodes are needed to describe the pin mux'ing options for the
|
||||
DPAUX pads. Furthermore, given that the pad functions are only
|
||||
applicable to a single set of pads, the child nodes only need
|
||||
to describe the pad group the functions are being applied to
|
||||
rather than the individual pads.
|
||||
type: object
|
||||
properties:
|
||||
groups:
|
||||
const: dpaux-io
|
||||
|
||||
function:
|
||||
enum:
|
||||
- aux
|
||||
- i2c
|
||||
- off
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- groups
|
||||
- function
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra210-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
dpaux: dpaux@545c0000 {
|
||||
compatible = "nvidia,tegra210-dpaux";
|
||||
reg = <0x545c0000 0x00040000>;
|
||||
interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_DPAUX>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_DP>;
|
||||
clock-names = "dpaux", "parent";
|
||||
resets = <&tegra_car 181>;
|
||||
reset-names = "dpaux";
|
||||
power-domains = <&pd_sor>;
|
||||
status = "disabled";
|
||||
|
||||
state_dpaux_aux: pinmux-aux {
|
||||
groups = "dpaux-io";
|
||||
function = "aux";
|
||||
};
|
||||
|
||||
state_dpaux_i2c: pinmux-i2c {
|
||||
groups = "dpaux-io";
|
||||
function = "i2c";
|
||||
};
|
||||
|
||||
state_dpaux_off: pinmux-off {
|
||||
groups = "dpaux-io";
|
||||
function = "off";
|
||||
};
|
||||
|
||||
i2c-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
@ -0,0 +1,197 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra124-sor.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra SOR Output Encoder
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
description: |
|
||||
The Serial Output Resource (SOR) can be used to drive HDMI, LVDS, eDP
|
||||
and DP outputs.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^sor@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- nvidia,tegra124-sor
|
||||
- nvidia,tegra210-sor
|
||||
- nvidia,tegra210-sor1
|
||||
- nvidia,tegra186-sor
|
||||
- nvidia,tegra186-sor1
|
||||
- nvidia,tegra194-sor
|
||||
|
||||
- items:
|
||||
- const: nvidia,tegra132-sor
|
||||
- const: nvidia,tegra124-sor
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 5
|
||||
maxItems: 6
|
||||
|
||||
clock-names:
|
||||
minItems: 5
|
||||
maxItems: 6
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: sor
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
avdd-io-hdmi-dp-supply:
|
||||
description: I/O supply for HDMI/DP
|
||||
|
||||
vdd-hdmi-dp-pll-supply:
|
||||
description: PLL supply for HDMI/DP
|
||||
|
||||
hdmi-supply:
|
||||
description: +5.0V HDMI connector supply, required for HDMI
|
||||
|
||||
# Tegra186 and later
|
||||
nvidia,interface:
|
||||
description: index of the SOR interface
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
nvidia,ddc-i2c-bus:
|
||||
description: phandle of an I2C controller used for DDC EDID
|
||||
probing
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
nvidia,hpd-gpio:
|
||||
description: specifies a GPIO used for hotplug detection
|
||||
maxItems: 1
|
||||
|
||||
nvidia,edid:
|
||||
description: supplies a binary EDID blob
|
||||
$ref: "/schemas/types.yaml#/definitions/uint8-array"
|
||||
|
||||
nvidia,panel:
|
||||
description: phandle of a display panel, required for eDP
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
nvidia,xbar-cfg:
|
||||
description: 5 cells containing the crossbar configuration.
|
||||
Each lane of the SOR, identified by the cell's index, is
|
||||
mapped via the crossbar to the pad specified by the cell's
|
||||
value.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32-array"
|
||||
|
||||
# optional when driving an eDP output
|
||||
nvidia,dpaux:
|
||||
description: phandle to a DispayPort AUX interface
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra186-sor
|
||||
- nvidia,tegra194-sor
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: clock input for the SOR hardware
|
||||
- description: SOR output clock
|
||||
- description: input for the pixel clock
|
||||
- description: reference clock for the SOR clock
|
||||
- description: safe reference clock for the SOR clock
|
||||
during power up
|
||||
- description: SOR pad output clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: sor
|
||||
- enum:
|
||||
- source # deprecated
|
||||
- out
|
||||
- const: parent
|
||||
- const: dp
|
||||
- const: safe
|
||||
- const: pad
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: clock input for the SOR hardware
|
||||
- description: SOR output clock
|
||||
- description: input for the pixel clock
|
||||
- description: reference clock for the SOR clock
|
||||
- description: safe reference clock for the SOR clock
|
||||
during power up
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: sor
|
||||
- enum:
|
||||
- source # deprecated
|
||||
- out
|
||||
- const: parent
|
||||
- const: dp
|
||||
- const: safe
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- avdd-io-hdmi-dp-supply
|
||||
- vdd-hdmi-dp-pll-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra210-car.h>
|
||||
#include <dt-bindings/gpio/tegra-gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
sor0: sor@54540000 {
|
||||
compatible = "nvidia,tegra210-sor";
|
||||
reg = <0x54540000 0x00040000>;
|
||||
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_SOR0>,
|
||||
<&tegra_car TEGRA210_CLK_SOR0_OUT>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_D_OUT0>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_DP>,
|
||||
<&tegra_car TEGRA210_CLK_SOR_SAFE>;
|
||||
clock-names = "sor", "out", "parent", "dp", "safe";
|
||||
resets = <&tegra_car 182>;
|
||||
reset-names = "sor";
|
||||
pinctrl-0 = <&state_dpaux_aux>;
|
||||
pinctrl-1 = <&state_dpaux_i2c>;
|
||||
pinctrl-2 = <&state_dpaux_off>;
|
||||
pinctrl-names = "aux", "i2c", "off";
|
||||
power-domains = <&pd_sor>;
|
||||
|
||||
avdd-io-hdmi-dp-supply = <&avdd_1v05>;
|
||||
vdd-hdmi-dp-pll-supply = <&vdd_1v8>;
|
||||
hdmi-supply = <&vdd_hdmi>;
|
||||
|
||||
nvidia,ddc-i2c-bus = <&hdmi_ddc>;
|
||||
nvidia,hpd-gpio = <&gpio TEGRA_GPIO(CC, 1) GPIO_ACTIVE_LOW>;
|
||||
};
|
@ -0,0 +1,72 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra124-vic.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra Video Image Composer
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^vic@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- nvidia,tegra124-vic
|
||||
- nvidia,tegra210-vic
|
||||
- nvidia,tegra186-vic
|
||||
- nvidia,tegra194-vic
|
||||
- nvidia,tegra234-vic
|
||||
|
||||
- items:
|
||||
- const: nvidia,tegra132-vic
|
||||
- const: nvidia,tegra124-vic
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: clock input for the VIC hardware
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: vic
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: vic
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
description: Description of the interconnect paths for the VIC;
|
||||
see ../interconnect/interconnect.txt for details.
|
||||
items:
|
||||
- description: memory read client for VIC
|
||||
- description: memory write client for VIC
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: dma-mem # read
|
||||
- const: write
|
||||
|
||||
dma-coherent: true
|
||||
|
||||
additionalProperties: false
|
@ -0,0 +1,85 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra186-dc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra186 (and later) Display Controller
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^display@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra186-dc
|
||||
- nvidia,tegra194-dc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: display controller pixel clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: dc
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: display controller reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: dc
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
description: Description of the interconnect paths for the
|
||||
display controller; see ../interconnect/interconnect.txt
|
||||
for details.
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: dma-mem # read-0
|
||||
- const: read-1
|
||||
|
||||
nvidia,outputs:
|
||||
description: A list of phandles of outputs that this display
|
||||
controller can drive.
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle-array"
|
||||
|
||||
nvidia,head:
|
||||
description: The number of the display controller head. This
|
||||
is used to setup the various types of output to receive
|
||||
video data from the given head.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- power-domains
|
||||
- nvidia,outputs
|
||||
- nvidia,head
|
||||
|
||||
# see nvidia,tegra186-display.yaml for examples
|
@ -0,0 +1,310 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra186-display.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra186 (and later) Display Hub
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^display-hub@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra186-display
|
||||
- nvidia,tegra194-display
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: display hub reset
|
||||
- description: window group 0 reset
|
||||
- description: window group 1 reset
|
||||
- description: window group 2 reset
|
||||
- description: window group 3 reset
|
||||
- description: window group 4 reset
|
||||
- description: window group 5 reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: misc
|
||||
- const: wgrp0
|
||||
- const: wgrp1
|
||||
- const: wgrp2
|
||||
- const: wgrp3
|
||||
- const: wgrp4
|
||||
- const: wgrp5
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
ranges:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^display@[0-9a-f]+$":
|
||||
type: object
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: nvidia,tegra186-display
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: display core clock
|
||||
- description: display stream compression clock
|
||||
- description: display hub clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: disp
|
||||
- const: dsc
|
||||
- const: hub
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: display core clock
|
||||
- description: display hub clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: disp
|
||||
- const: hub
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- power-domains
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- ranges
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra186-clock.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/memory/tegra186-mc.h>
|
||||
#include <dt-bindings/power/tegra186-powergate.h>
|
||||
#include <dt-bindings/reset/tegra186-reset.h>
|
||||
|
||||
display-hub@15200000 {
|
||||
compatible = "nvidia,tegra186-display";
|
||||
reg = <0x15200000 0x00040000>;
|
||||
resets = <&bpmp TEGRA186_RESET_NVDISPLAY0_MISC>,
|
||||
<&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP0>,
|
||||
<&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP1>,
|
||||
<&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP2>,
|
||||
<&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP3>,
|
||||
<&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP4>,
|
||||
<&bpmp TEGRA186_RESET_NVDISPLAY0_WGRP5>;
|
||||
reset-names = "misc", "wgrp0", "wgrp1", "wgrp2",
|
||||
"wgrp3", "wgrp4", "wgrp5";
|
||||
clocks = <&bpmp TEGRA186_CLK_NVDISPLAY_DISP>,
|
||||
<&bpmp TEGRA186_CLK_NVDISPLAY_DSC>,
|
||||
<&bpmp TEGRA186_CLK_NVDISPLAYHUB>;
|
||||
clock-names = "disp", "dsc", "hub";
|
||||
status = "disabled";
|
||||
|
||||
power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISP>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0x15200000 0x15200000 0x40000>;
|
||||
|
||||
display@15200000 {
|
||||
compatible = "nvidia,tegra186-dc";
|
||||
reg = <0x15200000 0x10000>;
|
||||
interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bpmp TEGRA186_CLK_NVDISPLAY_P0>;
|
||||
clock-names = "dc";
|
||||
resets = <&bpmp TEGRA186_RESET_NVDISPLAY0_HEAD0>;
|
||||
reset-names = "dc";
|
||||
|
||||
power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISP>;
|
||||
interconnects = <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR &emc>,
|
||||
<&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
|
||||
interconnect-names = "dma-mem", "read-1";
|
||||
iommus = <&smmu TEGRA186_SID_NVDISPLAY>;
|
||||
|
||||
nvidia,outputs = <&dsia &dsib &sor0 &sor1>;
|
||||
nvidia,head = <0>;
|
||||
};
|
||||
|
||||
display@15210000 {
|
||||
compatible = "nvidia,tegra186-dc";
|
||||
reg = <0x15210000 0x10000>;
|
||||
interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bpmp TEGRA186_CLK_NVDISPLAY_P1>;
|
||||
clock-names = "dc";
|
||||
resets = <&bpmp TEGRA186_RESET_NVDISPLAY0_HEAD1>;
|
||||
reset-names = "dc";
|
||||
|
||||
power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISPB>;
|
||||
interconnects = <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR &emc>,
|
||||
<&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
|
||||
interconnect-names = "dma-mem", "read-1";
|
||||
iommus = <&smmu TEGRA186_SID_NVDISPLAY>;
|
||||
|
||||
nvidia,outputs = <&dsia &dsib &sor0 &sor1>;
|
||||
nvidia,head = <1>;
|
||||
};
|
||||
|
||||
display@15220000 {
|
||||
compatible = "nvidia,tegra186-dc";
|
||||
reg = <0x15220000 0x10000>;
|
||||
interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bpmp TEGRA186_CLK_NVDISPLAY_P2>;
|
||||
clock-names = "dc";
|
||||
resets = <&bpmp TEGRA186_RESET_NVDISPLAY0_HEAD2>;
|
||||
reset-names = "dc";
|
||||
|
||||
power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISPC>;
|
||||
interconnects = <&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR &emc>,
|
||||
<&mc TEGRA186_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
|
||||
interconnect-names = "dma-mem", "read-1";
|
||||
iommus = <&smmu TEGRA186_SID_NVDISPLAY>;
|
||||
|
||||
nvidia,outputs = <&sor0 &sor1>;
|
||||
nvidia,head = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra194-clock.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/memory/tegra194-mc.h>
|
||||
#include <dt-bindings/power/tegra194-powergate.h>
|
||||
#include <dt-bindings/reset/tegra194-reset.h>
|
||||
|
||||
display-hub@15200000 {
|
||||
compatible = "nvidia,tegra194-display";
|
||||
reg = <0x15200000 0x00040000>;
|
||||
resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_MISC>,
|
||||
<&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP0>,
|
||||
<&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP1>,
|
||||
<&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP2>,
|
||||
<&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP3>,
|
||||
<&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP4>,
|
||||
<&bpmp TEGRA194_RESET_NVDISPLAY0_WGRP5>;
|
||||
reset-names = "misc", "wgrp0", "wgrp1", "wgrp2",
|
||||
"wgrp3", "wgrp4", "wgrp5";
|
||||
clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_DISP>,
|
||||
<&bpmp TEGRA194_CLK_NVDISPLAYHUB>;
|
||||
clock-names = "disp", "hub";
|
||||
status = "disabled";
|
||||
|
||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0x15200000 0x15200000 0x40000>;
|
||||
|
||||
display@15200000 {
|
||||
compatible = "nvidia,tegra194-dc";
|
||||
reg = <0x15200000 0x10000>;
|
||||
interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_P0>;
|
||||
clock-names = "dc";
|
||||
resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_HEAD0>;
|
||||
reset-names = "dc";
|
||||
|
||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>;
|
||||
interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR &emc>,
|
||||
<&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
|
||||
interconnect-names = "dma-mem", "read-1";
|
||||
|
||||
nvidia,outputs = <&sor0 &sor1 &sor2 &sor3>;
|
||||
nvidia,head = <0>;
|
||||
};
|
||||
|
||||
display@15210000 {
|
||||
compatible = "nvidia,tegra194-dc";
|
||||
reg = <0x15210000 0x10000>;
|
||||
interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_P1>;
|
||||
clock-names = "dc";
|
||||
resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_HEAD1>;
|
||||
reset-names = "dc";
|
||||
|
||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISPB>;
|
||||
interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR &emc>,
|
||||
<&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
|
||||
interconnect-names = "dma-mem", "read-1";
|
||||
|
||||
nvidia,outputs = <&sor0 &sor1 &sor2 &sor3>;
|
||||
nvidia,head = <1>;
|
||||
};
|
||||
|
||||
display@15220000 {
|
||||
compatible = "nvidia,tegra194-dc";
|
||||
reg = <0x15220000 0x10000>;
|
||||
interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_P2>;
|
||||
clock-names = "dc";
|
||||
resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_HEAD2>;
|
||||
reset-names = "dc";
|
||||
|
||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISPC>;
|
||||
interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR &emc>,
|
||||
<&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
|
||||
interconnect-names = "dma-mem", "read-1";
|
||||
|
||||
nvidia,outputs = <&sor0 &sor1 &sor2 &sor3>;
|
||||
nvidia,head = <2>;
|
||||
};
|
||||
|
||||
display@15230000 {
|
||||
compatible = "nvidia,tegra194-dc";
|
||||
reg = <0x15230000 0x10000>;
|
||||
interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bpmp TEGRA194_CLK_NVDISPLAY_P3>;
|
||||
clock-names = "dc";
|
||||
resets = <&bpmp TEGRA194_RESET_NVDISPLAY0_HEAD3>;
|
||||
reset-names = "dc";
|
||||
|
||||
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISPC>;
|
||||
interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR &emc>,
|
||||
<&mc TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 &emc>;
|
||||
interconnect-names = "dma-mem", "read-1";
|
||||
|
||||
nvidia,outputs = <&sor0 &sor1 &sor2 &sor3>;
|
||||
nvidia,head = <3>;
|
||||
};
|
||||
};
|
@ -0,0 +1,45 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra186-dsi-padctl.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra MIPI DSI pad controller
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^padctl@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
const: nvidia,tegra186-dsi-padctl
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: dsi
|
||||
|
||||
allOf:
|
||||
- $ref: "/schemas/reset/reset.yaml"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/reset/tegra186-reset.h>
|
||||
|
||||
padctl@15880000 {
|
||||
compatible = "nvidia,tegra186-dsi-padctl";
|
||||
reg = <0x15880000 0x10000>;
|
||||
resets = <&bpmp TEGRA186_RESET_DSI>;
|
||||
reset-names = "dsi";
|
||||
};
|
@ -0,0 +1,183 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-dc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra Display Controller
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^dc@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- nvidia,tegra20-dc
|
||||
- nvidia,tegra30-dc
|
||||
- nvidia,tegra114-dc
|
||||
- nvidia,tegra124-dc
|
||||
- nvidia,tegra210-dc
|
||||
|
||||
- items:
|
||||
- const: nvidia,tegra124-dc
|
||||
- const: nvidia,tegra132-dc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: display controller pixel clock
|
||||
- description: parent clock # optional
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: dc
|
||||
- const: parent # optional
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: dc
|
||||
|
||||
interconnect-names: true
|
||||
interconnects: true
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the core power domain
|
||||
|
||||
memory-region: true
|
||||
|
||||
nvidia,head:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: The number of the display controller head. This is used to setup the various
|
||||
types of output to receive video data from the given head.
|
||||
|
||||
nvidia,outputs:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: A list of phandles of outputs that this display controller can drive.
|
||||
|
||||
rgb:
|
||||
type: object
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra20-dc
|
||||
- nvidia,tegra30-dc
|
||||
- nvidia,tegra114-dc
|
||||
then:
|
||||
properties:
|
||||
interconnects:
|
||||
items:
|
||||
- description: window A memory client
|
||||
- description: window B memory client
|
||||
- description: window B memory client (vertical filter)
|
||||
- description: window C memory client
|
||||
- description: cursor memory client
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: wina
|
||||
- const: winb
|
||||
- const: winb-vfilter
|
||||
- const: winc
|
||||
- const: cursor
|
||||
|
||||
rgb:
|
||||
description: Each display controller node has a child node, named "rgb", that represents
|
||||
the RGB output associated with the controller.
|
||||
type: object
|
||||
properties:
|
||||
nvidia,ddc-i2c-bus:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: phandle of an I2C controller used for DDC EDID probing
|
||||
|
||||
nvidia,hpd-gpio:
|
||||
description: specifies a GPIO used for hotplug detection
|
||||
maxItems: 1
|
||||
|
||||
nvidia,edid:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: supplies a binary EDID blob
|
||||
|
||||
nvidia,panel:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: phandle of a display panel
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra124-dc
|
||||
then:
|
||||
properties:
|
||||
interconnects:
|
||||
minItems: 4
|
||||
items:
|
||||
- description: window A memory client
|
||||
- description: window B memory client
|
||||
- description: window C memory client
|
||||
- description: cursor memory client
|
||||
- description: window D memory client
|
||||
- description: window T memory client
|
||||
|
||||
interconnect-names:
|
||||
minItems: 4
|
||||
items:
|
||||
- const: wina
|
||||
- const: winb
|
||||
- const: winc
|
||||
- const: cursor
|
||||
- const: wind
|
||||
- const: wint
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
dc@54200000 {
|
||||
compatible = "nvidia,tegra20-dc";
|
||||
reg = <0x54200000 0x00040000>;
|
||||
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_DISP1>;
|
||||
clock-names = "dc";
|
||||
resets = <&tegra_car 27>;
|
||||
reset-names = "dc";
|
||||
};
|
@ -0,0 +1,159 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-dsi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra Display Serial Interface
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- nvidia,tegra20-dsi
|
||||
- nvidia,tegra30-dsi
|
||||
- nvidia,tegra114-dsi
|
||||
- nvidia,tegra124-dsi
|
||||
- nvidia,tegra210-dsi
|
||||
- nvidia,tegra186-dsi
|
||||
|
||||
- items:
|
||||
- const: nvidia,tegra132-dsi
|
||||
- const: nvidia,tegra124-dsi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: dsi
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
avdd-dsi-csi-supply:
|
||||
description: phandle of a supply that powers the DSI controller
|
||||
|
||||
nvidia,mipi-calibrate:
|
||||
description: Should contain a phandle and a specifier specifying
|
||||
which pads are used by this DSI output and need to be
|
||||
calibrated. See nvidia,tegra114-mipi.yaml for details.
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle-array"
|
||||
|
||||
nvidia,ddc-i2c-bus:
|
||||
description: phandle of an I2C controller used for DDC EDID
|
||||
probing
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
nvidia,hpd-gpio:
|
||||
description: specifies a GPIO used for hotplug detection
|
||||
maxItems: 1
|
||||
|
||||
nvidia,edid:
|
||||
description: supplies a binary EDID blob
|
||||
$ref: "/schemas/types.yaml#/definitions/uint8-array"
|
||||
|
||||
nvidia,panel:
|
||||
description: phandle of a display panel
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
nvidia,ganged-mode:
|
||||
description: contains a phandle to a second DSI controller to
|
||||
gang up with in order to support up to 8 data lanes
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
allOf:
|
||||
- $ref: "../dsi-controller.yaml#"
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra20-dsi
|
||||
- nvidia,tegra30-dsi
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: DSI module clock
|
||||
- description: input for the pixel clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: dsi
|
||||
- const: parent
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: DSI module clock
|
||||
- description: low-power module clock
|
||||
- description: input for the pixel clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: dsi
|
||||
- const: lp
|
||||
- const: parent
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: nvidia,tegra186-dsi
|
||||
then:
|
||||
required:
|
||||
- interrupts
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra186-clock.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/tegra186-powergate.h>
|
||||
#include <dt-bindings/reset/tegra186-reset.h>
|
||||
|
||||
dsi@15300000 {
|
||||
compatible = "nvidia,tegra186-dsi";
|
||||
reg = <0x15300000 0x10000>;
|
||||
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bpmp TEGRA186_CLK_DSI>,
|
||||
<&bpmp TEGRA186_CLK_DSIA_LP>,
|
||||
<&bpmp TEGRA186_CLK_PLLD>;
|
||||
clock-names = "dsi", "lp", "parent";
|
||||
resets = <&bpmp TEGRA186_RESET_DSI>;
|
||||
reset-names = "dsi";
|
||||
|
||||
power-domains = <&bpmp TEGRA186_POWER_DOMAIN_DISP>;
|
||||
};
|
@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-epp.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra Encoder Pre-Processor
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^epp@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra20-epp
|
||||
- nvidia,tegra30-epp
|
||||
- nvidia,tegra114-epp
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: epp
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 4
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 4
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the core power domain
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
epp@540c0000 {
|
||||
compatible = "nvidia,tegra20-epp";
|
||||
reg = <0x540c0000 0x00040000>;
|
||||
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_EPP>;
|
||||
resets = <&tegra_car 19>;
|
||||
reset-names = "epp";
|
||||
};
|
@ -0,0 +1,74 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-gr2d.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA 2D graphics engine
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^gr2d@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra20-gr2d
|
||||
- nvidia,tegra30-gr2d
|
||||
- nvidia,tegra114-gr2d
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
- description: memory client hotflush reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: 2d
|
||||
- const: mc
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 4
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 4
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the HEG or core power domain
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/memory/tegra20-mc.h>
|
||||
|
||||
gr2d@54140000 {
|
||||
compatible = "nvidia,tegra20-gr2d";
|
||||
reg = <0x54140000 0x00040000>;
|
||||
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_GR2D>;
|
||||
resets = <&tegra_car 21>, <&mc TEGRA20_MC_RESET_2D>;
|
||||
reset-names = "2d", "mc";
|
||||
};
|
@ -0,0 +1,215 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-gr3d.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA 3D graphics engine
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^gr3d@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra20-gr3d
|
||||
- nvidia,tegra30-gr3d
|
||||
- nvidia,tegra114-gr3d
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
resets:
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
|
||||
reset-names:
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
|
||||
iommus:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interconnects:
|
||||
minItems: 4
|
||||
maxItems: 10
|
||||
|
||||
interconnect-names:
|
||||
minItems: 4
|
||||
maxItems: 10
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
power-domain-names:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: nvidia,tegra20-gr2d
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: 3d
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
- description: memory client hotflush reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: 3d
|
||||
- const: mc
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
|
||||
interconnect-names:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the TD power domain
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: nvidia,tegra30-gr3d
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: primary module clock
|
||||
- description: secondary module clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: 3d
|
||||
- const: 3d2
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: primary module reset
|
||||
- description: secondary module reset
|
||||
- description: primary memory client hotflush reset
|
||||
- description: secondary memory client hotflush reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: 3d
|
||||
- const: 3d2
|
||||
- const: mc
|
||||
- const: mc2
|
||||
|
||||
iommus:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
interconnects:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
|
||||
interconnect-names:
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the TD power domain
|
||||
- description: phandle to the TD2 power domain
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: 3d0
|
||||
- const: 3d1
|
||||
|
||||
dependencies:
|
||||
power-domains: [ power-domain-names ]
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: nvidia,tegra114-gr2d
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: 3d
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
- description: memory client hotflush reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: 3d
|
||||
- const: mc
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
minItems: 10
|
||||
maxItems: 10
|
||||
|
||||
interconnect-names:
|
||||
minItems: 10
|
||||
maxItems: 10
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the TD power domain
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/memory/tegra20-mc.h>
|
||||
|
||||
gr3d@54180000 {
|
||||
compatible = "nvidia,tegra20-gr3d";
|
||||
reg = <0x54180000 0x00040000>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_GR3D>;
|
||||
resets = <&tegra_car 24>, <&mc TEGRA20_MC_RESET_3D>;
|
||||
reset-names = "3d", "mc";
|
||||
};
|
@ -0,0 +1,126 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-hdmi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra HDMI Output Encoder
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^hdmi@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- nvidia,tegra20-hdmi
|
||||
- nvidia,tegra30-hdmi
|
||||
- nvidia,tegra114-hdmi
|
||||
- nvidia,tegra124-hdmi
|
||||
|
||||
- items:
|
||||
- const: nvidia,tegra132-hdmi
|
||||
- const: nvidia,tegra124-hdmi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
- description: parent clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: hdmi
|
||||
- const: parent
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: hdmi
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the core power domain
|
||||
|
||||
hdmi-supply:
|
||||
description: supply for the +5V HDMI connector pin
|
||||
|
||||
vdd-supply:
|
||||
description: regulator for supply voltage
|
||||
|
||||
pll-supply:
|
||||
description: regulator for PLL
|
||||
|
||||
nvidia,ddc-i2c-bus:
|
||||
description: phandle of an I2C controller used for DDC EDID
|
||||
probing
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
nvidia,hpd-gpio:
|
||||
description: specifies a GPIO used for hotplug detection
|
||||
maxItems: 1
|
||||
|
||||
nvidia,edid:
|
||||
description: supplies a binary EDID blob
|
||||
$ref: "/schemas/types.yaml#/definitions/uint8-array"
|
||||
|
||||
nvidia,panel:
|
||||
description: phandle of a display panel
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- pll-supply
|
||||
- vdd-supply
|
||||
- nvidia,ddc-i2c-bus
|
||||
- nvidia,hpd-gpio
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra124-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/gpio/tegra-gpio.h>
|
||||
|
||||
hdmi@54280000 {
|
||||
compatible = "nvidia,tegra124-hdmi";
|
||||
reg = <0x54280000 0x00040000>;
|
||||
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_HDMI>,
|
||||
<&tegra_car TEGRA124_CLK_PLL_D2_OUT0>;
|
||||
clock-names = "hdmi", "parent";
|
||||
resets = <&tegra_car 51>;
|
||||
reset-names = "hdmi";
|
||||
|
||||
hdmi-supply = <&vdd_5v0_hdmi>;
|
||||
pll-supply = <&vdd_hdmi_pll>;
|
||||
vdd-supply = <&vdd_3v3_hdmi>;
|
||||
|
||||
nvidia,ddc-i2c-bus = <&hdmi_ddc>;
|
||||
nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
|
||||
};
|
@ -1,675 +0,0 @@
|
||||
NVIDIA Tegra host1x
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-host1x"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
For pre-Tegra186, one entry describing the whole register area.
|
||||
For Tegra186, one entry for each entry in reg-names:
|
||||
"vm" - VM region assigned to Linux
|
||||
"hypervisor" - Hypervisor region (only if Linux acts as hypervisor)
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- #address-cells: The number of cells used to represent physical base addresses
|
||||
in the host1x address space. Should be 1.
|
||||
- #size-cells: The number of cells used to represent the size of an address
|
||||
range in the host1x address space. Should be 1.
|
||||
- ranges: The mapping of the host1x address space to the CPU address space.
|
||||
- clocks: Must contain one entry, for the module clock.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- host1x
|
||||
- mc
|
||||
|
||||
Optional properties:
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
- power-domains: Phandle to HEG or core power domain.
|
||||
|
||||
For each opp entry in 'operating-points-v2' table of host1x and its modules:
|
||||
- opp-supported-hw: One bitfield indicating:
|
||||
On Tegra20: SoC process ID mask
|
||||
On Tegra30+: SoC speedo ID mask
|
||||
|
||||
A bitwise AND is performed against the value and if any bit
|
||||
matches, the OPP gets enabled.
|
||||
|
||||
Each host1x client module having to perform DMA through the Memory Controller
|
||||
should have the interconnect endpoints set to the Memory Client and External
|
||||
Memory respectively.
|
||||
|
||||
The host1x top-level node defines a number of children, each representing one
|
||||
of the following host1x client modules:
|
||||
|
||||
- mpe: video encoder
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-mpe"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain one entry, for the module clock.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- mpe
|
||||
|
||||
Optional properties:
|
||||
- interconnects: Must contain entry for the MPE memory clients.
|
||||
- interconnect-names: Must include name of the interconnect path for each
|
||||
interconnect entry. Consult TRM documentation for information about
|
||||
available memory clients, see MEMORY CONTROLLER section.
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
- power-domains: Phandle to MPE power domain.
|
||||
|
||||
- vi: video input
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-vi"
|
||||
- reg: Physical base address and length of the controller registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: clocks: Must contain one entry, for the module clock.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- Tegra20/Tegra30/Tegra114/Tegra124:
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- vi
|
||||
- Tegra210:
|
||||
- power-domains: Must include venc powergate node as vi is in VE partition.
|
||||
|
||||
ports (optional node)
|
||||
vi can have optional ports node and max 6 ports are supported. Each port
|
||||
should have single 'endpoint' child node. All port nodes are grouped under
|
||||
ports node. Please refer to the bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
|
||||
csi (required node)
|
||||
Tegra210 has CSI part of VI sharing same host interface and register space.
|
||||
So, VI device node should have CSI child node.
|
||||
|
||||
- csi: mipi csi interface to vi
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra210-csi"
|
||||
- reg: Physical base address offset to parent and length of the controller
|
||||
registers.
|
||||
- clocks: Must contain entries csi, cilab, cilcd, cile, csi_tpg clocks.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- power-domains: Must include sor powergate node as csicil is in
|
||||
SOR partition.
|
||||
|
||||
channel (optional nodes)
|
||||
Maximum 6 channels are supported with each csi brick as either x4 or x2
|
||||
based on hw connectivity to sensor.
|
||||
|
||||
Required properties:
|
||||
- reg: csi port number. Valid port numbers are 0 through 5.
|
||||
- nvidia,mipi-calibrate: Should contain a phandle and a specifier
|
||||
specifying which pads are used by this CSI port and need to be
|
||||
calibrated. See also ../display/tegra/nvidia,tegra114-mipi.txt.
|
||||
|
||||
Each channel node must contain 2 port nodes which can be grouped
|
||||
under 'ports' node and each port should have a single child 'endpoint'
|
||||
node.
|
||||
|
||||
ports node
|
||||
Please refer to the bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
|
||||
ports node must contain below 2 port nodes.
|
||||
port@0 with single child 'endpoint' node always a sink.
|
||||
port@1 with single child 'endpoint' node always a source.
|
||||
|
||||
port@0 (required node)
|
||||
Required properties:
|
||||
- reg: 0
|
||||
|
||||
endpoint (required node)
|
||||
Required properties:
|
||||
- data-lanes: an array of data lane from 1 to 8. Valid array
|
||||
lengths are 1/2/4/8.
|
||||
- remote-endpoint: phandle to sensor 'endpoint' node.
|
||||
|
||||
port@1 (required node)
|
||||
Required properties:
|
||||
- reg: 1
|
||||
|
||||
endpoint (required node)
|
||||
Required properties:
|
||||
- remote-endpoint: phandle to vi port 'endpoint' node.
|
||||
|
||||
Optional properties:
|
||||
- interconnects: Must contain entry for the VI memory clients.
|
||||
- interconnect-names: Must include name of the interconnect path for each
|
||||
interconnect entry. Consult TRM documentation for information about
|
||||
available memory clients, see MEMORY CONTROLLER section.
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
- power-domains: Phandle to VENC power domain.
|
||||
|
||||
- epp: encoder pre-processor
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-epp"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain one entry, for the module clock.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- epp
|
||||
|
||||
Optional properties:
|
||||
- interconnects: Must contain entry for the EPP memory clients.
|
||||
- interconnect-names: Must include name of the interconnect path for each
|
||||
interconnect entry. Consult TRM documentation for information about
|
||||
available memory clients, see MEMORY CONTROLLER section.
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
- power-domains: Phandle to HEG or core power domain.
|
||||
|
||||
- isp: image signal processor
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-isp"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain one entry, for the module clock.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- isp
|
||||
|
||||
Optional properties:
|
||||
- interconnects: Must contain entry for the ISP memory clients.
|
||||
- interconnect-names: Must include name of the interconnect path for each
|
||||
interconnect entry. Consult TRM documentation for information about
|
||||
available memory clients, see MEMORY CONTROLLER section.
|
||||
- power-domains: Phandle to VENC or core power domain.
|
||||
|
||||
- gr2d: 2D graphics engine
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-gr2d"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain one entry, for the module clock.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- 2d
|
||||
- mc
|
||||
|
||||
Optional properties:
|
||||
- interconnects: Must contain entry for the GR2D memory clients.
|
||||
- interconnect-names: Must include name of the interconnect path for each
|
||||
interconnect entry. Consult TRM documentation for information about
|
||||
available memory clients, see MEMORY CONTROLLER section.
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
- power-domains: Phandle to HEG or core power domain.
|
||||
|
||||
- gr3d: 3D graphics engine
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-gr3d"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
(This property may be omitted if the only clock in the list is "3d")
|
||||
- 3d
|
||||
This MUST be the first entry.
|
||||
- 3d2 (Only required on SoCs with two 3D clocks)
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- 3d
|
||||
- 3d2 (Only required on SoCs with two 3D clocks)
|
||||
- mc
|
||||
- mc2 (Only required on SoCs with two 3D clocks)
|
||||
|
||||
Optional properties:
|
||||
- interconnects: Must contain entry for the GR3D memory clients.
|
||||
- interconnect-names: Must include name of the interconnect path for each
|
||||
interconnect entry. Consult TRM documentation for information about
|
||||
available memory clients, see MEMORY CONTROLLER section.
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
- power-domains: Phandles to 3D or core power domain.
|
||||
|
||||
- dc: display controller
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-dc"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- dc
|
||||
This MUST be the first entry.
|
||||
- parent
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- dc
|
||||
- nvidia,head: The number of the display controller head. This is used to
|
||||
setup the various types of output to receive video data from the given
|
||||
head.
|
||||
|
||||
Each display controller node has a child node, named "rgb", that represents
|
||||
the RGB output associated with the controller. It can take the following
|
||||
optional properties:
|
||||
- nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
|
||||
- nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
|
||||
- nvidia,edid: supplies a binary EDID blob
|
||||
- nvidia,panel: phandle of a display panel
|
||||
- interconnects: Must contain entry for the DC memory clients.
|
||||
- interconnect-names: Must include name of the interconnect path for each
|
||||
interconnect entry. Consult TRM documentation for information about
|
||||
available memory clients, see MEMORY CONTROLLER section.
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
- power-domains: Phandle to core power domain.
|
||||
|
||||
- hdmi: High Definition Multimedia Interface
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-hdmi"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- hdmi-supply: supply for the +5V HDMI connector pin
|
||||
- vdd-supply: regulator for supply voltage
|
||||
- pll-supply: regulator for PLL
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- hdmi
|
||||
This MUST be the first entry.
|
||||
- parent
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- hdmi
|
||||
|
||||
Optional properties:
|
||||
- nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
|
||||
- nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
|
||||
- nvidia,edid: supplies a binary EDID blob
|
||||
- nvidia,panel: phandle of a display panel
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
|
||||
- tvo: TV encoder output
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-tvo"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain one entry, for the module clock.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
|
||||
Optional properties:
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
- power-domains: Phandle to core power domain.
|
||||
|
||||
- dsi: display serial interface
|
||||
|
||||
Required properties:
|
||||
- compatible: "nvidia,tegra<chip>-dsi"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- dsi
|
||||
This MUST be the first entry.
|
||||
- lp
|
||||
- parent
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- dsi
|
||||
- avdd-dsi-supply: phandle of a supply that powers the DSI controller
|
||||
- nvidia,mipi-calibrate: Should contain a phandle and a specifier specifying
|
||||
which pads are used by this DSI output and need to be calibrated. See also
|
||||
../display/tegra/nvidia,tegra114-mipi.txt.
|
||||
|
||||
Optional properties:
|
||||
- nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
|
||||
- nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
|
||||
- nvidia,edid: supplies a binary EDID blob
|
||||
- nvidia,panel: phandle of a display panel
|
||||
- nvidia,ganged-mode: contains a phandle to a second DSI controller to gang
|
||||
up with in order to support up to 8 data lanes
|
||||
- operating-points-v2: See ../bindings/opp/opp.txt for details.
|
||||
|
||||
- sor: serial output resource
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be:
|
||||
- "nvidia,tegra124-sor": for Tegra124 and Tegra132
|
||||
- "nvidia,tegra132-sor": for Tegra132
|
||||
- "nvidia,tegra210-sor": for Tegra210
|
||||
- "nvidia,tegra210-sor1": for Tegra210
|
||||
- "nvidia,tegra186-sor": for Tegra186
|
||||
- "nvidia,tegra186-sor1": for Tegra186
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- sor: clock input for the SOR hardware
|
||||
- out: SOR output clock
|
||||
- parent: input for the pixel clock
|
||||
- dp: reference clock for the SOR clock
|
||||
- safe: safe reference for the SOR clock during power up
|
||||
|
||||
For Tegra186 and later:
|
||||
- pad: SOR pad output clock (on Tegra186 and later)
|
||||
|
||||
Obsolete:
|
||||
- source: source clock for the SOR clock (obsolete, use "out" instead)
|
||||
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- sor
|
||||
|
||||
Required properties on Tegra186 and later:
|
||||
- nvidia,interface: index of the SOR interface
|
||||
|
||||
Optional properties:
|
||||
- nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
|
||||
- nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
|
||||
- nvidia,edid: supplies a binary EDID blob
|
||||
- nvidia,panel: phandle of a display panel
|
||||
- nvidia,xbar-cfg: 5 cells containing the crossbar configuration. Each lane
|
||||
of the SOR, identified by the cell's index, is mapped via the crossbar to
|
||||
the pad specified by the cell's value.
|
||||
|
||||
Optional properties when driving an eDP output:
|
||||
- nvidia,dpaux: phandle to a DispayPort AUX interface
|
||||
|
||||
- dpaux: DisplayPort AUX interface
|
||||
- compatible : Should contain one of the following:
|
||||
- "nvidia,tegra124-dpaux": for Tegra124 and Tegra132
|
||||
- "nvidia,tegra210-dpaux": for Tegra210
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- dpaux: clock input for the DPAUX hardware
|
||||
- parent: reference clock
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- dpaux
|
||||
- vdd-supply: phandle of a supply that powers the DisplayPort link
|
||||
- i2c-bus: Subnode where I2C slave devices are listed. This subnode
|
||||
must be always present. If there are no I2C slave devices, an empty
|
||||
node should be added. See ../../i2c/i2c.txt for more information.
|
||||
|
||||
See ../pinctrl/nvidia,tegra124-dpaux-padctl.txt for information
|
||||
regarding the DPAUX pad controller bindings.
|
||||
|
||||
- vic: Video Image Compositor
|
||||
- compatible : "nvidia,tegra<chip>-vic"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- vic: clock input for the VIC hardware
|
||||
- resets: Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names: Must include the following entries:
|
||||
- vic
|
||||
|
||||
Optional properties:
|
||||
- interconnects: Must contain entry for the VIC memory clients.
|
||||
- interconnect-names: Must include name of the interconnect path for each
|
||||
interconnect entry. Consult TRM documentation for information about
|
||||
available memory clients, see MEMORY CONTROLLER section.
|
||||
|
||||
Example:
|
||||
|
||||
/ {
|
||||
...
|
||||
|
||||
host1x {
|
||||
compatible = "nvidia,tegra20-host1x", "simple-bus";
|
||||
reg = <0x50000000 0x00024000>;
|
||||
interrupts = <0 65 0x04 /* mpcore syncpt */
|
||||
0 67 0x04>; /* mpcore general */
|
||||
clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
|
||||
resets = <&tegra_car 28>;
|
||||
reset-names = "host1x";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
power-domains = <&domain>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0x54000000 0x54000000 0x04000000>;
|
||||
|
||||
mpe {
|
||||
compatible = "nvidia,tegra20-mpe";
|
||||
reg = <0x54040000 0x00040000>;
|
||||
interrupts = <0 68 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_MPE>;
|
||||
resets = <&tegra_car 60>;
|
||||
reset-names = "mpe";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
power-domains = <&domain>;
|
||||
};
|
||||
|
||||
vi@54080000 {
|
||||
compatible = "nvidia,tegra210-vi";
|
||||
reg = <0x0 0x54080000 0x0 0x700>;
|
||||
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_VI>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_VI>;
|
||||
power-domains = <&pd_venc>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0x0 0x0 0x54080000 0x2000>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
imx219_vi_in0: endpoint {
|
||||
remote-endpoint = <&imx219_csi_out0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
csi@838 {
|
||||
compatible = "nvidia,tegra210-csi";
|
||||
reg = <0x838 0x1300>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_CILAB>,
|
||||
<&tegra_car TEGRA210_CLK_CILCD>,
|
||||
<&tegra_car TEGRA210_CLK_CILE>,
|
||||
<&tegra_car TEGRA210_CLK_CSI_TPG>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_P>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_P>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_P>;
|
||||
assigned-clock-rates = <102000000>,
|
||||
<102000000>,
|
||||
<102000000>,
|
||||
<972000000>;
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_CSI>,
|
||||
<&tegra_car TEGRA210_CLK_CILAB>,
|
||||
<&tegra_car TEGRA210_CLK_CILCD>,
|
||||
<&tegra_car TEGRA210_CLK_CILE>,
|
||||
<&tegra_car TEGRA210_CLK_CSI_TPG>;
|
||||
clock-names = "csi", "cilab", "cilcd", "cile", "csi_tpg";
|
||||
power-domains = <&pd_sor>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
nvidia,mipi-calibrate = <&mipi 0x001>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
imx219_csi_in0: endpoint {
|
||||
data-lanes = <1 2>;
|
||||
remote-endpoint = <&imx219_out0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
imx219_csi_out0: endpoint {
|
||||
remote-endpoint = <&imx219_vi_in0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
epp {
|
||||
compatible = "nvidia,tegra20-epp";
|
||||
reg = <0x540c0000 0x00040000>;
|
||||
interrupts = <0 70 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_EPP>;
|
||||
resets = <&tegra_car 19>;
|
||||
reset-names = "epp";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
power-domains = <&domain>;
|
||||
};
|
||||
|
||||
isp {
|
||||
compatible = "nvidia,tegra20-isp";
|
||||
reg = <0x54100000 0x00040000>;
|
||||
interrupts = <0 71 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_ISP>;
|
||||
resets = <&tegra_car 23>;
|
||||
reset-names = "isp";
|
||||
};
|
||||
|
||||
gr2d {
|
||||
compatible = "nvidia,tegra20-gr2d";
|
||||
reg = <0x54140000 0x00040000>;
|
||||
interrupts = <0 72 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_GR2D>;
|
||||
resets = <&tegra_car 21>;
|
||||
reset-names = "2d";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
power-domains = <&domain>;
|
||||
};
|
||||
|
||||
gr3d {
|
||||
compatible = "nvidia,tegra20-gr3d";
|
||||
reg = <0x54180000 0x00040000>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_GR3D>;
|
||||
resets = <&tegra_car 24>;
|
||||
reset-names = "3d";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
power-domains = <&domain>;
|
||||
};
|
||||
|
||||
dc@54200000 {
|
||||
compatible = "nvidia,tegra20-dc";
|
||||
reg = <0x54200000 0x00040000>;
|
||||
interrupts = <0 73 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_DISP1>,
|
||||
<&tegra_car TEGRA20_CLK_PLL_P>;
|
||||
clock-names = "dc", "parent";
|
||||
resets = <&tegra_car 27>;
|
||||
reset-names = "dc";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
power-domains = <&domain>;
|
||||
|
||||
interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
|
||||
<&mc TEGRA20_MC_DISPLAY0B &emc>,
|
||||
<&mc TEGRA20_MC_DISPLAY0C &emc>,
|
||||
<&mc TEGRA20_MC_DISPLAYHC &emc>;
|
||||
interconnect-names = "wina",
|
||||
"winb",
|
||||
"winc",
|
||||
"cursor";
|
||||
|
||||
rgb {
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
dc@54240000 {
|
||||
compatible = "nvidia,tegra20-dc";
|
||||
reg = <0x54240000 0x00040000>;
|
||||
interrupts = <0 74 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_DISP2>,
|
||||
<&tegra_car TEGRA20_CLK_PLL_P>;
|
||||
clock-names = "dc", "parent";
|
||||
resets = <&tegra_car 26>;
|
||||
reset-names = "dc";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
power-domains = <&domain>;
|
||||
|
||||
interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>,
|
||||
<&mc TEGRA20_MC_DISPLAY0BB &emc>,
|
||||
<&mc TEGRA20_MC_DISPLAY0CB &emc>,
|
||||
<&mc TEGRA20_MC_DISPLAYHCB &emc>;
|
||||
interconnect-names = "wina",
|
||||
"winb",
|
||||
"winc",
|
||||
"cursor";
|
||||
|
||||
rgb {
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
hdmi {
|
||||
compatible = "nvidia,tegra20-hdmi";
|
||||
reg = <0x54280000 0x00040000>;
|
||||
interrupts = <0 75 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_HDMI>,
|
||||
<&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
|
||||
clock-names = "hdmi", "parent";
|
||||
resets = <&tegra_car 51>;
|
||||
reset-names = "hdmi";
|
||||
status = "disabled";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
};
|
||||
|
||||
tvo {
|
||||
compatible = "nvidia,tegra20-tvo";
|
||||
reg = <0x542c0000 0x00040000>;
|
||||
interrupts = <0 76 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_TVO>;
|
||||
status = "disabled";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
};
|
||||
|
||||
dsi {
|
||||
compatible = "nvidia,tegra20-dsi";
|
||||
reg = <0x54300000 0x00040000>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_DSI>,
|
||||
<&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
|
||||
clock-names = "dsi", "parent";
|
||||
resets = <&tegra_car 48>;
|
||||
reset-names = "dsi";
|
||||
status = "disabled";
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
};
|
@ -0,0 +1,431 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-host1x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra host1x controller
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
description: The host1x top-level node defines a number of children, each
|
||||
representing one of the host1x client modules defined in this binding.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- nvidia,tegra20-host1x
|
||||
- nvidia,tegra30-host1x
|
||||
- nvidia,tegra114-host1x
|
||||
- nvidia,tegra124-host1x
|
||||
- nvidia,tegra210-host1x
|
||||
- nvidia,tegra186-host1x
|
||||
- nvidia,tegra194-host1x
|
||||
- nvidia,tegra234-host1x
|
||||
|
||||
- items:
|
||||
- const: nvidia,tegra132-host1x
|
||||
- const: nvidia,tegra124-host1x
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 9
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
maxItems: 9
|
||||
|
||||
'#address-cells':
|
||||
description: The number of cells used to represent physical base addresses
|
||||
in the host1x address space.
|
||||
enum: [1, 2]
|
||||
|
||||
'#size-cells':
|
||||
description: The number of cells used to represent the size of an address
|
||||
range in the host1x address space.
|
||||
enum: [1, 2]
|
||||
|
||||
ranges:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: Must contain one entry, for the module clock. See
|
||||
../clocks/clock-bindings.txt for details.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: host1x
|
||||
|
||||
resets:
|
||||
minItems: 1 # MC reset is optional on Tegra186 and later
|
||||
items:
|
||||
- description: module reset
|
||||
- description: memory client hotflush reset
|
||||
|
||||
reset-names:
|
||||
minItems: 1 # MC reset is optional on Tegra186 and later
|
||||
items:
|
||||
- const: host1x
|
||||
- const: mc
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
items:
|
||||
- description: memory read client for host1x
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: dma-mem # read
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the HEG or core power domain
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
- ranges
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties:
|
||||
type: object
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra20-host1x
|
||||
- nvidia,tegra30-host1x
|
||||
- nvidia,tegra114-host1x
|
||||
- nvidia,tegra124-host1x
|
||||
- nvidia,tegra210-host1x
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
items:
|
||||
- description: host1x syncpoint interrupt
|
||||
- description: host1x general interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: syncpt
|
||||
- const: host1x
|
||||
required:
|
||||
- resets
|
||||
- reset-names
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra186-host1x
|
||||
- nvidia,tegra194-host1x
|
||||
then:
|
||||
properties:
|
||||
reg-names:
|
||||
items:
|
||||
- const: hypervisor
|
||||
- const: vm
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: region used by the hypervisor
|
||||
- description: region assigned to the virtual machine
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: host1x syncpoint interrupt
|
||||
- description: host1x general interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: syncpt
|
||||
- const: host1x
|
||||
|
||||
iommu-map:
|
||||
description: Specification of stream IDs available for memory context device
|
||||
use. Should be a mapping of IDs 0..n to IOMMU entries corresponding to
|
||||
usable stream IDs.
|
||||
|
||||
required:
|
||||
- reg-names
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra234-host1x
|
||||
then:
|
||||
properties:
|
||||
reg-names:
|
||||
items:
|
||||
- const: common
|
||||
- const: hypervisor
|
||||
- const: vm
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: region used by host1x server
|
||||
- description: region used by the hypervisor
|
||||
- description: region assigned to the virtual machine
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: host1x syncpoint interrupt 0
|
||||
- description: host1x syncpoint interrupt 1
|
||||
- description: host1x syncpoint interrupt 2
|
||||
- description: host1x syncpoint interrupt 3
|
||||
- description: host1x syncpoint interrupt 4
|
||||
- description: host1x syncpoint interrupt 5
|
||||
- description: host1x syncpoint interrupt 6
|
||||
- description: host1x syncpoint interrupt 7
|
||||
- description: host1x general interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: syncpt0
|
||||
- const: syncpt1
|
||||
- const: syncpt2
|
||||
- const: syncpt3
|
||||
- const: syncpt4
|
||||
- const: syncpt5
|
||||
- const: syncpt6
|
||||
- const: syncpt7
|
||||
- const: host1x
|
||||
|
||||
iommu-map:
|
||||
description: Specification of stream IDs available for memory context device
|
||||
use. Should be a mapping of IDs 0..n to IOMMU entries corresponding to
|
||||
usable stream IDs.
|
||||
|
||||
required:
|
||||
- reg-names
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/gpio/tegra-gpio.h>
|
||||
#include <dt-bindings/memory/tegra20-mc.h>
|
||||
|
||||
host1x@50000000 {
|
||||
compatible = "nvidia,tegra20-host1x";
|
||||
reg = <0x50000000 0x00024000>;
|
||||
interrupts = <0 65 0x04>, /* mpcore syncpt */
|
||||
<0 67 0x04>; /* mpcore general */
|
||||
interrupt-names = "syncpt", "host1x";
|
||||
clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
|
||||
clock-names = "host1x";
|
||||
resets = <&tegra_car 28>, <&mc TEGRA20_MC_RESET_HC>;
|
||||
reset-names = "host1x", "mc";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0x54000000 0x54000000 0x04000000>;
|
||||
|
||||
mpe@54040000 {
|
||||
compatible = "nvidia,tegra20-mpe";
|
||||
reg = <0x54040000 0x00040000>;
|
||||
interrupts = <0 68 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_MPE>;
|
||||
resets = <&tegra_car 60>;
|
||||
reset-names = "mpe";
|
||||
};
|
||||
|
||||
vi@54080000 {
|
||||
compatible = "nvidia,tegra20-vi";
|
||||
reg = <0x54080000 0x00040000>;
|
||||
interrupts = <0 69 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_VI>;
|
||||
resets = <&tegra_car 100>;
|
||||
reset-names = "vi";
|
||||
};
|
||||
|
||||
epp@540c0000 {
|
||||
compatible = "nvidia,tegra20-epp";
|
||||
reg = <0x540c0000 0x00040000>;
|
||||
interrupts = <0 70 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_EPP>;
|
||||
resets = <&tegra_car 19>;
|
||||
reset-names = "epp";
|
||||
};
|
||||
|
||||
isp@54100000 {
|
||||
compatible = "nvidia,tegra20-isp";
|
||||
reg = <0x54100000 0x00040000>;
|
||||
interrupts = <0 71 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_ISP>;
|
||||
resets = <&tegra_car 23>;
|
||||
reset-names = "isp";
|
||||
};
|
||||
|
||||
gr2d@54140000 {
|
||||
compatible = "nvidia,tegra20-gr2d";
|
||||
reg = <0x54140000 0x00040000>;
|
||||
interrupts = <0 72 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_GR2D>;
|
||||
resets = <&tegra_car 21>, <&mc TEGRA20_MC_RESET_2D>;
|
||||
reset-names = "2d", "mc";
|
||||
};
|
||||
|
||||
gr3d@54180000 {
|
||||
compatible = "nvidia,tegra20-gr3d";
|
||||
reg = <0x54180000 0x00040000>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_GR3D>;
|
||||
resets = <&tegra_car 24>, <&mc TEGRA20_MC_RESET_3D>;
|
||||
reset-names = "3d", "mc";
|
||||
};
|
||||
|
||||
dc@54200000 {
|
||||
compatible = "nvidia,tegra20-dc";
|
||||
reg = <0x54200000 0x00040000>;
|
||||
interrupts = <0 73 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_DISP1>;
|
||||
clock-names = "dc";
|
||||
resets = <&tegra_car 27>;
|
||||
reset-names = "dc";
|
||||
|
||||
rgb {
|
||||
};
|
||||
};
|
||||
|
||||
dc@54240000 {
|
||||
compatible = "nvidia,tegra20-dc";
|
||||
reg = <0x54240000 0x00040000>;
|
||||
interrupts = <0 74 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_DISP2>;
|
||||
clock-names = "dc";
|
||||
resets = <&tegra_car 26>;
|
||||
reset-names = "dc";
|
||||
|
||||
rgb {
|
||||
};
|
||||
};
|
||||
|
||||
hdmi@54280000 {
|
||||
compatible = "nvidia,tegra20-hdmi";
|
||||
reg = <0x54280000 0x00040000>;
|
||||
interrupts = <0 75 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_HDMI>,
|
||||
<&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
|
||||
clock-names = "hdmi", "parent";
|
||||
resets = <&tegra_car 51>;
|
||||
reset-names = "hdmi";
|
||||
|
||||
hdmi-supply = <&vdd_5v0_hdmi>;
|
||||
pll-supply = <&vdd_hdmi_pll>;
|
||||
vdd-supply = <&vdd_3v3_hdmi>;
|
||||
|
||||
nvidia,ddc-i2c-bus = <&hdmi_ddc>;
|
||||
nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
tvo@542c0000 {
|
||||
compatible = "nvidia,tegra20-tvo";
|
||||
reg = <0x542c0000 0x00040000>;
|
||||
interrupts = <0 76 0x04>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_TVO>;
|
||||
};
|
||||
|
||||
dsi@54300000 {
|
||||
compatible = "nvidia,tegra20-dsi";
|
||||
reg = <0x54300000 0x00040000>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_DSI>,
|
||||
<&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
|
||||
clock-names = "dsi", "parent";
|
||||
resets = <&tegra_car 48>;
|
||||
reset-names = "dsi";
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra210-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/memory/tegra210-mc.h>
|
||||
|
||||
host1x@50000000 {
|
||||
compatible = "nvidia,tegra210-host1x";
|
||||
reg = <0x50000000 0x00024000>;
|
||||
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, /* mpcore syncpt */
|
||||
<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* mpcore general */
|
||||
interrupt-names = "syncpt", "host1x";
|
||||
clocks = <&tegra_car TEGRA210_CLK_HOST1X>;
|
||||
clock-names = "host1x";
|
||||
resets = <&tegra_car 28>;
|
||||
reset-names = "host1x";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0x54000000 0x54000000 0x01000000>;
|
||||
iommus = <&mc TEGRA_SWGROUP_HC>;
|
||||
|
||||
vi@54080000 {
|
||||
compatible = "nvidia,tegra210-vi";
|
||||
reg = <0x54080000 0x00000700>;
|
||||
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_VI>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_VI>;
|
||||
power-domains = <&pd_venc>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0x0 0x54080000 0x2000>;
|
||||
|
||||
csi@838 {
|
||||
compatible = "nvidia,tegra210-csi";
|
||||
reg = <0x838 0x1300>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_CILAB>,
|
||||
<&tegra_car TEGRA210_CLK_CILCD>,
|
||||
<&tegra_car TEGRA210_CLK_CILE>,
|
||||
<&tegra_car TEGRA210_CLK_CSI_TPG>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_P>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_P>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_P>;
|
||||
assigned-clock-rates = <102000000>,
|
||||
<102000000>,
|
||||
<102000000>,
|
||||
<972000000>;
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_CSI>,
|
||||
<&tegra_car TEGRA210_CLK_CILAB>,
|
||||
<&tegra_car TEGRA210_CLK_CILCD>,
|
||||
<&tegra_car TEGRA210_CLK_CILE>,
|
||||
<&tegra_car TEGRA210_CLK_CSI_TPG>;
|
||||
clock-names = "csi", "cilab", "cilcd", "cile", "csi_tpg";
|
||||
power-domains = <&pd_sor>;
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,67 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-isp.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra ISP processor
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra20-isp
|
||||
- nvidia,tegra30-isp
|
||||
- nvidia,tegra210-isp
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: isp
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
items:
|
||||
- description: memory write client
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: dma-mem # write
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the VENC or core power domain
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
isp@54100000 {
|
||||
compatible = "nvidia,tegra20-isp";
|
||||
reg = <0x54100000 0x00040000>;
|
||||
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_ISP>;
|
||||
resets = <&tegra_car 23>;
|
||||
reset-names = "isp";
|
||||
};
|
@ -0,0 +1,73 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-mpe.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra Video Encoder
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^mpe@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra20-mpe
|
||||
- nvidia,tegra30-mpe
|
||||
- nvidia,tegra114-mpe
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: mpe
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
|
||||
interconnect-names:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the MPE power domain
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
mpe@54040000 {
|
||||
compatible = "nvidia,tegra20-mpe";
|
||||
reg = <0x54040000 0x00040000>;
|
||||
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_MPE>;
|
||||
resets = <&tegra_car 60>;
|
||||
reset-names = "mpe";
|
||||
};
|
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-tvo.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra TV Encoder Output
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^tvo@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra20-tvo
|
||||
- nvidia,tegra30-tvo
|
||||
- nvidia,tegra114-tvo
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the core power domain
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
tvo@542c0000 {
|
||||
compatible = "nvidia,tegra20-tvo";
|
||||
reg = <0x542c0000 0x00040000>;
|
||||
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_TVO>;
|
||||
};
|
@ -0,0 +1,163 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-vi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra Video Input controller
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^vi@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nvidia,tegra20-vi
|
||||
- const: nvidia,tegra30-vi
|
||||
- const: nvidia,tegra114-vi
|
||||
- const: nvidia,tegra124-vi
|
||||
- items:
|
||||
- const: nvidia,tegra132-vi
|
||||
- const: nvidia,tegra124-vi
|
||||
- const: nvidia,tegra210-vi
|
||||
- const: nvidia,tegra186-vi
|
||||
- const: nvidia,tegra194-vi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: module reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: vi
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
minItems: 4
|
||||
maxItems: 5
|
||||
|
||||
interconnect-names:
|
||||
minItems: 4
|
||||
maxItems: 5
|
||||
|
||||
operating-points-v2:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: phandle to the VENC power domain
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 1
|
||||
|
||||
ranges:
|
||||
maxItems: 1
|
||||
|
||||
avdd-dsi-csi-supply:
|
||||
description: DSI/CSI power supply. Must supply 1.2 V.
|
||||
|
||||
patternProperties:
|
||||
"^csi@[0-9a-f]+$":
|
||||
type: object
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- nvidia,tegra20-vi
|
||||
- nvidia,tegra30-vi
|
||||
- nvidia,tegra114-vi
|
||||
- nvidia,tegra124-vi
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
- reset-names
|
||||
else:
|
||||
required:
|
||||
- power-domains
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
vi@54080000 {
|
||||
compatible = "nvidia,tegra20-vi";
|
||||
reg = <0x54080000 0x00040000>;
|
||||
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA20_CLK_VI>;
|
||||
resets = <&tegra_car 100>;
|
||||
reset-names = "vi";
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra210-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
vi@54080000 {
|
||||
compatible = "nvidia,tegra210-vi";
|
||||
reg = <0x54080000 0x00000700>;
|
||||
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_VI>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_VI>;
|
||||
power-domains = <&pd_venc>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ranges = <0x0 0x54080000 0x2000>;
|
||||
|
||||
csi@838 {
|
||||
compatible = "nvidia,tegra210-csi";
|
||||
reg = <0x838 0x1300>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_CILAB>,
|
||||
<&tegra_car TEGRA210_CLK_CILCD>,
|
||||
<&tegra_car TEGRA210_CLK_CILE>,
|
||||
<&tegra_car TEGRA210_CLK_CSI_TPG>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_P>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_P>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_P>;
|
||||
assigned-clock-rates = <102000000>,
|
||||
<102000000>,
|
||||
<102000000>,
|
||||
<972000000>;
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_CSI>,
|
||||
<&tegra_car TEGRA210_CLK_CILAB>,
|
||||
<&tegra_car TEGRA210_CLK_CILCD>,
|
||||
<&tegra_car TEGRA210_CLK_CILE>,
|
||||
<&tegra_car TEGRA210_CLK_CSI_TPG>;
|
||||
clock-names = "csi", "cilab", "cilcd", "cile", "csi_tpg";
|
||||
power-domains = <&pd_sor>;
|
||||
};
|
||||
};
|
@ -0,0 +1,52 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra210-csi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra CSI controller
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^csi@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra210-csi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: module clock
|
||||
- description: A/B lanes clock
|
||||
- description: C/D lanes clock
|
||||
- description: E lane clock
|
||||
- description: test pattern generator clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: csi
|
||||
- const: cilab
|
||||
- const: cilcd
|
||||
- const: cile
|
||||
- const: csi_tpg
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
|
||||
# see nvidia,tegra20-vi.yaml for an example
|
@ -14,16 +14,21 @@ properties:
|
||||
pattern: '^gpu@[a-f0-9]+$'
|
||||
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- amlogic,meson-g12a-mali
|
||||
- mediatek,mt8183-mali
|
||||
- realtek,rtd1619-mali
|
||||
- renesas,r9a07g044-mali
|
||||
- renesas,r9a07g054-mali
|
||||
- rockchip,px30-mali
|
||||
- rockchip,rk3568-mali
|
||||
- const: arm,mali-bifrost # Mali Bifrost GPU model/revision is fully discoverable
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,meson-g12a-mali
|
||||
- mediatek,mt8183-mali
|
||||
- realtek,rtd1619-mali
|
||||
- renesas,r9a07g044-mali
|
||||
- renesas,r9a07g054-mali
|
||||
- rockchip,px30-mali
|
||||
- rockchip,rk3568-mali
|
||||
- const: arm,mali-bifrost # Mali Bifrost GPU model/revision is fully discoverable
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt8192-mali
|
||||
- const: arm,mali-valhall-jm # Mali Valhall GPU model/revision is fully discoverable
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -16,6 +16,7 @@ properties:
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- brcm,2711-v3d
|
||||
- brcm,7268-v3d
|
||||
- brcm,7278-v3d
|
||||
|
||||
|
192
Documentation/devicetree/bindings/mfd/fsl,imx8qxp-csr.yaml
Normal file
192
Documentation/devicetree/bindings/mfd/fsl,imx8qxp-csr.yaml
Normal file
@ -0,0 +1,192 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/fsl,imx8qxp-csr.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale i.MX8qm/qxp Control and Status Registers Module Bindings
|
||||
|
||||
maintainers:
|
||||
- Liu Ying <victor.liu@nxp.com>
|
||||
|
||||
description: |
|
||||
As a system controller, the Freescale i.MX8qm/qxp Control and Status
|
||||
Registers(CSR) module represents a set of miscellaneous registers of a
|
||||
specific subsystem. It may provide control and/or status report interfaces
|
||||
to a mix of standalone hardware devices within that subsystem. One typical
|
||||
use-case is for some other nodes to acquire a reference to the syscon node
|
||||
by phandle, and the other typical use-case is that the operating system
|
||||
should consider all subnodes of the CSR module as separate child devices.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^syscon@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- fsl,imx8qxp-mipi-lvds-csr
|
||||
- fsl,imx8qm-lvds-csr
|
||||
- const: syscon
|
||||
- const: simple-mfd
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: ipg
|
||||
|
||||
patternProperties:
|
||||
"^(ldb|phy|pxl2dpi)$":
|
||||
type: object
|
||||
description: The possible child devices of the CSR module.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx8qxp-mipi-lvds-csr
|
||||
then:
|
||||
required:
|
||||
- pxl2dpi
|
||||
- ldb
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,imx8qm-lvds-csr
|
||||
then:
|
||||
required:
|
||||
- phy
|
||||
- ldb
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx8-lpcg.h>
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
mipi_lvds_0_csr: syscon@56221000 {
|
||||
compatible = "fsl,imx8qxp-mipi-lvds-csr", "syscon", "simple-mfd";
|
||||
reg = <0x56221000 0x1000>;
|
||||
clocks = <&mipi_lvds_0_di_mipi_lvds_regs_lpcg IMX_LPCG_CLK_4>;
|
||||
clock-names = "ipg";
|
||||
|
||||
mipi_lvds_0_pxl2dpi: pxl2dpi {
|
||||
compatible = "fsl,imx8qxp-pxl2dpi";
|
||||
fsl,sc-resource = <IMX_SC_R_MIPI_0>;
|
||||
power-domains = <&pd IMX_SC_R_MIPI_0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
mipi_lvds_0_pxl2dpi_dc0_pixel_link0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&dc0_pixel_link0_mipi_lvds_0_pxl2dpi>;
|
||||
};
|
||||
|
||||
mipi_lvds_0_pxl2dpi_dc0_pixel_link1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&dc0_pixel_link1_mipi_lvds_0_pxl2dpi>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi>;
|
||||
};
|
||||
|
||||
mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mipi_lvds_0_ldb: ldb {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,imx8qxp-ldb";
|
||||
clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_MISC2>,
|
||||
<&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_BYPASS>;
|
||||
clock-names = "pixel", "bypass";
|
||||
power-domains = <&pd IMX_SC_R_LVDS_0>;
|
||||
|
||||
channel@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
phys = <&mipi_lvds_0_phy>;
|
||||
phy-names = "lvds_phy";
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mipi_lvds_0_ldb_ch0_mipi_lvds_0_pxl2dpi: endpoint {
|
||||
remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
/* ... */
|
||||
};
|
||||
};
|
||||
|
||||
channel@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
phys = <&mipi_lvds_0_phy>;
|
||||
phy-names = "lvds_phy";
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mipi_lvds_0_ldb_ch1_mipi_lvds_0_pxl2dpi: endpoint {
|
||||
remote-endpoint = <&mipi_lvds_0_pxl2dpi_mipi_lvds_0_ldb_ch1>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
/* ... */
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mipi_lvds_0_phy: phy@56228300 {
|
||||
compatible = "fsl,imx8qxp-mipi-dphy";
|
||||
reg = <0x56228300 0x100>;
|
||||
clocks = <&clk IMX_SC_R_LVDS_0 IMX_SC_PM_CLK_PHY>;
|
||||
clock-names = "phy_ref";
|
||||
#phy-cells = <0>;
|
||||
fsl,syscon = <&mipi_lvds_0_csr>;
|
||||
power-domains = <&pd IMX_SC_R_MIPI_0>;
|
||||
};
|
104
Documentation/devicetree/bindings/phy/qcom,hdmi-phy-other.yaml
Normal file
104
Documentation/devicetree/bindings/phy/qcom,hdmi-phy-other.yaml
Normal file
@ -0,0 +1,104 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
|
||||
$id: http://devicetree.org/schemas/phy/qcom,hdmi-phy-other.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Adreno/Snapdragon HDMI phy
|
||||
|
||||
maintainers:
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,hdmi-phy-8660
|
||||
- qcom,hdmi-phy-8960
|
||||
- qcom,hdmi-phy-8974
|
||||
- qcom,hdmi-phy-8084
|
||||
|
||||
reg:
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: hdmi_phy
|
||||
- const: hdmi_pll
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
core-vdda-supply:
|
||||
description: phandle to VDDA supply regulator
|
||||
|
||||
vddio-supply:
|
||||
description: phandle to VDD I/O supply regulator
|
||||
|
||||
'#phy-cells':
|
||||
const: 0
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,hdmi-phy-8660
|
||||
- qcom,hdmi-phy-8960
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 1
|
||||
clock-names:
|
||||
items:
|
||||
- const: slave_iface
|
||||
vddio-supply: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,hdmi-phy-8084
|
||||
- qcom,hdmi-phy-8974
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 2
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: alt_iface
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- reg
|
||||
- reg-names
|
||||
- '#phy-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
hdmi_phy: phy@4a00400 {
|
||||
compatible = "qcom,hdmi-phy-8960";
|
||||
reg-names = "hdmi_phy",
|
||||
"hdmi_pll";
|
||||
reg = <0x4a00400 0x60>,
|
||||
<0x4a00500 0x100>;
|
||||
#phy-cells = <0>;
|
||||
power-domains = <&mmcc 1>;
|
||||
clock-names = "slave_iface";
|
||||
clocks = <&clk 21>;
|
||||
core-vdda-supply = <&pm8921_hdmi_mvs>;
|
||||
};
|
85
Documentation/devicetree/bindings/phy/qcom,hdmi-phy-qmp.yaml
Normal file
85
Documentation/devicetree/bindings/phy/qcom,hdmi-phy-qmp.yaml
Normal file
@ -0,0 +1,85 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
|
||||
$id: http://devicetree.org/schemas/phy/qcom,hdmi-phy-qmp.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Adreno/Snapdragon QMP HDMI phy
|
||||
|
||||
maintainers:
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,hdmi-phy-8996
|
||||
|
||||
reg:
|
||||
maxItems: 6
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: hdmi_pll
|
||||
- const: hdmi_tx_l0
|
||||
- const: hdmi_tx_l1
|
||||
- const: hdmi_tx_l2
|
||||
- const: hdmi_tx_l3
|
||||
- const: hdmi_phy
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: ref
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
vcca-supply:
|
||||
description: phandle to VCCA supply regulator
|
||||
|
||||
vddio-supply:
|
||||
description: phandle to VDD I/O supply regulator
|
||||
|
||||
'#phy-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
- reg-names
|
||||
- '#phy-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
hdmi-phy@9a0600 {
|
||||
compatible = "qcom,hdmi-phy-8996";
|
||||
reg = <0x009a0600 0x1c4>,
|
||||
<0x009a0a00 0x124>,
|
||||
<0x009a0c00 0x124>,
|
||||
<0x009a0e00 0x124>,
|
||||
<0x009a1000 0x124>,
|
||||
<0x009a1200 0x0c8>;
|
||||
reg-names = "hdmi_pll",
|
||||
"hdmi_tx_l0",
|
||||
"hdmi_tx_l1",
|
||||
"hdmi_tx_l2",
|
||||
"hdmi_tx_l3",
|
||||
"hdmi_phy";
|
||||
|
||||
clocks = <&mmcc 116>,
|
||||
<&gcc 214>;
|
||||
clock-names = "iface",
|
||||
"ref";
|
||||
#phy-cells = <0>;
|
||||
|
||||
vddio-supply = <&vreg_l12a_1p8>;
|
||||
vcca-supply = <&vreg_l28a_0p925>;
|
||||
};
|
@ -8,7 +8,6 @@ title: Samsung Exynos SoC HDMI PHY
|
||||
|
||||
maintainers:
|
||||
- Inki Dae <inki.dae@samsung.com>
|
||||
- Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
- Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
- Kyungmin Park <kyungmin.park@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
@ -1,59 +0,0 @@
|
||||
Device tree binding for NVIDIA Tegra DPAUX pad controller
|
||||
========================================================
|
||||
|
||||
The Tegra Display Port Auxiliary (DPAUX) pad controller manages two pins
|
||||
which can be assigned to either the DPAUX channel or to an I2C
|
||||
controller.
|
||||
|
||||
This document defines the device-specific binding for the DPAUX pad
|
||||
controller. Refer to pinctrl-bindings.txt in this directory for generic
|
||||
information about pin controller device tree bindings. Please refer to
|
||||
the binding document ../display/tegra/nvidia,tegra20-host1x.txt for more
|
||||
details on the DPAUX binding.
|
||||
|
||||
Pin muxing:
|
||||
-----------
|
||||
|
||||
Child nodes contain the pinmux configurations following the conventions
|
||||
from the pinctrl-bindings.txt document.
|
||||
|
||||
Since only three configurations are possible, only three child nodes are
|
||||
needed to describe the pin mux'ing options for the DPAUX pads.
|
||||
Furthermore, given that the pad functions are only applicable to a
|
||||
single set of pads, the child nodes only need to describe the pad group
|
||||
the functions are being applied to rather than the individual pads.
|
||||
|
||||
Required properties:
|
||||
- groups: Must be "dpaux-io"
|
||||
- function: Must be either "aux", "i2c" or "off".
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
dpaux@545c0000 {
|
||||
...
|
||||
|
||||
state_dpaux_aux: pinmux-aux {
|
||||
groups = "dpaux-io";
|
||||
function = "aux";
|
||||
};
|
||||
|
||||
state_dpaux_i2c: pinmux-i2c {
|
||||
groups = "dpaux-io";
|
||||
function = "i2c";
|
||||
};
|
||||
|
||||
state_dpaux_off: pinmux-off {
|
||||
groups = "dpaux-io";
|
||||
function = "off";
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
i2c@7000d100 {
|
||||
...
|
||||
pinctrl-0 = <&state_dpaux_i2c>;
|
||||
pinctrl-1 = <&state_dpaux_off>;
|
||||
pinctrl-names = "default", "idle";
|
||||
};
|
@ -350,6 +350,8 @@ patternProperties:
|
||||
description: Embedded Artists AB
|
||||
"^ebang,.*":
|
||||
description: Zhejiang Ebang Communication Co., Ltd
|
||||
"^ebbg,.*":
|
||||
description: EBBG
|
||||
"^ebs-systart,.*":
|
||||
description: EBS-SYSTART GmbH
|
||||
"^ebv,.*":
|
||||
|
13
Documentation/driver-api/aperture.rst
Normal file
13
Documentation/driver-api/aperture.rst
Normal file
@ -0,0 +1,13 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Managing Ownership of the Framebuffer Aperture
|
||||
==============================================
|
||||
|
||||
.. kernel-doc:: drivers/video/aperture.c
|
||||
:doc: overview
|
||||
|
||||
.. kernel-doc:: include/linux/aperture.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/video/aperture.c
|
||||
:export:
|
@ -27,6 +27,7 @@ available subsections can be seen below.
|
||||
component
|
||||
message-based
|
||||
infiniband
|
||||
aperture
|
||||
frame-buffer
|
||||
regulator
|
||||
reset
|
||||
|
@ -75,7 +75,7 @@ we have a dedicated glossary for Display Core at
|
||||
PSP
|
||||
Platform Security Processor
|
||||
|
||||
RCL
|
||||
RLC
|
||||
RunList Controller
|
||||
|
||||
SDMA
|
||||
|
@ -63,3 +63,44 @@ gpu_metrics
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/pm/amdgpu_pm.c
|
||||
:doc: gpu_metrics
|
||||
|
||||
GFXOFF
|
||||
======
|
||||
|
||||
GFXOFF is a feature found in most recent GPUs that saves power at runtime. The
|
||||
card's RLC (RunList Controller) firmware powers off the gfx engine
|
||||
dynamically when there is no workload on gfx or compute pipes. GFXOFF is on by
|
||||
default on supported GPUs.
|
||||
|
||||
Userspace can interact with GFXOFF through a debugfs interface:
|
||||
|
||||
``amdgpu_gfxoff``
|
||||
-----------------
|
||||
|
||||
Use it to enable/disable GFXOFF, and to check if it's current enabled/disabled::
|
||||
|
||||
$ xxd -l1 -p /sys/kernel/debug/dri/0/amdgpu_gfxoff
|
||||
01
|
||||
|
||||
- Write 0 to disable it, and 1 to enable it.
|
||||
- Read 0 means it's disabled, 1 it's enabled.
|
||||
|
||||
If it's enabled, that means that the GPU is free to enter into GFXOFF mode as
|
||||
needed. Disabled means that it will never enter GFXOFF mode.
|
||||
|
||||
``amdgpu_gfxoff_status``
|
||||
------------------------
|
||||
|
||||
Read it to check current GFXOFF's status of a GPU::
|
||||
|
||||
$ xxd -l1 -p /sys/kernel/debug/dri/0/amdgpu_gfxoff_status
|
||||
02
|
||||
|
||||
- 0: GPU is in GFXOFF state, the gfx engine is powered down.
|
||||
- 1: Transition out of GFXOFF state
|
||||
- 2: Not in GFXOFF state
|
||||
- 3: Transition into GFXOFF state
|
||||
|
||||
If GFXOFF is enabled, the value will be transitioning around [0, 3], always
|
||||
getting into 0 when possible. When it's disabled, it's always at 2. Returns
|
||||
``-EINVAL`` if it's not supported.
|
||||
|
@ -207,6 +207,38 @@ Utilities
|
||||
:internal:
|
||||
|
||||
|
||||
Unit testing
|
||||
============
|
||||
|
||||
KUnit
|
||||
-----
|
||||
|
||||
KUnit (Kernel unit testing framework) provides a common framework for unit tests
|
||||
within the Linux kernel.
|
||||
|
||||
This section covers the specifics for the DRM subsystem. For general information
|
||||
about KUnit, please refer to Documentation/dev-tools/kunit/start.rst.
|
||||
|
||||
How to run the tests?
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In order to facilitate running the test suite, a configuration file is present
|
||||
in ``drivers/gpu/drm/tests/.kunitconfig``. It can be used by ``kunit.py`` as
|
||||
follows:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/tests \
|
||||
--kconfig_add CONFIG_VIRTIO_UML=y \
|
||||
--kconfig_add CONFIG_UML_PCI_OVER_VIRTIO=y
|
||||
|
||||
.. note::
|
||||
The configuration included in ``.kunitconfig`` should be as generic as
|
||||
possible.
|
||||
``CONFIG_VIRTIO_UML`` and ``CONFIG_UML_PCI_OVER_VIRTIO`` are not
|
||||
included in it because they are only required for User Mode Linux.
|
||||
|
||||
|
||||
Legacy Support Code
|
||||
===================
|
||||
|
||||
|
@ -105,6 +105,27 @@ object belong to this client, in the respective memory region.
|
||||
Default unit shall be bytes with optional unit specifiers of 'KiB' or 'MiB'
|
||||
indicating kibi- or mebi-bytes.
|
||||
|
||||
- drm-cycles-<str> <uint>
|
||||
|
||||
Engine identifier string must be the same as the one specified in the
|
||||
drm-engine-<str> tag and shall contain the number of busy cycles for the given
|
||||
engine.
|
||||
|
||||
Values are not required to be constantly monotonic if it makes the driver
|
||||
implementation easier, but are required to catch up with the previously reported
|
||||
larger value within a reasonable period. Upon observing a value lower than what
|
||||
was previously read, userspace is expected to stay with that larger previous
|
||||
value until a monotonic update is seen.
|
||||
|
||||
- drm-maxfreq-<str> <uint> [Hz|MHz|KHz]
|
||||
|
||||
Engine identifier string must be the same as the one specified in the
|
||||
drm-engine-<str> tag and shall contain the maximum frequency for the given
|
||||
engine. Taken together with drm-cycles-<str>, this can be used to calculate
|
||||
percentage utilization of the engine, whereas drm-engine-<str> only reflects
|
||||
time active without considering what frequency the engine is operating as a
|
||||
percentage of it's maximum frequency.
|
||||
|
||||
===============================
|
||||
Driver specific implementations
|
||||
===============================
|
||||
|
@ -246,6 +246,18 @@ Display State Buffer
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dsb.c
|
||||
:internal:
|
||||
|
||||
GT Programming
|
||||
==============
|
||||
|
||||
Multicast/Replicated (MCR) Registers
|
||||
------------------------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_gt_mcr.c
|
||||
:doc: GT Multicast/Replicated (MCR) Register Support
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_gt_mcr.c
|
||||
:internal:
|
||||
|
||||
Memory Management and Command Submission
|
||||
========================================
|
||||
|
||||
|
189
Documentation/gpu/rfc/i915_small_bar.h
Normal file
189
Documentation/gpu/rfc/i915_small_bar.h
Normal file
@ -0,0 +1,189 @@
|
||||
/**
|
||||
* struct __drm_i915_memory_region_info - Describes one region as known to the
|
||||
* driver.
|
||||
*
|
||||
* Note this is using both struct drm_i915_query_item and struct drm_i915_query.
|
||||
* For this new query we are adding the new query id DRM_I915_QUERY_MEMORY_REGIONS
|
||||
* at &drm_i915_query_item.query_id.
|
||||
*/
|
||||
struct __drm_i915_memory_region_info {
|
||||
/** @region: The class:instance pair encoding */
|
||||
struct drm_i915_gem_memory_class_instance region;
|
||||
|
||||
/** @rsvd0: MBZ */
|
||||
__u32 rsvd0;
|
||||
|
||||
/**
|
||||
* @probed_size: Memory probed by the driver
|
||||
*
|
||||
* Note that it should not be possible to ever encounter a zero value
|
||||
* here, also note that no current region type will ever return -1 here.
|
||||
* Although for future region types, this might be a possibility. The
|
||||
* same applies to the other size fields.
|
||||
*/
|
||||
__u64 probed_size;
|
||||
|
||||
/**
|
||||
* @unallocated_size: Estimate of memory remaining
|
||||
*
|
||||
* Requires CAP_PERFMON or CAP_SYS_ADMIN to get reliable accounting.
|
||||
* Without this (or if this is an older kernel) the value here will
|
||||
* always equal the @probed_size. Note this is only currently tracked
|
||||
* for I915_MEMORY_CLASS_DEVICE regions (for other types the value here
|
||||
* will always equal the @probed_size).
|
||||
*/
|
||||
__u64 unallocated_size;
|
||||
|
||||
union {
|
||||
/** @rsvd1: MBZ */
|
||||
__u64 rsvd1[8];
|
||||
struct {
|
||||
/**
|
||||
* @probed_cpu_visible_size: Memory probed by the driver
|
||||
* that is CPU accessible.
|
||||
*
|
||||
* This will be always be <= @probed_size, and the
|
||||
* remainder (if there is any) will not be CPU
|
||||
* accessible.
|
||||
*
|
||||
* On systems without small BAR, the @probed_size will
|
||||
* always equal the @probed_cpu_visible_size, since all
|
||||
* of it will be CPU accessible.
|
||||
*
|
||||
* Note this is only tracked for
|
||||
* I915_MEMORY_CLASS_DEVICE regions (for other types the
|
||||
* value here will always equal the @probed_size).
|
||||
*
|
||||
* Note that if the value returned here is zero, then
|
||||
* this must be an old kernel which lacks the relevant
|
||||
* small-bar uAPI support (including
|
||||
* I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS), but on
|
||||
* such systems we should never actually end up with a
|
||||
* small BAR configuration, assuming we are able to load
|
||||
* the kernel module. Hence it should be safe to treat
|
||||
* this the same as when @probed_cpu_visible_size ==
|
||||
* @probed_size.
|
||||
*/
|
||||
__u64 probed_cpu_visible_size;
|
||||
|
||||
/**
|
||||
* @unallocated_cpu_visible_size: Estimate of CPU
|
||||
* visible memory remaining
|
||||
*
|
||||
* Note this is only tracked for
|
||||
* I915_MEMORY_CLASS_DEVICE regions (for other types the
|
||||
* value here will always equal the
|
||||
* @probed_cpu_visible_size).
|
||||
*
|
||||
* Requires CAP_PERFMON or CAP_SYS_ADMIN to get reliable
|
||||
* accounting. Without this the value here will always
|
||||
* equal the @probed_cpu_visible_size. Note this is only
|
||||
* currently tracked for I915_MEMORY_CLASS_DEVICE
|
||||
* regions (for other types the value here will also
|
||||
* always equal the @probed_cpu_visible_size).
|
||||
*
|
||||
* If this is an older kernel the value here will be
|
||||
* zero, see also @probed_cpu_visible_size.
|
||||
*/
|
||||
__u64 unallocated_cpu_visible_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* struct __drm_i915_gem_create_ext - Existing gem_create behaviour, with added
|
||||
* extension support using struct i915_user_extension.
|
||||
*
|
||||
* Note that new buffer flags should be added here, at least for the stuff that
|
||||
* is immutable. Previously we would have two ioctls, one to create the object
|
||||
* with gem_create, and another to apply various parameters, however this
|
||||
* creates some ambiguity for the params which are considered immutable. Also in
|
||||
* general we're phasing out the various SET/GET ioctls.
|
||||
*/
|
||||
struct __drm_i915_gem_create_ext {
|
||||
/**
|
||||
* @size: Requested size for the object.
|
||||
*
|
||||
* The (page-aligned) allocated size for the object will be returned.
|
||||
*
|
||||
* Note that for some devices we have might have further minimum
|
||||
* page-size restrictions (larger than 4K), like for device local-memory.
|
||||
* However in general the final size here should always reflect any
|
||||
* rounding up, if for example using the I915_GEM_CREATE_EXT_MEMORY_REGIONS
|
||||
* extension to place the object in device local-memory. The kernel will
|
||||
* always select the largest minimum page-size for the set of possible
|
||||
* placements as the value to use when rounding up the @size.
|
||||
*/
|
||||
__u64 size;
|
||||
|
||||
/**
|
||||
* @handle: Returned handle for the object.
|
||||
*
|
||||
* Object handles are nonzero.
|
||||
*/
|
||||
__u32 handle;
|
||||
|
||||
/**
|
||||
* @flags: Optional flags.
|
||||
*
|
||||
* Supported values:
|
||||
*
|
||||
* I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS - Signal to the kernel that
|
||||
* the object will need to be accessed via the CPU.
|
||||
*
|
||||
* Only valid when placing objects in I915_MEMORY_CLASS_DEVICE, and only
|
||||
* strictly required on configurations where some subset of the device
|
||||
* memory is directly visible/mappable through the CPU (which we also
|
||||
* call small BAR), like on some DG2+ systems. Note that this is quite
|
||||
* undesirable, but due to various factors like the client CPU, BIOS etc
|
||||
* it's something we can expect to see in the wild. See
|
||||
* &__drm_i915_memory_region_info.probed_cpu_visible_size for how to
|
||||
* determine if this system applies.
|
||||
*
|
||||
* Note that one of the placements MUST be I915_MEMORY_CLASS_SYSTEM, to
|
||||
* ensure the kernel can always spill the allocation to system memory,
|
||||
* if the object can't be allocated in the mappable part of
|
||||
* I915_MEMORY_CLASS_DEVICE.
|
||||
*
|
||||
* Also note that since the kernel only supports flat-CCS on objects
|
||||
* that can *only* be placed in I915_MEMORY_CLASS_DEVICE, we therefore
|
||||
* don't support I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS together with
|
||||
* flat-CCS.
|
||||
*
|
||||
* Without this hint, the kernel will assume that non-mappable
|
||||
* I915_MEMORY_CLASS_DEVICE is preferred for this object. Note that the
|
||||
* kernel can still migrate the object to the mappable part, as a last
|
||||
* resort, if userspace ever CPU faults this object, but this might be
|
||||
* expensive, and so ideally should be avoided.
|
||||
*
|
||||
* On older kernels which lack the relevant small-bar uAPI support (see
|
||||
* also &__drm_i915_memory_region_info.probed_cpu_visible_size),
|
||||
* usage of the flag will result in an error, but it should NEVER be
|
||||
* possible to end up with a small BAR configuration, assuming we can
|
||||
* also successfully load the i915 kernel module. In such cases the
|
||||
* entire I915_MEMORY_CLASS_DEVICE region will be CPU accessible, and as
|
||||
* such there are zero restrictions on where the object can be placed.
|
||||
*/
|
||||
#define I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS (1 << 0)
|
||||
__u32 flags;
|
||||
|
||||
/**
|
||||
* @extensions: The chain of extensions to apply to this object.
|
||||
*
|
||||
* This will be useful in the future when we need to support several
|
||||
* different extensions, and we need to apply more than one when
|
||||
* creating the object. See struct i915_user_extension.
|
||||
*
|
||||
* If we don't supply any extensions then we get the same old gem_create
|
||||
* behaviour.
|
||||
*
|
||||
* For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
|
||||
* struct drm_i915_gem_create_ext_memory_regions.
|
||||
*
|
||||
* For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
|
||||
* struct drm_i915_gem_create_ext_protected_content.
|
||||
*/
|
||||
#define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
|
||||
#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
|
||||
__u64 extensions;
|
||||
};
|
47
Documentation/gpu/rfc/i915_small_bar.rst
Normal file
47
Documentation/gpu/rfc/i915_small_bar.rst
Normal file
@ -0,0 +1,47 @@
|
||||
==========================
|
||||
I915 Small BAR RFC Section
|
||||
==========================
|
||||
Starting from DG2 we will have resizable BAR support for device local-memory(i.e
|
||||
I915_MEMORY_CLASS_DEVICE), but in some cases the final BAR size might still be
|
||||
smaller than the total probed_size. In such cases, only some subset of
|
||||
I915_MEMORY_CLASS_DEVICE will be CPU accessible(for example the first 256M),
|
||||
while the remainder is only accessible via the GPU.
|
||||
|
||||
I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS flag
|
||||
----------------------------------------------
|
||||
New gem_create_ext flag to tell the kernel that a BO will require CPU access.
|
||||
This becomes important when placing an object in I915_MEMORY_CLASS_DEVICE, where
|
||||
underneath the device has a small BAR, meaning only some portion of it is CPU
|
||||
accessible. Without this flag the kernel will assume that CPU access is not
|
||||
required, and prioritize using the non-CPU visible portion of
|
||||
I915_MEMORY_CLASS_DEVICE.
|
||||
|
||||
.. kernel-doc:: Documentation/gpu/rfc/i915_small_bar.h
|
||||
:functions: __drm_i915_gem_create_ext
|
||||
|
||||
probed_cpu_visible_size attribute
|
||||
---------------------------------
|
||||
New struct__drm_i915_memory_region attribute which returns the total size of the
|
||||
CPU accessible portion, for the particular region. This should only be
|
||||
applicable for I915_MEMORY_CLASS_DEVICE. We also report the
|
||||
unallocated_cpu_visible_size, alongside the unallocated_size.
|
||||
|
||||
Vulkan will need this as part of creating a separate VkMemoryHeap with the
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set, to represent the CPU visible portion,
|
||||
where the total size of the heap needs to be known. It also wants to be able to
|
||||
give a rough estimate of how memory can potentially be allocated.
|
||||
|
||||
.. kernel-doc:: Documentation/gpu/rfc/i915_small_bar.h
|
||||
:functions: __drm_i915_memory_region_info
|
||||
|
||||
Error Capture restrictions
|
||||
--------------------------
|
||||
With error capture we have two new restrictions:
|
||||
|
||||
1) Error capture is best effort on small BAR systems; if the pages are not
|
||||
CPU accessible, at the time of capture, then the kernel is free to skip
|
||||
trying to capture them.
|
||||
|
||||
2) On discrete and newer integrated platforms we now reject error capture
|
||||
on recoverable contexts. In the future the kernel may want to blit during
|
||||
error capture, when for example something is not currently CPU accessible.
|
291
Documentation/gpu/rfc/i915_vm_bind.h
Normal file
291
Documentation/gpu/rfc/i915_vm_bind.h
Normal file
@ -0,0 +1,291 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: I915_PARAM_VM_BIND_VERSION
|
||||
*
|
||||
* VM_BIND feature version supported.
|
||||
* See typedef drm_i915_getparam_t param.
|
||||
*
|
||||
* Specifies the VM_BIND feature version supported.
|
||||
* The following versions of VM_BIND have been defined:
|
||||
*
|
||||
* 0: No VM_BIND support.
|
||||
*
|
||||
* 1: In VM_UNBIND calls, the UMD must specify the exact mappings created
|
||||
* previously with VM_BIND, the ioctl will not support unbinding multiple
|
||||
* mappings or splitting them. Similarly, VM_BIND calls will not replace
|
||||
* any existing mappings.
|
||||
*
|
||||
* 2: The restrictions on unbinding partial or multiple mappings is
|
||||
* lifted, Similarly, binding will replace any mappings in the given range.
|
||||
*
|
||||
* See struct drm_i915_gem_vm_bind and struct drm_i915_gem_vm_unbind.
|
||||
*/
|
||||
#define I915_PARAM_VM_BIND_VERSION 57
|
||||
|
||||
/**
|
||||
* DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
|
||||
*
|
||||
* Flag to opt-in for VM_BIND mode of binding during VM creation.
|
||||
* See struct drm_i915_gem_vm_control flags.
|
||||
*
|
||||
* The older execbuf2 ioctl will not support VM_BIND mode of operation.
|
||||
* For VM_BIND mode, we have new execbuf3 ioctl which will not accept any
|
||||
* execlist (See struct drm_i915_gem_execbuffer3 for more details).
|
||||
*/
|
||||
#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0)
|
||||
|
||||
/* VM_BIND related ioctls */
|
||||
#define DRM_I915_GEM_VM_BIND 0x3d
|
||||
#define DRM_I915_GEM_VM_UNBIND 0x3e
|
||||
#define DRM_I915_GEM_EXECBUFFER3 0x3f
|
||||
|
||||
#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
|
||||
#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
|
||||
#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3)
|
||||
|
||||
/**
|
||||
* struct drm_i915_gem_timeline_fence - An input or output timeline fence.
|
||||
*
|
||||
* The operation will wait for input fence to signal.
|
||||
*
|
||||
* The returned output fence will be signaled after the completion of the
|
||||
* operation.
|
||||
*/
|
||||
struct drm_i915_gem_timeline_fence {
|
||||
/** @handle: User's handle for a drm_syncobj to wait on or signal. */
|
||||
__u32 handle;
|
||||
|
||||
/**
|
||||
* @flags: Supported flags are:
|
||||
*
|
||||
* I915_TIMELINE_FENCE_WAIT:
|
||||
* Wait for the input fence before the operation.
|
||||
*
|
||||
* I915_TIMELINE_FENCE_SIGNAL:
|
||||
* Return operation completion fence as output.
|
||||
*/
|
||||
__u32 flags;
|
||||
#define I915_TIMELINE_FENCE_WAIT (1 << 0)
|
||||
#define I915_TIMELINE_FENCE_SIGNAL (1 << 1)
|
||||
#define __I915_TIMELINE_FENCE_UNKNOWN_FLAGS (-(I915_TIMELINE_FENCE_SIGNAL << 1))
|
||||
|
||||
/**
|
||||
* @value: A point in the timeline.
|
||||
* Value must be 0 for a binary drm_syncobj. A Value of 0 for a
|
||||
* timeline drm_syncobj is invalid as it turns a drm_syncobj into a
|
||||
* binary one.
|
||||
*/
|
||||
__u64 value;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_i915_gem_vm_bind - VA to object mapping to bind.
|
||||
*
|
||||
* This structure is passed to VM_BIND ioctl and specifies the mapping of GPU
|
||||
* virtual address (VA) range to the section of an object that should be bound
|
||||
* in the device page table of the specified address space (VM).
|
||||
* The VA range specified must be unique (ie., not currently bound) and can
|
||||
* be mapped to whole object or a section of the object (partial binding).
|
||||
* Multiple VA mappings can be created to the same section of the object
|
||||
* (aliasing).
|
||||
*
|
||||
* The @start, @offset and @length must be 4K page aligned. However the DG2
|
||||
* and XEHPSDV has 64K page size for device local memory and has compact page
|
||||
* table. On those platforms, for binding device local-memory objects, the
|
||||
* @start, @offset and @length must be 64K aligned. Also, UMDs should not mix
|
||||
* the local memory 64K page and the system memory 4K page bindings in the same
|
||||
* 2M range.
|
||||
*
|
||||
* Error code -EINVAL will be returned if @start, @offset and @length are not
|
||||
* properly aligned. In version 1 (See I915_PARAM_VM_BIND_VERSION), error code
|
||||
* -ENOSPC will be returned if the VA range specified can't be reserved.
|
||||
*
|
||||
* VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently
|
||||
* are not ordered. Furthermore, parts of the VM_BIND operation can be done
|
||||
* asynchronously, if valid @fence is specified.
|
||||
*/
|
||||
struct drm_i915_gem_vm_bind {
|
||||
/** @vm_id: VM (address space) id to bind */
|
||||
__u32 vm_id;
|
||||
|
||||
/** @handle: Object handle */
|
||||
__u32 handle;
|
||||
|
||||
/** @start: Virtual Address start to bind */
|
||||
__u64 start;
|
||||
|
||||
/** @offset: Offset in object to bind */
|
||||
__u64 offset;
|
||||
|
||||
/** @length: Length of mapping to bind */
|
||||
__u64 length;
|
||||
|
||||
/**
|
||||
* @flags: Supported flags are:
|
||||
*
|
||||
* I915_GEM_VM_BIND_CAPTURE:
|
||||
* Capture this mapping in the dump upon GPU error.
|
||||
*
|
||||
* Note that @fence carries its own flags.
|
||||
*/
|
||||
__u64 flags;
|
||||
#define I915_GEM_VM_BIND_CAPTURE (1 << 0)
|
||||
|
||||
/**
|
||||
* @fence: Timeline fence for bind completion signaling.
|
||||
*
|
||||
* Timeline fence is of format struct drm_i915_gem_timeline_fence.
|
||||
*
|
||||
* It is an out fence, hence using I915_TIMELINE_FENCE_WAIT flag
|
||||
* is invalid, and an error will be returned.
|
||||
*
|
||||
* If I915_TIMELINE_FENCE_SIGNAL flag is not set, then out fence
|
||||
* is not requested and binding is completed synchronously.
|
||||
*/
|
||||
struct drm_i915_gem_timeline_fence fence;
|
||||
|
||||
/**
|
||||
* @extensions: Zero-terminated chain of extensions.
|
||||
*
|
||||
* For future extensions. See struct i915_user_extension.
|
||||
*/
|
||||
__u64 extensions;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_i915_gem_vm_unbind - VA to object mapping to unbind.
|
||||
*
|
||||
* This structure is passed to VM_UNBIND ioctl and specifies the GPU virtual
|
||||
* address (VA) range that should be unbound from the device page table of the
|
||||
* specified address space (VM). VM_UNBIND will force unbind the specified
|
||||
* range from device page table without waiting for any GPU job to complete.
|
||||
* It is UMDs responsibility to ensure the mapping is no longer in use before
|
||||
* calling VM_UNBIND.
|
||||
*
|
||||
* If the specified mapping is not found, the ioctl will simply return without
|
||||
* any error.
|
||||
*
|
||||
* VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently
|
||||
* are not ordered. Furthermore, parts of the VM_UNBIND operation can be done
|
||||
* asynchronously, if valid @fence is specified.
|
||||
*/
|
||||
struct drm_i915_gem_vm_unbind {
|
||||
/** @vm_id: VM (address space) id to bind */
|
||||
__u32 vm_id;
|
||||
|
||||
/** @rsvd: Reserved, MBZ */
|
||||
__u32 rsvd;
|
||||
|
||||
/** @start: Virtual Address start to unbind */
|
||||
__u64 start;
|
||||
|
||||
/** @length: Length of mapping to unbind */
|
||||
__u64 length;
|
||||
|
||||
/**
|
||||
* @flags: Currently reserved, MBZ.
|
||||
*
|
||||
* Note that @fence carries its own flags.
|
||||
*/
|
||||
__u64 flags;
|
||||
|
||||
/**
|
||||
* @fence: Timeline fence for unbind completion signaling.
|
||||
*
|
||||
* Timeline fence is of format struct drm_i915_gem_timeline_fence.
|
||||
*
|
||||
* It is an out fence, hence using I915_TIMELINE_FENCE_WAIT flag
|
||||
* is invalid, and an error will be returned.
|
||||
*
|
||||
* If I915_TIMELINE_FENCE_SIGNAL flag is not set, then out fence
|
||||
* is not requested and unbinding is completed synchronously.
|
||||
*/
|
||||
struct drm_i915_gem_timeline_fence fence;
|
||||
|
||||
/**
|
||||
* @extensions: Zero-terminated chain of extensions.
|
||||
*
|
||||
* For future extensions. See struct i915_user_extension.
|
||||
*/
|
||||
__u64 extensions;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_i915_gem_execbuffer3 - Structure for DRM_I915_GEM_EXECBUFFER3
|
||||
* ioctl.
|
||||
*
|
||||
* DRM_I915_GEM_EXECBUFFER3 ioctl only works in VM_BIND mode and VM_BIND mode
|
||||
* only works with this ioctl for submission.
|
||||
* See I915_VM_CREATE_FLAGS_USE_VM_BIND.
|
||||
*/
|
||||
struct drm_i915_gem_execbuffer3 {
|
||||
/**
|
||||
* @ctx_id: Context id
|
||||
*
|
||||
* Only contexts with user engine map are allowed.
|
||||
*/
|
||||
__u32 ctx_id;
|
||||
|
||||
/**
|
||||
* @engine_idx: Engine index
|
||||
*
|
||||
* An index in the user engine map of the context specified by @ctx_id.
|
||||
*/
|
||||
__u32 engine_idx;
|
||||
|
||||
/**
|
||||
* @batch_address: Batch gpu virtual address/es.
|
||||
*
|
||||
* For normal submission, it is the gpu virtual address of the batch
|
||||
* buffer. For parallel submission, it is a pointer to an array of
|
||||
* batch buffer gpu virtual addresses with array size equal to the
|
||||
* number of (parallel) engines involved in that submission (See
|
||||
* struct i915_context_engines_parallel_submit).
|
||||
*/
|
||||
__u64 batch_address;
|
||||
|
||||
/** @flags: Currently reserved, MBZ */
|
||||
__u64 flags;
|
||||
|
||||
/** @rsvd1: Reserved, MBZ */
|
||||
__u32 rsvd1;
|
||||
|
||||
/** @fence_count: Number of fences in @timeline_fences array. */
|
||||
__u32 fence_count;
|
||||
|
||||
/**
|
||||
* @timeline_fences: Pointer to an array of timeline fences.
|
||||
*
|
||||
* Timeline fences are of format struct drm_i915_gem_timeline_fence.
|
||||
*/
|
||||
__u64 timeline_fences;
|
||||
|
||||
/** @rsvd2: Reserved, MBZ */
|
||||
__u64 rsvd2;
|
||||
|
||||
/**
|
||||
* @extensions: Zero-terminated chain of extensions.
|
||||
*
|
||||
* For future extensions. See struct i915_user_extension.
|
||||
*/
|
||||
__u64 extensions;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_i915_gem_create_ext_vm_private - Extension to make the object
|
||||
* private to the specified VM.
|
||||
*
|
||||
* See struct drm_i915_gem_create_ext.
|
||||
*/
|
||||
struct drm_i915_gem_create_ext_vm_private {
|
||||
#define I915_GEM_CREATE_EXT_VM_PRIVATE 2
|
||||
/** @base: Extension link. See struct i915_user_extension. */
|
||||
struct i915_user_extension base;
|
||||
|
||||
/** @vm_id: Id of the VM to which the object is private */
|
||||
__u32 vm_id;
|
||||
};
|
245
Documentation/gpu/rfc/i915_vm_bind.rst
Normal file
245
Documentation/gpu/rfc/i915_vm_bind.rst
Normal file
@ -0,0 +1,245 @@
|
||||
==========================================
|
||||
I915 VM_BIND feature design and use cases
|
||||
==========================================
|
||||
|
||||
VM_BIND feature
|
||||
================
|
||||
DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer
|
||||
objects (BOs) or sections of a BOs at specified GPU virtual addresses on a
|
||||
specified address space (VM). These mappings (also referred to as persistent
|
||||
mappings) will be persistent across multiple GPU submissions (execbuf calls)
|
||||
issued by the UMD, without user having to provide a list of all required
|
||||
mappings during each submission (as required by older execbuf mode).
|
||||
|
||||
The VM_BIND/UNBIND calls allow UMDs to request a timeline out fence for
|
||||
signaling the completion of bind/unbind operation.
|
||||
|
||||
VM_BIND feature is advertised to user via I915_PARAM_VM_BIND_VERSION.
|
||||
User has to opt-in for VM_BIND mode of binding for an address space (VM)
|
||||
during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension.
|
||||
|
||||
VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently are
|
||||
not ordered. Furthermore, parts of the VM_BIND/UNBIND operations can be done
|
||||
asynchronously, when valid out fence is specified.
|
||||
|
||||
VM_BIND features include:
|
||||
|
||||
* Multiple Virtual Address (VA) mappings can map to the same physical pages
|
||||
of an object (aliasing).
|
||||
* VA mapping can map to a partial section of the BO (partial binding).
|
||||
* Support capture of persistent mappings in the dump upon GPU error.
|
||||
* Support for userptr gem objects (no special uapi is required for this).
|
||||
|
||||
TLB flush consideration
|
||||
------------------------
|
||||
The i915 driver flushes the TLB for each submission and when an object's
|
||||
pages are released. The VM_BIND/UNBIND operation will not do any additional
|
||||
TLB flush. Any VM_BIND mapping added will be in the working set for subsequent
|
||||
submissions on that VM and will not be in the working set for currently running
|
||||
batches (which would require additional TLB flushes, which is not supported).
|
||||
|
||||
Execbuf ioctl in VM_BIND mode
|
||||
-------------------------------
|
||||
A VM in VM_BIND mode will not support older execbuf mode of binding.
|
||||
The execbuf ioctl handling in VM_BIND mode differs significantly from the
|
||||
older execbuf2 ioctl (See struct drm_i915_gem_execbuffer2).
|
||||
Hence, a new execbuf3 ioctl has been added to support VM_BIND mode. (See
|
||||
struct drm_i915_gem_execbuffer3). The execbuf3 ioctl will not accept any
|
||||
execlist. Hence, no support for implicit sync. It is expected that the below
|
||||
work will be able to support requirements of object dependency setting in all
|
||||
use cases:
|
||||
|
||||
"dma-buf: Add an API for exporting sync files"
|
||||
(https://lwn.net/Articles/859290/)
|
||||
|
||||
The new execbuf3 ioctl only works in VM_BIND mode and the VM_BIND mode only
|
||||
works with execbuf3 ioctl for submission. All BOs mapped on that VM (through
|
||||
VM_BIND call) at the time of execbuf3 call are deemed required for that
|
||||
submission.
|
||||
|
||||
The execbuf3 ioctl directly specifies the batch addresses instead of as
|
||||
object handles as in execbuf2 ioctl. The execbuf3 ioctl will also not
|
||||
support many of the older features like in/out/submit fences, fence array,
|
||||
default gem context and many more (See struct drm_i915_gem_execbuffer3).
|
||||
|
||||
In VM_BIND mode, VA allocation is completely managed by the user instead of
|
||||
the i915 driver. Hence all VA assignment, eviction are not applicable in
|
||||
VM_BIND mode. Also, for determining object activeness, VM_BIND mode will not
|
||||
be using the i915_vma active reference tracking. It will instead use dma-resv
|
||||
object for that (See `VM_BIND dma_resv usage`_).
|
||||
|
||||
So, a lot of existing code supporting execbuf2 ioctl, like relocations, VA
|
||||
evictions, vma lookup table, implicit sync, vma active reference tracking etc.,
|
||||
are not applicable for execbuf3 ioctl. Hence, all execbuf3 specific handling
|
||||
should be in a separate file and only functionalities common to these ioctls
|
||||
can be the shared code where possible.
|
||||
|
||||
VM_PRIVATE objects
|
||||
-------------------
|
||||
By default, BOs can be mapped on multiple VMs and can also be dma-buf
|
||||
exported. Hence these BOs are referred to as Shared BOs.
|
||||
During each execbuf submission, the request fence must be added to the
|
||||
dma-resv fence list of all shared BOs mapped on the VM.
|
||||
|
||||
VM_BIND feature introduces an optimization where user can create BO which
|
||||
is private to a specified VM via I915_GEM_CREATE_EXT_VM_PRIVATE flag during
|
||||
BO creation. Unlike Shared BOs, these VM private BOs can only be mapped on
|
||||
the VM they are private to and can't be dma-buf exported.
|
||||
All private BOs of a VM share the dma-resv object. Hence during each execbuf
|
||||
submission, they need only one dma-resv fence list updated. Thus, the fast
|
||||
path (where required mappings are already bound) submission latency is O(1)
|
||||
w.r.t the number of VM private BOs.
|
||||
|
||||
VM_BIND locking hirarchy
|
||||
-------------------------
|
||||
The locking design here supports the older (execlist based) execbuf mode, the
|
||||
newer VM_BIND mode, the VM_BIND mode with GPU page faults and possible future
|
||||
system allocator support (See `Shared Virtual Memory (SVM) support`_).
|
||||
The older execbuf mode and the newer VM_BIND mode without page faults manages
|
||||
residency of backing storage using dma_fence. The VM_BIND mode with page faults
|
||||
and the system allocator support do not use any dma_fence at all.
|
||||
|
||||
VM_BIND locking order is as below.
|
||||
|
||||
1) Lock-A: A vm_bind mutex will protect vm_bind lists. This lock is taken in
|
||||
vm_bind/vm_unbind ioctl calls, in the execbuf path and while releasing the
|
||||
mapping.
|
||||
|
||||
In future, when GPU page faults are supported, we can potentially use a
|
||||
rwsem instead, so that multiple page fault handlers can take the read side
|
||||
lock to lookup the mapping and hence can run in parallel.
|
||||
The older execbuf mode of binding do not need this lock.
|
||||
|
||||
2) Lock-B: The object's dma-resv lock will protect i915_vma state and needs to
|
||||
be held while binding/unbinding a vma in the async worker and while updating
|
||||
dma-resv fence list of an object. Note that private BOs of a VM will all
|
||||
share a dma-resv object.
|
||||
|
||||
The future system allocator support will use the HMM prescribed locking
|
||||
instead.
|
||||
|
||||
3) Lock-C: Spinlock/s to protect some of the VM's lists like the list of
|
||||
invalidated vmas (due to eviction and userptr invalidation) etc.
|
||||
|
||||
When GPU page faults are supported, the execbuf path do not take any of these
|
||||
locks. There we will simply smash the new batch buffer address into the ring and
|
||||
then tell the scheduler run that. The lock taking only happens from the page
|
||||
fault handler, where we take lock-A in read mode, whichever lock-B we need to
|
||||
find the backing storage (dma_resv lock for gem objects, and hmm/core mm for
|
||||
system allocator) and some additional locks (lock-D) for taking care of page
|
||||
table races. Page fault mode should not need to ever manipulate the vm lists,
|
||||
so won't ever need lock-C.
|
||||
|
||||
VM_BIND LRU handling
|
||||
---------------------
|
||||
We need to ensure VM_BIND mapped objects are properly LRU tagged to avoid
|
||||
performance degradation. We will also need support for bulk LRU movement of
|
||||
VM_BIND objects to avoid additional latencies in execbuf path.
|
||||
|
||||
The page table pages are similar to VM_BIND mapped objects (See
|
||||
`Evictable page table allocations`_) and are maintained per VM and needs to
|
||||
be pinned in memory when VM is made active (ie., upon an execbuf call with
|
||||
that VM). So, bulk LRU movement of page table pages is also needed.
|
||||
|
||||
VM_BIND dma_resv usage
|
||||
-----------------------
|
||||
Fences needs to be added to all VM_BIND mapped objects. During each execbuf
|
||||
submission, they are added with DMA_RESV_USAGE_BOOKKEEP usage to prevent
|
||||
over sync (See enum dma_resv_usage). One can override it with either
|
||||
DMA_RESV_USAGE_READ or DMA_RESV_USAGE_WRITE usage during explicit object
|
||||
dependency setting.
|
||||
|
||||
Note that DRM_I915_GEM_WAIT and DRM_I915_GEM_BUSY ioctls do not check for
|
||||
DMA_RESV_USAGE_BOOKKEEP usage and hence should not be used for end of batch
|
||||
check. Instead, the execbuf3 out fence should be used for end of batch check
|
||||
(See struct drm_i915_gem_execbuffer3).
|
||||
|
||||
Also, in VM_BIND mode, use dma-resv apis for determining object activeness
|
||||
(See dma_resv_test_signaled() and dma_resv_wait_timeout()) and do not use the
|
||||
older i915_vma active reference tracking which is deprecated. This should be
|
||||
easier to get it working with the current TTM backend.
|
||||
|
||||
Mesa use case
|
||||
--------------
|
||||
VM_BIND can potentially reduce the CPU overhead in Mesa (both Vulkan and Iris),
|
||||
hence improving performance of CPU-bound applications. It also allows us to
|
||||
implement Vulkan's Sparse Resources. With increasing GPU hardware performance,
|
||||
reducing CPU overhead becomes more impactful.
|
||||
|
||||
|
||||
Other VM_BIND use cases
|
||||
========================
|
||||
|
||||
Long running Compute contexts
|
||||
------------------------------
|
||||
Usage of dma-fence expects that they complete in reasonable amount of time.
|
||||
Compute on the other hand can be long running. Hence it is appropriate for
|
||||
compute to use user/memory fence (See `User/Memory Fence`_) and dma-fence usage
|
||||
must be limited to in-kernel consumption only.
|
||||
|
||||
Where GPU page faults are not available, kernel driver upon buffer invalidation
|
||||
will initiate a suspend (preemption) of long running context, finish the
|
||||
invalidation, revalidate the BO and then resume the compute context. This is
|
||||
done by having a per-context preempt fence which is enabled when someone tries
|
||||
to wait on it and triggers the context preemption.
|
||||
|
||||
User/Memory Fence
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
User/Memory fence is a <address, value> pair. To signal the user fence, the
|
||||
specified value will be written at the specified virtual address and wakeup the
|
||||
waiting process. User fence can be signaled either by the GPU or kernel async
|
||||
worker (like upon bind completion). User can wait on a user fence with a new
|
||||
user fence wait ioctl.
|
||||
|
||||
Here is some prior work on this:
|
||||
https://patchwork.freedesktop.org/patch/349417/
|
||||
|
||||
Low Latency Submission
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Allows compute UMD to directly submit GPU jobs instead of through execbuf
|
||||
ioctl. This is made possible by VM_BIND is not being synchronized against
|
||||
execbuf. VM_BIND allows bind/unbind of mappings required for the directly
|
||||
submitted jobs.
|
||||
|
||||
Debugger
|
||||
---------
|
||||
With debug event interface user space process (debugger) is able to keep track
|
||||
of and act upon resources created by another process (debugged) and attached
|
||||
to GPU via vm_bind interface.
|
||||
|
||||
GPU page faults
|
||||
----------------
|
||||
GPU page faults when supported (in future), will only be supported in the
|
||||
VM_BIND mode. While both the older execbuf mode and the newer VM_BIND mode of
|
||||
binding will require using dma-fence to ensure residency, the GPU page faults
|
||||
mode when supported, will not use any dma-fence as residency is purely managed
|
||||
by installing and removing/invalidating page table entries.
|
||||
|
||||
Page level hints settings
|
||||
--------------------------
|
||||
VM_BIND allows any hints setting per mapping instead of per BO. Possible hints
|
||||
include placement and atomicity. Sub-BO level placement hint will be even more
|
||||
relevant with upcoming GPU on-demand page fault support.
|
||||
|
||||
Page level Cache/CLOS settings
|
||||
-------------------------------
|
||||
VM_BIND allows cache/CLOS settings per mapping instead of per BO.
|
||||
|
||||
Evictable page table allocations
|
||||
---------------------------------
|
||||
Make pagetable allocations evictable and manage them similar to VM_BIND
|
||||
mapped objects. Page table pages are similar to persistent mappings of a
|
||||
VM (difference here are that the page table pages will not have an i915_vma
|
||||
structure and after swapping pages back in, parent page link needs to be
|
||||
updated).
|
||||
|
||||
Shared Virtual Memory (SVM) support
|
||||
------------------------------------
|
||||
VM_BIND interface can be used to map system memory directly (without gem BO
|
||||
abstraction) using the HMM interface. SVM is only supported with GPU page
|
||||
faults enabled.
|
||||
|
||||
VM_BIND UAPI
|
||||
=============
|
||||
|
||||
.. kernel-doc:: Documentation/gpu/rfc/i915_vm_bind.h
|
@ -23,3 +23,11 @@ host such documentation:
|
||||
.. toctree::
|
||||
|
||||
i915_scheduler.rst
|
||||
|
||||
.. toctree::
|
||||
|
||||
i915_small_bar.rst
|
||||
|
||||
.. toctree::
|
||||
|
||||
i915_vm_bind.rst
|
||||
|
@ -617,6 +617,17 @@ Contact: Javier Martinez Canillas <javierm@redhat.com>
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Convert Kernel Selftests (kselftest) to KUnit tests when appropriate
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Many of the `Kselftest <https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html>`_
|
||||
tests in DRM could be converted to Kunit tests instead, since that framework
|
||||
is more suitable for unit testing.
|
||||
|
||||
Contact: Javier Martinez Canillas <javierm@redhat.com>
|
||||
|
||||
Level: Starter
|
||||
|
||||
Enable trinity for DRM
|
||||
----------------------
|
||||
|
||||
|
@ -102,12 +102,6 @@ Debugging:
|
||||
|
||||
- kms_plane: some test cases are failing due to timeout on capturing CRC;
|
||||
|
||||
- kms_flip: when running test cases in sequence, some successful individual
|
||||
test cases are failing randomly; when individually, some successful test
|
||||
cases display in the log the following error::
|
||||
|
||||
[drm:vkms_prepare_fb [vkms]] ERROR vmap failed: -4
|
||||
|
||||
Virtual hardware (vblank-less) mode:
|
||||
|
||||
- VKMS already has support for vblanks simulated via hrtimers, which can be
|
||||
|
@ -1492,6 +1492,80 @@ The following tables list existing packed RGB formats.
|
||||
- b\ :sub:`2`
|
||||
- b\ :sub:`1`
|
||||
- b\ :sub:`0`
|
||||
* .. _MEDIA-BUS-FMT-RGB666-1X30-CPADLO:
|
||||
|
||||
- MEDIA_BUS_FMT_RGB666_1X30-CPADLO
|
||||
- 0x101e
|
||||
-
|
||||
-
|
||||
-
|
||||
- r\ :sub:`5`
|
||||
- r\ :sub:`4`
|
||||
- r\ :sub:`3`
|
||||
- r\ :sub:`2`
|
||||
- r\ :sub:`1`
|
||||
- r\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- g\ :sub:`5`
|
||||
- g\ :sub:`4`
|
||||
- g\ :sub:`3`
|
||||
- g\ :sub:`2`
|
||||
- g\ :sub:`1`
|
||||
- g\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- b\ :sub:`5`
|
||||
- b\ :sub:`4`
|
||||
- b\ :sub:`3`
|
||||
- b\ :sub:`2`
|
||||
- b\ :sub:`1`
|
||||
- b\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
* .. _MEDIA-BUS-FMT-RGB888-1X30-CPADLO:
|
||||
|
||||
- MEDIA_BUS_FMT_RGB888_1X30-CPADLO
|
||||
- 0x101f
|
||||
-
|
||||
-
|
||||
-
|
||||
- r\ :sub:`7`
|
||||
- r\ :sub:`6`
|
||||
- r\ :sub:`5`
|
||||
- r\ :sub:`4`
|
||||
- r\ :sub:`3`
|
||||
- r\ :sub:`2`
|
||||
- r\ :sub:`1`
|
||||
- r\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- g\ :sub:`7`
|
||||
- g\ :sub:`6`
|
||||
- g\ :sub:`5`
|
||||
- g\ :sub:`4`
|
||||
- g\ :sub:`3`
|
||||
- g\ :sub:`2`
|
||||
- g\ :sub:`1`
|
||||
- g\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- b\ :sub:`7`
|
||||
- b\ :sub:`6`
|
||||
- b\ :sub:`5`
|
||||
- b\ :sub:`4`
|
||||
- b\ :sub:`3`
|
||||
- b\ :sub:`2`
|
||||
- b\ :sub:`1`
|
||||
- b\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
* .. _MEDIA-BUS-FMT-ARGB888-1X32:
|
||||
|
||||
- MEDIA_BUS_FMT_ARGB888_1X32
|
||||
@ -1669,6 +1743,88 @@ The following table list existing packed 36bit wide RGB formats.
|
||||
- 2
|
||||
- 1
|
||||
- 0
|
||||
* .. _MEDIA-BUS-FMT-RGB666-1X36-CPADLO:
|
||||
|
||||
- MEDIA_BUS_FMT_RGB666_1X36_CPADLO
|
||||
- 0x1020
|
||||
-
|
||||
- r\ :sub:`5`
|
||||
- r\ :sub:`4`
|
||||
- r\ :sub:`3`
|
||||
- r\ :sub:`2`
|
||||
- r\ :sub:`1`
|
||||
- r\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- g\ :sub:`5`
|
||||
- g\ :sub:`4`
|
||||
- g\ :sub:`3`
|
||||
- g\ :sub:`2`
|
||||
- g\ :sub:`1`
|
||||
- g\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- b\ :sub:`5`
|
||||
- b\ :sub:`4`
|
||||
- b\ :sub:`3`
|
||||
- b\ :sub:`2`
|
||||
- b\ :sub:`1`
|
||||
- b\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
* .. _MEDIA-BUS-FMT-RGB888-1X36-CPADLO:
|
||||
|
||||
- MEDIA_BUS_FMT_RGB888_1X36_CPADLO
|
||||
- 0x1021
|
||||
-
|
||||
- r\ :sub:`7`
|
||||
- r\ :sub:`6`
|
||||
- r\ :sub:`5`
|
||||
- r\ :sub:`4`
|
||||
- r\ :sub:`3`
|
||||
- r\ :sub:`2`
|
||||
- r\ :sub:`1`
|
||||
- r\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- g\ :sub:`7`
|
||||
- g\ :sub:`6`
|
||||
- g\ :sub:`5`
|
||||
- g\ :sub:`4`
|
||||
- g\ :sub:`3`
|
||||
- g\ :sub:`2`
|
||||
- g\ :sub:`1`
|
||||
- g\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- b\ :sub:`7`
|
||||
- b\ :sub:`6`
|
||||
- b\ :sub:`5`
|
||||
- b\ :sub:`4`
|
||||
- b\ :sub:`3`
|
||||
- b\ :sub:`2`
|
||||
- b\ :sub:`1`
|
||||
- b\ :sub:`0`
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
* .. _MEDIA-BUS-FMT-RGB121212-1X36:
|
||||
|
||||
- MEDIA_BUS_FMT_RGB121212_1X36
|
||||
|
38
MAINTAINERS
38
MAINTAINERS
@ -6369,6 +6369,13 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml
|
||||
F: drivers/gpu/drm/bridge/chipone-icn6211.c
|
||||
|
||||
DRM DRIVER FOR EBBG FT8719 PANEL
|
||||
M: Joel Selvaraj <jo@jsfamily.in>
|
||||
S: Maintained
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
F: Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml
|
||||
F: drivers/gpu/drm/panel/panel-ebbg-ft8719.c
|
||||
|
||||
DRM DRIVER FOR FARADAY TVE200 TV ENCODER
|
||||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
S: Maintained
|
||||
@ -6427,6 +6434,12 @@ S: Orphan / Obsolete
|
||||
F: drivers/gpu/drm/i810/
|
||||
F: include/uapi/drm/i810_drm.h
|
||||
|
||||
DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER
|
||||
M: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
||||
S: Supported
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
F: drivers/gpu/drm/logicvc/
|
||||
|
||||
DRM DRIVER FOR LVDS PANELS
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
@ -6603,12 +6616,17 @@ S: Orphan / Obsolete
|
||||
F: drivers/gpu/drm/savage/
|
||||
F: include/uapi/drm/savage_drm.h
|
||||
|
||||
DRM DRIVER FOR SIMPLE FRAMEBUFFERS
|
||||
DRM DRIVER FOR FIRMWARE FRAMEBUFFERS
|
||||
M: Thomas Zimmermann <tzimmermann@suse.de>
|
||||
M: Javier Martinez Canillas <javierm@redhat.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
F: drivers/gpu/drm/drm_aperture.c
|
||||
F: drivers/gpu/drm/tiny/simpledrm.c
|
||||
F: drivers/video/aperture.c
|
||||
F: include/drm/drm_aperture.h
|
||||
F: include/linux/aperture.h
|
||||
|
||||
DRM DRIVER FOR SIS VIDEO CARDS
|
||||
S: Orphan / Obsolete
|
||||
@ -6646,6 +6664,12 @@ DRM DRIVER FOR TDFX VIDEO CARDS
|
||||
S: Orphan / Obsolete
|
||||
F: drivers/gpu/drm/tdfx/
|
||||
|
||||
DRM DRIVER FOR TI DLPC3433 MIPI DSI TO DMD BRIDGE
|
||||
M: Jagan Teki <jagan@amarulasolutions.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml
|
||||
F: drivers/gpu/drm/bridge/ti-dlpc3433.c
|
||||
|
||||
DRM DRIVER FOR TI SN65DSI86 BRIDGE CHIP
|
||||
R: Douglas Anderson <dianders@chromium.org>
|
||||
F: Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml
|
||||
@ -6775,7 +6799,6 @@ F: drivers/gpu/drm/bridge/
|
||||
|
||||
DRM DRIVERS FOR EXYNOS
|
||||
M: Inki Dae <inki.dae@samsung.com>
|
||||
M: Joonyoung Shim <jy0922.shim@samsung.com>
|
||||
M: Seung-Woo Kim <sw0312.kim@samsung.com>
|
||||
M: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
@ -6804,6 +6827,16 @@ F: Documentation/devicetree/bindings/display/imx/
|
||||
F: drivers/gpu/drm/imx/
|
||||
F: drivers/gpu/ipu-v3/
|
||||
|
||||
DRM DRIVERS FOR FREESCALE IMX BRIDGE
|
||||
M: Liu Ying <victor.liu@nxp.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-ldb.yaml
|
||||
F: Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-pixel-combiner.yaml
|
||||
F: Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-pixel-link.yaml
|
||||
F: Documentation/devicetree/bindings/display/bridge/fsl,imx8qxp-pxl2dpi.yaml
|
||||
F: drivers/gpu/drm/bridge/imx/
|
||||
|
||||
DRM DRIVERS FOR GMA500 (Poulsbo, Moorestown and derivative chipsets)
|
||||
M: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
@ -6934,6 +6967,7 @@ F: drivers/gpu/drm/omapdrm/
|
||||
|
||||
DRM DRIVERS FOR V3D
|
||||
M: Emma Anholt <emma@anholt.net>
|
||||
M: Melissa Wen <mwen@igalia.com>
|
||||
S: Supported
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
F: Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
|
||||
|
@ -744,7 +744,7 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry,
|
||||
writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
|
||||
}
|
||||
|
||||
bool intel_enable_gtt(void)
|
||||
bool intel_gmch_enable_gtt(void)
|
||||
{
|
||||
u8 __iomem *reg;
|
||||
|
||||
@ -787,7 +787,7 @@ bool intel_enable_gtt(void)
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(intel_enable_gtt);
|
||||
EXPORT_SYMBOL(intel_gmch_enable_gtt);
|
||||
|
||||
static int i830_setup(void)
|
||||
{
|
||||
@ -821,8 +821,8 @@ static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge)
|
||||
|
||||
static int intel_fake_agp_configure(void)
|
||||
{
|
||||
if (!intel_enable_gtt())
|
||||
return -EIO;
|
||||
if (!intel_gmch_enable_gtt())
|
||||
return -EIO;
|
||||
|
||||
intel_private.clear_fake_agp = true;
|
||||
agp_bridge->gart_bus_addr = intel_private.gma_bus_addr;
|
||||
@ -844,20 +844,20 @@ static bool i830_check_flags(unsigned int flags)
|
||||
return false;
|
||||
}
|
||||
|
||||
void intel_gtt_insert_page(dma_addr_t addr,
|
||||
unsigned int pg,
|
||||
unsigned int flags)
|
||||
void intel_gmch_gtt_insert_page(dma_addr_t addr,
|
||||
unsigned int pg,
|
||||
unsigned int flags)
|
||||
{
|
||||
intel_private.driver->write_entry(addr, pg, flags);
|
||||
readl(intel_private.gtt + pg);
|
||||
if (intel_private.driver->chipset_flush)
|
||||
intel_private.driver->chipset_flush();
|
||||
}
|
||||
EXPORT_SYMBOL(intel_gtt_insert_page);
|
||||
EXPORT_SYMBOL(intel_gmch_gtt_insert_page);
|
||||
|
||||
void intel_gtt_insert_sg_entries(struct sg_table *st,
|
||||
unsigned int pg_start,
|
||||
unsigned int flags)
|
||||
void intel_gmch_gtt_insert_sg_entries(struct sg_table *st,
|
||||
unsigned int pg_start,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
unsigned int len, m;
|
||||
@ -879,13 +879,13 @@ void intel_gtt_insert_sg_entries(struct sg_table *st,
|
||||
if (intel_private.driver->chipset_flush)
|
||||
intel_private.driver->chipset_flush();
|
||||
}
|
||||
EXPORT_SYMBOL(intel_gtt_insert_sg_entries);
|
||||
EXPORT_SYMBOL(intel_gmch_gtt_insert_sg_entries);
|
||||
|
||||
#if IS_ENABLED(CONFIG_AGP_INTEL)
|
||||
static void intel_gtt_insert_pages(unsigned int first_entry,
|
||||
unsigned int num_entries,
|
||||
struct page **pages,
|
||||
unsigned int flags)
|
||||
static void intel_gmch_gtt_insert_pages(unsigned int first_entry,
|
||||
unsigned int num_entries,
|
||||
struct page **pages,
|
||||
unsigned int flags)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
@ -905,7 +905,7 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
|
||||
if (intel_private.clear_fake_agp) {
|
||||
int start = intel_private.stolen_size / PAGE_SIZE;
|
||||
int end = intel_private.gtt_mappable_entries;
|
||||
intel_gtt_clear_range(start, end - start);
|
||||
intel_gmch_gtt_clear_range(start, end - start);
|
||||
intel_private.clear_fake_agp = false;
|
||||
}
|
||||
|
||||
@ -934,12 +934,12 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
intel_gtt_insert_sg_entries(&st, pg_start, type);
|
||||
intel_gmch_gtt_insert_sg_entries(&st, pg_start, type);
|
||||
mem->sg_list = st.sgl;
|
||||
mem->num_sg = st.nents;
|
||||
} else
|
||||
intel_gtt_insert_pages(pg_start, mem->page_count, mem->pages,
|
||||
type);
|
||||
intel_gmch_gtt_insert_pages(pg_start, mem->page_count, mem->pages,
|
||||
type);
|
||||
|
||||
out:
|
||||
ret = 0;
|
||||
@ -949,7 +949,7 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
|
||||
}
|
||||
#endif
|
||||
|
||||
void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
|
||||
void intel_gmch_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -959,7 +959,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
|
||||
}
|
||||
wmb();
|
||||
}
|
||||
EXPORT_SYMBOL(intel_gtt_clear_range);
|
||||
EXPORT_SYMBOL(intel_gmch_gtt_clear_range);
|
||||
|
||||
#if IS_ENABLED(CONFIG_AGP_INTEL)
|
||||
static int intel_fake_agp_remove_entries(struct agp_memory *mem,
|
||||
@ -968,7 +968,7 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem,
|
||||
if (mem->page_count == 0)
|
||||
return 0;
|
||||
|
||||
intel_gtt_clear_range(pg_start, mem->page_count);
|
||||
intel_gmch_gtt_clear_range(pg_start, mem->page_count);
|
||||
|
||||
if (intel_private.needs_dmar) {
|
||||
intel_gtt_unmap_memory(mem->sg_list, mem->num_sg);
|
||||
@ -1431,22 +1431,22 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
|
||||
}
|
||||
EXPORT_SYMBOL(intel_gmch_probe);
|
||||
|
||||
void intel_gtt_get(u64 *gtt_total,
|
||||
phys_addr_t *mappable_base,
|
||||
resource_size_t *mappable_end)
|
||||
void intel_gmch_gtt_get(u64 *gtt_total,
|
||||
phys_addr_t *mappable_base,
|
||||
resource_size_t *mappable_end)
|
||||
{
|
||||
*gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT;
|
||||
*mappable_base = intel_private.gma_bus_addr;
|
||||
*mappable_end = intel_private.gtt_mappable_entries << PAGE_SHIFT;
|
||||
}
|
||||
EXPORT_SYMBOL(intel_gtt_get);
|
||||
EXPORT_SYMBOL(intel_gmch_gtt_get);
|
||||
|
||||
void intel_gtt_chipset_flush(void)
|
||||
void intel_gmch_gtt_flush(void)
|
||||
{
|
||||
if (intel_private.driver->chipset_flush)
|
||||
intel_private.driver->chipset_flush();
|
||||
}
|
||||
EXPORT_SYMBOL(intel_gtt_chipset_flush);
|
||||
EXPORT_SYMBOL(intel_gmch_gtt_flush);
|
||||
|
||||
void intel_gmch_remove(void)
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ menuconfig DMABUF_HEAPS
|
||||
between drivers.
|
||||
|
||||
menuconfig DMABUF_SYSFS_STATS
|
||||
bool "DMA-BUF sysfs statistics"
|
||||
bool "DMA-BUF sysfs statistics (DEPRECATED)"
|
||||
depends on DMA_SHARED_BUFFER
|
||||
help
|
||||
Choose this option to enable DMA-BUF sysfs statistics
|
||||
@ -85,6 +85,10 @@ menuconfig DMABUF_SYSFS_STATS
|
||||
statistics for the DMA-BUF with the unique inode number
|
||||
<inode_number>.
|
||||
|
||||
This option is deprecated and should sooner or later be removed.
|
||||
Android is the only user of this and it turned out that this resulted
|
||||
in quite some performance problems.
|
||||
|
||||
source "drivers/dma-buf/heaps/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
|
||||
dma-resv.o
|
||||
dma-fence-unwrap.o dma-resv.o
|
||||
obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
|
||||
obj-$(CONFIG_DMABUF_HEAPS) += heaps/
|
||||
obj-$(CONFIG_SYNC_FILE) += sync_file.o
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/sync_file.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/dma-resv.h>
|
||||
#include <linux/mm.h>
|
||||
@ -192,6 +193,9 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)
|
||||
* Note that this only signals the completion of the respective fences, i.e. the
|
||||
* DMA transfers are complete. Cache flushing and any other necessary
|
||||
* preparations before CPU access can begin still need to happen.
|
||||
*
|
||||
* As an alternative to poll(), the set of fences on DMA buffer can be
|
||||
* exported as a &sync_file using &dma_buf_sync_file_export.
|
||||
*/
|
||||
|
||||
static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
|
||||
@ -326,6 +330,101 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SYNC_FILE)
|
||||
static long dma_buf_export_sync_file(struct dma_buf *dmabuf,
|
||||
void __user *user_data)
|
||||
{
|
||||
struct dma_buf_export_sync_file arg;
|
||||
enum dma_resv_usage usage;
|
||||
struct dma_fence *fence = NULL;
|
||||
struct sync_file *sync_file;
|
||||
int fd, ret;
|
||||
|
||||
if (copy_from_user(&arg, user_data, sizeof(arg)))
|
||||
return -EFAULT;
|
||||
|
||||
if (arg.flags & ~DMA_BUF_SYNC_RW)
|
||||
return -EINVAL;
|
||||
|
||||
if ((arg.flags & DMA_BUF_SYNC_RW) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
fd = get_unused_fd_flags(O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
usage = dma_resv_usage_rw(arg.flags & DMA_BUF_SYNC_WRITE);
|
||||
ret = dma_resv_get_singleton(dmabuf->resv, usage, &fence);
|
||||
if (ret)
|
||||
goto err_put_fd;
|
||||
|
||||
if (!fence)
|
||||
fence = dma_fence_get_stub();
|
||||
|
||||
sync_file = sync_file_create(fence);
|
||||
|
||||
dma_fence_put(fence);
|
||||
|
||||
if (!sync_file) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put_fd;
|
||||
}
|
||||
|
||||
arg.fd = fd;
|
||||
if (copy_to_user(user_data, &arg, sizeof(arg))) {
|
||||
ret = -EFAULT;
|
||||
goto err_put_file;
|
||||
}
|
||||
|
||||
fd_install(fd, sync_file->file);
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_file:
|
||||
fput(sync_file->file);
|
||||
err_put_fd:
|
||||
put_unused_fd(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
|
||||
const void __user *user_data)
|
||||
{
|
||||
struct dma_buf_import_sync_file arg;
|
||||
struct dma_fence *fence;
|
||||
enum dma_resv_usage usage;
|
||||
int ret = 0;
|
||||
|
||||
if (copy_from_user(&arg, user_data, sizeof(arg)))
|
||||
return -EFAULT;
|
||||
|
||||
if (arg.flags & ~DMA_BUF_SYNC_RW)
|
||||
return -EINVAL;
|
||||
|
||||
if ((arg.flags & DMA_BUF_SYNC_RW) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
fence = sync_file_get_fence(arg.fd);
|
||||
if (!fence)
|
||||
return -EINVAL;
|
||||
|
||||
usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE :
|
||||
DMA_RESV_USAGE_READ;
|
||||
|
||||
dma_resv_lock(dmabuf->resv, NULL);
|
||||
|
||||
ret = dma_resv_reserve_fences(dmabuf->resv, 1);
|
||||
if (!ret)
|
||||
dma_resv_add_fence(dmabuf->resv, fence, usage);
|
||||
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
|
||||
dma_fence_put(fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static long dma_buf_ioctl(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
@ -369,6 +468,13 @@ static long dma_buf_ioctl(struct file *file,
|
||||
case DMA_BUF_SET_NAME_B:
|
||||
return dma_buf_set_name(dmabuf, (const char __user *)arg);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SYNC_FILE)
|
||||
case DMA_BUF_IOCTL_EXPORT_SYNC_FILE:
|
||||
return dma_buf_export_sync_file(dmabuf, (void __user *)arg);
|
||||
case DMA_BUF_IOCTL_IMPORT_SYNC_FILE:
|
||||
return dma_buf_import_sync_file(dmabuf, (const void __user *)arg);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
@ -1358,7 +1464,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
|
||||
return ret;
|
||||
|
||||
seq_puts(s, "\nDma-buf Objects:\n");
|
||||
seq_printf(s, "%-8s\t%-8s\t%-8s\t%-8s\texp_name\t%-8s\n",
|
||||
seq_printf(s, "%-8s\t%-8s\t%-8s\t%-8s\texp_name\t%-8s\tname\n",
|
||||
"size", "flags", "mode", "count", "ino");
|
||||
|
||||
list_for_each_entry(buf_obj, &db_list.head, list_node) {
|
||||
@ -1375,7 +1481,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
|
||||
file_count(buf_obj->file),
|
||||
buf_obj->exp_name,
|
||||
file_inode(buf_obj->file)->i_ino,
|
||||
buf_obj->name ?: "");
|
||||
buf_obj->name ?: "<none>");
|
||||
spin_unlock(&buf_obj->name_lock);
|
||||
|
||||
dma_resv_describe(buf_obj->resv, s);
|
||||
|
@ -62,8 +62,8 @@ struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence)
|
||||
replacement = NULL;
|
||||
}
|
||||
|
||||
tmp = cmpxchg((struct dma_fence __force **)&chain->prev,
|
||||
prev, replacement);
|
||||
tmp = unrcu_pointer(cmpxchg(&chain->prev, RCU_INITIALIZER(prev),
|
||||
RCU_INITIALIZER(replacement)));
|
||||
if (tmp == prev)
|
||||
dma_fence_put(tmp);
|
||||
else
|
||||
|
163
drivers/dma-buf/dma-fence-unwrap.c
Normal file
163
drivers/dma-buf/dma-fence-unwrap.c
Normal file
@ -0,0 +1,163 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* dma-fence-util: misc functions for dma_fence objects
|
||||
*
|
||||
* Copyright (C) 2022 Advanced Micro Devices, Inc.
|
||||
* Authors:
|
||||
* Christian König <christian.koenig@amd.com>
|
||||
*/
|
||||
|
||||
#include <linux/dma-fence.h>
|
||||
#include <linux/dma-fence-array.h>
|
||||
#include <linux/dma-fence-chain.h>
|
||||
#include <linux/dma-fence-unwrap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* Internal helper to start new array iteration, don't use directly */
|
||||
static struct dma_fence *
|
||||
__dma_fence_unwrap_array(struct dma_fence_unwrap *cursor)
|
||||
{
|
||||
cursor->array = dma_fence_chain_contained(cursor->chain);
|
||||
cursor->index = 0;
|
||||
return dma_fence_array_first(cursor->array);
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_fence_unwrap_first - return the first fence from fence containers
|
||||
* @head: the entrypoint into the containers
|
||||
* @cursor: current position inside the containers
|
||||
*
|
||||
* Unwraps potential dma_fence_chain/dma_fence_array containers and return the
|
||||
* first fence.
|
||||
*/
|
||||
struct dma_fence *dma_fence_unwrap_first(struct dma_fence *head,
|
||||
struct dma_fence_unwrap *cursor)
|
||||
{
|
||||
cursor->chain = dma_fence_get(head);
|
||||
return __dma_fence_unwrap_array(cursor);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_fence_unwrap_first);
|
||||
|
||||
/**
|
||||
* dma_fence_unwrap_next - return the next fence from a fence containers
|
||||
* @cursor: current position inside the containers
|
||||
*
|
||||
* Continue unwrapping the dma_fence_chain/dma_fence_array containers and return
|
||||
* the next fence from them.
|
||||
*/
|
||||
struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor)
|
||||
{
|
||||
struct dma_fence *tmp;
|
||||
|
||||
++cursor->index;
|
||||
tmp = dma_fence_array_next(cursor->array, cursor->index);
|
||||
if (tmp)
|
||||
return tmp;
|
||||
|
||||
cursor->chain = dma_fence_chain_walk(cursor->chain);
|
||||
return __dma_fence_unwrap_array(cursor);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_fence_unwrap_next);
|
||||
|
||||
/* 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,
|
||||
struct dma_fence_unwrap *iter)
|
||||
{
|
||||
struct dma_fence_array *result;
|
||||
struct dma_fence *tmp, **array;
|
||||
unsigned int i;
|
||||
size_t count;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < num_fences; ++i) {
|
||||
dma_fence_unwrap_for_each(tmp, &iter[i], fences[i])
|
||||
if (!dma_fence_is_signaled(tmp))
|
||||
++count;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return dma_fence_get_stub();
|
||||
|
||||
array = kmalloc_array(count, sizeof(*array), GFP_KERNEL);
|
||||
if (!array)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* This trashes the input fence array and uses it as position for the
|
||||
* following merge loop. This works because the dma_fence_merge()
|
||||
* wrapper macro is creating this temporary array on the stack together
|
||||
* with the iterators.
|
||||
*/
|
||||
for (i = 0; i < num_fences; ++i)
|
||||
fences[i] = dma_fence_unwrap_first(fences[i], &iter[i]);
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
unsigned int sel;
|
||||
|
||||
restart:
|
||||
tmp = NULL;
|
||||
for (i = 0; i < num_fences; ++i) {
|
||||
struct dma_fence *next;
|
||||
|
||||
while (fences[i] && dma_fence_is_signaled(fences[i]))
|
||||
fences[i] = dma_fence_unwrap_next(&iter[i]);
|
||||
|
||||
next = fences[i];
|
||||
if (!next)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We can't guarantee that inpute fences are ordered by
|
||||
* context, but it is still quite likely when this
|
||||
* function is used multiple times. So attempt to order
|
||||
* the fences by context as we pass over them and merge
|
||||
* fences with the same context.
|
||||
*/
|
||||
if (!tmp || tmp->context > next->context) {
|
||||
tmp = next;
|
||||
sel = i;
|
||||
|
||||
} else if (tmp->context < next->context) {
|
||||
continue;
|
||||
|
||||
} else if (dma_fence_is_later(tmp, next)) {
|
||||
fences[i] = dma_fence_unwrap_next(&iter[i]);
|
||||
goto restart;
|
||||
} else {
|
||||
fences[sel] = dma_fence_unwrap_next(&iter[sel]);
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp) {
|
||||
array[count++] = dma_fence_get(tmp);
|
||||
fences[sel] = dma_fence_unwrap_next(&iter[sel]);
|
||||
}
|
||||
} while (tmp);
|
||||
|
||||
if (count == 0) {
|
||||
tmp = dma_fence_get_stub();
|
||||
goto return_tmp;
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
tmp = array[0];
|
||||
goto return_tmp;
|
||||
}
|
||||
|
||||
result = dma_fence_array_create(count, array,
|
||||
dma_fence_context_alloc(1),
|
||||
1, false);
|
||||
if (!result) {
|
||||
tmp = NULL;
|
||||
goto return_tmp;
|
||||
}
|
||||
return &result->base;
|
||||
|
||||
return_tmp:
|
||||
kfree(array);
|
||||
return tmp;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__dma_fence_unwrap_merge);
|
@ -4,27 +4,19 @@
|
||||
* Copyright (C) 2022 Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/dma-fence.h>
|
||||
#include <linux/dma-fence-array.h>
|
||||
#include <linux/dma-fence-chain.h>
|
||||
#include <linux/dma-fence-unwrap.h>
|
||||
#if 0
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/random.h>
|
||||
#endif
|
||||
|
||||
#include "selftest.h"
|
||||
|
||||
#define CHAIN_SZ (4 << 10)
|
||||
|
||||
static inline struct mock_fence {
|
||||
struct mock_fence {
|
||||
struct dma_fence base;
|
||||
spinlock_t lock;
|
||||
} *to_mock_fence(struct dma_fence *f) {
|
||||
return container_of(f, struct mock_fence, base);
|
||||
}
|
||||
};
|
||||
|
||||
static const char *mock_name(struct dma_fence *f)
|
||||
{
|
||||
@ -45,7 +37,8 @@ static struct dma_fence *mock_fence(void)
|
||||
return NULL;
|
||||
|
||||
spin_lock_init(&f->lock);
|
||||
dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0);
|
||||
dma_fence_init(&f->base, &mock_ops, &f->lock,
|
||||
dma_fence_context_alloc(1), 1);
|
||||
|
||||
return &f->base;
|
||||
}
|
||||
@ -59,7 +52,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...)
|
||||
|
||||
fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
|
||||
if (!fences)
|
||||
return NULL;
|
||||
goto error_put;
|
||||
|
||||
va_start(valist, num_fences);
|
||||
for (i = 0; i < num_fences; ++i)
|
||||
@ -70,13 +63,17 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...)
|
||||
dma_fence_context_alloc(1),
|
||||
1, false);
|
||||
if (!array)
|
||||
goto cleanup;
|
||||
goto error_free;
|
||||
return &array->base;
|
||||
|
||||
cleanup:
|
||||
for (i = 0; i < num_fences; ++i)
|
||||
dma_fence_put(fences[i]);
|
||||
error_free:
|
||||
kfree(fences);
|
||||
|
||||
error_put:
|
||||
va_start(valist, num_fences);
|
||||
for (i = 0; i < num_fences; ++i)
|
||||
dma_fence_put(va_arg(valist, typeof(*fences)));
|
||||
va_end(valist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -113,7 +110,6 @@ static int sanitycheck(void *arg)
|
||||
if (!chain)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_signal(f);
|
||||
dma_fence_put(chain);
|
||||
return err;
|
||||
}
|
||||
@ -154,10 +150,8 @@ static int unwrap_array(void *arg)
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
dma_fence_signal(f1);
|
||||
dma_fence_signal(f2);
|
||||
dma_fence_put(array);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int unwrap_chain(void *arg)
|
||||
@ -196,10 +190,8 @@ static int unwrap_chain(void *arg)
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
dma_fence_signal(f1);
|
||||
dma_fence_signal(f2);
|
||||
dma_fence_put(chain);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int unwrap_chain_array(void *arg)
|
||||
@ -242,10 +234,115 @@ static int unwrap_chain_array(void *arg)
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
dma_fence_signal(f1);
|
||||
dma_fence_signal(f2);
|
||||
dma_fence_put(chain);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int unwrap_merge(void *arg)
|
||||
{
|
||||
struct dma_fence *fence, *f1, *f2, *f3;
|
||||
struct dma_fence_unwrap iter;
|
||||
int err = 0;
|
||||
|
||||
f1 = mock_fence();
|
||||
if (!f1)
|
||||
return -ENOMEM;
|
||||
|
||||
f2 = mock_fence();
|
||||
if (!f2) {
|
||||
err = -ENOMEM;
|
||||
goto error_put_f1;
|
||||
}
|
||||
|
||||
f3 = dma_fence_unwrap_merge(f1, f2);
|
||||
if (!f3) {
|
||||
err = -ENOMEM;
|
||||
goto error_put_f2;
|
||||
}
|
||||
|
||||
dma_fence_unwrap_for_each(fence, &iter, f3) {
|
||||
if (fence == f1) {
|
||||
dma_fence_put(f1);
|
||||
f1 = NULL;
|
||||
} else if (fence == f2) {
|
||||
dma_fence_put(f2);
|
||||
f2 = NULL;
|
||||
} else {
|
||||
pr_err("Unexpected fence!\n");
|
||||
err = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (f1 || f2) {
|
||||
pr_err("Not all fences seen!\n");
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
dma_fence_put(f3);
|
||||
error_put_f2:
|
||||
dma_fence_put(f2);
|
||||
error_put_f1:
|
||||
dma_fence_put(f1);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int unwrap_merge_complex(void *arg)
|
||||
{
|
||||
struct dma_fence *fence, *f1, *f2, *f3, *f4, *f5;
|
||||
struct dma_fence_unwrap iter;
|
||||
int err = -ENOMEM;
|
||||
|
||||
f1 = mock_fence();
|
||||
if (!f1)
|
||||
return -ENOMEM;
|
||||
|
||||
f2 = mock_fence();
|
||||
if (!f2)
|
||||
goto error_put_f1;
|
||||
|
||||
f3 = dma_fence_unwrap_merge(f1, f2);
|
||||
if (!f3)
|
||||
goto error_put_f2;
|
||||
|
||||
/* The resulting array has the fences in reverse */
|
||||
f4 = dma_fence_unwrap_merge(f2, f1);
|
||||
if (!f4)
|
||||
goto error_put_f3;
|
||||
|
||||
/* Signaled fences should be filtered, the two arrays merged. */
|
||||
f5 = dma_fence_unwrap_merge(f3, f4, dma_fence_get_stub());
|
||||
if (!f5)
|
||||
goto error_put_f4;
|
||||
|
||||
err = 0;
|
||||
dma_fence_unwrap_for_each(fence, &iter, f5) {
|
||||
if (fence == f1) {
|
||||
dma_fence_put(f1);
|
||||
f1 = NULL;
|
||||
} else if (fence == f2) {
|
||||
dma_fence_put(f2);
|
||||
f2 = NULL;
|
||||
} else {
|
||||
pr_err("Unexpected fence!\n");
|
||||
err = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (f1 || f2) {
|
||||
pr_err("Not all fences seen!\n");
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
dma_fence_put(f5);
|
||||
error_put_f4:
|
||||
dma_fence_put(f4);
|
||||
error_put_f3:
|
||||
dma_fence_put(f3);
|
||||
error_put_f2:
|
||||
dma_fence_put(f2);
|
||||
error_put_f1:
|
||||
dma_fence_put(f1);
|
||||
return err;
|
||||
}
|
||||
|
||||
int dma_fence_unwrap(void)
|
||||
@ -255,6 +352,8 @@ int dma_fence_unwrap(void)
|
||||
SUBTEST(unwrap_array),
|
||||
SUBTEST(unwrap_chain),
|
||||
SUBTEST(unwrap_chain_array),
|
||||
SUBTEST(unwrap_merge),
|
||||
SUBTEST(unwrap_merge_complex),
|
||||
};
|
||||
|
||||
return subtests(tests, NULL);
|
||||
|
@ -146,50 +146,6 @@ char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int sync_file_set_fence(struct sync_file *sync_file,
|
||||
struct dma_fence **fences, int num_fences)
|
||||
{
|
||||
struct dma_fence_array *array;
|
||||
|
||||
/*
|
||||
* The reference for the fences in the new sync_file and held
|
||||
* in add_fence() during the merge procedure, so for num_fences == 1
|
||||
* we already own a new reference to the fence. For num_fence > 1
|
||||
* we own the reference of the dma_fence_array creation.
|
||||
*/
|
||||
|
||||
if (num_fences == 0) {
|
||||
sync_file->fence = dma_fence_get_stub();
|
||||
kfree(fences);
|
||||
|
||||
} else if (num_fences == 1) {
|
||||
sync_file->fence = fences[0];
|
||||
kfree(fences);
|
||||
|
||||
} else {
|
||||
array = dma_fence_array_create(num_fences, fences,
|
||||
dma_fence_context_alloc(1),
|
||||
1, false);
|
||||
if (!array)
|
||||
return -ENOMEM;
|
||||
|
||||
sync_file->fence = &array->base;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_fence(struct dma_fence **fences,
|
||||
int *i, struct dma_fence *fence)
|
||||
{
|
||||
fences[*i] = fence;
|
||||
|
||||
if (!dma_fence_is_signaled(fence)) {
|
||||
dma_fence_get(fence);
|
||||
(*i)++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sync_file_merge() - merge two sync_files
|
||||
* @name: name of new fence
|
||||
@ -203,84 +159,21 @@ static void add_fence(struct dma_fence **fences,
|
||||
static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
|
||||
struct sync_file *b)
|
||||
{
|
||||
struct dma_fence *a_fence, *b_fence, **fences;
|
||||
struct dma_fence_unwrap a_iter, b_iter;
|
||||
unsigned int index, num_fences;
|
||||
struct sync_file *sync_file;
|
||||
struct dma_fence *fence;
|
||||
|
||||
sync_file = sync_file_alloc();
|
||||
if (!sync_file)
|
||||
return NULL;
|
||||
|
||||
num_fences = 0;
|
||||
dma_fence_unwrap_for_each(a_fence, &a_iter, a->fence)
|
||||
++num_fences;
|
||||
dma_fence_unwrap_for_each(b_fence, &b_iter, b->fence)
|
||||
++num_fences;
|
||||
|
||||
if (num_fences > INT_MAX)
|
||||
goto err_free_sync_file;
|
||||
|
||||
fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
|
||||
if (!fences)
|
||||
goto err_free_sync_file;
|
||||
|
||||
/*
|
||||
* We can't guarantee that fences in both a and b are ordered, but it is
|
||||
* still quite likely.
|
||||
*
|
||||
* So attempt to order the fences as we pass over them and merge fences
|
||||
* with the same context.
|
||||
*/
|
||||
|
||||
index = 0;
|
||||
for (a_fence = dma_fence_unwrap_first(a->fence, &a_iter),
|
||||
b_fence = dma_fence_unwrap_first(b->fence, &b_iter);
|
||||
a_fence || b_fence; ) {
|
||||
|
||||
if (!b_fence) {
|
||||
add_fence(fences, &index, a_fence);
|
||||
a_fence = dma_fence_unwrap_next(&a_iter);
|
||||
|
||||
} else if (!a_fence) {
|
||||
add_fence(fences, &index, b_fence);
|
||||
b_fence = dma_fence_unwrap_next(&b_iter);
|
||||
|
||||
} else if (a_fence->context < b_fence->context) {
|
||||
add_fence(fences, &index, a_fence);
|
||||
a_fence = dma_fence_unwrap_next(&a_iter);
|
||||
|
||||
} else if (b_fence->context < a_fence->context) {
|
||||
add_fence(fences, &index, b_fence);
|
||||
b_fence = dma_fence_unwrap_next(&b_iter);
|
||||
|
||||
} else if (__dma_fence_is_later(a_fence->seqno, b_fence->seqno,
|
||||
a_fence->ops)) {
|
||||
add_fence(fences, &index, a_fence);
|
||||
a_fence = dma_fence_unwrap_next(&a_iter);
|
||||
b_fence = dma_fence_unwrap_next(&b_iter);
|
||||
|
||||
} else {
|
||||
add_fence(fences, &index, b_fence);
|
||||
a_fence = dma_fence_unwrap_next(&a_iter);
|
||||
b_fence = dma_fence_unwrap_next(&b_iter);
|
||||
}
|
||||
fence = dma_fence_unwrap_merge(a->fence, b->fence);
|
||||
if (!fence) {
|
||||
fput(sync_file->file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sync_file_set_fence(sync_file, fences, index) < 0)
|
||||
goto err_put_fences;
|
||||
|
||||
sync_file->fence = fence;
|
||||
strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name));
|
||||
return sync_file;
|
||||
|
||||
err_put_fences:
|
||||
while (index)
|
||||
dma_fence_put(fences[--index]);
|
||||
kfree(fences);
|
||||
|
||||
err_free_sync_file:
|
||||
fput(sync_file->file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int sync_file_release(struct inode *inode, struct file *file)
|
||||
|
@ -368,7 +368,23 @@ static struct miscdevice udmabuf_misc = {
|
||||
|
||||
static int __init udmabuf_dev_init(void)
|
||||
{
|
||||
return misc_register(&udmabuf_misc);
|
||||
int ret;
|
||||
|
||||
ret = misc_register(&udmabuf_misc);
|
||||
if (ret < 0) {
|
||||
pr_err("Could not initialize udmabuf device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dma_coerce_mask_and_coherent(udmabuf_misc.this_device,
|
||||
DMA_BIT_MASK(64));
|
||||
if (ret < 0) {
|
||||
pr_err("Could not setup DMA mask for udmabuf device\n");
|
||||
misc_deregister(&udmabuf_misc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit udmabuf_dev_exit(void)
|
||||
|
@ -70,6 +70,22 @@ config DRM_DEBUG_SELFTEST
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_KUNIT_TEST
|
||||
tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
|
||||
depends on DRM && KUNIT=y
|
||||
select DRM_KMS_HELPER
|
||||
default KUNIT_ALL_TESTS
|
||||
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
|
||||
@ -256,6 +272,7 @@ config DRM_AMDGPU
|
||||
select HWMON
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
select INTERVAL_TREE
|
||||
select DRM_BUDDY
|
||||
help
|
||||
Choose this option if you have a recent AMD Radeon graphics card.
|
||||
|
||||
@ -350,6 +367,8 @@ source "drivers/gpu/drm/etnaviv/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/hisilicon/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/logicvc/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/mediatek/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/mxsfb/Kconfig"
|
||||
|
@ -76,6 +76,7 @@ obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
|
||||
#
|
||||
|
||||
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
|
||||
obj-$(CONFIG_DRM_KUNIT_TEST) += tests/
|
||||
|
||||
obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o
|
||||
obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
|
||||
@ -121,6 +122,7 @@ obj-$(CONFIG_DRM_STM) += stm/
|
||||
obj-$(CONFIG_DRM_STI) += sti/
|
||||
obj-y += imx/
|
||||
obj-$(CONFIG_DRM_INGENIC) += ingenic/
|
||||
obj-$(CONFIG_DRM_LOGICVC) += logicvc/
|
||||
obj-$(CONFIG_DRM_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_DRM_MESON) += meson/
|
||||
obj-y += i2c/
|
||||
@ -129,7 +131,7 @@ obj-y += bridge/
|
||||
obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
|
||||
obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/
|
||||
obj-y += hisilicon/
|
||||
obj-$(CONFIG_DRM_MXSFB) += mxsfb/
|
||||
obj-y += mxsfb/
|
||||
obj-y += tiny/
|
||||
obj-$(CONFIG_DRM_PL111) += pl111/
|
||||
obj-$(CONFIG_DRM_TVE200) += tve200/
|
||||
|
@ -4,7 +4,7 @@ config DRM_AMDGPU_SI
|
||||
depends on DRM_AMDGPU
|
||||
help
|
||||
Choose this option if you want to enable experimental support
|
||||
for SI asics.
|
||||
for SI (Southern Islands) asics.
|
||||
|
||||
SI is already supported in radeon. Experimental support for SI
|
||||
in amdgpu will be disabled by default and is still provided by
|
||||
@ -16,7 +16,8 @@ config DRM_AMDGPU_CIK
|
||||
bool "Enable amdgpu support for CIK parts"
|
||||
depends on DRM_AMDGPU
|
||||
help
|
||||
Choose this option if you want to enable support for CIK asics.
|
||||
Choose this option if you want to enable support for CIK (Sea
|
||||
Islands) asics.
|
||||
|
||||
CIK is already supported in radeon. Support for CIK in amdgpu
|
||||
will be disabled by default and is still provided by radeon.
|
||||
|
@ -88,11 +88,12 @@ amdgpu-y += \
|
||||
gmc_v8_0.o \
|
||||
gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \
|
||||
gfxhub_v2_0.o mmhub_v2_0.o gmc_v10_0.o gfxhub_v2_1.o mmhub_v2_3.o \
|
||||
mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o
|
||||
mmhub_v1_7.o gfxhub_v3_0.o mmhub_v3_0.o mmhub_v3_0_2.o gmc_v11_0.o \
|
||||
mmhub_v3_0_1.o
|
||||
|
||||
# add UMC block
|
||||
amdgpu-y += \
|
||||
umc_v6_0.o umc_v6_1.o umc_v6_7.o umc_v8_7.o
|
||||
umc_v6_0.o umc_v6_1.o umc_v6_7.o umc_v8_7.o umc_v8_10.o
|
||||
|
||||
# add IH block
|
||||
amdgpu-y += \
|
||||
@ -114,7 +115,8 @@ amdgpu-y += \
|
||||
psp_v11_0.o \
|
||||
psp_v11_0_8.o \
|
||||
psp_v12_0.o \
|
||||
psp_v13_0.o
|
||||
psp_v13_0.o \
|
||||
psp_v13_0_4.o
|
||||
|
||||
# add DCE block
|
||||
amdgpu-y += \
|
||||
|
@ -197,6 +197,7 @@ extern uint amdgpu_smu_memory_pool_size;
|
||||
extern int amdgpu_smu_pptable_id;
|
||||
extern uint amdgpu_dc_feature_mask;
|
||||
extern uint amdgpu_dc_debug_mask;
|
||||
extern uint amdgpu_dc_visual_confirm;
|
||||
extern uint amdgpu_dm_abm_level;
|
||||
extern int amdgpu_backlight;
|
||||
extern struct amdgpu_mgpu_info mgpu_info;
|
||||
@ -223,6 +224,9 @@ static const int __maybe_unused sched_policy = KFD_SCHED_POLICY_HWS;
|
||||
static const bool __maybe_unused debug_evictions; /* = false */
|
||||
static const bool __maybe_unused no_system_mem_limit;
|
||||
#endif
|
||||
#ifdef CONFIG_HSA_AMD_P2P
|
||||
extern bool pcie_p2p;
|
||||
#endif
|
||||
|
||||
extern int amdgpu_tmz;
|
||||
extern int amdgpu_reset_method;
|
||||
@ -274,7 +278,7 @@ extern int amdgpu_vcnfw_log;
|
||||
#define CIK_CURSOR_WIDTH 128
|
||||
#define CIK_CURSOR_HEIGHT 128
|
||||
|
||||
/* smasrt shift bias level limits */
|
||||
/* smart shift bias level limits */
|
||||
#define AMDGPU_SMARTSHIFT_MAX_BIAS (100)
|
||||
#define AMDGPU_SMARTSHIFT_MIN_BIAS (-100)
|
||||
|
||||
@ -667,6 +671,7 @@ enum amd_hw_ip_block_type {
|
||||
RSMU_HWIP,
|
||||
XGMI_HWIP,
|
||||
DCI_HWIP,
|
||||
PCIE_HWIP,
|
||||
MAX_HWIP
|
||||
};
|
||||
|
||||
@ -1007,7 +1012,6 @@ struct amdgpu_device {
|
||||
uint64_t df_perfmon_config_assign_mask[AMDGPU_MAX_DF_PERFMONS];
|
||||
|
||||
/* enable runtime pm on the device */
|
||||
bool runpm;
|
||||
bool in_runpm;
|
||||
bool has_pr3;
|
||||
|
||||
@ -1016,7 +1020,7 @@ struct amdgpu_device {
|
||||
bool psp_sysfs_en;
|
||||
|
||||
/* Chip product information */
|
||||
char product_number[16];
|
||||
char product_number[20];
|
||||
char product_name[AMDGPU_PRODUCT_NAME_LEN];
|
||||
char serial[20];
|
||||
|
||||
@ -1044,10 +1048,18 @@ struct amdgpu_device {
|
||||
|
||||
/* reset dump register */
|
||||
uint32_t *reset_dump_reg_list;
|
||||
uint32_t *reset_dump_reg_value;
|
||||
int num_regs;
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
struct amdgpu_task_info reset_task_info;
|
||||
bool reset_vram_lost;
|
||||
struct timespec64 reset_time;
|
||||
#endif
|
||||
|
||||
bool scpm_enabled;
|
||||
uint32_t scpm_status;
|
||||
|
||||
struct work_struct reset_work;
|
||||
};
|
||||
|
||||
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
|
||||
@ -1241,9 +1253,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
||||
bool amdgpu_device_has_job_running(struct amdgpu_device *adev);
|
||||
bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev);
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
struct amdgpu_job* job);
|
||||
int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job);
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_reset_context *reset_context);
|
||||
void amdgpu_device_pci_config_reset(struct amdgpu_device *adev);
|
||||
int amdgpu_device_pci_reset(struct amdgpu_device *adev);
|
||||
bool amdgpu_device_need_post(struct amdgpu_device *adev);
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <sound/designware_i2s.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "atom.h"
|
||||
@ -36,6 +38,7 @@
|
||||
|
||||
#include "acp_gfx_if.h"
|
||||
|
||||
#define ST_JADEITE 1
|
||||
#define ACP_TILE_ON_MASK 0x03
|
||||
#define ACP_TILE_OFF_MASK 0x02
|
||||
#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f
|
||||
@ -85,6 +88,8 @@
|
||||
#define ACP_DEVS 4
|
||||
#define ACP_SRC_ID 162
|
||||
|
||||
static unsigned long acp_machine_id;
|
||||
|
||||
enum {
|
||||
ACP_TILE_P1 = 0,
|
||||
ACP_TILE_P2,
|
||||
@ -128,16 +133,14 @@ static int acp_poweroff(struct generic_pm_domain *genpd)
|
||||
struct amdgpu_device *adev;
|
||||
|
||||
apd = container_of(genpd, struct acp_pm_domain, gpd);
|
||||
if (apd != NULL) {
|
||||
adev = apd->adev;
|
||||
adev = apd->adev;
|
||||
/* call smu to POWER GATE ACP block
|
||||
* smu will
|
||||
* 1. turn off the acp clock
|
||||
* 2. power off the acp tiles
|
||||
* 3. check and enter ulv state
|
||||
*/
|
||||
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
|
||||
}
|
||||
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -147,16 +150,14 @@ static int acp_poweron(struct generic_pm_domain *genpd)
|
||||
struct amdgpu_device *adev;
|
||||
|
||||
apd = container_of(genpd, struct acp_pm_domain, gpd);
|
||||
if (apd != NULL) {
|
||||
adev = apd->adev;
|
||||
adev = apd->adev;
|
||||
/* call smu to UNGATE ACP block
|
||||
* smu will
|
||||
* 1. exit ulv
|
||||
* 2. turn on acp clock
|
||||
* 3. power on acp tiles
|
||||
*/
|
||||
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false);
|
||||
}
|
||||
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -184,6 +185,37 @@ static int acp_genpd_remove_device(struct device *dev, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acp_quirk_cb(const struct dmi_system_id *id)
|
||||
{
|
||||
acp_machine_id = ST_JADEITE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id acp_quirk_table[] = {
|
||||
{
|
||||
.callback = acp_quirk_cb,
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMD"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jadeite"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.callback = acp_quirk_cb,
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "IP3 Technology CO.,Ltd."),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN1D"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = acp_quirk_cb,
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Standard"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN10"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
/**
|
||||
* acp_hw_init - start and test ACP block
|
||||
*
|
||||
@ -193,7 +225,7 @@ static int acp_genpd_remove_device(struct device *dev, void *data)
|
||||
static int acp_hw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
uint64_t acp_base;
|
||||
u64 acp_base;
|
||||
u32 val = 0;
|
||||
u32 count = 0;
|
||||
struct i2s_platform_data *i2s_pdata = NULL;
|
||||
@ -220,141 +252,202 @@ static int acp_hw_init(void *handle)
|
||||
return -EINVAL;
|
||||
|
||||
acp_base = adev->rmmio_base;
|
||||
|
||||
|
||||
adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
|
||||
if (adev->acp.acp_genpd == NULL)
|
||||
if (!adev->acp.acp_genpd)
|
||||
return -ENOMEM;
|
||||
|
||||
adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";
|
||||
adev->acp.acp_genpd->gpd.power_off = acp_poweroff;
|
||||
adev->acp.acp_genpd->gpd.power_on = acp_poweron;
|
||||
|
||||
|
||||
adev->acp.acp_genpd->adev = adev;
|
||||
|
||||
pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);
|
||||
dmi_check_system(acp_quirk_table);
|
||||
switch (acp_machine_id) {
|
||||
case ST_JADEITE:
|
||||
{
|
||||
adev->acp.acp_cell = kcalloc(2, sizeof(struct mfd_cell),
|
||||
GFP_KERNEL);
|
||||
if (!adev->acp.acp_cell) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
|
||||
GFP_KERNEL);
|
||||
adev->acp.acp_res = kcalloc(3, sizeof(struct resource), GFP_KERNEL);
|
||||
if (!adev->acp.acp_res) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (adev->acp.acp_cell == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
i2s_pdata = kcalloc(1, sizeof(struct i2s_platform_data), GFP_KERNEL);
|
||||
if (!i2s_pdata) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
|
||||
if (adev->acp.acp_res == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
|
||||
if (i2s_pdata == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_STONEY:
|
||||
i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
|
||||
DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
|
||||
break;
|
||||
default:
|
||||
i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
|
||||
}
|
||||
i2s_pdata[0].cap = DWC_I2S_PLAY;
|
||||
i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
|
||||
i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET;
|
||||
i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET;
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_STONEY:
|
||||
i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
|
||||
DW_I2S_QUIRK_COMP_PARAM1 |
|
||||
DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
|
||||
break;
|
||||
default:
|
||||
i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
|
||||
DW_I2S_QUIRK_COMP_PARAM1;
|
||||
}
|
||||
DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
|
||||
i2s_pdata[0].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
|
||||
i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
|
||||
i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
|
||||
i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
|
||||
|
||||
i2s_pdata[1].cap = DWC_I2S_RECORD;
|
||||
i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000;
|
||||
i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
|
||||
i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
|
||||
adev->acp.acp_res[0].name = "acp2x_dma";
|
||||
adev->acp.acp_res[0].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[0].start = acp_base;
|
||||
adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
|
||||
|
||||
i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_STONEY:
|
||||
i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
|
||||
break;
|
||||
default:
|
||||
adev->acp.acp_res[1].name = "acp2x_dw_i2s_play_cap";
|
||||
adev->acp.acp_res[1].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[1].start = acp_base + ACP_I2S_CAP_REGS_START;
|
||||
adev->acp.acp_res[1].end = acp_base + ACP_I2S_CAP_REGS_END;
|
||||
|
||||
adev->acp.acp_res[2].name = "acp2x_dma_irq";
|
||||
adev->acp.acp_res[2].flags = IORESOURCE_IRQ;
|
||||
adev->acp.acp_res[2].start = amdgpu_irq_create_mapping(adev, 162);
|
||||
adev->acp.acp_res[2].end = adev->acp.acp_res[2].start;
|
||||
|
||||
adev->acp.acp_cell[0].name = "acp_audio_dma";
|
||||
adev->acp.acp_cell[0].num_resources = 3;
|
||||
adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
|
||||
adev->acp.acp_cell[0].platform_data = &adev->asic_type;
|
||||
adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
|
||||
|
||||
adev->acp.acp_cell[1].name = "designware-i2s";
|
||||
adev->acp.acp_cell[1].num_resources = 1;
|
||||
adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
|
||||
adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
|
||||
adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
|
||||
r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, 2);
|
||||
if (r)
|
||||
goto failure;
|
||||
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
|
||||
acp_genpd_add_device);
|
||||
if (r)
|
||||
goto failure;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
|
||||
GFP_KERNEL);
|
||||
|
||||
i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
|
||||
i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000;
|
||||
i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
|
||||
i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
|
||||
if (!adev->acp.acp_cell) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
adev->acp.acp_res[0].name = "acp2x_dma";
|
||||
adev->acp.acp_res[0].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[0].start = acp_base;
|
||||
adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
|
||||
adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
|
||||
if (!adev->acp.acp_res) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
adev->acp.acp_res[1].name = "acp2x_dw_i2s_play";
|
||||
adev->acp.acp_res[1].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START;
|
||||
adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END;
|
||||
i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
|
||||
if (!i2s_pdata) {
|
||||
r = -ENOMEM;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap";
|
||||
adev->acp.acp_res[2].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START;
|
||||
adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END;
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_STONEY:
|
||||
i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
|
||||
DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
|
||||
break;
|
||||
default:
|
||||
i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
|
||||
}
|
||||
i2s_pdata[0].cap = DWC_I2S_PLAY;
|
||||
i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
|
||||
i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET;
|
||||
i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET;
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_STONEY:
|
||||
i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
|
||||
DW_I2S_QUIRK_COMP_PARAM1 |
|
||||
DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
|
||||
break;
|
||||
default:
|
||||
i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
|
||||
DW_I2S_QUIRK_COMP_PARAM1;
|
||||
}
|
||||
|
||||
adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap";
|
||||
adev->acp.acp_res[3].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START;
|
||||
adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END;
|
||||
i2s_pdata[1].cap = DWC_I2S_RECORD;
|
||||
i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000;
|
||||
i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
|
||||
i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
|
||||
|
||||
adev->acp.acp_res[4].name = "acp2x_dma_irq";
|
||||
adev->acp.acp_res[4].flags = IORESOURCE_IRQ;
|
||||
adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162);
|
||||
adev->acp.acp_res[4].end = adev->acp.acp_res[4].start;
|
||||
i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_STONEY:
|
||||
i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
adev->acp.acp_cell[0].name = "acp_audio_dma";
|
||||
adev->acp.acp_cell[0].num_resources = 5;
|
||||
adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
|
||||
adev->acp.acp_cell[0].platform_data = &adev->asic_type;
|
||||
adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
|
||||
i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
|
||||
i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000;
|
||||
i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
|
||||
i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
|
||||
|
||||
adev->acp.acp_cell[1].name = "designware-i2s";
|
||||
adev->acp.acp_cell[1].num_resources = 1;
|
||||
adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
|
||||
adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
|
||||
adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
|
||||
adev->acp.acp_res[0].name = "acp2x_dma";
|
||||
adev->acp.acp_res[0].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[0].start = acp_base;
|
||||
adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
|
||||
|
||||
adev->acp.acp_cell[2].name = "designware-i2s";
|
||||
adev->acp.acp_cell[2].num_resources = 1;
|
||||
adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2];
|
||||
adev->acp.acp_cell[2].platform_data = &i2s_pdata[1];
|
||||
adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data);
|
||||
adev->acp.acp_res[1].name = "acp2x_dw_i2s_play";
|
||||
adev->acp.acp_res[1].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START;
|
||||
adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END;
|
||||
|
||||
adev->acp.acp_cell[3].name = "designware-i2s";
|
||||
adev->acp.acp_cell[3].num_resources = 1;
|
||||
adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3];
|
||||
adev->acp.acp_cell[3].platform_data = &i2s_pdata[2];
|
||||
adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data);
|
||||
adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap";
|
||||
adev->acp.acp_res[2].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START;
|
||||
adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END;
|
||||
|
||||
r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,
|
||||
ACP_DEVS);
|
||||
if (r)
|
||||
goto failure;
|
||||
adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap";
|
||||
adev->acp.acp_res[3].flags = IORESOURCE_MEM;
|
||||
adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START;
|
||||
adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END;
|
||||
|
||||
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
|
||||
acp_genpd_add_device);
|
||||
if (r)
|
||||
goto failure;
|
||||
adev->acp.acp_res[4].name = "acp2x_dma_irq";
|
||||
adev->acp.acp_res[4].flags = IORESOURCE_IRQ;
|
||||
adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162);
|
||||
adev->acp.acp_res[4].end = adev->acp.acp_res[4].start;
|
||||
|
||||
adev->acp.acp_cell[0].name = "acp_audio_dma";
|
||||
adev->acp.acp_cell[0].num_resources = 5;
|
||||
adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
|
||||
adev->acp.acp_cell[0].platform_data = &adev->asic_type;
|
||||
adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
|
||||
|
||||
adev->acp.acp_cell[1].name = "designware-i2s";
|
||||
adev->acp.acp_cell[1].num_resources = 1;
|
||||
adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
|
||||
adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
|
||||
adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
|
||||
|
||||
adev->acp.acp_cell[2].name = "designware-i2s";
|
||||
adev->acp.acp_cell[2].num_resources = 1;
|
||||
adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2];
|
||||
adev->acp.acp_cell[2].platform_data = &i2s_pdata[1];
|
||||
adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data);
|
||||
|
||||
adev->acp.acp_cell[3].name = "designware-i2s";
|
||||
adev->acp.acp_cell[3].num_resources = 1;
|
||||
adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3];
|
||||
adev->acp.acp_cell[3].platform_data = &i2s_pdata[2];
|
||||
adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data);
|
||||
|
||||
r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, ACP_DEVS);
|
||||
if (r)
|
||||
goto failure;
|
||||
|
||||
r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
|
||||
acp_genpd_add_device);
|
||||
if (r)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Assert Soft reset of ACP */
|
||||
val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
|
||||
@ -546,8 +639,7 @@ static const struct amd_ip_funcs acp_ip_funcs = {
|
||||
.set_powergating_state = acp_set_powergating_state,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version acp_ip_block =
|
||||
{
|
||||
const struct amdgpu_ip_block_version acp_ip_block = {
|
||||
.type = AMD_IP_BLOCK_TYPE_ACP,
|
||||
.major = 2,
|
||||
.minor = 2,
|
||||
|
@ -66,9 +66,7 @@ struct amdgpu_atif {
|
||||
struct amdgpu_atif_notifications notifications;
|
||||
struct amdgpu_atif_functions functions;
|
||||
struct amdgpu_atif_notification_cfg notification_cfg;
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
struct backlight_device *bd;
|
||||
#endif
|
||||
struct amdgpu_dm_backlight_caps backlight_caps;
|
||||
};
|
||||
|
||||
@ -436,7 +434,6 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
|
||||
DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
|
||||
|
||||
if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) {
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
if (atif->bd) {
|
||||
DRM_DEBUG_DRIVER("Changing brightness to %d\n",
|
||||
req.backlight_level);
|
||||
@ -447,7 +444,6 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
|
||||
*/
|
||||
backlight_device_set_brightness(atif->bd, req.backlight_level);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
|
||||
@ -849,7 +845,6 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
|
||||
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
if (atif->notifications.brightness_change) {
|
||||
if (amdgpu_device_has_dc_support(adev)) {
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
@ -876,7 +871,6 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
adev->acpi_nb.notifier_call = amdgpu_acpi_event;
|
||||
register_acpi_notifier(&adev->acpi_nb);
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <uapi/linux/kfd_ioctl.h>
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_umc.h"
|
||||
#include "amdgpu_reset.h"
|
||||
|
||||
/* Total memory size in system memory and all GPU VRAM. Used to
|
||||
* estimate worst case amount of memory to reserve for page tables
|
||||
@ -122,6 +123,22 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void amdgpu_amdkfd_reset_work(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
|
||||
kfd.reset_work);
|
||||
|
||||
struct amdgpu_reset_context reset_context;
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
|
||||
amdgpu_device_gpu_recover(adev, NULL, &reset_context);
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int i;
|
||||
@ -180,6 +197,8 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
|
||||
|
||||
adev->kfd.init_complete = kgd2kfd_device_init(adev->kfd.dev,
|
||||
adev_to_drm(adev), &gpu_resources);
|
||||
|
||||
INIT_WORK(&adev->kfd.reset_work, amdgpu_amdkfd_reset_work);
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,7 +266,8 @@ int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev)
|
||||
void amdgpu_amdkfd_gpu_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_device_should_recover_gpu(adev))
|
||||
amdgpu_device_gpu_recover(adev, NULL);
|
||||
amdgpu_reset_domain_schedule(adev->reset_domain,
|
||||
&adev->kfd.reset_work);
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size,
|
||||
@ -671,6 +691,8 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
|
||||
goto err_ib_sched;
|
||||
}
|
||||
|
||||
/* Drop the initial kref_init count (see drm_sched_main as example) */
|
||||
dma_fence_put(f);
|
||||
ret = dma_fence_wait(f, false);
|
||||
|
||||
err_ib_sched:
|
||||
|
@ -48,6 +48,7 @@ enum kfd_mem_attachment_type {
|
||||
KFD_MEM_ATT_SHARED, /* Share kgd_mem->bo or another attachment's */
|
||||
KFD_MEM_ATT_USERPTR, /* SG bo to DMA map pages from a userptr bo */
|
||||
KFD_MEM_ATT_DMABUF, /* DMAbuf to DMA map TTM BOs */
|
||||
KFD_MEM_ATT_SG /* Tag to DMA map SG BOs */
|
||||
};
|
||||
|
||||
struct kfd_mem_attachment {
|
||||
@ -96,6 +97,7 @@ struct amdgpu_kfd_dev {
|
||||
struct kfd_dev *dev;
|
||||
uint64_t vram_used;
|
||||
bool init_complete;
|
||||
struct work_struct reset_work;
|
||||
};
|
||||
|
||||
enum kgd_engine_type {
|
||||
@ -170,6 +172,9 @@ int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev,
|
||||
struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
|
||||
struct mm_struct *mm,
|
||||
struct svm_range_bo *svm_bo);
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
int kfd_debugfs_kfd_mem_limits(struct seq_file *m, void *data);
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_HSA_AMD)
|
||||
bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm);
|
||||
struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f);
|
||||
@ -266,6 +271,7 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
|
||||
void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
|
||||
void *drm_priv);
|
||||
uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv);
|
||||
size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
struct amdgpu_device *adev, uint64_t va, uint64_t size,
|
||||
void *drm_priv, struct kgd_mem **mem,
|
||||
@ -279,10 +285,11 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_sync_memory(
|
||||
struct amdgpu_device *adev, struct kgd_mem *mem, bool intr);
|
||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem, void **kptr, uint64_t *size);
|
||||
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem);
|
||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,
|
||||
void **kptr, uint64_t *size);
|
||||
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem);
|
||||
|
||||
int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo);
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
|
||||
struct dma_fence **ef);
|
||||
@ -301,6 +308,10 @@ bool amdgpu_amdkfd_bo_mapped_to_dev(struct amdgpu_device *adev, struct kgd_mem *
|
||||
void amdgpu_amdkfd_block_mmu_notifications(void *p);
|
||||
int amdgpu_amdkfd_criu_resume(void *p);
|
||||
bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
||||
uint64_t size, u32 alloc_flag);
|
||||
void amdgpu_amdkfd_unreserve_mem_limit(struct amdgpu_device *adev,
|
||||
uint64_t size, u32 alloc_flag);
|
||||
|
||||
#if IS_ENABLED(CONFIG_HSA_AMD)
|
||||
void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
|
||||
@ -332,7 +343,7 @@ void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo)
|
||||
}
|
||||
#endif
|
||||
/* KGD2KFD callbacks */
|
||||
int kgd2kfd_quiesce_mm(struct mm_struct *mm);
|
||||
int kgd2kfd_quiesce_mm(struct mm_struct *mm, uint32_t trigger);
|
||||
int kgd2kfd_resume_mm(struct mm_struct *mm);
|
||||
int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm,
|
||||
struct dma_fence *fence);
|
||||
|
@ -159,11 +159,14 @@ static void amdkfd_fence_release(struct dma_fence *f)
|
||||
}
|
||||
|
||||
/**
|
||||
* amdkfd_fence_check_mm - Check if @mm is same as that of the fence @f
|
||||
* if same return TRUE else return FALSE.
|
||||
* amdkfd_fence_check_mm - Check whether to prevent eviction of @f by @mm
|
||||
*
|
||||
* @f: [IN] fence
|
||||
* @mm: [IN] mm that needs to be verified
|
||||
*
|
||||
* Check if @mm is same as that of the fence @f, if same return TRUE else
|
||||
* return FALSE.
|
||||
* For svm bo, which support vram overcommitment, always return FALSE.
|
||||
*/
|
||||
bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm)
|
||||
{
|
||||
@ -171,7 +174,7 @@ bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm)
|
||||
|
||||
if (!fence)
|
||||
return false;
|
||||
else if (fence->mm == mm)
|
||||
else if (fence->mm == mm && !fence->svm_bo)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -32,12 +32,19 @@
|
||||
#include "amdgpu_dma_buf.h"
|
||||
#include <uapi/linux/kfd_ioctl.h>
|
||||
#include "amdgpu_xgmi.h"
|
||||
#include "kfd_smi_events.h"
|
||||
|
||||
/* Userptr restore delay, just long enough to allow consecutive VM
|
||||
* changes to accumulate
|
||||
*/
|
||||
#define AMDGPU_USERPTR_RESTORE_DELAY_MS 1
|
||||
|
||||
/*
|
||||
* Align VRAM allocations to 2MB to avoid fragmentation caused by 4K allocations in the tail 2MB
|
||||
* BO chunk
|
||||
*/
|
||||
#define VRAM_ALLOCATION_ALIGN (1 << 21)
|
||||
|
||||
/* Impose limit on how much memory KFD can use */
|
||||
static struct {
|
||||
uint64_t max_system_mem_limit;
|
||||
@ -108,21 +115,12 @@ void amdgpu_amdkfd_reserve_system_mem(uint64_t size)
|
||||
* compromise that should work in most cases without reserving too
|
||||
* much memory for page tables unnecessarily (factor 16K, >> 14).
|
||||
*/
|
||||
#define ESTIMATE_PT_SIZE(mem_size) ((mem_size) >> 14)
|
||||
|
||||
static size_t amdgpu_amdkfd_acc_size(uint64_t size)
|
||||
{
|
||||
size >>= PAGE_SHIFT;
|
||||
size *= sizeof(dma_addr_t) + sizeof(void *);
|
||||
|
||||
return __roundup_pow_of_two(sizeof(struct amdgpu_bo)) +
|
||||
__roundup_pow_of_two(sizeof(struct ttm_tt)) +
|
||||
PAGE_ALIGN(size);
|
||||
}
|
||||
#define ESTIMATE_PT_SIZE(mem_size) max(((mem_size) >> 14), AMDGPU_VM_RESERVED_VRAM)
|
||||
|
||||
/**
|
||||
* amdgpu_amdkfd_reserve_mem_limit() - Decrease available memory by size
|
||||
* of buffer including any reserved for control structures
|
||||
* of buffer.
|
||||
*
|
||||
* @adev: Device to which allocated BO belongs to
|
||||
* @size: Size of buffer, in bytes, encapsulated by B0. This should be
|
||||
@ -131,33 +129,32 @@ static size_t amdgpu_amdkfd_acc_size(uint64_t size)
|
||||
*
|
||||
* Return: returns -ENOMEM in case of error, ZERO otherwise
|
||||
*/
|
||||
static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
||||
int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
||||
uint64_t size, u32 alloc_flag)
|
||||
{
|
||||
uint64_t reserved_for_pt =
|
||||
ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
|
||||
size_t acc_size, system_mem_needed, ttm_mem_needed, vram_needed;
|
||||
size_t system_mem_needed, ttm_mem_needed, vram_needed;
|
||||
int ret = 0;
|
||||
|
||||
acc_size = amdgpu_amdkfd_acc_size(size);
|
||||
|
||||
system_mem_needed = 0;
|
||||
ttm_mem_needed = 0;
|
||||
vram_needed = 0;
|
||||
if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_GTT) {
|
||||
system_mem_needed = acc_size + size;
|
||||
ttm_mem_needed = acc_size + size;
|
||||
system_mem_needed = size;
|
||||
ttm_mem_needed = size;
|
||||
} else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
system_mem_needed = acc_size;
|
||||
ttm_mem_needed = acc_size;
|
||||
vram_needed = size;
|
||||
/*
|
||||
* Conservatively round up the allocation requirement to 2 MB
|
||||
* to avoid fragmentation caused by 4K allocations in the tail
|
||||
* 2M BO chunk.
|
||||
*/
|
||||
vram_needed = ALIGN(size, VRAM_ALLOCATION_ALIGN);
|
||||
} else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
|
||||
system_mem_needed = acc_size + size;
|
||||
ttm_mem_needed = acc_size;
|
||||
} else if (alloc_flag &
|
||||
(KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
|
||||
KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
|
||||
system_mem_needed = acc_size;
|
||||
ttm_mem_needed = acc_size;
|
||||
} else {
|
||||
system_mem_needed = size;
|
||||
} else if (!(alloc_flag &
|
||||
(KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
|
||||
KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP))) {
|
||||
pr_err("%s: Invalid BO type %#x\n", __func__, alloc_flag);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -172,8 +169,10 @@ static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
||||
kfd_mem_limit.max_system_mem_limit && !no_system_mem_limit) ||
|
||||
(kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
|
||||
kfd_mem_limit.max_ttm_mem_limit) ||
|
||||
(adev->kfd.vram_used + vram_needed >
|
||||
adev->gmc.real_vram_size - reserved_for_pt)) {
|
||||
(adev && adev->kfd.vram_used + vram_needed >
|
||||
adev->gmc.real_vram_size -
|
||||
atomic64_read(&adev->vram_pin_size) -
|
||||
reserved_for_pt)) {
|
||||
ret = -ENOMEM;
|
||||
goto release;
|
||||
}
|
||||
@ -181,7 +180,10 @@ static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
||||
/* Update memory accounting by decreasing available system
|
||||
* memory, TTM memory and GPU memory as computed above
|
||||
*/
|
||||
adev->kfd.vram_used += vram_needed;
|
||||
WARN_ONCE(vram_needed && !adev,
|
||||
"adev reference can't be null when vram is used");
|
||||
if (adev)
|
||||
adev->kfd.vram_used += vram_needed;
|
||||
kfd_mem_limit.system_mem_used += system_mem_needed;
|
||||
kfd_mem_limit.ttm_mem_used += ttm_mem_needed;
|
||||
|
||||
@ -190,36 +192,28 @@ static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void unreserve_mem_limit(struct amdgpu_device *adev,
|
||||
void amdgpu_amdkfd_unreserve_mem_limit(struct amdgpu_device *adev,
|
||||
uint64_t size, u32 alloc_flag)
|
||||
{
|
||||
size_t acc_size;
|
||||
|
||||
acc_size = amdgpu_amdkfd_acc_size(size);
|
||||
|
||||
spin_lock(&kfd_mem_limit.mem_limit_lock);
|
||||
|
||||
if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_GTT) {
|
||||
kfd_mem_limit.system_mem_used -= (acc_size + size);
|
||||
kfd_mem_limit.ttm_mem_used -= (acc_size + size);
|
||||
kfd_mem_limit.system_mem_used -= size;
|
||||
kfd_mem_limit.ttm_mem_used -= size;
|
||||
} else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
kfd_mem_limit.system_mem_used -= acc_size;
|
||||
kfd_mem_limit.ttm_mem_used -= acc_size;
|
||||
adev->kfd.vram_used -= size;
|
||||
WARN_ONCE(!adev,
|
||||
"adev reference can't be null when alloc mem flags vram is set");
|
||||
if (adev)
|
||||
adev->kfd.vram_used -= ALIGN(size, VRAM_ALLOCATION_ALIGN);
|
||||
} else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
|
||||
kfd_mem_limit.system_mem_used -= (acc_size + size);
|
||||
kfd_mem_limit.ttm_mem_used -= acc_size;
|
||||
} else if (alloc_flag &
|
||||
(KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
|
||||
KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) {
|
||||
kfd_mem_limit.system_mem_used -= acc_size;
|
||||
kfd_mem_limit.ttm_mem_used -= acc_size;
|
||||
} else {
|
||||
kfd_mem_limit.system_mem_used -= size;
|
||||
} else if (!(alloc_flag &
|
||||
(KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL |
|
||||
KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP))) {
|
||||
pr_err("%s: Invalid BO type %#x\n", __func__, alloc_flag);
|
||||
goto release;
|
||||
}
|
||||
|
||||
WARN_ONCE(adev->kfd.vram_used < 0,
|
||||
WARN_ONCE(adev && adev->kfd.vram_used < 0,
|
||||
"KFD VRAM memory accounting unbalanced");
|
||||
WARN_ONCE(kfd_mem_limit.ttm_mem_used < 0,
|
||||
"KFD TTM memory accounting unbalanced");
|
||||
@ -236,11 +230,47 @@ void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo)
|
||||
u32 alloc_flags = bo->kfd_bo->alloc_flags;
|
||||
u64 size = amdgpu_bo_size(bo);
|
||||
|
||||
unreserve_mem_limit(adev, size, alloc_flags);
|
||||
amdgpu_amdkfd_unreserve_mem_limit(adev, size, alloc_flags);
|
||||
|
||||
kfree(bo->kfd_bo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @create_dmamap_sg_bo: Creates a amdgpu_bo object to reflect information
|
||||
* about USERPTR or DOOREBELL or MMIO BO.
|
||||
* @adev: Device for which dmamap BO is being created
|
||||
* @mem: BO of peer device that is being DMA mapped. Provides parameters
|
||||
* in building the dmamap BO
|
||||
* @bo_out: Output parameter updated with handle of dmamap BO
|
||||
*/
|
||||
static int
|
||||
create_dmamap_sg_bo(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem, struct amdgpu_bo **bo_out)
|
||||
{
|
||||
struct drm_gem_object *gem_obj;
|
||||
int ret, align;
|
||||
|
||||
ret = amdgpu_bo_reserve(mem->bo, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
align = 1;
|
||||
ret = amdgpu_gem_object_create(adev, mem->bo->tbo.base.size, align,
|
||||
AMDGPU_GEM_DOMAIN_CPU, AMDGPU_GEM_CREATE_PREEMPTIBLE,
|
||||
ttm_bo_type_sg, mem->bo->tbo.base.resv, &gem_obj);
|
||||
|
||||
amdgpu_bo_unreserve(mem->bo);
|
||||
|
||||
if (ret) {
|
||||
pr_err("Error in creating DMA mappable SG BO on domain: %d\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*bo_out = gem_to_amdgpu_bo(gem_obj);
|
||||
(*bo_out)->parent = amdgpu_bo_ref(mem->bo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* amdgpu_amdkfd_remove_eviction_fence - Removes eviction fence from BO's
|
||||
* reservation object.
|
||||
*
|
||||
@ -350,22 +380,8 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = amdgpu_amdkfd_validate_vm_bo(NULL, pd);
|
||||
if (ret) {
|
||||
pr_err("failed to validate PD\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
vm->pd_phys_addr = amdgpu_gmc_pd_addr(vm->root.bo);
|
||||
|
||||
if (vm->use_cpu_for_update) {
|
||||
ret = amdgpu_bo_kmap(pd, NULL);
|
||||
if (ret) {
|
||||
pr_err("failed to kmap PD, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -399,45 +415,42 @@ static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_ARCTURUS:
|
||||
if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
if (bo_adev == adev)
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_RW;
|
||||
else
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
|
||||
} else {
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
|
||||
}
|
||||
break;
|
||||
case CHIP_ALDEBARAN:
|
||||
if (coherent && uncached) {
|
||||
if (adev->gmc.xgmi.connected_to_cpu ||
|
||||
!(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM))
|
||||
snoop = true;
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_UC;
|
||||
} else if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
if (bo_adev == adev) {
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_CC : AMDGPU_VM_MTYPE_RW;
|
||||
if (adev->gmc.xgmi.connected_to_cpu)
|
||||
if (uncached)
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_UC;
|
||||
else if (coherent)
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_CC;
|
||||
else
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_RW;
|
||||
if (adev->asic_type == CHIP_ALDEBARAN &&
|
||||
adev->gmc.xgmi.connected_to_cpu)
|
||||
snoop = true;
|
||||
} else {
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
|
||||
if (uncached || coherent)
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_UC;
|
||||
else
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_NC;
|
||||
if (amdgpu_xgmi_same_hive(adev, bo_adev))
|
||||
snoop = true;
|
||||
}
|
||||
} else {
|
||||
if (uncached || coherent)
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_UC;
|
||||
else
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_NC;
|
||||
snoop = true;
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mapping_flags |= coherent ?
|
||||
AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
|
||||
if (uncached || coherent)
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_UC;
|
||||
else
|
||||
mapping_flags |= AMDGPU_VM_MTYPE_NC;
|
||||
|
||||
if (!(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM))
|
||||
snoop = true;
|
||||
}
|
||||
|
||||
pte_flags = amdgpu_gem_va_map_flags(adev, mapping_flags);
|
||||
@ -446,6 +459,38 @@ static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
|
||||
return pte_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_sg_table() - Create an sg_table for a contiguous DMA addr range
|
||||
* @addr: The starting address to point to
|
||||
* @size: Size of memory area in bytes being pointed to
|
||||
*
|
||||
* Allocates an instance of sg_table and initializes it to point to memory
|
||||
* area specified by input parameters. The address used to build is assumed
|
||||
* to be DMA mapped, if needed.
|
||||
*
|
||||
* DOORBELL or MMIO BOs use only one scatterlist node in their sg_table
|
||||
* because they are physically contiguous.
|
||||
*
|
||||
* Return: Initialized instance of SG Table or NULL
|
||||
*/
|
||||
static struct sg_table *create_sg_table(uint64_t addr, uint32_t size)
|
||||
{
|
||||
struct sg_table *sg = kmalloc(sizeof(*sg), GFP_KERNEL);
|
||||
|
||||
if (!sg)
|
||||
return NULL;
|
||||
if (sg_alloc_table(sg, 1, GFP_KERNEL)) {
|
||||
kfree(sg);
|
||||
return NULL;
|
||||
}
|
||||
sg_dma_address(sg->sgl) = addr;
|
||||
sg->sgl->length = size;
|
||||
#ifdef CONFIG_NEED_SG_DMA_LENGTH
|
||||
sg->sgl->dma_length = size;
|
||||
#endif
|
||||
return sg;
|
||||
}
|
||||
|
||||
static int
|
||||
kfd_mem_dmamap_userptr(struct kgd_mem *mem,
|
||||
struct kfd_mem_attachment *attachment)
|
||||
@ -510,6 +555,87 @@ kfd_mem_dmamap_dmabuf(struct kfd_mem_attachment *attachment)
|
||||
return ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* kfd_mem_dmamap_sg_bo() - Create DMA mapped sg_table to access DOORBELL or MMIO BO
|
||||
* @mem: SG BO of the DOORBELL or MMIO resource on the owning device
|
||||
* @attachment: Virtual address attachment of the BO on accessing device
|
||||
*
|
||||
* An access request from the device that owns DOORBELL does not require DMA mapping.
|
||||
* This is because the request doesn't go through PCIe root complex i.e. it instead
|
||||
* loops back. The need to DMA map arises only when accessing peer device's DOORBELL
|
||||
*
|
||||
* In contrast, all access requests for MMIO need to be DMA mapped without regard to
|
||||
* device ownership. This is because access requests for MMIO go through PCIe root
|
||||
* complex.
|
||||
*
|
||||
* This is accomplished in two steps:
|
||||
* - Obtain DMA mapped address of DOORBELL or MMIO memory that could be used
|
||||
* in updating requesting device's page table
|
||||
* - Signal TTM to mark memory pointed to by requesting device's BO as GPU
|
||||
* accessible. This allows an update of requesting device's page table
|
||||
* with entries associated with DOOREBELL or MMIO memory
|
||||
*
|
||||
* This method is invoked in the following contexts:
|
||||
* - Mapping of DOORBELL or MMIO BO of same or peer device
|
||||
* - Validating an evicted DOOREBELL or MMIO BO on device seeking access
|
||||
*
|
||||
* Return: ZERO if successful, NON-ZERO otherwise
|
||||
*/
|
||||
static int
|
||||
kfd_mem_dmamap_sg_bo(struct kgd_mem *mem,
|
||||
struct kfd_mem_attachment *attachment)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = {.interruptible = true};
|
||||
struct amdgpu_bo *bo = attachment->bo_va->base.bo;
|
||||
struct amdgpu_device *adev = attachment->adev;
|
||||
struct ttm_tt *ttm = bo->tbo.ttm;
|
||||
enum dma_data_direction dir;
|
||||
dma_addr_t dma_addr;
|
||||
bool mmio;
|
||||
int ret;
|
||||
|
||||
/* Expect SG Table of dmapmap BO to be NULL */
|
||||
mmio = (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP);
|
||||
if (unlikely(ttm->sg)) {
|
||||
pr_err("SG Table of %d BO for peer device is UNEXPECTEDLY NON-NULL", mmio);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dir = mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ?
|
||||
DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
|
||||
dma_addr = mem->bo->tbo.sg->sgl->dma_address;
|
||||
pr_debug("%d BO size: %d\n", mmio, mem->bo->tbo.sg->sgl->length);
|
||||
pr_debug("%d BO address before DMA mapping: %llx\n", mmio, dma_addr);
|
||||
dma_addr = dma_map_resource(adev->dev, dma_addr,
|
||||
mem->bo->tbo.sg->sgl->length, dir, DMA_ATTR_SKIP_CPU_SYNC);
|
||||
ret = dma_mapping_error(adev->dev, dma_addr);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
pr_debug("%d BO address after DMA mapping: %llx\n", mmio, dma_addr);
|
||||
|
||||
ttm->sg = create_sg_table(dma_addr, mem->bo->tbo.sg->sgl->length);
|
||||
if (unlikely(!ttm->sg)) {
|
||||
ret = -ENOMEM;
|
||||
goto unmap_sg;
|
||||
}
|
||||
|
||||
amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
|
||||
ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
if (unlikely(ret))
|
||||
goto free_sg;
|
||||
|
||||
return ret;
|
||||
|
||||
free_sg:
|
||||
sg_free_table(ttm->sg);
|
||||
kfree(ttm->sg);
|
||||
ttm->sg = NULL;
|
||||
unmap_sg:
|
||||
dma_unmap_resource(adev->dev, dma_addr, mem->bo->tbo.sg->sgl->length,
|
||||
dir, DMA_ATTR_SKIP_CPU_SYNC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
kfd_mem_dmamap_attachment(struct kgd_mem *mem,
|
||||
struct kfd_mem_attachment *attachment)
|
||||
@ -521,6 +647,8 @@ kfd_mem_dmamap_attachment(struct kgd_mem *mem,
|
||||
return kfd_mem_dmamap_userptr(mem, attachment);
|
||||
case KFD_MEM_ATT_DMABUF:
|
||||
return kfd_mem_dmamap_dmabuf(attachment);
|
||||
case KFD_MEM_ATT_SG:
|
||||
return kfd_mem_dmamap_sg_bo(mem, attachment);
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
@ -561,6 +689,50 @@ kfd_mem_dmaunmap_dmabuf(struct kfd_mem_attachment *attachment)
|
||||
ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* kfd_mem_dmaunmap_sg_bo() - Free DMA mapped sg_table of DOORBELL or MMIO BO
|
||||
* @mem: SG BO of the DOORBELL or MMIO resource on the owning device
|
||||
* @attachment: Virtual address attachment of the BO on accessing device
|
||||
*
|
||||
* The method performs following steps:
|
||||
* - Signal TTM to mark memory pointed to by BO as GPU inaccessible
|
||||
* - Free SG Table that is used to encapsulate DMA mapped memory of
|
||||
* peer device's DOORBELL or MMIO memory
|
||||
*
|
||||
* This method is invoked in the following contexts:
|
||||
* UNMapping of DOORBELL or MMIO BO on a device having access to its memory
|
||||
* Eviction of DOOREBELL or MMIO BO on device having access to its memory
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void
|
||||
kfd_mem_dmaunmap_sg_bo(struct kgd_mem *mem,
|
||||
struct kfd_mem_attachment *attachment)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = {.interruptible = true};
|
||||
struct amdgpu_bo *bo = attachment->bo_va->base.bo;
|
||||
struct amdgpu_device *adev = attachment->adev;
|
||||
struct ttm_tt *ttm = bo->tbo.ttm;
|
||||
enum dma_data_direction dir;
|
||||
|
||||
if (unlikely(!ttm->sg)) {
|
||||
pr_err("SG Table of BO is UNEXPECTEDLY NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU);
|
||||
ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
|
||||
dir = mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ?
|
||||
DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
|
||||
dma_unmap_resource(adev->dev, ttm->sg->sgl->dma_address,
|
||||
ttm->sg->sgl->length, dir, DMA_ATTR_SKIP_CPU_SYNC);
|
||||
sg_free_table(ttm->sg);
|
||||
kfree(ttm->sg);
|
||||
ttm->sg = NULL;
|
||||
bo->tbo.sg = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
kfd_mem_dmaunmap_attachment(struct kgd_mem *mem,
|
||||
struct kfd_mem_attachment *attachment)
|
||||
@ -574,38 +746,14 @@ kfd_mem_dmaunmap_attachment(struct kgd_mem *mem,
|
||||
case KFD_MEM_ATT_DMABUF:
|
||||
kfd_mem_dmaunmap_dmabuf(attachment);
|
||||
break;
|
||||
case KFD_MEM_ATT_SG:
|
||||
kfd_mem_dmaunmap_sg_bo(mem, attachment);
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
kfd_mem_attach_userptr(struct amdgpu_device *adev, struct kgd_mem *mem,
|
||||
struct amdgpu_bo **bo)
|
||||
{
|
||||
unsigned long bo_size = mem->bo->tbo.base.size;
|
||||
struct drm_gem_object *gobj;
|
||||
int ret;
|
||||
|
||||
ret = amdgpu_bo_reserve(mem->bo, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = amdgpu_gem_object_create(adev, bo_size, 1,
|
||||
AMDGPU_GEM_DOMAIN_CPU,
|
||||
AMDGPU_GEM_CREATE_PREEMPTIBLE,
|
||||
ttm_bo_type_sg, mem->bo->tbo.base.resv,
|
||||
&gobj);
|
||||
amdgpu_bo_unreserve(mem->bo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*bo = gem_to_amdgpu_bo(gobj);
|
||||
(*bo)->parent = amdgpu_bo_ref(mem->bo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem,
|
||||
struct amdgpu_bo **bo)
|
||||
@ -630,7 +778,6 @@ kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem,
|
||||
|
||||
*bo = gem_to_amdgpu_bo(gobj);
|
||||
(*bo)->flags |= AMDGPU_GEM_CREATE_PREEMPTIBLE;
|
||||
(*bo)->parent = amdgpu_bo_ref(mem->bo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -656,6 +803,7 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
|
||||
uint64_t va = mem->va;
|
||||
struct kfd_mem_attachment *attachment[2] = {NULL, NULL};
|
||||
struct amdgpu_bo *bo[2] = {NULL, NULL};
|
||||
bool same_hive = false;
|
||||
int i, ret;
|
||||
|
||||
if (!va) {
|
||||
@ -663,6 +811,24 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Determine access to VRAM, MMIO and DOORBELL BOs of peer devices
|
||||
*
|
||||
* The access path of MMIO and DOORBELL BOs of is always over PCIe.
|
||||
* In contrast the access path of VRAM BOs depens upon the type of
|
||||
* link that connects the peer device. Access over PCIe is allowed
|
||||
* if peer device has large BAR. In contrast, access over xGMI is
|
||||
* allowed for both small and large BAR configurations of peer device
|
||||
*/
|
||||
if ((adev != bo_adev) &&
|
||||
((mem->domain == AMDGPU_GEM_DOMAIN_VRAM) ||
|
||||
(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) ||
|
||||
(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP))) {
|
||||
if (mem->domain == AMDGPU_GEM_DOMAIN_VRAM)
|
||||
same_hive = amdgpu_xgmi_same_hive(adev, bo_adev);
|
||||
if (!same_hive && !amdgpu_device_is_peer_accessible(bo_adev, adev))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i <= is_aql; i++) {
|
||||
attachment[i] = kzalloc(sizeof(*attachment[i]), GFP_KERNEL);
|
||||
if (unlikely(!attachment[i])) {
|
||||
@ -673,9 +839,9 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
|
||||
pr_debug("\t add VA 0x%llx - 0x%llx to vm %p\n", va,
|
||||
va + bo_size, vm);
|
||||
|
||||
if (adev == bo_adev ||
|
||||
(amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) && adev->ram_is_direct_mapped) ||
|
||||
(mem->domain == AMDGPU_GEM_DOMAIN_VRAM && amdgpu_xgmi_same_hive(adev, bo_adev))) {
|
||||
if ((adev == bo_adev && !(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) ||
|
||||
(amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) && adev->ram_is_direct_mapped) ||
|
||||
same_hive) {
|
||||
/* Mappings on the local GPU, or VRAM mappings in the
|
||||
* local hive, or userptr mapping IOMMU direct map mode
|
||||
* share the original BO
|
||||
@ -691,26 +857,30 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
|
||||
} else if (amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm)) {
|
||||
/* Create an SG BO to DMA-map userptrs on other GPUs */
|
||||
attachment[i]->type = KFD_MEM_ATT_USERPTR;
|
||||
ret = kfd_mem_attach_userptr(adev, mem, &bo[i]);
|
||||
ret = create_dmamap_sg_bo(adev, mem, &bo[i]);
|
||||
if (ret)
|
||||
goto unwind;
|
||||
} else if (mem->domain == AMDGPU_GEM_DOMAIN_GTT &&
|
||||
mem->bo->tbo.type != ttm_bo_type_sg) {
|
||||
/* GTT BOs use DMA-mapping ability of dynamic-attach
|
||||
* DMA bufs. TODO: The same should work for VRAM on
|
||||
* large-BAR GPUs.
|
||||
*/
|
||||
/* Handle DOORBELL BOs of peer devices and MMIO BOs of local and peer devices */
|
||||
} else if (mem->bo->tbo.type == ttm_bo_type_sg) {
|
||||
WARN_ONCE(!(mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL ||
|
||||
mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP),
|
||||
"Handing invalid SG BO in ATTACH request");
|
||||
attachment[i]->type = KFD_MEM_ATT_SG;
|
||||
ret = create_dmamap_sg_bo(adev, mem, &bo[i]);
|
||||
if (ret)
|
||||
goto unwind;
|
||||
/* Enable acces to GTT and VRAM BOs of peer devices */
|
||||
} else if (mem->domain == AMDGPU_GEM_DOMAIN_GTT ||
|
||||
mem->domain == AMDGPU_GEM_DOMAIN_VRAM) {
|
||||
attachment[i]->type = KFD_MEM_ATT_DMABUF;
|
||||
ret = kfd_mem_attach_dmabuf(adev, mem, &bo[i]);
|
||||
if (ret)
|
||||
goto unwind;
|
||||
pr_debug("Employ DMABUF mechanism to enable peer GPU access\n");
|
||||
} else {
|
||||
/* FIXME: Need to DMA-map other BO types:
|
||||
* large-BAR VRAM, doorbells, MMIO remap
|
||||
*/
|
||||
attachment[i]->type = KFD_MEM_ATT_SHARED;
|
||||
bo[i] = mem->bo;
|
||||
drm_gem_object_get(&bo[i]->tbo.base);
|
||||
WARN_ONCE(true, "Handling invalid ATTACH request");
|
||||
ret = -EINVAL;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
/* Add BO to VM internal data structures */
|
||||
@ -1111,24 +1281,6 @@ static int map_bo_to_gpuvm(struct kgd_mem *mem,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sg_table *create_doorbell_sg(uint64_t addr, uint32_t size)
|
||||
{
|
||||
struct sg_table *sg = kmalloc(sizeof(*sg), GFP_KERNEL);
|
||||
|
||||
if (!sg)
|
||||
return NULL;
|
||||
if (sg_alloc_table(sg, 1, GFP_KERNEL)) {
|
||||
kfree(sg);
|
||||
return NULL;
|
||||
}
|
||||
sg->sgl->dma_address = addr;
|
||||
sg->sgl->length = size;
|
||||
#ifdef CONFIG_NEED_SG_DMA_LENGTH
|
||||
sg->sgl->dma_length = size;
|
||||
#endif
|
||||
return sg;
|
||||
}
|
||||
|
||||
static int process_validate_vms(struct amdkfd_process_info *process_info)
|
||||
{
|
||||
struct amdgpu_vm *peer_vm;
|
||||
@ -1451,6 +1603,22 @@ int amdgpu_amdkfd_criu_resume(void *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t amdgpu_amdkfd_get_available_memory(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t reserved_for_pt =
|
||||
ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size);
|
||||
size_t available;
|
||||
|
||||
spin_lock(&kfd_mem_limit.mem_limit_lock);
|
||||
available = adev->gmc.real_vram_size
|
||||
- adev->kfd.vram_used
|
||||
- atomic64_read(&adev->vram_pin_size)
|
||||
- reserved_for_pt;
|
||||
spin_unlock(&kfd_mem_limit.mem_limit_lock);
|
||||
|
||||
return ALIGN_DOWN(available, VRAM_ALLOCATION_ALIGN);
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
struct amdgpu_device *adev, uint64_t va, uint64_t size,
|
||||
void *drm_priv, struct kgd_mem **mem,
|
||||
@ -1491,7 +1659,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
bo_type = ttm_bo_type_sg;
|
||||
if (size > UINT_MAX)
|
||||
return -EINVAL;
|
||||
sg = create_doorbell_sg(*offset, size);
|
||||
sg = create_sg_table(*offset, size);
|
||||
if (!sg)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
@ -1585,7 +1753,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
/* Don't unreserve system mem limit twice */
|
||||
goto err_reserve_limit;
|
||||
err_bo_create:
|
||||
unreserve_mem_limit(adev, size, flags);
|
||||
amdgpu_amdkfd_unreserve_mem_limit(adev, size, flags);
|
||||
err_reserve_limit:
|
||||
mutex_destroy(&(*mem)->lock);
|
||||
if (gobj)
|
||||
@ -1606,6 +1774,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
||||
{
|
||||
struct amdkfd_process_info *process_info = mem->process_info;
|
||||
unsigned long bo_size = mem->bo->tbo.base.size;
|
||||
bool use_release_notifier = (mem->bo->kfd_bo == mem);
|
||||
struct kfd_mem_attachment *entry, *tmp;
|
||||
struct bo_vm_reservation_context ctx;
|
||||
struct ttm_validate_buffer *bo_list_entry;
|
||||
@ -1697,6 +1866,13 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
||||
*/
|
||||
drm_gem_object_put(&mem->bo->tbo.base);
|
||||
|
||||
/*
|
||||
* For kgd_mem allocated in amdgpu_amdkfd_gpuvm_import_dmabuf(),
|
||||
* explicitly free it here.
|
||||
*/
|
||||
if (!use_release_notifier)
|
||||
kfree(mem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1901,8 +2077,69 @@ int amdgpu_amdkfd_gpuvm_sync_memory(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem, void **kptr, uint64_t *size)
|
||||
/**
|
||||
* amdgpu_amdkfd_map_gtt_bo_to_gart - Map BO to GART and increment reference count
|
||||
* @adev: Device to which allocated BO belongs
|
||||
* @bo: Buffer object to be mapped
|
||||
*
|
||||
* Before return, bo reference count is incremented. To release the reference and unpin/
|
||||
* unmap the BO, call amdgpu_amdkfd_free_gtt_mem.
|
||||
*/
|
||||
int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = amdgpu_bo_reserve(bo, true);
|
||||
if (ret) {
|
||||
pr_err("Failed to reserve bo. ret %d\n", ret);
|
||||
goto err_reserve_bo_failed;
|
||||
}
|
||||
|
||||
ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);
|
||||
if (ret) {
|
||||
pr_err("Failed to pin bo. ret %d\n", ret);
|
||||
goto err_pin_bo_failed;
|
||||
}
|
||||
|
||||
ret = amdgpu_ttm_alloc_gart(&bo->tbo);
|
||||
if (ret) {
|
||||
pr_err("Failed to bind bo to GART. ret %d\n", ret);
|
||||
goto err_map_bo_gart_failed;
|
||||
}
|
||||
|
||||
amdgpu_amdkfd_remove_eviction_fence(
|
||||
bo, bo->kfd_bo->process_info->eviction_fence);
|
||||
|
||||
amdgpu_bo_unreserve(bo);
|
||||
|
||||
bo = amdgpu_bo_ref(bo);
|
||||
|
||||
return 0;
|
||||
|
||||
err_map_bo_gart_failed:
|
||||
amdgpu_bo_unpin(bo);
|
||||
err_pin_bo_failed:
|
||||
amdgpu_bo_unreserve(bo);
|
||||
err_reserve_bo_failed:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel() - Map a GTT BO for kernel CPU access
|
||||
*
|
||||
* @mem: Buffer object to be mapped for CPU access
|
||||
* @kptr[out]: pointer in kernel CPU address space
|
||||
* @size[out]: size of the buffer
|
||||
*
|
||||
* Pins the BO and maps it for kernel CPU access. The eviction fence is removed
|
||||
* from the BO, since pinned BOs cannot be evicted. The bo must remain on the
|
||||
* validate_list, so the GPU mapping can be restored after a page table was
|
||||
* evicted.
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,
|
||||
void **kptr, uint64_t *size)
|
||||
{
|
||||
int ret;
|
||||
struct amdgpu_bo *bo = mem->bo;
|
||||
@ -1953,8 +2190,15 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct amdgpu_device *adev,
|
||||
struct kgd_mem *mem)
|
||||
/** amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel() - Unmap a GTT BO for kernel CPU access
|
||||
*
|
||||
* @mem: Buffer object to be unmapped for CPU access
|
||||
*
|
||||
* Removes the kernel CPU mapping and unpins the BO. It does not restore the
|
||||
* eviction fence, so this function should only be used for cleanup before the
|
||||
* BO is destroyed.
|
||||
*/
|
||||
void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct kgd_mem *mem)
|
||||
{
|
||||
struct amdgpu_bo *bo = mem->bo;
|
||||
|
||||
@ -2066,7 +2310,7 @@ int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem,
|
||||
evicted_bos = atomic_inc_return(&process_info->evicted_bos);
|
||||
if (evicted_bos == 1) {
|
||||
/* First eviction, stop the queues */
|
||||
r = kgd2kfd_quiesce_mm(mm);
|
||||
r = kgd2kfd_quiesce_mm(mm, KFD_QUEUE_EVICTION_TRIGGER_USERPTR);
|
||||
if (r)
|
||||
pr_err("Failed to quiesce KFD\n");
|
||||
schedule_delayed_work(&process_info->restore_userptr_work,
|
||||
@ -2340,13 +2584,16 @@ static void amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work)
|
||||
|
||||
unlock_out:
|
||||
mutex_unlock(&process_info->lock);
|
||||
mmput(mm);
|
||||
put_task_struct(usertask);
|
||||
|
||||
/* If validation failed, reschedule another attempt */
|
||||
if (evicted_bos)
|
||||
if (evicted_bos) {
|
||||
schedule_delayed_work(&process_info->restore_userptr_work,
|
||||
msecs_to_jiffies(AMDGPU_USERPTR_RESTORE_DELAY_MS));
|
||||
|
||||
kfd_smi_event_queue_restore_rescheduled(mm);
|
||||
}
|
||||
mmput(mm);
|
||||
put_task_struct(usertask);
|
||||
}
|
||||
|
||||
/** amdgpu_amdkfd_gpuvm_restore_process_bos - Restore all BOs for the given
|
||||
@ -2648,3 +2895,22 @@ bool amdgpu_amdkfd_bo_mapped_to_dev(struct amdgpu_device *adev, struct kgd_mem *
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
|
||||
int kfd_debugfs_kfd_mem_limits(struct seq_file *m, void *data)
|
||||
{
|
||||
|
||||
spin_lock(&kfd_mem_limit.mem_limit_lock);
|
||||
seq_printf(m, "System mem used %lldM out of %lluM\n",
|
||||
(kfd_mem_limit.system_mem_used >> 20),
|
||||
(kfd_mem_limit.max_system_mem_limit >> 20));
|
||||
seq_printf(m, "TTM mem used %lldM out of %lluM\n",
|
||||
(kfd_mem_limit.ttm_mem_used >> 20),
|
||||
(kfd_mem_limit.max_ttm_mem_limit >> 20));
|
||||
spin_unlock(&kfd_mem_limit.mem_limit_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -110,7 +110,7 @@ static int amdgpu_ctx_priority_permit(struct drm_file *filp,
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
static enum amdgpu_gfx_pipe_priority amdgpu_ctx_prio_to_compute_prio(int32_t prio)
|
||||
static enum amdgpu_gfx_pipe_priority amdgpu_ctx_prio_to_gfx_pipe_prio(int32_t prio)
|
||||
{
|
||||
switch (prio) {
|
||||
case AMDGPU_CTX_PRIORITY_HIGH:
|
||||
@ -143,8 +143,9 @@ static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip)
|
||||
ctx->init_priority : ctx->override_priority;
|
||||
|
||||
switch (hw_ip) {
|
||||
case AMDGPU_HW_IP_GFX:
|
||||
case AMDGPU_HW_IP_COMPUTE:
|
||||
hw_prio = amdgpu_ctx_prio_to_compute_prio(ctx_prio);
|
||||
hw_prio = amdgpu_ctx_prio_to_gfx_pipe_prio(ctx_prio);
|
||||
break;
|
||||
case AMDGPU_HW_IP_VCE:
|
||||
case AMDGPU_HW_IP_VCN_ENC:
|
||||
@ -271,32 +272,6 @@ static ktime_t amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
|
||||
struct drm_file *filp, struct amdgpu_ctx *ctx)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = amdgpu_ctx_priority_permit(filp, priority);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
kref_init(&ctx->refcount);
|
||||
ctx->mgr = mgr;
|
||||
spin_lock_init(&ctx->ring_lock);
|
||||
mutex_init(&ctx->lock);
|
||||
|
||||
ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
|
||||
ctx->reset_counter_query = ctx->reset_counter;
|
||||
ctx->vram_lost_counter = atomic_read(&mgr->adev->vram_lost_counter);
|
||||
ctx->init_priority = priority;
|
||||
ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
|
||||
ctx->stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
|
||||
u32 *stable_pstate)
|
||||
{
|
||||
@ -325,6 +300,38 @@ static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
|
||||
struct drm_file *filp, struct amdgpu_ctx *ctx)
|
||||
{
|
||||
u32 current_stable_pstate;
|
||||
int r;
|
||||
|
||||
r = amdgpu_ctx_priority_permit(filp, priority);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
kref_init(&ctx->refcount);
|
||||
ctx->mgr = mgr;
|
||||
spin_lock_init(&ctx->ring_lock);
|
||||
mutex_init(&ctx->lock);
|
||||
|
||||
ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
|
||||
ctx->reset_counter_query = ctx->reset_counter;
|
||||
ctx->vram_lost_counter = atomic_read(&mgr->adev->vram_lost_counter);
|
||||
ctx->init_priority = priority;
|
||||
ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
|
||||
|
||||
r = amdgpu_ctx_get_stable_pstate(ctx, ¤t_stable_pstate);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ctx->stable_pstate = current_stable_pstate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
|
||||
u32 stable_pstate)
|
||||
{
|
||||
@ -396,7 +403,7 @@ static void amdgpu_ctx_fini(struct kref *ref)
|
||||
}
|
||||
|
||||
if (drm_dev_enter(&adev->ddev, &idx)) {
|
||||
amdgpu_ctx_set_stable_pstate(ctx, AMDGPU_CTX_STABLE_PSTATE_NONE);
|
||||
amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
|
||||
drm_dev_exit(idx);
|
||||
}
|
||||
|
||||
@ -779,7 +786,7 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
|
||||
amdgpu_ctx_to_drm_sched_prio(priority));
|
||||
|
||||
/* set hw priority */
|
||||
if (hw_ip == AMDGPU_HW_IP_COMPUTE) {
|
||||
if (hw_ip == AMDGPU_HW_IP_COMPUTE || hw_ip == AMDGPU_HW_IP_GFX) {
|
||||
hw_prio = amdgpu_ctx_get_hw_prio(ctx, hw_ip);
|
||||
hw_prio = array_index_nospec(hw_prio, AMDGPU_RING_PRIO_MAX);
|
||||
scheds = adev->gpu_sched[hw_ip][hw_prio].sched;
|
||||
|
@ -383,12 +383,8 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
||||
|
||||
value = RREG32_PCIE(*pos);
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
@ -396,11 +392,12 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -441,12 +438,8 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
|
||||
uint32_t value;
|
||||
|
||||
r = get_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
WREG32_PCIE(*pos, value);
|
||||
|
||||
@ -456,11 +449,12 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -502,12 +496,8 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
||||
|
||||
value = RREG32_DIDT(*pos >> 2);
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
@ -515,11 +505,12 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -560,12 +551,8 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
|
||||
uint32_t value;
|
||||
|
||||
r = get_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
WREG32_DIDT(*pos >> 2, value);
|
||||
|
||||
@ -575,11 +562,12 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -621,12 +609,8 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
||||
|
||||
value = RREG32_SMC(*pos);
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
@ -634,11 +618,12 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -679,12 +664,8 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
|
||||
uint32_t value;
|
||||
|
||||
r = get_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return r;
|
||||
}
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
WREG32_SMC(*pos, value);
|
||||
|
||||
@ -694,11 +675,12 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1090,11 +1072,8 @@ static ssize_t amdgpu_debugfs_gfxoff_write(struct file *f, const char __user *bu
|
||||
uint32_t value;
|
||||
|
||||
r = get_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
return r;
|
||||
}
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
amdgpu_gfx_off_ctrl(adev, value ? true : false);
|
||||
|
||||
@ -1104,10 +1083,12 @@ static ssize_t amdgpu_debugfs_gfxoff_write(struct file *f, const char __user *bu
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@ -1136,21 +1117,11 @@ static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf,
|
||||
}
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
u32 value = adev->gfx.gfx_off_state;
|
||||
|
||||
r = amdgpu_get_gfx_off_status(adev, &value);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
return r;
|
||||
}
|
||||
r = put_user(value, (u32 *)buf);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
@ -1158,10 +1129,53 @@ static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf,
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
return result;
|
||||
return r;
|
||||
}
|
||||
|
||||
static ssize_t amdgpu_debugfs_gfxoff_status_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
struct amdgpu_device *adev = file_inode(f)->i_private;
|
||||
ssize_t result = 0;
|
||||
int r;
|
||||
|
||||
if (size & 0x3 || *pos & 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
|
||||
if (r < 0) {
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
while (size) {
|
||||
u32 value;
|
||||
|
||||
r = amdgpu_get_gfx_off_status(adev, &value);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = put_user(value, (u32 *)buf);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
*pos += 4;
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
r = result;
|
||||
out:
|
||||
pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct file_operations amdgpu_debugfs_regs2_fops = {
|
||||
@ -1229,6 +1243,12 @@ static const struct file_operations amdgpu_debugfs_gfxoff_fops = {
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct file_operations amdgpu_debugfs_gfxoff_status_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = amdgpu_debugfs_gfxoff_status_read,
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct file_operations *debugfs_regs[] = {
|
||||
&amdgpu_debugfs_regs_fops,
|
||||
&amdgpu_debugfs_regs2_fops,
|
||||
@ -1240,6 +1260,7 @@ static const struct file_operations *debugfs_regs[] = {
|
||||
&amdgpu_debugfs_wave_fops,
|
||||
&amdgpu_debugfs_gpr_fops,
|
||||
&amdgpu_debugfs_gfxoff_fops,
|
||||
&amdgpu_debugfs_gfxoff_status_fops,
|
||||
};
|
||||
|
||||
static const char *debugfs_regs_names[] = {
|
||||
@ -1253,6 +1274,7 @@ static const char *debugfs_regs_names[] = {
|
||||
"amdgpu_wave",
|
||||
"amdgpu_gpr",
|
||||
"amdgpu_gfxoff",
|
||||
"amdgpu_gfxoff_status",
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1709,17 +1731,24 @@ static ssize_t amdgpu_reset_dump_register_list_write(struct file *f,
|
||||
i++;
|
||||
} while (len < size);
|
||||
|
||||
new = kmalloc_array(i, sizeof(uint32_t), GFP_KERNEL);
|
||||
if (!new) {
|
||||
ret = -ENOMEM;
|
||||
goto error_free;
|
||||
}
|
||||
ret = down_write_killable(&adev->reset_domain->sem);
|
||||
if (ret)
|
||||
goto error_free;
|
||||
|
||||
swap(adev->reset_dump_reg_list, tmp);
|
||||
swap(adev->reset_dump_reg_value, new);
|
||||
adev->num_regs = i;
|
||||
up_write(&adev->reset_domain->sem);
|
||||
ret = size;
|
||||
|
||||
error_free:
|
||||
kfree(tmp);
|
||||
kfree(new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,9 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/devcoredump.h>
|
||||
#include <generated/utsrelease.h>
|
||||
#include <linux/pci-p2pdma.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
@ -1942,35 +1945,6 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev)
|
||||
}
|
||||
|
||||
switch (adev->asic_type) {
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
case CHIP_VERDE:
|
||||
case CHIP_TAHITI:
|
||||
case CHIP_PITCAIRN:
|
||||
case CHIP_OLAND:
|
||||
case CHIP_HAINAN:
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_KAVERI:
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
#endif
|
||||
case CHIP_TOPAZ:
|
||||
case CHIP_TONGA:
|
||||
case CHIP_FIJI:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_VEGAM:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
case CHIP_VEGA20:
|
||||
case CHIP_ALDEBARAN:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
case CHIP_BEIGE_GOBY:
|
||||
default:
|
||||
return 0;
|
||||
case CHIP_VEGA10:
|
||||
@ -3316,38 +3290,12 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
||||
case CHIP_MULLINS:
|
||||
/*
|
||||
* We have systems in the wild with these ASICs that require
|
||||
* LVDS and VGA support which is not supported with DC.
|
||||
* VGA support which is not supported with DC.
|
||||
*
|
||||
* Fallback to the non-DC driver here by default so as not to
|
||||
* cause regressions.
|
||||
*/
|
||||
return amdgpu_dc > 0;
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
case CHIP_VEGAM:
|
||||
case CHIP_TONGA:
|
||||
case CHIP_FIJI:
|
||||
case CHIP_VEGA10:
|
||||
case CHIP_VEGA12:
|
||||
case CHIP_VEGA20:
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
case CHIP_RAVEN:
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI14:
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_RENOIR:
|
||||
case CHIP_CYAN_SKILLFISH:
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
case CHIP_NAVY_FLOUNDER:
|
||||
case CHIP_DIMGREY_CAVEFISH:
|
||||
case CHIP_BEIGE_GOBY:
|
||||
case CHIP_VANGOGH:
|
||||
case CHIP_YELLOW_CARP:
|
||||
#endif
|
||||
default:
|
||||
return amdgpu_dc != 0;
|
||||
#else
|
||||
@ -3369,7 +3317,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
|
||||
*/
|
||||
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev) ||
|
||||
if (amdgpu_sriov_vf(adev) ||
|
||||
adev->enable_virtual_display ||
|
||||
(adev->harvest_ip_mask & AMD_HARVEST_IP_DMU_MASK))
|
||||
return false;
|
||||
@ -3667,14 +3615,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
if (amdgpu_mcbp)
|
||||
DRM_INFO("MCBP is enabled\n");
|
||||
|
||||
if (adev->asic_type >= CHIP_NAVI10) {
|
||||
if (amdgpu_mes || amdgpu_mes_kiq)
|
||||
adev->enable_mes = true;
|
||||
|
||||
if (amdgpu_mes_kiq)
|
||||
adev->enable_mes_kiq = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset domain needs to be present early, before XGMI hive discovered
|
||||
* (if any) and intitialized to use reset sem and in_gpu reset flag
|
||||
@ -4666,6 +4606,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
amdgpu_virt_fini_data_exchange(adev);
|
||||
}
|
||||
|
||||
amdgpu_fence_driver_isr_toggle(adev, true);
|
||||
|
||||
/* block all schedulers and reset given job's ring */
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
@ -4681,6 +4623,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
amdgpu_fence_driver_force_completion(ring);
|
||||
}
|
||||
|
||||
amdgpu_fence_driver_isr_toggle(adev, false);
|
||||
|
||||
if (job && job->vm)
|
||||
drm_sched_increase_karma(&job->base);
|
||||
|
||||
@ -4721,20 +4665,72 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
|
||||
static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg_value;
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&adev->reset_domain->sem);
|
||||
dump_stack();
|
||||
|
||||
for (i = 0; i < adev->num_regs; i++) {
|
||||
reg_value = RREG32(adev->reset_dump_reg_list[i]);
|
||||
trace_amdgpu_reset_reg_dumps(adev->reset_dump_reg_list[i], reg_value);
|
||||
adev->reset_dump_reg_value[i] = RREG32(adev->reset_dump_reg_list[i]);
|
||||
trace_amdgpu_reset_reg_dumps(adev->reset_dump_reg_list[i],
|
||||
adev->reset_dump_reg_value[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset,
|
||||
size_t count, void *data, size_t datalen)
|
||||
{
|
||||
struct drm_printer p;
|
||||
struct amdgpu_device *adev = data;
|
||||
struct drm_print_iterator iter;
|
||||
int i;
|
||||
|
||||
iter.data = buffer;
|
||||
iter.offset = 0;
|
||||
iter.start = offset;
|
||||
iter.remain = count;
|
||||
|
||||
p = drm_coredump_printer(&iter);
|
||||
|
||||
drm_printf(&p, "**** AMDGPU Device Coredump ****\n");
|
||||
drm_printf(&p, "kernel: " UTS_RELEASE "\n");
|
||||
drm_printf(&p, "module: " KBUILD_MODNAME "\n");
|
||||
drm_printf(&p, "time: %lld.%09ld\n", adev->reset_time.tv_sec, adev->reset_time.tv_nsec);
|
||||
if (adev->reset_task_info.pid)
|
||||
drm_printf(&p, "process_name: %s PID: %d\n",
|
||||
adev->reset_task_info.process_name,
|
||||
adev->reset_task_info.pid);
|
||||
|
||||
if (adev->reset_vram_lost)
|
||||
drm_printf(&p, "VRAM is lost due to GPU reset!\n");
|
||||
if (adev->num_regs) {
|
||||
drm_printf(&p, "AMDGPU register dumps:\nOffset: Value:\n");
|
||||
|
||||
for (i = 0; i < adev->num_regs; i++)
|
||||
drm_printf(&p, "0x%08x: 0x%08x\n",
|
||||
adev->reset_dump_reg_list[i],
|
||||
adev->reset_dump_reg_value[i]);
|
||||
}
|
||||
|
||||
return count - iter.remain;
|
||||
}
|
||||
|
||||
static void amdgpu_devcoredump_free(void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static void amdgpu_reset_capture_coredumpm(struct amdgpu_device *adev)
|
||||
{
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
|
||||
ktime_get_ts64(&adev->reset_time);
|
||||
dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_KERNEL,
|
||||
amdgpu_devcoredump_read, amdgpu_devcoredump_free);
|
||||
}
|
||||
#endif
|
||||
|
||||
int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
@ -4819,6 +4815,15 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
|
||||
goto out;
|
||||
|
||||
vram_lost = amdgpu_device_check_vram_lost(tmp_adev);
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
tmp_adev->reset_vram_lost = vram_lost;
|
||||
memset(&tmp_adev->reset_task_info, 0,
|
||||
sizeof(tmp_adev->reset_task_info));
|
||||
if (reset_context->job && reset_context->job->vm)
|
||||
tmp_adev->reset_task_info =
|
||||
reset_context->job->vm->task_info;
|
||||
amdgpu_reset_capture_coredumpm(tmp_adev);
|
||||
#endif
|
||||
if (vram_lost) {
|
||||
DRM_INFO("VRAM is lost due to GPU reset!\n");
|
||||
amdgpu_inc_vram_lost(tmp_adev);
|
||||
@ -5004,16 +5009,32 @@ static void amdgpu_device_recheck_guilty_jobs(
|
||||
|
||||
/* clear job's guilty and depend the folowing step to decide the real one */
|
||||
drm_sched_reset_karma(s_job);
|
||||
/* for the real bad job, it will be resubmitted twice, adding a dma_fence_get
|
||||
* to make sure fence is balanced */
|
||||
dma_fence_get(s_job->s_fence->parent);
|
||||
drm_sched_resubmit_jobs_ext(&ring->sched, 1);
|
||||
|
||||
if (!s_job->s_fence->parent) {
|
||||
DRM_WARN("Failed to get a HW fence for job!");
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = dma_fence_wait_timeout(s_job->s_fence->parent, false, ring->sched.timeout);
|
||||
if (ret == 0) { /* timeout */
|
||||
DRM_ERROR("Found the real bad job! ring:%s, job_id:%llx\n",
|
||||
ring->sched.name, s_job->id);
|
||||
|
||||
|
||||
amdgpu_fence_driver_isr_toggle(adev, true);
|
||||
|
||||
/* Clear this failed job from fence array */
|
||||
amdgpu_fence_driver_clear_job_fences(ring);
|
||||
|
||||
amdgpu_fence_driver_isr_toggle(adev, false);
|
||||
|
||||
/* Since the job won't signal and we go for
|
||||
* another resubmit drop this parent pointer
|
||||
*/
|
||||
dma_fence_put(s_job->s_fence->parent);
|
||||
s_job->s_fence->parent = NULL;
|
||||
|
||||
/* set guilty */
|
||||
drm_sched_increase_karma(s_job);
|
||||
retry:
|
||||
@ -5042,7 +5063,6 @@ static void amdgpu_device_recheck_guilty_jobs(
|
||||
|
||||
/* got the hw fence, signal finished fence */
|
||||
atomic_dec(ring->sched.score);
|
||||
dma_fence_put(s_job->s_fence->parent);
|
||||
dma_fence_get(&s_job->s_fence->finished);
|
||||
dma_fence_signal(&s_job->s_fence->finished);
|
||||
dma_fence_put(&s_job->s_fence->finished);
|
||||
@ -5055,8 +5075,29 @@ static void amdgpu_device_recheck_guilty_jobs(
|
||||
}
|
||||
}
|
||||
|
||||
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
cancel_work(&adev->reset_work);
|
||||
#endif
|
||||
|
||||
if (adev->kfd.dev)
|
||||
cancel_work(&adev->kfd.reset_work);
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
cancel_work(&adev->virt.flr_work);
|
||||
|
||||
if (con && adev->ras_enabled)
|
||||
cancel_work(&con->recovery_work);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* amdgpu_device_gpu_recover_imp - reset the asic and recover scheduler
|
||||
* amdgpu_device_gpu_recover - reset the asic and recover scheduler
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @job: which job trigger hang
|
||||
@ -5066,8 +5107,9 @@ static void amdgpu_device_recheck_guilty_jobs(
|
||||
* Returns 0 for success or an error on failure.
|
||||
*/
|
||||
|
||||
int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job)
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
struct list_head device_list, *device_list_handle = NULL;
|
||||
bool job_signaled = false;
|
||||
@ -5077,9 +5119,6 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
bool need_emergency_restart = false;
|
||||
bool audio_suspended = false;
|
||||
int tmp_vram_lost_counter;
|
||||
struct amdgpu_reset_context reset_context;
|
||||
|
||||
memset(&reset_context, 0, sizeof(reset_context));
|
||||
|
||||
/*
|
||||
* Special case: RAS triggered and full reset isn't supported
|
||||
@ -5105,12 +5144,8 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
if (hive)
|
||||
mutex_lock(&hive->hive_lock);
|
||||
|
||||
reset_context.method = AMD_RESET_METHOD_NONE;
|
||||
reset_context.reset_req_dev = adev;
|
||||
reset_context.job = job;
|
||||
reset_context.hive = hive;
|
||||
clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
|
||||
|
||||
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
|
||||
@ -5194,8 +5229,7 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
*
|
||||
* job->base holds a reference to parent fence
|
||||
*/
|
||||
if (job && job->base.s_fence->parent &&
|
||||
dma_fence_is_signaled(job->base.s_fence->parent)) {
|
||||
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;
|
||||
@ -5203,13 +5237,19 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
|
||||
retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
r = amdgpu_device_pre_asic_reset(tmp_adev, &reset_context);
|
||||
r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context);
|
||||
/*TODO Should we stop ?*/
|
||||
if (r) {
|
||||
dev_err(tmp_adev->dev, "GPU pre asic reset failed with err, %d for drm dev, %s ",
|
||||
r, adev_to_drm(tmp_adev)->unique);
|
||||
tmp_adev->asic_reset_res = r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop all pending non scheduler resets. Scheduler resets
|
||||
* were already dropped during drm_sched_stop
|
||||
*/
|
||||
amdgpu_device_stop_pending_resets(tmp_adev);
|
||||
}
|
||||
|
||||
tmp_vram_lost_counter = atomic_read(&((adev)->vram_lost_counter));
|
||||
@ -5224,7 +5264,7 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2))
|
||||
amdgpu_ras_resume(adev);
|
||||
} else {
|
||||
r = amdgpu_do_asic_reset(device_list_handle, &reset_context);
|
||||
r = amdgpu_do_asic_reset(device_list_handle, reset_context);
|
||||
if (r && r == -EAGAIN)
|
||||
goto retry;
|
||||
}
|
||||
@ -5244,7 +5284,7 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
if (amdgpu_gpu_recovery == 2 &&
|
||||
!(tmp_vram_lost_counter < atomic_read(&adev->vram_lost_counter)))
|
||||
amdgpu_device_recheck_guilty_jobs(
|
||||
tmp_adev, device_list_handle, &reset_context);
|
||||
tmp_adev, device_list_handle, reset_context);
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = tmp_adev->rings[i];
|
||||
@ -5259,6 +5299,9 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
|
||||
}
|
||||
|
||||
if (adev->enable_mes)
|
||||
amdgpu_mes_self_test(tmp_adev);
|
||||
|
||||
if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) {
|
||||
drm_helper_resume_force_mode(adev_to_drm(tmp_adev));
|
||||
}
|
||||
@ -5308,40 +5351,11 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev,
|
||||
|
||||
if (r)
|
||||
dev_info(adev->dev, "GPU reset end with ret = %d\n", r);
|
||||
|
||||
atomic_set(&adev->reset_domain->reset_res, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
struct amdgpu_recover_work_struct {
|
||||
struct work_struct base;
|
||||
struct amdgpu_device *adev;
|
||||
struct amdgpu_job *job;
|
||||
int ret;
|
||||
};
|
||||
|
||||
static void amdgpu_device_queue_gpu_recover_work(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_recover_work_struct *recover_work = container_of(work, struct amdgpu_recover_work_struct, base);
|
||||
|
||||
recover_work->ret = amdgpu_device_gpu_recover_imp(recover_work->adev, recover_work->job);
|
||||
}
|
||||
/*
|
||||
* Serialize gpu recover into reset domain single threaded wq
|
||||
*/
|
||||
int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct amdgpu_recover_work_struct work = {.adev = adev, .job = job};
|
||||
|
||||
INIT_WORK(&work.base, amdgpu_device_queue_gpu_recover_work);
|
||||
|
||||
if (!amdgpu_reset_domain_schedule(adev->reset_domain, &work.base))
|
||||
return -EAGAIN;
|
||||
|
||||
flush_work(&work.base);
|
||||
|
||||
return work.ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
|
||||
*
|
||||
@ -5490,6 +5504,36 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_is_peer_accessible - Check peer access through PCIe BAR
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @peer_adev: amdgpu_device pointer for peer device trying to access @adev
|
||||
*
|
||||
* Return true if @peer_adev can access (DMA) @adev through the PCIe
|
||||
* BAR, i.e. @adev is "large BAR" and the BAR matches the DMA mask of
|
||||
* @peer_adev.
|
||||
*/
|
||||
bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
|
||||
struct amdgpu_device *peer_adev)
|
||||
{
|
||||
#ifdef CONFIG_HSA_AMD_P2P
|
||||
uint64_t address_mask = peer_adev->dev->dma_mask ?
|
||||
~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1);
|
||||
resource_size_t aper_limit =
|
||||
adev->gmc.aper_base + adev->gmc.aper_size - 1;
|
||||
bool p2p_access = !(pci_p2pdma_distance_many(adev->pdev,
|
||||
&peer_adev->dev, 1, true) < 0);
|
||||
|
||||
return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size &&
|
||||
adev->gmc.real_vram_size == adev->gmc.visible_vram_size &&
|
||||
!(adev->gmc.aper_base & address_mask ||
|
||||
aper_limit & address_mask));
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int amdgpu_device_baco_enter(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
|
@ -194,6 +194,7 @@ static int hw_id_map[MAX_HWIP] = {
|
||||
[UMC_HWIP] = UMC_HWID,
|
||||
[XGMI_HWIP] = XGMI_HWID,
|
||||
[DCI_HWIP] = DCI_HWID,
|
||||
[PCIE_HWIP] = PCIE_HWID,
|
||||
};
|
||||
|
||||
static int amdgpu_discovery_read_binary_from_vram(struct amdgpu_device *adev, uint8_t *binary)
|
||||
@ -1435,6 +1436,11 @@ static int amdgpu_discovery_get_vcn_info(struct amdgpu_device *adev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* num_vcn_inst is currently limited to AMDGPU_MAX_VCN_INSTANCES
|
||||
* which is smaller than VCN_INFO_TABLE_MAX_NUM_INSTANCES
|
||||
* but that may change in the future with new GPUs so keep this
|
||||
* check for defensive purposes.
|
||||
*/
|
||||
if (adev->vcn.num_vcn_inst > VCN_INFO_TABLE_MAX_NUM_INSTANCES) {
|
||||
dev_err(adev->dev, "invalid vcn instances\n");
|
||||
return -EINVAL;
|
||||
@ -1450,6 +1456,9 @@ static int amdgpu_discovery_get_vcn_info(struct amdgpu_device *adev)
|
||||
|
||||
switch (le16_to_cpu(vcn_info->v1.header.version_major)) {
|
||||
case 1:
|
||||
/* num_vcn_inst is currently limited to AMDGPU_MAX_VCN_INSTANCES
|
||||
* so this won't overflow.
|
||||
*/
|
||||
for (v = 0; v < adev->vcn.num_vcn_inst; v++) {
|
||||
adev->vcn.vcn_codec_disable_mask[v] =
|
||||
le32_to_cpu(vcn_info->v1.instance_info[v].fuse_data.all_bits);
|
||||
@ -1621,12 +1630,14 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(13, 0, 1):
|
||||
case IP_VERSION(13, 0, 2):
|
||||
case IP_VERSION(13, 0, 3):
|
||||
case IP_VERSION(13, 0, 4):
|
||||
case IP_VERSION(13, 0, 5):
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 4):
|
||||
amdgpu_device_ip_block_add(adev, &psp_v13_0_4_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
"Failed to add psp ip block(MP0_HWIP:0x%x)\n",
|
||||
@ -1707,8 +1718,11 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(3, 0, 1):
|
||||
case IP_VERSION(3, 1, 2):
|
||||
case IP_VERSION(3, 1, 3):
|
||||
case IP_VERSION(3, 1, 4):
|
||||
case IP_VERSION(3, 1, 5):
|
||||
case IP_VERSION(3, 1, 6):
|
||||
case IP_VERSION(3, 2, 0):
|
||||
case IP_VERSION(3, 2, 1):
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
break;
|
||||
default:
|
||||
@ -1886,6 +1900,7 @@ static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev)
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(4, 0, 0):
|
||||
case IP_VERSION(4, 0, 2):
|
||||
case IP_VERSION(4, 0, 4):
|
||||
amdgpu_device_ip_block_add(adev, &vcn_v4_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &jpeg_v4_0_ip_block);
|
||||
@ -2194,12 +2209,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
break;
|
||||
case IP_VERSION(7, 4, 0):
|
||||
case IP_VERSION(7, 4, 1):
|
||||
adev->nbio.funcs = &nbio_v7_4_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(7, 4, 4):
|
||||
adev->nbio.funcs = &nbio_v7_4_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg_ald;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(7, 2, 0):
|
||||
case IP_VERSION(7, 2, 1):
|
||||
@ -2213,15 +2225,12 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(2, 3, 0):
|
||||
case IP_VERSION(2, 3, 1):
|
||||
case IP_VERSION(2, 3, 2):
|
||||
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(3, 3, 0):
|
||||
case IP_VERSION(3, 3, 1):
|
||||
case IP_VERSION(3, 3, 2):
|
||||
case IP_VERSION(3, 3, 3):
|
||||
adev->nbio.funcs = &nbio_v2_3_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg_sc;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(4, 3, 0):
|
||||
case IP_VERSION(4, 3, 1):
|
||||
@ -2321,6 +2330,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
|
||||
switch (adev->ip_versions[LSDMA_HWIP][0]) {
|
||||
case IP_VERSION(6, 0, 0):
|
||||
case IP_VERSION(6, 0, 1):
|
||||
case IP_VERSION(6, 0, 2):
|
||||
adev->lsdma.funcs = &lsdma_v6_0_funcs;
|
||||
break;
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include "atom.h"
|
||||
#include "amdgpu_connectors.h"
|
||||
#include "amdgpu_display.h"
|
||||
#include "soc15_common.h"
|
||||
#include "gc/gc_11_0_0_offset.h"
|
||||
#include "gc/gc_11_0_0_sh_mask.h"
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <linux/pci.h>
|
||||
@ -663,6 +666,11 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
|
||||
uint64_t modifier = 0;
|
||||
int num_pipes = 0;
|
||||
int num_pkrs = 0;
|
||||
|
||||
num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
|
||||
num_pipes = adev->gfx.config.gb_addr_config_fields.num_pipes;
|
||||
|
||||
if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) {
|
||||
modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
@ -675,7 +683,7 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
int bank_xor_bits = 0;
|
||||
int packers = 0;
|
||||
int rb = 0;
|
||||
int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
|
||||
int pipes = ilog2(num_pipes);
|
||||
uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, DCC_OFFSET_256B);
|
||||
|
||||
switch (swizzle >> 2) {
|
||||
@ -691,12 +699,17 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
case 6: /* 64 KiB _X */
|
||||
block_size_bits = 16;
|
||||
break;
|
||||
case 7: /* 256 KiB */
|
||||
block_size_bits = 18;
|
||||
break;
|
||||
default:
|
||||
/* RESERVED or VAR */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
|
||||
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0))
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX11;
|
||||
else if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
|
||||
else if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0))
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX10;
|
||||
@ -707,19 +720,32 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
case 0: /* Z microtiling */
|
||||
return -EINVAL;
|
||||
case 1: /* S microtiling */
|
||||
if (!has_xor)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0)) {
|
||||
if (!has_xor)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (!has_xor && afb->base.format->cpp[0] != 4)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
if (adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0)) {
|
||||
if (!has_xor && afb->base.format->cpp[0] != 4)
|
||||
version = AMD_FMT_MOD_TILE_VER_GFX9;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_xor) {
|
||||
if (num_pipes == num_pkrs && num_pkrs == 0) {
|
||||
DRM_ERROR("invalid number of pipes and packers\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (version) {
|
||||
case AMD_FMT_MOD_TILE_VER_GFX11:
|
||||
pipe_xor_bits = min(block_size_bits - 8, pipes);
|
||||
packers = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
|
||||
break;
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
|
||||
pipe_xor_bits = min(block_size_bits - 8, pipes);
|
||||
packers = min(block_size_bits - 8 - pipe_xor_bits,
|
||||
@ -753,9 +779,10 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
|
||||
u64 render_dcc_offset;
|
||||
|
||||
/* Enable constant encode on RAVEN2 and later. */
|
||||
bool dcc_constant_encode = adev->asic_type > CHIP_RAVEN ||
|
||||
bool dcc_constant_encode = (adev->asic_type > CHIP_RAVEN ||
|
||||
(adev->asic_type == CHIP_RAVEN &&
|
||||
adev->external_rev_id >= 0x81);
|
||||
adev->external_rev_id >= 0x81)) &&
|
||||
adev->ip_versions[GC_HWIP][0] < IP_VERSION(11, 0, 0);
|
||||
|
||||
int max_cblock_size = dcc_i64b ? AMD_FMT_MOD_DCC_BLOCK_64B :
|
||||
dcc_i128b ? AMD_FMT_MOD_DCC_BLOCK_128B :
|
||||
@ -870,10 +897,11 @@ static unsigned int get_dcc_block_size(uint64_t modifier, bool rb_aligned,
|
||||
return max(10 + (rb_aligned ? (int)AMD_FMT_MOD_GET(RB, modifier) : 0), 12);
|
||||
}
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10:
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS: {
|
||||
case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
|
||||
case AMD_FMT_MOD_TILE_VER_GFX11: {
|
||||
int pipes_log2 = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
|
||||
|
||||
if (ver == AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 &&
|
||||
if (ver >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS && pipes_log2 > 1 &&
|
||||
AMD_FMT_MOD_GET(PACKERS, modifier) == pipes_log2)
|
||||
++pipes_log2;
|
||||
|
||||
@ -966,6 +994,9 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb)
|
||||
case DC_SW_64KB_S_X:
|
||||
block_size_log2 = 16;
|
||||
break;
|
||||
case DC_SW_VAR_S_X:
|
||||
block_size_log2 = 18;
|
||||
break;
|
||||
default:
|
||||
drm_dbg_kms(rfb->base.dev,
|
||||
"Swizzle mode with unknown block size: %d\n", swizzle);
|
||||
|
@ -35,8 +35,6 @@
|
||||
#define amdgpu_display_add_encoder(adev, e, s, c) (adev)->mode_info.funcs->add_encoder((adev), (e), (s), (c))
|
||||
#define amdgpu_display_add_connector(adev, ci, sd, ct, ib, coi, h, r) (adev)->mode_info.funcs->add_connector((adev), (ci), (sd), (ct), (ib), (coi), (h), (r))
|
||||
|
||||
int amdgpu_display_freesync_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filp);
|
||||
void amdgpu_display_update_priority(struct amdgpu_device *adev);
|
||||
uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
|
||||
uint64_t bo_flags);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user