Merge a594533df0 ("Merge tag 'drm-next-2022-12-13' of git://anongit.freedesktop.org/drm/drm") into android-mainline
Steps on the way to 6.2-rc1 Resolves merge conflicts in: drivers/dma-buf/dma-buf.c drivers/dma-buf/heaps/system_heap.c include/linux/dma-buf.h Change-Id: I0b65680a68e10f3da6e510b8e4f58fcaff625fdf Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/in0_input
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
Description: RO. Current Voltage in millivolt.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_max
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
Description: RW. Card reactive sustained (PL1/Tau) power limit in microwatts.
|
||||
|
||||
The power controller will throttle the operating frequency
|
||||
if the power averaged over a window (typically seconds)
|
||||
exceeds this limit.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_rated_max
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
Description: RO. Card default power limit (default TDP setting).
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_max_interval
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
Description: RW. Sustained power limit interval (Tau in PL1/Tau) in
|
||||
milliseconds over which sustained power is averaged.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/power1_crit
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
Description: RW. Card reactive critical (I1) power limit in microwatts.
|
||||
|
||||
Card reactive critical (I1) power limit in microwatts is exposed
|
||||
for client products. The power controller will throttle the
|
||||
operating frequency if the power averaged over a window exceeds
|
||||
this limit.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/curr1_crit
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
Description: RW. Card reactive critical (I1) power limit in milliamperes.
|
||||
|
||||
Card reactive critical (I1) power limit in milliamperes is
|
||||
exposed for server products. The power controller will throttle
|
||||
the operating frequency if the power averaged over a window
|
||||
exceeds this limit.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
|
||||
What: /sys/devices/.../hwmon/hwmon<i>/energy1_input
|
||||
Date: February 2023
|
||||
KernelVersion: 6.2
|
||||
Contact: intel-gfx@lists.freedesktop.org
|
||||
Description: RO. Energy input of device or gt in microjoules.
|
||||
|
||||
For i915 device level hwmon devices (name "i915") this
|
||||
reflects energy input for the entire device. For gt level
|
||||
hwmon devices (name "i915_gtN") this reflects energy input
|
||||
for the gt.
|
||||
|
||||
Only supported for particular Intel i915 graphics platforms.
|
||||
@@ -0,0 +1,17 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
====================
|
||||
Compute Accelerators
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
introduction
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
||||
@@ -0,0 +1,110 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
============
|
||||
Introduction
|
||||
============
|
||||
|
||||
The Linux compute accelerators subsystem is designed to expose compute
|
||||
accelerators in a common way to user-space and provide a common set of
|
||||
functionality.
|
||||
|
||||
These devices can be either stand-alone ASICs or IP blocks inside an SoC/GPU.
|
||||
Although these devices are typically designed to accelerate
|
||||
Machine-Learning (ML) and/or Deep-Learning (DL) computations, the accel layer
|
||||
is not limited to handling these types of accelerators.
|
||||
|
||||
Typically, a compute accelerator will belong to one of the following
|
||||
categories:
|
||||
|
||||
- Edge AI - doing inference at an edge device. It can be an embedded ASIC/FPGA,
|
||||
or an IP inside a SoC (e.g. laptop web camera). These devices
|
||||
are typically configured using registers and can work with or without DMA.
|
||||
|
||||
- Inference data-center - single/multi user devices in a large server. This
|
||||
type of device can be stand-alone or an IP inside a SoC or a GPU. It will
|
||||
have on-board DRAM (to hold the DL topology), DMA engines and
|
||||
command submission queues (either kernel or user-space queues).
|
||||
It might also have an MMU to manage multiple users and might also enable
|
||||
virtualization (SR-IOV) to support multiple VMs on the same device. In
|
||||
addition, these devices will usually have some tools, such as profiler and
|
||||
debugger.
|
||||
|
||||
- Training data-center - Similar to Inference data-center cards, but typically
|
||||
have more computational power and memory b/w (e.g. HBM) and will likely have
|
||||
a method of scaling-up/out, i.e. connecting to other training cards inside
|
||||
the server or in other servers, respectively.
|
||||
|
||||
All these devices typically have different runtime user-space software stacks,
|
||||
that are tailored-made to their h/w. In addition, they will also probably
|
||||
include a compiler to generate programs to their custom-made computational
|
||||
engines. Typically, the common layer in user-space will be the DL frameworks,
|
||||
such as PyTorch and TensorFlow.
|
||||
|
||||
Sharing code with DRM
|
||||
=====================
|
||||
|
||||
Because this type of devices can be an IP inside GPUs or have similar
|
||||
characteristics as those of GPUs, the accel subsystem will use the
|
||||
DRM subsystem's code and functionality. i.e. the accel core code will
|
||||
be part of the DRM subsystem and an accel device will be a new type of DRM
|
||||
device.
|
||||
|
||||
This will allow us to leverage the extensive DRM code-base and
|
||||
collaborate with DRM developers that have experience with this type of
|
||||
devices. In addition, new features that will be added for the accelerator
|
||||
drivers can be of use to GPU drivers as well.
|
||||
|
||||
Differentiation from GPUs
|
||||
=========================
|
||||
|
||||
Because we want to prevent the extensive user-space graphic software stack
|
||||
from trying to use an accelerator as a GPU, the compute accelerators will be
|
||||
differentiated from GPUs by using a new major number and new device char files.
|
||||
|
||||
Furthermore, the drivers will be located in a separate place in the kernel
|
||||
tree - drivers/accel/.
|
||||
|
||||
The accelerator devices will be exposed to the user space with the dedicated
|
||||
261 major number and will have the following convention:
|
||||
|
||||
- device char files - /dev/accel/accel*
|
||||
- sysfs - /sys/class/accel/accel*/
|
||||
- debugfs - /sys/kernel/debug/accel/accel*/
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
First, read the DRM documentation at Documentation/gpu/index.rst.
|
||||
Not only it will explain how to write a new DRM driver but it will also
|
||||
contain all the information on how to contribute, the Code Of Conduct and
|
||||
what is the coding style/documentation. All of that is the same for the
|
||||
accel subsystem.
|
||||
|
||||
Second, make sure the kernel is configured with CONFIG_DRM_ACCEL.
|
||||
|
||||
To expose your device as an accelerator, two changes are needed to
|
||||
be done in your driver (as opposed to a standard DRM driver):
|
||||
|
||||
- Add the DRIVER_COMPUTE_ACCEL feature flag in your drm_driver's
|
||||
driver_features field. It is important to note that this driver feature is
|
||||
mutually exclusive with DRIVER_RENDER and DRIVER_MODESET. Devices that want
|
||||
to expose both graphics and compute device char files should be handled by
|
||||
two drivers that are connected using the auxiliary bus framework.
|
||||
|
||||
- Change the open callback in your driver fops structure to accel_open().
|
||||
Alternatively, your driver can use DEFINE_DRM_ACCEL_FOPS macro to easily
|
||||
set the correct function operations pointers structure.
|
||||
|
||||
External References
|
||||
===================
|
||||
|
||||
email threads
|
||||
-------------
|
||||
|
||||
* `Initial discussion on the New subsystem for acceleration devices <https://lkml.org/lkml/2022/7/31/83>`_ - Oded Gabbay (2022)
|
||||
* `patch-set to add the new subsystem <https://lkml.org/lkml/2022/10/22/544>`_ - Oded Gabbay (2022)
|
||||
|
||||
Conference talks
|
||||
----------------
|
||||
|
||||
* `LPC 2022 Accelerators BOF outcomes summary <https://airlied.blogspot.com/2022/09/accelerators-bof-outcomes-summary.html>`_ - Dave Airlie (2022)
|
||||
@@ -3080,6 +3080,11 @@
|
||||
...
|
||||
255 = /dev/osd255 256th OSD Device
|
||||
|
||||
261 char Compute Acceleration Devices
|
||||
0 = /dev/accel/accel0 First acceleration device
|
||||
1 = /dev/accel/accel1 Second acceleration device
|
||||
...
|
||||
|
||||
384-511 char RESERVED FOR DYNAMIC ASSIGNMENT
|
||||
Character devices that request a dynamic allocation of major
|
||||
number will take numbers starting from 511 and downward,
|
||||
|
||||
@@ -3793,12 +3793,15 @@
|
||||
shutdown the other cpus. Instead use the REBOOT_VECTOR
|
||||
irq.
|
||||
|
||||
nomodeset Disable kernel modesetting. DRM drivers will not perform
|
||||
display-mode changes or accelerated rendering. Only the
|
||||
system framebuffer will be available for use if this was
|
||||
set-up by the firmware or boot loader.
|
||||
nomodeset Disable kernel modesetting. Most systems' firmware
|
||||
sets up a display mode and provides framebuffer memory
|
||||
for output. With nomodeset, DRM and fbdev drivers will
|
||||
not load if they could possibly displace the pre-
|
||||
initialized output. Only the system framebuffer will
|
||||
be available for use. The respective drivers will not
|
||||
perform display-mode changes or accelerated rendering.
|
||||
|
||||
Useful as fallback, or for testing and debugging.
|
||||
Useful as error fallback, or for testing and debugging.
|
||||
|
||||
nomodule Disable module load
|
||||
|
||||
|
||||
@@ -12,9 +12,14 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun6i-a31-mipi-dsi
|
||||
- allwinner,sun50i-a64-mipi-dsi
|
||||
oneOf:
|
||||
- enum:
|
||||
- allwinner,sun6i-a31-mipi-dsi
|
||||
- allwinner,sun50i-a64-mipi-dsi
|
||||
- allwinner,sun50i-a100-mipi-dsi
|
||||
- items:
|
||||
- const: allwinner,sun20i-d1-mipi-dsi
|
||||
- const: allwinner,sun50i-a100-mipi-dsi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -59,7 +64,6 @@ required:
|
||||
- phys
|
||||
- phy-names
|
||||
- resets
|
||||
- vcc-dsi-supply
|
||||
- port
|
||||
|
||||
allOf:
|
||||
@@ -68,7 +72,9 @@ allOf:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: allwinner,sun6i-a31-mipi-dsi
|
||||
enum:
|
||||
- allwinner,sun6i-a31-mipi-dsi
|
||||
- allwinner,sun50i-a100-mipi-dsi
|
||||
|
||||
then:
|
||||
properties:
|
||||
@@ -78,16 +84,22 @@ allOf:
|
||||
required:
|
||||
- clock-names
|
||||
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: allwinner,sun50i-a64-mipi-dsi
|
||||
enum:
|
||||
- allwinner,sun6i-a31-mipi-dsi
|
||||
- allwinner,sun50i-a64-mipi-dsi
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 1
|
||||
required:
|
||||
- vcc-dsi-supply
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/bridge/renesas,dsi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas RZ/G2L MIPI DSI Encoder
|
||||
|
||||
maintainers:
|
||||
- Biju Das <biju.das.jz@bp.renesas.com>
|
||||
|
||||
description: |
|
||||
This binding describes the MIPI DSI encoder embedded in the Renesas
|
||||
RZ/G2L alike family of SoC's. The encoder can operate in DSI mode, with
|
||||
up to four data lanes.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/display/dsi-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r9a07g044-mipi-dsi # RZ/G2{L,LC}
|
||||
- const: renesas,rzg2l-mipi-dsi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: Sequence operation channel 0 interrupt
|
||||
- description: Sequence operation channel 1 interrupt
|
||||
- description: Video-Input operation channel 1 interrupt
|
||||
- description: DSI Packet Receive interrupt
|
||||
- description: DSI Fatal Error interrupt
|
||||
- description: DSI D-PHY PPI interrupt
|
||||
- description: Debug interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: seq0
|
||||
- const: seq1
|
||||
- const: vin1
|
||||
- const: rcv
|
||||
- const: ferr
|
||||
- const: ppi
|
||||
- const: debug
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: DSI D-PHY PLL multiplied clock
|
||||
- description: DSI D-PHY system clock
|
||||
- description: DSI AXI bus clock
|
||||
- description: DSI Register access clock
|
||||
- description: DSI Video clock
|
||||
- description: DSI D-PHY Escape mode transmit clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pllclk
|
||||
- const: sysclk
|
||||
- const: aclk
|
||||
- const: pclk
|
||||
- const: vclk
|
||||
- const: lpclk
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MIPI_DSI_CMN_RSTB
|
||||
- description: MIPI_DSI_ARESET_N
|
||||
- description: MIPI_DSI_PRESET_N
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: rst
|
||||
- const: arst
|
||||
- const: prst
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Parallel input port
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description: DSI output port
|
||||
|
||||
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
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- power-domains
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r9a07g044-cpg.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
dsi0: dsi@10850000 {
|
||||
compatible = "renesas,r9a07g044-mipi-dsi", "renesas,rzg2l-mipi-dsi";
|
||||
reg = <0x10850000 0x20000>;
|
||||
interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "seq0", "seq1", "vin1", "rcv",
|
||||
"ferr", "ppi", "debug";
|
||||
clocks = <&cpg CPG_MOD R9A07G044_MIPI_DSI_PLLCLK>,
|
||||
<&cpg CPG_MOD R9A07G044_MIPI_DSI_SYSCLK>,
|
||||
<&cpg CPG_MOD R9A07G044_MIPI_DSI_ACLK>,
|
||||
<&cpg CPG_MOD R9A07G044_MIPI_DSI_PCLK>,
|
||||
<&cpg CPG_MOD R9A07G044_MIPI_DSI_VCLK>,
|
||||
<&cpg CPG_MOD R9A07G044_MIPI_DSI_LPCLK>;
|
||||
clock-names = "pllclk", "sysclk", "aclk", "pclk", "vclk", "lpclk";
|
||||
resets = <&cpg R9A07G044_MIPI_DSI_CMN_RSTB>,
|
||||
<&cpg R9A07G044_MIPI_DSI_ARESET_N>,
|
||||
<&cpg R9A07G044_MIPI_DSI_PRESET_N>;
|
||||
reset-names = "rst", "arst", "prst";
|
||||
power-domains = <&cpg>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&du_out_dsi0>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
data-lanes = <1 2 3 4>;
|
||||
remote-endpoint = <&adv7535_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -23,6 +23,7 @@ properties:
|
||||
- mediatek,mt8173-dpi
|
||||
- mediatek,mt8183-dpi
|
||||
- mediatek,mt8186-dpi
|
||||
- mediatek,mt8188-dp-intf
|
||||
- mediatek,mt8192-dpi
|
||||
- mediatek,mt8195-dp-intf
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/dpu-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU common properties
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
description: |
|
||||
Common properties for QCom DPU display controller.
|
||||
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
Contains the list of output ports from DPU device. These ports
|
||||
connect to interfaces that are external to the DPU hardware,
|
||||
such as DSI, DP etc.
|
||||
|
||||
patternProperties:
|
||||
"^port@[0-9a-f]+$":
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
# at least one port is required
|
||||
required:
|
||||
- port@0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- interrupts
|
||||
- power-domains
|
||||
- operating-points-v2
|
||||
- ports
|
||||
|
||||
additionalProperties: true
|
||||
@@ -1,223 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/dpu-msm8998.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for MSM8998 target
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
description: |
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS and DPU are mentioned for MSM8998 target.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,msm8998-mdss
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
const: mdss
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock
|
||||
- description: Display AXI clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#address-cells": true
|
||||
|
||||
"#size-cells": true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
|
||||
iommus:
|
||||
items:
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
|
||||
|
||||
ranges: true
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
description: Node containing the properties of DPU.
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,msm8998-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for regdma register set
|
||||
- description: Address offset and size for vbif register set
|
||||
- description: Address offset and size for non-realtime vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: regdma
|
||||
- const: vbif
|
||||
- const: vbif_nrt
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display ahb clock
|
||||
- description: Display axi clock
|
||||
- description: Display mem-noc clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: mnoc
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
Contains the list of output ports from DPU device. These ports
|
||||
connect to interfaces that are external to the DPU hardware,
|
||||
such as DSI, DP etc. Each output port contains an endpoint that
|
||||
describes how it is connected to an external interface.
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF1 (DSI1)
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF2 (DSI2)
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- interrupts
|
||||
- power-domains
|
||||
- operating-points-v2
|
||||
- ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- iommus
|
||||
- ranges
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,mmcc-msm8998.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
mdss: display-subsystem@c900000 {
|
||||
compatible = "qcom,msm8998-mdss";
|
||||
reg = <0x0c900000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
clocks = <&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_AXI_CLK>,
|
||||
<&mmcc MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "bus", "core";
|
||||
|
||||
#address-cells = <1>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
iommus = <&mmss_smmu 0>;
|
||||
|
||||
power-domains = <&mmcc MDSS_GDSC>;
|
||||
ranges;
|
||||
|
||||
display-controller@c901000 {
|
||||
compatible = "qcom,msm8998-dpu";
|
||||
reg = <0x0c901000 0x8f000>,
|
||||
<0x0c9a8e00 0xf0>,
|
||||
<0x0c9b0000 0x2008>,
|
||||
<0x0c9b8000 0x1040>;
|
||||
reg-names = "mdp", "regdma", "vbif", "vbif_nrt";
|
||||
|
||||
clocks = <&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_AXI_CLK>,
|
||||
<&mmcc MNOC_AHB_CLK>,
|
||||
<&mmcc MDSS_MDP_CLK>,
|
||||
<&mmcc MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface", "bus", "mnoc", "core", "vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd MSM8998_VDDMX>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -1,222 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/dpu-qcm2290.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for QCM2290 target
|
||||
|
||||
maintainers:
|
||||
- Loic Poulain <loic.poulain@linaro.org>
|
||||
|
||||
description: |
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS
|
||||
and DPU are mentioned for QCM2290 target.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,qcm2290-mdss
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
const: mdss
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AXI clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#address-cells": true
|
||||
|
||||
"#size-cells": true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
|
||||
iommus:
|
||||
items:
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port1
|
||||
|
||||
ranges: true
|
||||
|
||||
interconnects:
|
||||
items:
|
||||
- description: Interconnect path specifying the port ids for data bus
|
||||
|
||||
interconnect-names:
|
||||
const: mdp0-mem
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
description: Node containing the properties of DPU.
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,qcm2290-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AXI clock from gcc
|
||||
- description: Display AHB clock from dispcc
|
||||
- description: Display core clock from dispcc
|
||||
- description: Display lut clock from dispcc
|
||||
- description: Display vsync clock from dispcc
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: iface
|
||||
- const: core
|
||||
- const: lut
|
||||
- const: vsync
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
Contains the list of output ports from DPU device. These ports
|
||||
connect to interfaces that are external to the DPU hardware,
|
||||
such as DSI. Each output port contains an endpoint that
|
||||
describes how it is connected to an external interface.
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF1 (DSI1)
|
||||
|
||||
required:
|
||||
- port@0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- interrupts
|
||||
- power-domains
|
||||
- operating-points-v2
|
||||
- ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- iommus
|
||||
- ranges
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,qcm2290.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
mdss: mdss@5e00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,qcm2290-mdss";
|
||||
reg = <0x05e00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "bus", "core";
|
||||
|
||||
interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>;
|
||||
interconnect-names = "mdp0-mem";
|
||||
|
||||
iommus = <&apps_smmu 0x420 0x2>,
|
||||
<&apps_smmu 0x421 0x0>;
|
||||
ranges;
|
||||
|
||||
mdss_mdp: display-controller@5e01000 {
|
||||
compatible = "qcom,qcm2290-dpu";
|
||||
reg = <0x05e01000 0x8f000>,
|
||||
<0x05eb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "core", "lut", "vsync";
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd QCM2290_VDDCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -1,235 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/dpu-sc7180.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SC7180 target
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
description: |
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS and DPU are mentioned for SC7180 target.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sc7180-mdss
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
const: mdss
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AHB clock from dispcc
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: ahb
|
||||
- const: core
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#address-cells": true
|
||||
|
||||
"#size-cells": true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
|
||||
iommus:
|
||||
items:
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
|
||||
|
||||
ranges: true
|
||||
|
||||
interconnects:
|
||||
items:
|
||||
- description: Interconnect path specifying the port ids for data bus
|
||||
|
||||
interconnect-names:
|
||||
const: mdp0-mem
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
description: Node containing the properties of DPU.
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sc7180-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display hf axi clock
|
||||
- description: Display ahb clock
|
||||
- description: Display rotator clock
|
||||
- description: Display lut clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: iface
|
||||
- const: rot
|
||||
- const: lut
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
Contains the list of output ports from DPU device. These ports
|
||||
connect to interfaces that are external to the DPU hardware,
|
||||
such as DSI, DP etc. Each output port contains an endpoint that
|
||||
describes how it is connected to an external interface.
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF1 (DSI1)
|
||||
|
||||
port@2:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF0 (DP)
|
||||
|
||||
required:
|
||||
- port@0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- interrupts
|
||||
- power-domains
|
||||
- operating-points-v2
|
||||
- ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- iommus
|
||||
- ranges
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc7180.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sc7180.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sdm845.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,sc7180-mdss";
|
||||
reg = <0xae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "ahb", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
|
||||
interconnect-names = "mdp0-mem";
|
||||
|
||||
iommus = <&apps_smmu 0x800 0x2>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sc7180-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ROT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "rot", "lut", "core",
|
||||
"vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SC7180_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
dpu_intf0_out: endpoint {
|
||||
remote-endpoint = <&dp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -1,239 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/dpu-sc7280.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SC7280
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
description: |
|
||||
Device tree bindings for MSM Mobile Display Subsystem (MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS and DPU are mentioned for SC7280.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7280-mdss
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
const: mdss
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AHB clock from dispcc
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: ahb
|
||||
- const: core
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#address-cells": true
|
||||
|
||||
"#size-cells": true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
|
||||
iommus:
|
||||
items:
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
|
||||
|
||||
ranges: true
|
||||
|
||||
interconnects:
|
||||
items:
|
||||
- description: Interconnect path specifying the port ids for data bus
|
||||
|
||||
interconnect-names:
|
||||
const: mdp0-mem
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
description: Node containing the properties of DPU.
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7280-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display hf axi clock
|
||||
- description: Display sf axi clock
|
||||
- description: Display ahb clock
|
||||
- description: Display lut clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: nrt_bus
|
||||
- const: iface
|
||||
- const: lut
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
Contains the list of output ports from DPU device. These ports
|
||||
connect to interfaces that are external to the DPU hardware,
|
||||
such as DSI, DP etc. Each output port contains an endpoint that
|
||||
describes how it is connected to an external interface.
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF1 (DSI)
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF5 (EDP)
|
||||
|
||||
required:
|
||||
- port@0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- interrupts
|
||||
- power-domains
|
||||
- operating-points-v2
|
||||
- ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- iommus
|
||||
- ranges
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc7280.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sc7280.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sc7280.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,sc7280-mdss";
|
||||
reg = <0xae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>;
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface",
|
||||
"ahb",
|
||||
"core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
|
||||
interconnect-names = "mdp0-mem";
|
||||
|
||||
iommus = <&apps_smmu 0x900 0x402>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sc7280-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&gcc GCC_DISP_SF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus",
|
||||
"nrt_bus",
|
||||
"iface",
|
||||
"lut",
|
||||
"core",
|
||||
"vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SC7280_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf5_out: endpoint {
|
||||
remote-endpoint = <&edp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -1,217 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/dpu-sdm845.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SDM845 target
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
description: |
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS and DPU are mentioned for SDM845 target.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sdm845-mdss
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
const: mdss
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: core
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#address-cells": true
|
||||
|
||||
"#size-cells": true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
|
||||
iommus:
|
||||
items:
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port1
|
||||
|
||||
ranges: true
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
description: Node containing the properties of DPU.
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sdm845-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display ahb clock
|
||||
- description: Display axi clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
Contains the list of output ports from DPU device. These ports
|
||||
connect to interfaces that are external to the DPU hardware,
|
||||
such as DSI, DP etc. Each output port contains an endpoint that
|
||||
describes how it is connected to an external interface.
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF1 (DSI1)
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: DPU_INTF2 (DSI2)
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- interrupts
|
||||
- power-domains
|
||||
- operating-points-v2
|
||||
- ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- iommus
|
||||
- ranges
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,sdm845-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x880 0x8>,
|
||||
<&apps_smmu 0xc80 0x8>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sdm845-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface", "bus", "core", "vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SDM845_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -49,6 +49,7 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
phy-names:
|
||||
deprecated: true
|
||||
const: dsi
|
||||
|
||||
"#address-cells": true
|
||||
@@ -80,6 +81,9 @@ properties:
|
||||
|
||||
operating-points-v2: true
|
||||
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
ports:
|
||||
$ref: "/schemas/graph.yaml#/properties/ports"
|
||||
description: |
|
||||
@@ -131,7 +135,6 @@ required:
|
||||
- clocks
|
||||
- clock-names
|
||||
- phys
|
||||
- phy-names
|
||||
- assigned-clocks
|
||||
- assigned-clock-parents
|
||||
- power-domains
|
||||
|
||||
@@ -16,6 +16,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,dsi-phy-14nm
|
||||
- qcom,dsi-phy-14nm-2290
|
||||
- qcom,dsi-phy-14nm-660
|
||||
- qcom,dsi-phy-14nm-8953
|
||||
|
||||
|
||||
@@ -2,37 +2,9 @@ Qualcomm adreno/snapdragon MDP5 display controller
|
||||
|
||||
Description:
|
||||
|
||||
This is the bindings documentation for the Mobile Display Subsytem(MDSS) that
|
||||
encapsulates sub-blocks like MDP5, DSI, HDMI, eDP etc, and the MDP5 display
|
||||
This is the bindings documentation for the MDP5 display
|
||||
controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and MSM8996.
|
||||
|
||||
MDSS:
|
||||
Required properties:
|
||||
- compatible:
|
||||
* "qcom,mdss" - MDSS
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- reg-names: The names of register regions. The following regions are required:
|
||||
* "mdss_phys"
|
||||
* "vbif_phys"
|
||||
- interrupts: The interrupt signal from MDSS.
|
||||
- interrupt-controller: identifies the node as an interrupt controller.
|
||||
- #interrupt-cells: specifies the number of cells needed to encode an interrupt
|
||||
source, should be 1.
|
||||
- power-domains: a power domain consumer specifier according to
|
||||
Documentation/devicetree/bindings/power/power_domain.txt
|
||||
- clocks: device clocks. See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: the following clocks are required.
|
||||
* "iface"
|
||||
* "bus"
|
||||
* "vsync"
|
||||
- #address-cells: number of address cells for the MDSS children. Should be 1.
|
||||
- #size-cells: Should be 1.
|
||||
- ranges: parent bus address space is the same as the child bus address space.
|
||||
|
||||
Optional properties:
|
||||
- clock-names: the following clocks are optional:
|
||||
* "lut"
|
||||
|
||||
MDP5:
|
||||
Required properties:
|
||||
- compatible:
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/mdss-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display MDSS common properties
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
const: mdss
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#address-cells": true
|
||||
|
||||
"#size-cells": true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
|
||||
iommus:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port0
|
||||
- description: Phandle to apps_smmu node with SID mask for Hard-Fail port1
|
||||
|
||||
ranges: true
|
||||
|
||||
interconnects:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Interconnect path from mdp0 (or a single mdp) port to the data bus
|
||||
- description: Interconnect path from mdp1 port to the data bus
|
||||
|
||||
interconnect-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: mdp0-mem
|
||||
- const: mdp1-mem
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- iommus
|
||||
- ranges
|
||||
|
||||
additionalProperties: true
|
||||
@@ -0,0 +1,196 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Mobile Display SubSystem (MDSS)
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
description:
|
||||
This is the bindings documentation for the Mobile Display Subsytem(MDSS) that
|
||||
encapsulates sub-blocks like MDP5, DSI, HDMI, eDP, etc.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,mdss
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: mdss_phys
|
||||
- const: vbif_phys
|
||||
- const: vbif_nrt_phys
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
description: |
|
||||
The MDSS power domain provided by GCC
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Display abh clock
|
||||
- description: Display axi clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: vsync
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 1
|
||||
|
||||
ranges: true
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- "#interrupt-cells"
|
||||
- power-domains
|
||||
- clocks
|
||||
- clock-names
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- ranges
|
||||
|
||||
patternProperties:
|
||||
"^mdp@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdp5
|
||||
|
||||
"^dsi@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,dsi-phy-14nm
|
||||
- qcom,dsi-phy-14nm-660
|
||||
- qcom,dsi-phy-14nm-8953
|
||||
- qcom,dsi-phy-20nm
|
||||
- qcom,dsi-phy-28nm-hpm
|
||||
- qcom,dsi-phy-28nm-lp
|
||||
|
||||
"^hdmi-phy@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,hdmi-phy-8084
|
||||
- qcom,hdmi-phy-8660
|
||||
- qcom,hdmi-phy-8960
|
||||
- qcom,hdmi-phy-8974
|
||||
- qcom,hdmi-phy-8996
|
||||
|
||||
"^hdmi-tx@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
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
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-msm8916.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
mdss@1a00000 {
|
||||
compatible = "qcom,mdss";
|
||||
reg = <0x1a00000 0x1000>,
|
||||
<0x1ac8000 0x3000>;
|
||||
reg-names = "mdss_phys", "vbif_phys";
|
||||
|
||||
power-domains = <&gcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&gcc GCC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_MDSS_AXI_CLK>,
|
||||
<&gcc GCC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface",
|
||||
"bus",
|
||||
"vsync";
|
||||
|
||||
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
mdp@1a01000 {
|
||||
compatible = "qcom,mdp5";
|
||||
reg = <0x01a01000 0x89000>;
|
||||
reg-names = "mdp_phys";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
clocks = <&gcc GCC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_MDSS_AXI_CLK>,
|
||||
<&gcc GCC_MDSS_MDP_CLK>,
|
||||
<&gcc GCC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface",
|
||||
"bus",
|
||||
"core",
|
||||
"vsync";
|
||||
|
||||
iommus = <&apps_iommu 4>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
mdp5_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,95 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,msm8998-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for MSM8998 target
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,msm8998-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for regdma register set
|
||||
- description: Address offset and size for vbif register set
|
||||
- description: Address offset and size for non-realtime vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: regdma
|
||||
- const: vbif
|
||||
- const: vbif_nrt
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display ahb clock
|
||||
- description: Display axi clock
|
||||
- description: Display mem-noc clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: mnoc
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,mmcc-msm8998.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@c901000 {
|
||||
compatible = "qcom,msm8998-dpu";
|
||||
reg = <0x0c901000 0x8f000>,
|
||||
<0x0c9a8e00 0xf0>,
|
||||
<0x0c9b0000 0x2008>,
|
||||
<0x0c9b8000 0x1040>;
|
||||
reg-names = "mdp", "regdma", "vbif", "vbif_nrt";
|
||||
|
||||
clocks = <&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_AXI_CLK>,
|
||||
<&mmcc MNOC_AHB_CLK>,
|
||||
<&mmcc MDSS_MDP_CLK>,
|
||||
<&mmcc MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface", "bus", "mnoc", "core", "vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd MSM8998_VDDMX>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,268 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,msm8998-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm MSM8998 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS are mentioned for MSM8998 target.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,msm8998-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock
|
||||
- description: Display AXI clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,msm8998-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-10nm-8998
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,mmcc-msm8998.h>
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@c900000 {
|
||||
compatible = "qcom,msm8998-mdss";
|
||||
reg = <0x0c900000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
clocks = <&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_AXI_CLK>,
|
||||
<&mmcc MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "bus", "core";
|
||||
|
||||
#address-cells = <1>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
iommus = <&mmss_smmu 0>;
|
||||
|
||||
power-domains = <&mmcc MDSS_GDSC>;
|
||||
ranges;
|
||||
|
||||
display-controller@c901000 {
|
||||
compatible = "qcom,msm8998-dpu";
|
||||
reg = <0x0c901000 0x8f000>,
|
||||
<0x0c9a8e00 0xf0>,
|
||||
<0x0c9b0000 0x2008>,
|
||||
<0x0c9b8000 0x1040>;
|
||||
reg-names = "mdp", "regdma", "vbif", "vbif_nrt";
|
||||
|
||||
clocks = <&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_AXI_CLK>,
|
||||
<&mmcc MNOC_AHB_CLK>,
|
||||
<&mmcc MDSS_MDP_CLK>,
|
||||
<&mmcc MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface", "bus", "mnoc", "core", "vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd MSM8998_VDDMX>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@c994000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0c994000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&mmcc MDSS_BYTE0_CLK>,
|
||||
<&mmcc MDSS_BYTE0_INTF_CLK>,
|
||||
<&mmcc MDSS_PCLK0_CLK>,
|
||||
<&mmcc MDSS_ESC0_CLK>,
|
||||
<&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&mmcc BYTE0_CLK_SRC>, <&mmcc PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmpd MSM8998_VDDCX>;
|
||||
|
||||
phys = <&dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_phy: phy@c994400 {
|
||||
compatible = "qcom,dsi-phy-10nm-8998";
|
||||
reg = <0x0c994400 0x200>,
|
||||
<0x0c994600 0x280>,
|
||||
<0x0c994a00 0x1e0>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&mmcc MDSS_AHB_CLK>,
|
||||
<&rpmcc RPM_SMD_XO_CLK_SRC>;
|
||||
clock-names = "iface", "ref";
|
||||
|
||||
vdds-supply = <&pm8998_l1>;
|
||||
};
|
||||
|
||||
dsi@c996000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0c996000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <5>;
|
||||
|
||||
clocks = <&mmcc MDSS_BYTE1_CLK>,
|
||||
<&mmcc MDSS_BYTE1_INTF_CLK>,
|
||||
<&mmcc MDSS_PCLK1_CLK>,
|
||||
<&mmcc MDSS_ESC1_CLK>,
|
||||
<&mmcc MDSS_AHB_CLK>,
|
||||
<&mmcc MDSS_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&mmcc BYTE1_CLK_SRC>, <&mmcc PCLK1_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmpd MSM8998_VDDCX>;
|
||||
|
||||
phys = <&dsi1_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi1_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi1_phy: phy@c996400 {
|
||||
compatible = "qcom,dsi-phy-10nm-8998";
|
||||
reg = <0x0c996400 0x200>,
|
||||
<0x0c996600 0x280>,
|
||||
<0x0c996a00 0x10e>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&mmcc MDSS_AHB_CLK>,
|
||||
<&rpmcc RPM_SMD_XO_CLK_SRC>;
|
||||
clock-names = "iface", "ref";
|
||||
|
||||
vdds-supply = <&pm8998_l1>;
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,84 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for QCM2290 target
|
||||
|
||||
maintainers:
|
||||
- Loic Poulain <loic.poulain@linaro.org>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,qcm2290-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AXI clock from gcc
|
||||
- description: Display AHB clock from dispcc
|
||||
- description: Display core clock from dispcc
|
||||
- description: Display lut clock from dispcc
|
||||
- description: Display vsync clock from dispcc
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: iface
|
||||
- const: core
|
||||
- const: lut
|
||||
- const: vsync
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@5e01000 {
|
||||
compatible = "qcom,qcm2290-dpu";
|
||||
reg = <0x05e01000 0x8f000>,
|
||||
<0x05eb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "core", "lut", "vsync";
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd QCM2290_VDDCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,198 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QCM220 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Loic Poulain <loic.poulain@linaro.org>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS
|
||||
are mentioned for QCM2290 target.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,qcm2290-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AXI clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 2
|
||||
|
||||
interconnects:
|
||||
maxItems: 1
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,qcm2290-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-ctrl-6g-qcm2290
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-14nm-2290
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,qcm2290.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
mdss@5e00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,qcm2290-mdss";
|
||||
reg = <0x05e00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "bus", "core";
|
||||
|
||||
interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>;
|
||||
interconnect-names = "mdp0-mem";
|
||||
|
||||
iommus = <&apps_smmu 0x420 0x2>,
|
||||
<&apps_smmu 0x421 0x0>;
|
||||
ranges;
|
||||
|
||||
display-controller@5e01000 {
|
||||
compatible = "qcom,qcm2290-dpu";
|
||||
reg = <0x05e01000 0x8f000>,
|
||||
<0x05eb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "core", "lut", "vsync";
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd QCM2290_VDDCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@5e94000 {
|
||||
compatible = "qcom,dsi-ctrl-6g-qcm2290";
|
||||
reg = <0x05e94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>, <&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmpd QCM2290_VDDCX>;
|
||||
|
||||
phys = <&dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_phy: phy@5e94400 {
|
||||
compatible = "qcom,dsi-phy-14nm-2290";
|
||||
reg = <0x05e94400 0x100>,
|
||||
<0x05e94500 0x300>,
|
||||
<0x05e94800 0x188>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, <&rpmcc RPM_SMD_XO_CLK_SRC>;
|
||||
clock-names = "iface", "ref";
|
||||
vcca-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,95 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sc7180-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SC7180 target
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sc7180-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display hf axi clock
|
||||
- description: Display ahb clock
|
||||
- description: Display rotator clock
|
||||
- description: Display lut clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: iface
|
||||
- const: rot
|
||||
- const: lut
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc7180.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sc7180.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sc7180-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ROT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "rot", "lut", "core",
|
||||
"vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SC7180_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,304 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sc7180-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SC7180 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS are mentioned for SC7180 target.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sc7180-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AHB clock from dispcc
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: ahb
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 1
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7180-dpu
|
||||
|
||||
"^displayport-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7180-dp
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-10nm
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc7180.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sc7180.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sdm845.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,sc7180-mdss";
|
||||
reg = <0xae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "ahb", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
|
||||
interconnect-names = "mdp0-mem";
|
||||
|
||||
iommus = <&apps_smmu 0x800 0x2>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sc7180-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ROT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "rot", "lut", "core",
|
||||
"vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SC7180_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
dpu_intf0_out: endpoint {
|
||||
remote-endpoint = <&dp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>, <&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi_phy 0>, <&dsi_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SC7180_CX>;
|
||||
|
||||
phys = <&dsi_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-187500000 {
|
||||
opp-hz = /bits/ 64 <187500000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi_phy: phy@ae94400 {
|
||||
compatible = "qcom,dsi-phy-10nm";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94a00 0x1e0>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
|
||||
displayport-controller@ae90000 {
|
||||
compatible = "qcom,sc7180-dp";
|
||||
|
||||
reg = <0xae90000 0x200>,
|
||||
<0xae90200 0x200>,
|
||||
<0xae90400 0xc00>,
|
||||
<0xae91000 0x400>,
|
||||
<0xae91400 0x400>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <12>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_DP_AUX_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_DP_LINK_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_DP_PIXEL_CLK>;
|
||||
clock-names = "core_iface", "core_aux", "ctrl_link",
|
||||
"ctrl_link_iface", "stream_pixel";
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
|
||||
assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>;
|
||||
phys = <&dp_phy>;
|
||||
phy-names = "dp";
|
||||
|
||||
operating-points-v2 = <&dp_opp_table>;
|
||||
power-domains = <&rpmhpd SC7180_CX>;
|
||||
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dp_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dp_out: endpoint { };
|
||||
};
|
||||
};
|
||||
|
||||
dp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-160000000 {
|
||||
opp-hz = /bits/ 64 <160000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-270000000 {
|
||||
opp-hz = /bits/ 64 <270000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-540000000 {
|
||||
opp-hz = /bits/ 64 <540000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-810000000 {
|
||||
opp-hz = /bits/ 64 <810000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,98 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sc7280-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SC7280
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7280-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display hf axi clock
|
||||
- description: Display sf axi clock
|
||||
- description: Display ahb clock
|
||||
- description: Display lut clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: nrt_bus
|
||||
- const: iface
|
||||
- const: lut
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc7280.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sc7280.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sc7280-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&gcc GCC_DISP_SF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus",
|
||||
"nrt_bus",
|
||||
"iface",
|
||||
"lut",
|
||||
"core",
|
||||
"vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SC7280_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&edp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,422 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sc7280-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SC7280 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem (MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS are mentioned for SC7280.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7280-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AHB clock from dispcc
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: ahb
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 1
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7280-dpu
|
||||
|
||||
"^displayport-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7280-dp
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^edp@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7280-edp
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7280-dsi-phy-7nm
|
||||
- qcom,sc7280-edp-phy
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc7280.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sc7280.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sc7280.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,sc7280-mdss";
|
||||
reg = <0xae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>;
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface",
|
||||
"ahb",
|
||||
"core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
|
||||
interconnect-names = "mdp0-mem";
|
||||
|
||||
iommus = <&apps_smmu 0x900 0x402>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sc7280-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&gcc GCC_DISP_SF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus",
|
||||
"nrt_bus",
|
||||
"iface",
|
||||
"lut",
|
||||
"core",
|
||||
"vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SC7280_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf5_out: endpoint {
|
||||
remote-endpoint = <&edp_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
dpu_intf0_out: endpoint {
|
||||
remote-endpoint = <&dp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&mdss_dsi_phy 0>, <&mdss_dsi_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SC7280_CX>;
|
||||
|
||||
phys = <&mdss_dsi_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-187500000 {
|
||||
opp-hz = /bits/ 64 <187500000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss_dsi_phy: phy@ae94400 {
|
||||
compatible = "qcom,sc7280-dsi-phy-7nm";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94900 0x280>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
|
||||
vdds-supply = <&vreg_dsi_supply>;
|
||||
};
|
||||
|
||||
edp@aea0000 {
|
||||
compatible = "qcom,sc7280-edp";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&edp_hot_plug_det>;
|
||||
|
||||
reg = <0xaea0000 0x200>,
|
||||
<0xaea0200 0x200>,
|
||||
<0xaea0400 0xc00>,
|
||||
<0xaea1000 0x400>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <14>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_EDP_AUX_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_EDP_LINK_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_EDP_LINK_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK>;
|
||||
clock-names = "core_iface",
|
||||
"core_aux",
|
||||
"ctrl_link",
|
||||
"ctrl_link_iface",
|
||||
"stream_pixel";
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_EDP_LINK_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>;
|
||||
assigned-clock-parents = <&mdss_edp_phy 0>, <&mdss_edp_phy 1>;
|
||||
|
||||
phys = <&mdss_edp_phy>;
|
||||
phy-names = "dp";
|
||||
|
||||
operating-points-v2 = <&edp_opp_table>;
|
||||
power-domains = <&rpmhpd SC7280_CX>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
edp_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf5_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
mdss_edp_out: endpoint { };
|
||||
};
|
||||
};
|
||||
|
||||
edp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-160000000 {
|
||||
opp-hz = /bits/ 64 <160000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-270000000 {
|
||||
opp-hz = /bits/ 64 <270000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-540000000 {
|
||||
opp-hz = /bits/ 64 <540000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
|
||||
opp-810000000 {
|
||||
opp-hz = /bits/ 64 <810000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss_edp_phy: phy@aec2a00 {
|
||||
compatible = "qcom,sc7280-edp-phy";
|
||||
|
||||
reg = <0xaec2a00 0x19c>,
|
||||
<0xaec2200 0xa0>,
|
||||
<0xaec2600 0xa0>,
|
||||
<0xaec2000 0x1c0>;
|
||||
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&gcc GCC_EDP_CLKREF_EN>;
|
||||
clock-names = "aux",
|
||||
"cfg_ahb";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
displayport-controller@ae90000 {
|
||||
compatible = "qcom,sc7280-dp";
|
||||
|
||||
reg = <0xae90000 0x200>,
|
||||
<0xae90200 0x200>,
|
||||
<0xae90400 0xc00>,
|
||||
<0xae91000 0x400>,
|
||||
<0xae91400 0x400>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <12>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_DP_AUX_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_DP_LINK_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_DP_PIXEL_CLK>;
|
||||
clock-names = "core_iface",
|
||||
"core_aux",
|
||||
"ctrl_link",
|
||||
"ctrl_link_iface",
|
||||
"stream_pixel";
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
|
||||
assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>;
|
||||
phys = <&dp_phy>;
|
||||
phy-names = "dp";
|
||||
|
||||
operating-points-v2 = <&dp_opp_table>;
|
||||
power-domains = <&rpmhpd SC7280_CX>;
|
||||
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dp_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dp_out: endpoint { };
|
||||
};
|
||||
};
|
||||
|
||||
dp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-160000000 {
|
||||
opp-hz = /bits/ 64 <160000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-270000000 {
|
||||
opp-hz = /bits/ 64 <270000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-540000000 {
|
||||
opp-hz = /bits/ 64 <540000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-810000000 {
|
||||
opp-hz = /bits/ 64 <810000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,90 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sdm845-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SDM845 target
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sdm845-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display GCC bus clock
|
||||
- description: Display ahb clock
|
||||
- description: Display axi clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: gcc-bus
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sdm845-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "gcc-bus", "iface", "bus", "core", "vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SDM845_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,270 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sdm845-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SDM845 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS are mentioned for SDM845 target.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sdm845-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 2
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sdm845-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-10nm
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,sdm845-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x880 0x8>,
|
||||
<&apps_smmu 0xc80 0x8>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sdm845-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "gcc-bus", "iface", "bus", "core", "vsync";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
power-domains = <&rpmhpd SDM845_CX>;
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SDM845_CX>;
|
||||
|
||||
phys = <&dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,dsi-phy-10nm";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94a00 0x1e0>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <5>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SDM845_CX>;
|
||||
|
||||
phys = <&dsi1_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi1_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi1_phy: phy@ae96400 {
|
||||
compatible = "qcom,dsi-phy-10nm";
|
||||
reg = <0x0ae96400 0x200>,
|
||||
<0x0ae96600 0x280>,
|
||||
<0x0ae96a00 0x10e>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,94 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm6115-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SM6115 target
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm6115-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: MDP register set
|
||||
- description: VBIF register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AXI
|
||||
- description: Display AHB
|
||||
- description: Display core
|
||||
- description: Display lut
|
||||
- description: Display rotator
|
||||
- description: Display vsync
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: iface
|
||||
- const: core
|
||||
- const: lut
|
||||
- const: rot
|
||||
- const: vsync
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,sm6115-dispcc.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm6115.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@5e01000 {
|
||||
compatible = "qcom,sm6115-dpu";
|
||||
reg = <0x05e01000 0x8f000>,
|
||||
<0x05eb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ROT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "core", "lut", "rot", "vsync";
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd SM6115_VDDCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,182 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm6115-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM6115 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller and DSI. Device tree bindings of MDSS
|
||||
are mentioned for SM6115 target.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm6115-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AXI clock
|
||||
- description: Display core clock
|
||||
|
||||
iommus:
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm6115-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-ctrl-6g-qcm2290
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-14nm-2290
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,sm6115-dispcc.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm6115.h>
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
mdss@5e00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,sm6115-mdss";
|
||||
reg = <0x05e00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
|
||||
interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x420 0x2>,
|
||||
<&apps_smmu 0x421 0x0>;
|
||||
ranges;
|
||||
|
||||
display-controller@5e01000 {
|
||||
compatible = "qcom,sm6115-dpu";
|
||||
reg = <0x05e01000 0x8f000>,
|
||||
<0x05eb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ROT_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus", "iface", "core", "lut", "rot", "vsync";
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmpd SM6115_VDDCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@5e94000 {
|
||||
compatible = "qcom,dsi-ctrl-6g-qcm2290";
|
||||
reg = <0x05e94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>, <&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmpd SM6115_VDDCX>;
|
||||
phys = <&dsi0_phy>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_phy: phy@5e94400 {
|
||||
compatible = "qcom,dsi-phy-14nm-2290";
|
||||
reg = <0x05e94400 0x100>,
|
||||
<0x05e94500 0x300>,
|
||||
<0x05e94800 0x188>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, <&rpmcc RPM_SMD_XO_CLK_SRC>;
|
||||
clock-names = "iface", "ref";
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,92 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm8250-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM8250 Display DPU
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display ahb clock
|
||||
- description: Display hf axi clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sm8250.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sm8250.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm8250-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface", "bus", "core", "vsync";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd SM8250_MMCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,330 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm8250-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM8250 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS are mentioned for SM8250 target.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm8250-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display hf axi clock
|
||||
- description: Display sf axi clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: nrt_bus
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-7nm
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sm8250.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sm8250.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
compatible = "qcom,sm8250-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP_PORT0 &mc_virt SLAVE_EBI_CH0>,
|
||||
<&mmss_noc MASTER_MDP_PORT1 &mc_virt SLAVE_EBI_CH0>;
|
||||
interconnect-names = "mdp0-mem", "mdp1-mem";
|
||||
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&gcc GCC_DISP_SF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "bus", "nrt_bus", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x820 0x402>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm8250-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface", "bus", "core", "vsync";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd SM8250_MMCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-200000000 {
|
||||
opp-hz = /bits/ 64 <200000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-345000000 {
|
||||
opp-hz = /bits/ 64 <345000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-460000000 {
|
||||
opp-hz = /bits/ 64 <460000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SM8250_MMCX>;
|
||||
|
||||
phys = <&dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-187500000 {
|
||||
opp-hz = /bits/ 64 <187500000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,dsi-phy-7nm";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94900 0x260>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <5>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SM8250_MMCX>;
|
||||
|
||||
phys = <&dsi1_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi1_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi1_phy: phy@ae96400 {
|
||||
compatible = "qcom,dsi-phy-7nm";
|
||||
reg = <0x0ae96400 0x200>,
|
||||
<0x0ae96600 0x280>,
|
||||
<0x0ae96900 0x260>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/jadard,jd9365da-h3.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Jadard JD9365DA-HE WXGA DSI panel
|
||||
|
||||
maintainers:
|
||||
- Jagan Teki <jagan@edgeble.ai>
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- chongzhou,cz101b4001
|
||||
- const: jadard,jd9365da-h3
|
||||
|
||||
reg: true
|
||||
|
||||
vdd-supply:
|
||||
description: supply regulator for VDD, usually 3.3V
|
||||
|
||||
vccio-supply:
|
||||
description: supply regulator for VCCIO, usually 1.8V
|
||||
|
||||
reset-gpios: true
|
||||
|
||||
backlight: true
|
||||
|
||||
port: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
- vccio-supply
|
||||
- reset-gpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
panel@0 {
|
||||
compatible = "chongzhou,cz101b4001", "jadard,jd9365da-h3";
|
||||
reg = <0>;
|
||||
vdd-supply = <&lcd_3v3>;
|
||||
vccio-supply = <&vcca_1v8>;
|
||||
reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
|
||||
backlight = <&backlight>;
|
||||
|
||||
port {
|
||||
mipi_in_panel: endpoint {
|
||||
remote-endpoint = <&mipi_out_panel>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -0,0 +1,63 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/panel/newvision,nv3051d.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NewVision NV3051D based LCD panel
|
||||
|
||||
description: |
|
||||
The NewVision NV3051D is a driver chip used to drive DSI panels. For now,
|
||||
this driver only supports the 640x480 panels found in the Anbernic RG353
|
||||
based devices.
|
||||
|
||||
maintainers:
|
||||
- Chris Morgan <macromorgan@hotmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: panel-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- anbernic,rg353p-panel
|
||||
- anbernic,rg353v-panel
|
||||
- const: newvision,nv3051d
|
||||
|
||||
reg: true
|
||||
backlight: true
|
||||
port: true
|
||||
reset-gpios:
|
||||
description: Active low reset GPIO
|
||||
vdd-supply: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- backlight
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
dsi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
panel@0 {
|
||||
compatible = "anbernic,rg353p-panel", "newvision,nv3051d";
|
||||
reg = <0>;
|
||||
backlight = <&backlight>;
|
||||
reset-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
|
||||
vdd-supply = <&vcc3v3_lcd>;
|
||||
|
||||
port {
|
||||
mipi_in_panel: endpoint {
|
||||
remote-endpoint = <&mipi_out_panel>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -117,6 +117,45 @@ properties:
|
||||
- const: dp-phy0
|
||||
- const: dp-phy1
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
Connections to the programmable logic and the DisplayPort PHYs. Each port
|
||||
shall have a single endpoint.
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The live video input from the programmable logic
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The live graphics input from the programmable logic
|
||||
|
||||
port@2:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The live audio input from the programmable logic
|
||||
|
||||
port@3:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The blended video output to the programmable logic
|
||||
|
||||
port@4:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The mixed audio output to the programmable logic
|
||||
|
||||
port@5:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: The DisplayPort output
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
- port@2
|
||||
- port@3
|
||||
- port@4
|
||||
- port@5
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@@ -130,6 +169,7 @@ required:
|
||||
- dma-names
|
||||
- phys
|
||||
- phy-names
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@@ -164,6 +204,33 @@ examples:
|
||||
<&psgtr 0 PHY_TYPE_DP 1 3>;
|
||||
|
||||
phy-names = "dp-phy0", "dp-phy1";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
};
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
};
|
||||
port@5 {
|
||||
reg = <5>;
|
||||
dpsub_dp_out: endpoint {
|
||||
remote-endpoint = <&dp_connector>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
@@ -248,6 +248,8 @@ patternProperties:
|
||||
description: ChipOne
|
||||
"^chipspark,.*":
|
||||
description: ChipSPARK
|
||||
"^chongzhou,.*":
|
||||
description: Shenzhen Chongzhou Electronic Technology Co., Ltd
|
||||
"^chrontel,.*":
|
||||
description: Chrontel, Inc.
|
||||
"^chrp,.*":
|
||||
@@ -645,6 +647,8 @@ patternProperties:
|
||||
description: ITian Corporation
|
||||
"^iwave,.*":
|
||||
description: iWave Systems Technologies Pvt. Ltd.
|
||||
"^jadard,.*":
|
||||
description: Jadard Technology Inc.
|
||||
"^jdi,.*":
|
||||
description: Japan Display Inc.
|
||||
"^jedec,.*":
|
||||
@@ -889,6 +893,8 @@ patternProperties:
|
||||
description: Shenzhen Netxeon Technology CO., LTD
|
||||
"^neweast,.*":
|
||||
description: Guangdong Neweast Optoelectronics CO., LTD
|
||||
"^newvision,.*":
|
||||
description: New Vision Display (Shenzhen) Co., Ltd.
|
||||
"^nexbox,.*":
|
||||
description: Nexbox
|
||||
"^nextthing,.*":
|
||||
|
||||
@@ -119,6 +119,12 @@ DMA Buffer ioctls
|
||||
|
||||
.. kernel-doc:: include/uapi/linux/dma-buf.h
|
||||
|
||||
DMA-BUF locking convention
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/dma-buf/dma-buf.c
|
||||
:doc: locking convention
|
||||
|
||||
Kernel Functions and Structures Reference
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ Valid mode specifiers (mode_option argument)::
|
||||
with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a string.
|
||||
Things between square brackets are optional.
|
||||
|
||||
Valid names are::
|
||||
|
||||
- NSTC: 480i output, with the CCIR System-M TV mode and NTSC color encoding
|
||||
- PAL: 576i output, with the CCIR System-B TV mode and PAL color encoding
|
||||
|
||||
If 'M' is specified in the mode_option argument (after <yres> and before
|
||||
<bpp> and <refresh>, if specified) the timings will be calculated using
|
||||
VESA(TM) Coordinated Video Timings instead of looking up the mode from a table.
|
||||
|
||||
@@ -30,12 +30,35 @@ we have a dedicated glossary for Display Core at
|
||||
EOP
|
||||
End Of Pipe/Pipeline
|
||||
|
||||
GART
|
||||
Graphics Address Remapping Table. This is the name we use for the GPUVM
|
||||
page table used by the GPU kernel driver. It remaps system resources
|
||||
(memory or MMIO space) into the GPU's address space so the GPU can access
|
||||
them. The name GART harkens back to the days of AGP when the platform
|
||||
provided an MMU that the GPU could use to get a contiguous view of
|
||||
scattered pages for DMA. The MMU has since moved on to the GPU, but the
|
||||
name stuck.
|
||||
|
||||
GC
|
||||
Graphics and Compute
|
||||
|
||||
GMC
|
||||
Graphic Memory Controller
|
||||
|
||||
GPUVM
|
||||
GPU Virtual Memory. This is the GPU's MMU. The GPU supports multiple
|
||||
virtual address spaces that can be in flight at any given time. These
|
||||
allow the GPU to remap VRAM and system resources into GPU virtual address
|
||||
spaces for use by the GPU kernel driver and applications using the GPU.
|
||||
These provide memory protection for different applications using the GPU.
|
||||
|
||||
GTT
|
||||
Graphics Translation Tables. This is a memory pool managed through TTM
|
||||
which provides access to system resources (memory or MMIO space) for
|
||||
use by the GPU. These addresses can be mapped into the "GART" GPUVM page
|
||||
table for use by the kernel driver or into per process GPUVM page tables
|
||||
for application usage.
|
||||
|
||||
IH
|
||||
Interrupt Handler
|
||||
|
||||
|
||||
@@ -148,10 +148,10 @@ PRIME Buffer Sharing
|
||||
MMU Notifier
|
||||
============
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
|
||||
:doc: MMU Notifier
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
|
||||
.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
|
||||
:internal:
|
||||
|
||||
AMDGPU Virtual Memory
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
==========================
|
||||
|
||||
The drm/amdgpu driver supports all AMD Radeon GPUs based on the Graphics Core
|
||||
Next (GCN) architecture.
|
||||
Next (GCN), Radeon DNA (RDNA), and Compute DNA (CDNA) architectures.
|
||||
|
||||
.. toctree::
|
||||
|
||||
|
||||
@@ -116,6 +116,9 @@ fbdev Helper Functions Reference
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_fbdev_generic.c
|
||||
:export:
|
||||
|
||||
format Helper Functions Reference
|
||||
=================================
|
||||
|
||||
|
||||
@@ -126,7 +126,6 @@ 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
|
||||
===============================
|
||||
|
||||
|
||||
@@ -494,7 +494,7 @@ WOPCM
|
||||
WOPCM Layout
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/intel_wopcm.c
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_wopcm.c
|
||||
:doc: WOPCM Layout
|
||||
|
||||
GuC
|
||||
|
||||
@@ -651,17 +651,6 @@ See drivers/gpu/drm/amd/display/TODO for tasks.
|
||||
|
||||
Contact: Harry Wentland, Alex Deucher
|
||||
|
||||
vmwgfx: Replace hashtable with Linux' implementation
|
||||
----------------------------------------------------
|
||||
|
||||
The vmwgfx driver uses its own hashtable implementation. Replace the
|
||||
code with Linux' implementation and update the callers. It's mostly a
|
||||
refactoring task, but the interfaces are different.
|
||||
|
||||
Contact: Zack Rusin, Thomas Zimmermann <tzimmermann@suse.de>
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Bootsplash
|
||||
==========
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ needed).
|
||||
input/index
|
||||
hwmon/index
|
||||
gpu/index
|
||||
accel/index
|
||||
security/index
|
||||
sound/index
|
||||
crypto/index
|
||||
|
||||
+20
-1
@@ -6539,6 +6539,12 @@ S: Orphan / Obsolete
|
||||
F: drivers/gpu/drm/i810/
|
||||
F: include/uapi/drm/i810_drm.h
|
||||
|
||||
DRM DRIVER FOR JADARD JD9365DA-H3 MIPI-DSI LCD PANELS
|
||||
M: Jagan Teki <jagan@edgeble.ai>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml
|
||||
F: drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
|
||||
|
||||
DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER
|
||||
M: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
||||
S: Supported
|
||||
@@ -6728,10 +6734,13 @@ 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/ofdrm.c
|
||||
F: drivers/gpu/drm/tiny/simpledrm.c
|
||||
F: drivers/video/aperture.c
|
||||
F: drivers/video/nomodeset.c
|
||||
F: include/drm/drm_aperture.h
|
||||
F: include/linux/aperture.h
|
||||
F: include/video/nomodeset.h
|
||||
|
||||
DRM DRIVER FOR SIS VIDEO CARDS
|
||||
S: Orphan / Obsolete
|
||||
@@ -6860,6 +6869,15 @@ F: include/drm/drm*
|
||||
F: include/linux/vga*
|
||||
F: include/uapi/drm/drm*
|
||||
|
||||
DRM COMPUTE ACCELERATORS DRIVERS AND FRAMEWORK
|
||||
M: Oded Gabbay <ogabbay@kernel.org>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
C: irc://irc.oftc.net/dri-devel
|
||||
T: git https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/accel.git
|
||||
F: Documentation/accel/
|
||||
F: drivers/accel/
|
||||
|
||||
DRM DRIVERS FOR ALLWINNER A10
|
||||
M: Maxime Ripard <mripard@kernel.org>
|
||||
M: Chen-Yu Tsai <wens@csie.org>
|
||||
@@ -7148,7 +7166,7 @@ F: drivers/gpu/drm/ttm/
|
||||
F: include/drm/ttm/
|
||||
|
||||
DRM GPU SCHEDULER
|
||||
M: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
|
||||
M: Luben Tuikov <luben.tuikov@amd.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||
@@ -10273,6 +10291,7 @@ Q: http://patchwork.freedesktop.org/project/intel-gfx/
|
||||
B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs
|
||||
C: irc://irc.oftc.net/intel-gfx
|
||||
T: git git://anongit.freedesktop.org/drm-intel
|
||||
F: Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
|
||||
F: Documentation/gpu/i915.rst
|
||||
F: drivers/gpu/drm/i915/
|
||||
F: include/drm/i915*
|
||||
|
||||
@@ -150,6 +150,18 @@
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <114285000>;
|
||||
};
|
||||
|
||||
dpcon {
|
||||
compatible = "dp-connector";
|
||||
label = "P11";
|
||||
type = "full-size";
|
||||
|
||||
port {
|
||||
dpcon_in: endpoint {
|
||||
remote-endpoint = <&dpsub_dp_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&can1 {
|
||||
@@ -1015,4 +1027,12 @@
|
||||
phy-names = "dp-phy0", "dp-phy1";
|
||||
phys = <&psgtr 1 PHY_TYPE_DP 0 3>,
|
||||
<&psgtr 0 PHY_TYPE_DP 1 3>;
|
||||
|
||||
ports {
|
||||
port@5 {
|
||||
dpsub_dp_out: endpoint {
|
||||
remote-endpoint = <&dpcon_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -930,6 +930,30 @@
|
||||
<&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO1>,
|
||||
<&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO2>,
|
||||
<&zynqmp_dpdma ZYNQMP_DPDMA_GRAPHICS>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
};
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
};
|
||||
port@5 {
|
||||
reg = <5>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -99,6 +99,8 @@ source "drivers/media/Kconfig"
|
||||
|
||||
source "drivers/video/Kconfig"
|
||||
|
||||
source "drivers/accel/Kconfig"
|
||||
|
||||
source "sound/Kconfig"
|
||||
|
||||
source "drivers/hid/Kconfig"
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Compute Acceleration device configuration
|
||||
#
|
||||
# This framework provides support for compute acceleration devices, such
|
||||
# as, but not limited to, Machine-Learning and Deep-Learning acceleration
|
||||
# devices
|
||||
#
|
||||
menuconfig DRM_ACCEL
|
||||
bool "Compute Acceleration Framework"
|
||||
depends on DRM
|
||||
help
|
||||
Framework for device drivers of compute acceleration devices, such
|
||||
as, but not limited to, Machine-Learning and Deep-Learning
|
||||
acceleration devices.
|
||||
If you say Y here, you need to select the module that's right for
|
||||
your acceleration device from the list below.
|
||||
This framework is integrated with the DRM subsystem as compute
|
||||
accelerators and GPUs share a lot in common and can use almost the
|
||||
same infrastructure code.
|
||||
Having said that, acceleration devices will have a different
|
||||
major number than GPUs, and will be exposed to user-space using
|
||||
different device files, called accel/accel* (in /dev, sysfs
|
||||
and debugfs).
|
||||
@@ -0,0 +1,323 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
/*
|
||||
* Copyright 2022 HabanaLabs, Ltd.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/idr.h>
|
||||
|
||||
#include <drm/drm_accel.h>
|
||||
#include <drm/drm_debugfs.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_file.h>
|
||||
#include <drm/drm_ioctl.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
static DEFINE_SPINLOCK(accel_minor_lock);
|
||||
static struct idr accel_minors_idr;
|
||||
|
||||
static struct dentry *accel_debugfs_root;
|
||||
static struct class *accel_class;
|
||||
|
||||
static struct device_type accel_sysfs_device_minor = {
|
||||
.name = "accel_minor"
|
||||
};
|
||||
|
||||
static char *accel_devnode(struct device *dev, umode_t *mode)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "accel/%s", dev_name(dev));
|
||||
}
|
||||
|
||||
static int accel_sysfs_init(void)
|
||||
{
|
||||
accel_class = class_create(THIS_MODULE, "accel");
|
||||
if (IS_ERR(accel_class))
|
||||
return PTR_ERR(accel_class);
|
||||
|
||||
accel_class->devnode = accel_devnode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void accel_sysfs_destroy(void)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(accel_class))
|
||||
return;
|
||||
class_destroy(accel_class);
|
||||
accel_class = NULL;
|
||||
}
|
||||
|
||||
static int accel_name_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_minor *minor = node->minor;
|
||||
struct drm_device *dev = minor->dev;
|
||||
struct drm_master *master;
|
||||
|
||||
mutex_lock(&dev->master_mutex);
|
||||
master = dev->master;
|
||||
seq_printf(m, "%s", dev->driver->name);
|
||||
if (dev->dev)
|
||||
seq_printf(m, " dev=%s", dev_name(dev->dev));
|
||||
if (master && master->unique)
|
||||
seq_printf(m, " master=%s", master->unique);
|
||||
if (dev->unique)
|
||||
seq_printf(m, " unique=%s", dev->unique);
|
||||
seq_puts(m, "\n");
|
||||
mutex_unlock(&dev->master_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_info_list accel_debugfs_list[] = {
|
||||
{"name", accel_name_info, 0}
|
||||
};
|
||||
#define ACCEL_DEBUGFS_ENTRIES ARRAY_SIZE(accel_debugfs_list)
|
||||
|
||||
/**
|
||||
* accel_debugfs_init() - Initialize debugfs for accel minor
|
||||
* @minor: Pointer to the drm_minor instance.
|
||||
* @minor_id: The minor's id
|
||||
*
|
||||
* This function initializes the drm minor's debugfs members and creates
|
||||
* a root directory for the minor in debugfs. It also creates common files
|
||||
* for accelerators and calls the driver's debugfs init callback.
|
||||
*/
|
||||
void accel_debugfs_init(struct drm_minor *minor, int minor_id)
|
||||
{
|
||||
struct drm_device *dev = minor->dev;
|
||||
char name[64];
|
||||
|
||||
INIT_LIST_HEAD(&minor->debugfs_list);
|
||||
mutex_init(&minor->debugfs_lock);
|
||||
sprintf(name, "%d", minor_id);
|
||||
minor->debugfs_root = debugfs_create_dir(name, accel_debugfs_root);
|
||||
|
||||
drm_debugfs_create_files(accel_debugfs_list, ACCEL_DEBUGFS_ENTRIES,
|
||||
minor->debugfs_root, minor);
|
||||
|
||||
if (dev->driver->debugfs_init)
|
||||
dev->driver->debugfs_init(minor);
|
||||
}
|
||||
|
||||
/**
|
||||
* accel_set_device_instance_params() - Set some device parameters for accel device
|
||||
* @kdev: Pointer to the device instance.
|
||||
* @index: The minor's index
|
||||
*
|
||||
* This function creates the dev_t of the device using the accel major and
|
||||
* the device's minor number. In addition, it sets the class and type of the
|
||||
* device instance to the accel sysfs class and device type, respectively.
|
||||
*/
|
||||
void accel_set_device_instance_params(struct device *kdev, int index)
|
||||
{
|
||||
kdev->devt = MKDEV(ACCEL_MAJOR, index);
|
||||
kdev->class = accel_class;
|
||||
kdev->type = &accel_sysfs_device_minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* accel_minor_alloc() - Allocates a new accel minor
|
||||
*
|
||||
* This function access the accel minors idr and allocates from it
|
||||
* a new id to represent a new accel minor
|
||||
*
|
||||
* Return: A new id on success or error code in case idr_alloc failed
|
||||
*/
|
||||
int accel_minor_alloc(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
int r;
|
||||
|
||||
spin_lock_irqsave(&accel_minor_lock, flags);
|
||||
r = idr_alloc(&accel_minors_idr, NULL, 0, ACCEL_MAX_MINORS, GFP_NOWAIT);
|
||||
spin_unlock_irqrestore(&accel_minor_lock, flags);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* accel_minor_remove() - Remove an accel minor
|
||||
* @index: The minor id to remove.
|
||||
*
|
||||
* This function access the accel minors idr and removes from
|
||||
* it the member with the id that is passed to this function.
|
||||
*/
|
||||
void accel_minor_remove(int index)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&accel_minor_lock, flags);
|
||||
idr_remove(&accel_minors_idr, index);
|
||||
spin_unlock_irqrestore(&accel_minor_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* accel_minor_replace() - Replace minor pointer in accel minors idr.
|
||||
* @minor: Pointer to the new minor.
|
||||
* @index: The minor id to replace.
|
||||
*
|
||||
* This function access the accel minors idr structure and replaces the pointer
|
||||
* that is associated with an existing id. Because the minor pointer can be
|
||||
* NULL, we need to explicitly pass the index.
|
||||
*
|
||||
* Return: 0 for success, negative value for error
|
||||
*/
|
||||
void accel_minor_replace(struct drm_minor *minor, int index)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&accel_minor_lock, flags);
|
||||
idr_replace(&accel_minors_idr, minor, index);
|
||||
spin_unlock_irqrestore(&accel_minor_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks up the given minor-ID and returns the respective DRM-minor object. The
|
||||
* refence-count of the underlying device is increased so you must release this
|
||||
* object with accel_minor_release().
|
||||
*
|
||||
* The object can be only a drm_minor that represents an accel device.
|
||||
*
|
||||
* As long as you hold this minor, it is guaranteed that the object and the
|
||||
* minor->dev pointer will stay valid! However, the device may get unplugged and
|
||||
* unregistered while you hold the minor.
|
||||
*/
|
||||
static struct drm_minor *accel_minor_acquire(unsigned int minor_id)
|
||||
{
|
||||
struct drm_minor *minor;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&accel_minor_lock, flags);
|
||||
minor = idr_find(&accel_minors_idr, minor_id);
|
||||
if (minor)
|
||||
drm_dev_get(minor->dev);
|
||||
spin_unlock_irqrestore(&accel_minor_lock, flags);
|
||||
|
||||
if (!minor) {
|
||||
return ERR_PTR(-ENODEV);
|
||||
} else if (drm_dev_is_unplugged(minor->dev)) {
|
||||
drm_dev_put(minor->dev);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
return minor;
|
||||
}
|
||||
|
||||
static void accel_minor_release(struct drm_minor *minor)
|
||||
{
|
||||
drm_dev_put(minor->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* accel_open - open method for ACCEL file
|
||||
* @inode: device inode
|
||||
* @filp: file pointer.
|
||||
*
|
||||
* This function must be used by drivers as their &file_operations.open method.
|
||||
* It looks up the correct ACCEL device and instantiates all the per-file
|
||||
* resources for it. It also calls the &drm_driver.open driver callback.
|
||||
*
|
||||
* Return: 0 on success or negative errno value on failure.
|
||||
*/
|
||||
int accel_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct drm_device *dev;
|
||||
struct drm_minor *minor;
|
||||
int retcode;
|
||||
|
||||
minor = accel_minor_acquire(iminor(inode));
|
||||
if (IS_ERR(minor))
|
||||
return PTR_ERR(minor);
|
||||
|
||||
dev = minor->dev;
|
||||
|
||||
atomic_fetch_inc(&dev->open_count);
|
||||
|
||||
/* share address_space across all char-devs of a single device */
|
||||
filp->f_mapping = dev->anon_inode->i_mapping;
|
||||
|
||||
retcode = drm_open_helper(filp, minor);
|
||||
if (retcode)
|
||||
goto err_undo;
|
||||
|
||||
return 0;
|
||||
|
||||
err_undo:
|
||||
atomic_dec(&dev->open_count);
|
||||
accel_minor_release(minor);
|
||||
return retcode;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(accel_open);
|
||||
|
||||
static int accel_stub_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
const struct file_operations *new_fops;
|
||||
struct drm_minor *minor;
|
||||
int err;
|
||||
|
||||
minor = accel_minor_acquire(iminor(inode));
|
||||
if (IS_ERR(minor))
|
||||
return PTR_ERR(minor);
|
||||
|
||||
new_fops = fops_get(minor->dev->driver->fops);
|
||||
if (!new_fops) {
|
||||
err = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
replace_fops(filp, new_fops);
|
||||
if (filp->f_op->open)
|
||||
err = filp->f_op->open(inode, filp);
|
||||
else
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
accel_minor_release(minor);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct file_operations accel_stub_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = accel_stub_open,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
void accel_core_exit(void)
|
||||
{
|
||||
unregister_chrdev(ACCEL_MAJOR, "accel");
|
||||
debugfs_remove(accel_debugfs_root);
|
||||
accel_sysfs_destroy();
|
||||
idr_destroy(&accel_minors_idr);
|
||||
}
|
||||
|
||||
int __init accel_core_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
idr_init(&accel_minors_idr);
|
||||
|
||||
ret = accel_sysfs_init();
|
||||
if (ret < 0) {
|
||||
DRM_ERROR("Cannot create ACCEL class: %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
accel_debugfs_root = debugfs_create_dir("accel", NULL);
|
||||
|
||||
ret = register_chrdev(ACCEL_MAJOR, "accel", &accel_stub_fops);
|
||||
if (ret < 0)
|
||||
DRM_ERROR("Cannot register ACCEL major: %d\n", ret);
|
||||
|
||||
error:
|
||||
/*
|
||||
* Any cleanup due to errors will be done in drm_core_exit() that
|
||||
* will call accel_core_exit()
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
@@ -18,25 +18,6 @@
|
||||
|
||||
#include <soc/bcm2835/raspberrypi-firmware.h>
|
||||
|
||||
enum rpi_firmware_clk_id {
|
||||
RPI_FIRMWARE_EMMC_CLK_ID = 1,
|
||||
RPI_FIRMWARE_UART_CLK_ID,
|
||||
RPI_FIRMWARE_ARM_CLK_ID,
|
||||
RPI_FIRMWARE_CORE_CLK_ID,
|
||||
RPI_FIRMWARE_V3D_CLK_ID,
|
||||
RPI_FIRMWARE_H264_CLK_ID,
|
||||
RPI_FIRMWARE_ISP_CLK_ID,
|
||||
RPI_FIRMWARE_SDRAM_CLK_ID,
|
||||
RPI_FIRMWARE_PIXEL_CLK_ID,
|
||||
RPI_FIRMWARE_PWM_CLK_ID,
|
||||
RPI_FIRMWARE_HEVC_CLK_ID,
|
||||
RPI_FIRMWARE_EMMC2_CLK_ID,
|
||||
RPI_FIRMWARE_M2MC_CLK_ID,
|
||||
RPI_FIRMWARE_PIXEL_BVB_CLK_ID,
|
||||
RPI_FIRMWARE_VEC_CLK_ID,
|
||||
RPI_FIRMWARE_NUM_CLK_ID,
|
||||
};
|
||||
|
||||
static char *rpi_firmware_clk_names[] = {
|
||||
[RPI_FIRMWARE_EMMC_CLK_ID] = "emmc",
|
||||
[RPI_FIRMWARE_UART_CLK_ID] = "uart",
|
||||
|
||||
+192
-33
@@ -130,6 +130,7 @@ static struct file_system_type dma_buf_fs_type = {
|
||||
static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
struct dma_buf *dmabuf;
|
||||
int ret;
|
||||
|
||||
if (!is_dma_buf_file(file))
|
||||
return -EINVAL;
|
||||
@@ -145,7 +146,11 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
|
||||
dmabuf->size >> PAGE_SHIFT)
|
||||
return -EINVAL;
|
||||
|
||||
return dmabuf->ops->mmap(dmabuf, vma);
|
||||
dma_resv_lock(dmabuf->resv, NULL);
|
||||
ret = dmabuf->ops->mmap(dmabuf, vma);
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)
|
||||
@@ -668,7 +673,6 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
|
||||
dmabuf->file = file;
|
||||
|
||||
mutex_init(&dmabuf->lock);
|
||||
INIT_LIST_HEAD(&dmabuf->attachments);
|
||||
|
||||
mutex_lock(&db_list.lock);
|
||||
@@ -806,6 +810,70 @@ static struct sg_table * __map_dma_buf(struct dma_buf_attachment *attach,
|
||||
return sg_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* DOC: locking convention
|
||||
*
|
||||
* In order to avoid deadlock situations between dma-buf exports and importers,
|
||||
* all dma-buf API users must follow the common dma-buf locking convention.
|
||||
*
|
||||
* Convention for importers
|
||||
*
|
||||
* 1. Importers must hold the dma-buf reservation lock when calling these
|
||||
* functions:
|
||||
*
|
||||
* - dma_buf_pin()
|
||||
* - dma_buf_unpin()
|
||||
* - dma_buf_map_attachment()
|
||||
* - dma_buf_unmap_attachment()
|
||||
* - dma_buf_vmap()
|
||||
* - dma_buf_vunmap()
|
||||
*
|
||||
* 2. Importers must not hold the dma-buf reservation lock when calling these
|
||||
* functions:
|
||||
*
|
||||
* - dma_buf_attach()
|
||||
* - dma_buf_dynamic_attach()
|
||||
* - dma_buf_detach()
|
||||
* - dma_buf_export(
|
||||
* - dma_buf_fd()
|
||||
* - dma_buf_get()
|
||||
* - dma_buf_put()
|
||||
* - dma_buf_mmap()
|
||||
* - dma_buf_begin_cpu_access()
|
||||
* - dma_buf_end_cpu_access()
|
||||
* - dma_buf_map_attachment_unlocked()
|
||||
* - dma_buf_unmap_attachment_unlocked()
|
||||
* - dma_buf_vmap_unlocked()
|
||||
* - dma_buf_vunmap_unlocked()
|
||||
*
|
||||
* Convention for exporters
|
||||
*
|
||||
* 1. These &dma_buf_ops callbacks are invoked with unlocked dma-buf
|
||||
* reservation and exporter can take the lock:
|
||||
*
|
||||
* - &dma_buf_ops.attach()
|
||||
* - &dma_buf_ops.detach()
|
||||
* - &dma_buf_ops.release()
|
||||
* - &dma_buf_ops.begin_cpu_access()
|
||||
* - &dma_buf_ops.end_cpu_access()
|
||||
*
|
||||
* 2. These &dma_buf_ops callbacks are invoked with locked dma-buf
|
||||
* reservation and exporter can't take the lock:
|
||||
*
|
||||
* - &dma_buf_ops.pin()
|
||||
* - &dma_buf_ops.unpin()
|
||||
* - &dma_buf_ops.map_dma_buf()
|
||||
* - &dma_buf_ops.unmap_dma_buf()
|
||||
* - &dma_buf_ops.mmap()
|
||||
* - &dma_buf_ops.vmap()
|
||||
* - &dma_buf_ops.vunmap()
|
||||
*
|
||||
* 3. Exporters must hold the dma-buf reservation lock when calling these
|
||||
* functions:
|
||||
*
|
||||
* - dma_buf_move_notify()
|
||||
*/
|
||||
|
||||
/**
|
||||
* dma_buf_dynamic_attach - Add the device to dma_buf's attachments list
|
||||
* @dmabuf: [in] buffer to attach device to.
|
||||
@@ -870,8 +938,8 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
|
||||
dma_buf_is_dynamic(dmabuf)) {
|
||||
struct sg_table *sgt;
|
||||
|
||||
dma_resv_lock(attach->dmabuf->resv, NULL);
|
||||
if (dma_buf_is_dynamic(attach->dmabuf)) {
|
||||
dma_resv_lock(attach->dmabuf->resv, NULL);
|
||||
ret = dmabuf->ops->pin(attach);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
@@ -884,8 +952,7 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
|
||||
ret = PTR_ERR(sgt);
|
||||
goto err_unpin;
|
||||
}
|
||||
if (dma_buf_is_dynamic(attach->dmabuf))
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
attach->sgt = sgt;
|
||||
attach->dir = DMA_BIDIRECTIONAL;
|
||||
}
|
||||
@@ -901,8 +968,7 @@ err_unpin:
|
||||
dmabuf->ops->unpin(attach);
|
||||
|
||||
err_unlock:
|
||||
if (dma_buf_is_dynamic(attach->dmabuf))
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
|
||||
dma_buf_detach(dmabuf, attach);
|
||||
return ERR_PTR(ret);
|
||||
@@ -945,24 +1011,22 @@ static void __unmap_dma_buf(struct dma_buf_attachment *attach,
|
||||
*/
|
||||
void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
|
||||
{
|
||||
if (WARN_ON(!dmabuf || !attach))
|
||||
if (WARN_ON(!dmabuf || !attach || dmabuf != attach->dmabuf))
|
||||
return;
|
||||
|
||||
dma_resv_lock(dmabuf->resv, NULL);
|
||||
|
||||
if (attach->sgt) {
|
||||
if (dma_buf_is_dynamic(attach->dmabuf))
|
||||
dma_resv_lock(attach->dmabuf->resv, NULL);
|
||||
|
||||
__unmap_dma_buf(attach, attach->sgt, attach->dir);
|
||||
|
||||
if (dma_buf_is_dynamic(attach->dmabuf)) {
|
||||
if (dma_buf_is_dynamic(attach->dmabuf))
|
||||
dmabuf->ops->unpin(attach);
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
}
|
||||
}
|
||||
|
||||
dma_resv_lock(dmabuf->resv, NULL);
|
||||
list_del(&attach->node);
|
||||
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
|
||||
if (dmabuf->ops->detach)
|
||||
dmabuf->ops->detach(dmabuf, attach);
|
||||
|
||||
@@ -1053,8 +1117,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
||||
if (WARN_ON(!attach || !attach->dmabuf))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (dma_buf_attachment_is_dynamic(attach))
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
|
||||
if (attach->sgt) {
|
||||
/*
|
||||
@@ -1069,7 +1132,6 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
||||
}
|
||||
|
||||
if (dma_buf_is_dynamic(attach->dmabuf)) {
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
if (!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) {
|
||||
r = attach->dmabuf->ops->pin(attach);
|
||||
if (r)
|
||||
@@ -1111,6 +1173,34 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, DMA_BUF);
|
||||
|
||||
/**
|
||||
* dma_buf_map_attachment_unlocked - Returns the scatterlist table of the attachment;
|
||||
* mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
|
||||
* dma_buf_ops.
|
||||
* @attach: [in] attachment whose scatterlist is to be returned
|
||||
* @direction: [in] direction of DMA transfer
|
||||
*
|
||||
* Unlocked variant of dma_buf_map_attachment().
|
||||
*/
|
||||
struct sg_table *
|
||||
dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
struct sg_table *sg_table;
|
||||
|
||||
might_sleep();
|
||||
|
||||
if (WARN_ON(!attach || !attach->dmabuf))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
dma_resv_lock(attach->dmabuf->resv, NULL);
|
||||
sg_table = dma_buf_map_attachment(attach, direction);
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
|
||||
return sg_table;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, DMA_BUF);
|
||||
|
||||
/**
|
||||
* dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might
|
||||
* deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
|
||||
@@ -1130,15 +1220,11 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
|
||||
if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
|
||||
return;
|
||||
|
||||
if (dma_buf_attachment_is_dynamic(attach))
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
|
||||
if (attach->sgt == sg_table)
|
||||
return;
|
||||
|
||||
if (dma_buf_is_dynamic(attach->dmabuf))
|
||||
dma_resv_assert_held(attach->dmabuf->resv);
|
||||
|
||||
__unmap_dma_buf(attach, sg_table, direction);
|
||||
|
||||
if (dma_buf_is_dynamic(attach->dmabuf) &&
|
||||
@@ -1147,6 +1233,31 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, DMA_BUF);
|
||||
|
||||
/**
|
||||
* dma_buf_unmap_attachment_unlocked - unmaps and decreases usecount of the buffer;might
|
||||
* deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
|
||||
* dma_buf_ops.
|
||||
* @attach: [in] attachment to unmap buffer from
|
||||
* @sg_table: [in] scatterlist info of the buffer to unmap
|
||||
* @direction: [in] direction of DMA transfer
|
||||
*
|
||||
* Unlocked variant of dma_buf_unmap_attachment().
|
||||
*/
|
||||
void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
|
||||
struct sg_table *sg_table,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
|
||||
return;
|
||||
|
||||
dma_resv_lock(attach->dmabuf->resv, NULL);
|
||||
dma_buf_unmap_attachment(attach, sg_table, direction);
|
||||
dma_resv_unlock(attach->dmabuf->resv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment_unlocked, DMA_BUF);
|
||||
|
||||
/**
|
||||
* dma_buf_move_notify - notify attachments that DMA-buf is moving
|
||||
*
|
||||
@@ -1397,6 +1508,8 @@ EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access_partial);
|
||||
int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
|
||||
unsigned long pgoff)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(!dmabuf || !vma))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1417,7 +1530,11 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
|
||||
vma_set_file(vma, dmabuf->file);
|
||||
vma->vm_pgoff = pgoff;
|
||||
|
||||
return dmabuf->ops->mmap(dmabuf, vma);
|
||||
dma_resv_lock(dmabuf->resv, NULL);
|
||||
ret = dmabuf->ops->mmap(dmabuf, vma);
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF);
|
||||
|
||||
@@ -1440,41 +1557,67 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF);
|
||||
int dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
|
||||
{
|
||||
struct iosys_map ptr;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
iosys_map_clear(map);
|
||||
|
||||
if (WARN_ON(!dmabuf))
|
||||
return -EINVAL;
|
||||
|
||||
dma_resv_assert_held(dmabuf->resv);
|
||||
|
||||
if (!dmabuf->ops->vmap)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&dmabuf->lock);
|
||||
if (dmabuf->vmapping_counter) {
|
||||
dmabuf->vmapping_counter++;
|
||||
BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr));
|
||||
*map = dmabuf->vmap_ptr;
|
||||
goto out_unlock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BUG_ON(iosys_map_is_set(&dmabuf->vmap_ptr));
|
||||
|
||||
ret = dmabuf->ops->vmap(dmabuf, &ptr);
|
||||
if (WARN_ON_ONCE(ret))
|
||||
goto out_unlock;
|
||||
return ret;
|
||||
|
||||
dmabuf->vmap_ptr = ptr;
|
||||
dmabuf->vmapping_counter = 1;
|
||||
|
||||
*map = dmabuf->vmap_ptr;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&dmabuf->lock);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF);
|
||||
|
||||
/**
|
||||
* dma_buf_vmap_unlocked - Create virtual mapping for the buffer object into kernel
|
||||
* address space. Same restrictions as for vmap and friends apply.
|
||||
* @dmabuf: [in] buffer to vmap
|
||||
* @map: [out] returns the vmap pointer
|
||||
*
|
||||
* Unlocked version of dma_buf_vmap()
|
||||
*
|
||||
* Returns 0 on success, or a negative errno code otherwise.
|
||||
*/
|
||||
int dma_buf_vmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map)
|
||||
{
|
||||
int ret;
|
||||
|
||||
iosys_map_clear(map);
|
||||
|
||||
if (WARN_ON(!dmabuf))
|
||||
return -EINVAL;
|
||||
|
||||
dma_resv_lock(dmabuf->resv, NULL);
|
||||
ret = dma_buf_vmap(dmabuf, map);
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_vmap_unlocked, DMA_BUF);
|
||||
|
||||
/**
|
||||
* dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap.
|
||||
* @dmabuf: [in] buffer to vunmap
|
||||
@@ -1485,20 +1628,36 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
|
||||
if (WARN_ON(!dmabuf))
|
||||
return;
|
||||
|
||||
dma_resv_assert_held(dmabuf->resv);
|
||||
|
||||
BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr));
|
||||
BUG_ON(dmabuf->vmapping_counter == 0);
|
||||
BUG_ON(!iosys_map_is_equal(&dmabuf->vmap_ptr, map));
|
||||
|
||||
mutex_lock(&dmabuf->lock);
|
||||
if (--dmabuf->vmapping_counter == 0) {
|
||||
if (dmabuf->ops->vunmap)
|
||||
dmabuf->ops->vunmap(dmabuf, map);
|
||||
iosys_map_clear(&dmabuf->vmap_ptr);
|
||||
}
|
||||
mutex_unlock(&dmabuf->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap, DMA_BUF);
|
||||
|
||||
/**
|
||||
* dma_buf_vunmap_unlocked - Unmap a vmap obtained by dma_buf_vmap.
|
||||
* @dmabuf: [in] buffer to vunmap
|
||||
* @map: [in] vmap pointer to vunmap
|
||||
*/
|
||||
void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map)
|
||||
{
|
||||
if (WARN_ON(!dmabuf))
|
||||
return;
|
||||
|
||||
dma_resv_lock(dmabuf->resv, NULL);
|
||||
dma_buf_vunmap(dmabuf, map);
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, DMA_BUF);
|
||||
|
||||
int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-heap.h>
|
||||
#include <linux/dma-map-ops.h>
|
||||
#include <linux/dma-resv.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/io.h>
|
||||
@@ -184,6 +185,8 @@ static int cma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
|
||||
{
|
||||
struct cma_heap_buffer *buffer = dmabuf->priv;
|
||||
|
||||
dma_resv_assert_held(dmabuf->resv);
|
||||
|
||||
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dma-heap.h>
|
||||
#include <linux/dma-resv.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/mm.h>
|
||||
@@ -217,6 +218,8 @@ static int system_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
|
||||
struct sg_page_iter piter;
|
||||
int ret;
|
||||
|
||||
dma_resv_assert_held(dmabuf->resv);
|
||||
|
||||
if (buffer->uncached)
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <linux/cred.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-resv.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -49,6 +50,8 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma)
|
||||
{
|
||||
struct udmabuf *ubuf = buf->priv;
|
||||
|
||||
dma_resv_assert_held(buf->resv);
|
||||
|
||||
if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -228,6 +228,26 @@ static void rpi_register_clk_driver(struct device *dev)
|
||||
-1, NULL, 0);
|
||||
}
|
||||
|
||||
unsigned int rpi_firmware_clk_get_max_rate(struct rpi_firmware *fw, unsigned int id)
|
||||
{
|
||||
struct rpi_firmware_clk_rate_request msg =
|
||||
RPI_FIRMWARE_CLK_RATE_REQUEST(id);
|
||||
int ret;
|
||||
|
||||
ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
|
||||
&msg, sizeof(msg));
|
||||
if (ret)
|
||||
/*
|
||||
* If our firmware doesn't support that operation, or fails, we
|
||||
* assume the maximum clock rate is absolute maximum we can
|
||||
* store over our type.
|
||||
*/
|
||||
return UINT_MAX;
|
||||
|
||||
return le32_to_cpu(msg.rate);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpi_firmware_clk_get_max_rate);
|
||||
|
||||
static void rpi_firmware_delete(struct kref *kref)
|
||||
{
|
||||
struct rpi_firmware *fw = container_of(kref, struct rpi_firmware,
|
||||
@@ -308,6 +328,18 @@ static int rpi_firmware_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id rpi_firmware_of_match[] = {
|
||||
{ .compatible = "raspberrypi,bcm2835-firmware", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
|
||||
|
||||
struct device_node *rpi_firmware_find_node(void)
|
||||
{
|
||||
return of_find_matching_node(NULL, rpi_firmware_of_match);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpi_firmware_find_node);
|
||||
|
||||
/**
|
||||
* rpi_firmware_get - Get pointer to rpi_firmware structure.
|
||||
* @firmware_node: Pointer to the firmware Device Tree node.
|
||||
@@ -363,12 +395,6 @@ struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_rpi_firmware_get);
|
||||
|
||||
static const struct of_device_id rpi_firmware_of_match[] = {
|
||||
{ .compatible = "raspberrypi,bcm2835-firmware", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
|
||||
|
||||
static struct platform_driver rpi_firmware_driver = {
|
||||
.driver = {
|
||||
.name = "raspberrypi-firmware",
|
||||
|
||||
+1
-62
@@ -8,7 +8,6 @@
|
||||
menuconfig DRM
|
||||
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
|
||||
depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA
|
||||
select DRM_NOMODESET
|
||||
select DRM_PANEL_ORIENTATION_QUIRKS
|
||||
select HDMI
|
||||
select FB_CMDLINE
|
||||
@@ -19,6 +18,7 @@ menuconfig DRM
|
||||
# gallium uses SYS_kcmp for os_same_file_description() to de-duplicate
|
||||
# device and dmabuf fd. Let's make sure that is available for our userspace.
|
||||
select KCMP
|
||||
select VIDEO_NOMODESET
|
||||
help
|
||||
Kernel-level support for the Direct Rendering Infrastructure (DRI)
|
||||
introduced in XFree86 4.0. If you say Y here, you need to select
|
||||
@@ -233,64 +233,8 @@ source "drivers/gpu/drm/i2c/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/arm/Kconfig"
|
||||
|
||||
config DRM_RADEON
|
||||
tristate "ATI Radeon"
|
||||
depends on DRM && PCI && MMU
|
||||
depends on AGP || !AGP
|
||||
select FW_LOADER
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_TTM
|
||||
select DRM_TTM_HELPER
|
||||
select POWER_SUPPLY
|
||||
select HWMON
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
select INTERVAL_TREE
|
||||
# radeon depends on ACPI_VIDEO when ACPI is enabled, for select to work
|
||||
# ACPI_VIDEO's dependencies must also be selected.
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
# On x86 ACPI_VIDEO also needs ACPI_WMI
|
||||
select X86_PLATFORM_DEVICES if ACPI && X86
|
||||
select ACPI_WMI if ACPI && X86
|
||||
help
|
||||
Choose this option if you have an ATI Radeon graphics card. There
|
||||
are both PCI and AGP versions. You don't need to choose this to
|
||||
run the Radeon in plain VGA mode.
|
||||
|
||||
If M is selected, the module will be called radeon.
|
||||
|
||||
source "drivers/gpu/drm/radeon/Kconfig"
|
||||
|
||||
config DRM_AMDGPU
|
||||
tristate "AMD GPU"
|
||||
depends on DRM && PCI && MMU
|
||||
select FW_LOADER
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_HDMI_HELPER
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_SCHED
|
||||
select DRM_TTM
|
||||
select DRM_TTM_HELPER
|
||||
select POWER_SUPPLY
|
||||
select HWMON
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
select INTERVAL_TREE
|
||||
select DRM_BUDDY
|
||||
# amdgpu depends on ACPI_VIDEO when ACPI is enabled, for select to work
|
||||
# ACPI_VIDEO's dependencies must also be selected.
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
# On x86 ACPI_VIDEO also needs ACPI_WMI
|
||||
select X86_PLATFORM_DEVICES if ACPI && X86
|
||||
select ACPI_WMI if ACPI && X86
|
||||
help
|
||||
Choose this option if you have a recent AMD Radeon graphics card.
|
||||
|
||||
If M is selected, the module will be called amdgpu.
|
||||
|
||||
source "drivers/gpu/drm/amd/amdgpu/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/nouveau/Kconfig"
|
||||
@@ -514,11 +458,6 @@ config DRM_EXPORT_FOR_TESTS
|
||||
config DRM_PANEL_ORIENTATION_QUIRKS
|
||||
tristate
|
||||
|
||||
# Separate option because nomodeset parameter is global and expected built-in
|
||||
config DRM_NOMODESET
|
||||
bool
|
||||
default n
|
||||
|
||||
config DRM_LIB_RANDOM
|
||||
bool
|
||||
default n
|
||||
|
||||
+81
-32
@@ -5,35 +5,74 @@
|
||||
|
||||
CFLAGS-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += -DDYNAMIC_DEBUG_MODULE
|
||||
|
||||
drm-y := drm_aperture.o drm_auth.o drm_cache.o \
|
||||
drm_file.o drm_gem.o drm_ioctl.o \
|
||||
drm_drv.o \
|
||||
drm_sysfs.o drm_mm.o \
|
||||
drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o drm_displayid.o \
|
||||
drm_trace_points.o drm_prime.o \
|
||||
drm_vma_manager.o \
|
||||
drm_modeset_lock.o drm_atomic.o drm_bridge.o \
|
||||
drm_framebuffer.o drm_connector.o drm_blend.o \
|
||||
drm_encoder.o drm_mode_object.o drm_property.o \
|
||||
drm_plane.o drm_color_mgmt.o drm_print.o \
|
||||
drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
|
||||
drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
|
||||
drm_client_modeset.o drm_atomic_uapi.o \
|
||||
drm_managed.o drm_vblank_work.o
|
||||
drm-$(CONFIG_DRM_LEGACY) += drm_agpsupport.o drm_bufs.o drm_context.o drm_dma.o \
|
||||
drm_hashtab.o drm_irq.o drm_legacy_misc.o drm_lock.o \
|
||||
drm_memory.o drm_scatter.o drm_vm.o
|
||||
drm-y := \
|
||||
drm_aperture.o \
|
||||
drm_atomic.o \
|
||||
drm_atomic_uapi.o \
|
||||
drm_auth.o \
|
||||
drm_blend.o \
|
||||
drm_bridge.o \
|
||||
drm_cache.o \
|
||||
drm_client.o \
|
||||
drm_client_modeset.o \
|
||||
drm_color_mgmt.o \
|
||||
drm_connector.o \
|
||||
drm_crtc.o \
|
||||
drm_displayid.o \
|
||||
drm_drv.o \
|
||||
drm_dumb_buffers.o \
|
||||
drm_edid.o \
|
||||
drm_encoder.o \
|
||||
drm_file.o \
|
||||
drm_fourcc.o \
|
||||
drm_framebuffer.o \
|
||||
drm_gem.o \
|
||||
drm_ioctl.o \
|
||||
drm_lease.o \
|
||||
drm_managed.o \
|
||||
drm_mm.o \
|
||||
drm_mode_config.o \
|
||||
drm_mode_object.o \
|
||||
drm_modes.o \
|
||||
drm_modeset_lock.o \
|
||||
drm_plane.o \
|
||||
drm_prime.o \
|
||||
drm_print.o \
|
||||
drm_property.o \
|
||||
drm_syncobj.o \
|
||||
drm_sysfs.o \
|
||||
drm_trace_points.o \
|
||||
drm_vblank.o \
|
||||
drm_vblank_work.o \
|
||||
drm_vma_manager.o \
|
||||
drm_writeback.o
|
||||
drm-$(CONFIG_DRM_LEGACY) += \
|
||||
drm_agpsupport.o \
|
||||
drm_bufs.o \
|
||||
drm_context.o \
|
||||
drm_dma.o \
|
||||
drm_hashtab.o \
|
||||
drm_irq.o \
|
||||
drm_legacy_misc.o \
|
||||
drm_lock.o \
|
||||
drm_memory.o \
|
||||
drm_scatter.o \
|
||||
drm_vm.o
|
||||
drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
|
||||
drm-$(CONFIG_COMPAT) += drm_ioc32.o
|
||||
drm-$(CONFIG_DRM_PANEL) += drm_panel.o
|
||||
drm-$(CONFIG_OF) += drm_of.o
|
||||
drm-$(CONFIG_PCI) += drm_pci.o
|
||||
drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
|
||||
drm-$(CONFIG_DEBUG_FS) += \
|
||||
drm_debugfs.o \
|
||||
drm_debugfs_crc.o
|
||||
drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
|
||||
drm-$(CONFIG_DRM_PRIVACY_SCREEN) += drm_privacy_screen.o drm_privacy_screen_x86.o
|
||||
drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
|
||||
drm_privacy_screen.o \
|
||||
drm_privacy_screen_x86.o
|
||||
drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o
|
||||
obj-$(CONFIG_DRM) += drm.o
|
||||
|
||||
obj-$(CONFIG_DRM_NOMODESET) += drm_nomodeset.o
|
||||
obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
|
||||
|
||||
#
|
||||
@@ -59,18 +98,28 @@ obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
|
||||
# Modesetting helpers
|
||||
#
|
||||
|
||||
drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o \
|
||||
drm_encoder_slave.o drm_flip_work.o \
|
||||
drm_probe_helper.o \
|
||||
drm_plane_helper.o drm_atomic_helper.o \
|
||||
drm_kms_helper_common.o \
|
||||
drm_simple_kms_helper.o drm_modeset_helper.o \
|
||||
drm_gem_atomic_helper.o \
|
||||
drm_gem_framebuffer_helper.o \
|
||||
drm_atomic_state_helper.o drm_damage_helper.o \
|
||||
drm_format_helper.o drm_self_refresh_helper.o drm_rect.o
|
||||
drm_kms_helper-y := \
|
||||
drm_atomic_helper.o \
|
||||
drm_atomic_state_helper.o \
|
||||
drm_bridge_connector.o \
|
||||
drm_crtc_helper.o \
|
||||
drm_damage_helper.o \
|
||||
drm_encoder_slave.o \
|
||||
drm_flip_work.o \
|
||||
drm_format_helper.o \
|
||||
drm_gem_atomic_helper.o \
|
||||
drm_gem_framebuffer_helper.o \
|
||||
drm_kms_helper_common.o \
|
||||
drm_modeset_helper.o \
|
||||
drm_plane_helper.o \
|
||||
drm_probe_helper.o \
|
||||
drm_rect.o \
|
||||
drm_self_refresh_helper.o \
|
||||
drm_simple_kms_helper.o
|
||||
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
|
||||
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
|
||||
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \
|
||||
drm_fbdev_generic.o \
|
||||
drm_fb_helper.o
|
||||
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
|
||||
|
||||
#
|
||||
|
||||
@@ -1,4 +1,33 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
config DRM_AMDGPU
|
||||
tristate "AMD GPU"
|
||||
depends on DRM && PCI && MMU
|
||||
select FW_LOADER
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_HDMI_HELPER
|
||||
select DRM_DISPLAY_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_SCHED
|
||||
select DRM_TTM
|
||||
select DRM_TTM_HELPER
|
||||
select POWER_SUPPLY
|
||||
select HWMON
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
select INTERVAL_TREE
|
||||
select DRM_BUDDY
|
||||
# amdgpu depends on ACPI_VIDEO when ACPI is enabled, for select to work
|
||||
# ACPI_VIDEO's dependencies must also be selected.
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
# On x86 ACPI_VIDEO also needs ACPI_WMI
|
||||
select X86_PLATFORM_DEVICES if ACPI && X86
|
||||
select ACPI_WMI if ACPI && X86
|
||||
help
|
||||
Choose this option if you have a recent AMD Radeon graphics card.
|
||||
|
||||
If M is selected, the module will be called amdgpu.
|
||||
|
||||
config DRM_AMDGPU_SI
|
||||
bool "Enable amdgpu support for SI parts"
|
||||
depends on DRM_AMDGPU
|
||||
|
||||
@@ -58,7 +58,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
|
||||
amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \
|
||||
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \
|
||||
amdgpu_fw_attestation.o amdgpu_securedisplay.o \
|
||||
amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o
|
||||
amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \
|
||||
amdgpu_ring_mux.o
|
||||
|
||||
amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o
|
||||
|
||||
@@ -250,7 +251,7 @@ endif
|
||||
amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
|
||||
amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
|
||||
amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
|
||||
amdgpu-$(CONFIG_HMM_MIRROR) += amdgpu_mn.o
|
||||
amdgpu-$(CONFIG_HMM_MIRROR) += amdgpu_hmm.o
|
||||
|
||||
include $(FULL_AMD_PATH)/pm/Makefile
|
||||
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
#include "amdgpu_vce.h"
|
||||
#include "amdgpu_vcn.h"
|
||||
#include "amdgpu_jpeg.h"
|
||||
#include "amdgpu_mn.h"
|
||||
#include "amdgpu_gmc.h"
|
||||
#include "amdgpu_gfx.h"
|
||||
#include "amdgpu_sdma.h"
|
||||
@@ -219,10 +218,12 @@ extern int amdgpu_use_xgmi_p2p;
|
||||
extern int sched_policy;
|
||||
extern bool debug_evictions;
|
||||
extern bool no_system_mem_limit;
|
||||
extern int halt_if_hws_hang;
|
||||
#else
|
||||
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;
|
||||
static const int __maybe_unused halt_if_hws_hang;
|
||||
#endif
|
||||
#ifdef CONFIG_HSA_AMD_P2P
|
||||
extern bool pcie_p2p;
|
||||
@@ -675,7 +676,7 @@ enum amd_hw_ip_block_type {
|
||||
MAX_HWIP
|
||||
};
|
||||
|
||||
#define HWIP_MAX_INSTANCE 11
|
||||
#define HWIP_MAX_INSTANCE 28
|
||||
|
||||
#define HW_ID_MAX 300
|
||||
#define IP_VERSION(mj, mn, rv) (((mj) << 16) | ((mn) << 8) | (rv))
|
||||
@@ -1063,6 +1064,7 @@ struct amdgpu_device {
|
||||
struct work_struct reset_work;
|
||||
|
||||
bool job_hang;
|
||||
bool dc_enabled;
|
||||
};
|
||||
|
||||
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
|
||||
@@ -1120,6 +1122,8 @@ void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
||||
bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type);
|
||||
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
|
||||
|
||||
void amdgpu_device_set_sriov_virtual_display(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
|
||||
struct amdgpu_reset_context *reset_context);
|
||||
|
||||
|
||||
@@ -847,7 +847,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
|
||||
struct amdgpu_atif *atif = &amdgpu_acpi_priv.atif;
|
||||
|
||||
if (atif->notifications.brightness_change) {
|
||||
if (amdgpu_device_has_dc_support(adev)) {
|
||||
if (adev->dc_enabled) {
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
struct amdgpu_display_manager *dm = &adev->dm;
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ 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);
|
||||
&gpu_resources);
|
||||
|
||||
amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size;
|
||||
|
||||
@@ -673,7 +673,7 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = amdgpu_job_alloc(adev, 1, &job, NULL);
|
||||
ret = amdgpu_job_alloc(adev, NULL, NULL, NULL, 1, &job);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@@ -760,9 +760,7 @@ bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev)
|
||||
|
||||
void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev, bool reset)
|
||||
{
|
||||
struct ras_err_data err_data = {0, 0, 0, NULL};
|
||||
|
||||
amdgpu_umc_poison_handler(adev, &err_data, reset);
|
||||
amdgpu_umc_poison_handler(adev, reset);
|
||||
}
|
||||
|
||||
bool amdgpu_amdkfd_ras_query_utcl2_poison_status(struct amdgpu_device *adev)
|
||||
|
||||
@@ -353,7 +353,6 @@ int kgd2kfd_init(void);
|
||||
void kgd2kfd_exit(void);
|
||||
struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf);
|
||||
bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||
struct drm_device *ddev,
|
||||
const struct kgd2kfd_shared_resources *gpu_resources);
|
||||
void kgd2kfd_device_exit(struct kfd_dev *kfd);
|
||||
void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm);
|
||||
@@ -381,7 +380,7 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
|
||||
}
|
||||
|
||||
static inline
|
||||
bool kgd2kfd_device_init(struct kfd_dev *kfd, struct drm_device *ddev,
|
||||
bool kgd2kfd_device_init(struct kfd_dev *kfd,
|
||||
const struct kgd2kfd_shared_resources *gpu_resources)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -787,7 +787,7 @@ void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid,
|
||||
for (se_idx = 0; se_idx < se_cnt; se_idx++) {
|
||||
for (sh_idx = 0; sh_idx < sh_cnt; sh_idx++) {
|
||||
|
||||
gfx_v9_0_select_se_sh(adev, se_idx, sh_idx, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, se_idx, sh_idx, 0xffffffff);
|
||||
queue_map = RREG32_SOC15(GC, 0, mmSPI_CSQ_WF_ACTIVE_STATUS);
|
||||
|
||||
/*
|
||||
@@ -820,7 +820,7 @@ void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid,
|
||||
}
|
||||
}
|
||||
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
soc15_grbm_select(adev, 0, 0, 0, 0);
|
||||
unlock_spi_csq_mutexes(adev);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "amdgpu_object.h"
|
||||
#include "amdgpu_gem.h"
|
||||
#include "amdgpu_vm.h"
|
||||
#include "amdgpu_hmm.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu_dma_buf.h"
|
||||
#include <uapi/linux/kfd_ioctl.h>
|
||||
@@ -403,63 +404,15 @@ static int vm_update_pds(struct amdgpu_vm *vm, struct amdgpu_sync *sync)
|
||||
|
||||
static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
|
||||
{
|
||||
struct amdgpu_device *bo_adev = amdgpu_ttm_adev(mem->bo->tbo.bdev);
|
||||
bool coherent = mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_COHERENT;
|
||||
bool uncached = mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED;
|
||||
uint32_t mapping_flags;
|
||||
uint64_t pte_flags;
|
||||
bool snoop = false;
|
||||
uint32_t mapping_flags = AMDGPU_VM_PAGE_READABLE |
|
||||
AMDGPU_VM_MTYPE_DEFAULT;
|
||||
|
||||
mapping_flags = AMDGPU_VM_PAGE_READABLE;
|
||||
if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE)
|
||||
mapping_flags |= AMDGPU_VM_PAGE_WRITEABLE;
|
||||
if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE)
|
||||
mapping_flags |= AMDGPU_VM_PAGE_EXECUTABLE;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_ARCTURUS:
|
||||
case CHIP_ALDEBARAN:
|
||||
if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
|
||||
if (bo_adev == adev) {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
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);
|
||||
pte_flags |= snoop ? AMDGPU_PTE_SNOOPED : 0;
|
||||
|
||||
return pte_flags;
|
||||
return amdgpu_gem_va_map_flags(adev, mapping_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -997,7 +950,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = amdgpu_mn_register(bo, user_addr);
|
||||
ret = amdgpu_hmm_register(bo, user_addr);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to register MMU notifier: %d\n",
|
||||
__func__, ret);
|
||||
@@ -1037,7 +990,7 @@ release_out:
|
||||
amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
|
||||
unregister_out:
|
||||
if (ret)
|
||||
amdgpu_mn_unregister(bo);
|
||||
amdgpu_hmm_unregister(bo);
|
||||
out:
|
||||
mutex_unlock(&process_info->lock);
|
||||
return ret;
|
||||
@@ -1672,6 +1625,11 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & KFD_IOC_ALLOC_MEM_FLAGS_COHERENT)
|
||||
alloc_flags |= AMDGPU_GEM_CREATE_COHERENT;
|
||||
if (flags & KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED)
|
||||
alloc_flags |= AMDGPU_GEM_CREATE_UNCACHED;
|
||||
|
||||
*mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL);
|
||||
if (!*mem) {
|
||||
ret = -ENOMEM;
|
||||
@@ -1816,7 +1774,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
||||
mutex_unlock(&process_info->lock);
|
||||
|
||||
/* No more MMU notifiers */
|
||||
amdgpu_mn_unregister(mem->bo);
|
||||
amdgpu_hmm_unregister(mem->bo);
|
||||
|
||||
ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, &ctx);
|
||||
if (unlikely(ret))
|
||||
@@ -1906,16 +1864,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
|
||||
*/
|
||||
mutex_lock(&mem->process_info->lock);
|
||||
|
||||
/* Lock mmap-sem. If we find an invalid userptr BO, we can be
|
||||
* sure that the MMU notifier is no longer running
|
||||
* concurrently and the queues are actually stopped
|
||||
*/
|
||||
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
|
||||
mmap_write_lock(current->mm);
|
||||
is_invalid_userptr = atomic_read(&mem->invalid);
|
||||
mmap_write_unlock(current->mm);
|
||||
}
|
||||
|
||||
mutex_lock(&mem->lock);
|
||||
|
||||
domain = mem->domain;
|
||||
@@ -2256,7 +2204,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
|
||||
|
||||
ret = drm_vma_node_allow(&obj->vma_node, drm_priv);
|
||||
if (ret) {
|
||||
kfree(mem);
|
||||
kfree(*mem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,39 +101,101 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static int amdgpu_atomfirmware_allocate_fb_v2_1(struct amdgpu_device *adev,
|
||||
struct vram_usagebyfirmware_v2_1 *fw_usage, int *usage_bytes)
|
||||
{
|
||||
u32 start_addr, fw_size, drv_size;
|
||||
|
||||
start_addr = le32_to_cpu(fw_usage->start_address_in_kb);
|
||||
fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
|
||||
drv_size = le16_to_cpu(fw_usage->used_by_driver_in_kb);
|
||||
|
||||
DRM_DEBUG("atom firmware v2_1 requested %08x %dkb fw %dkb drv\n",
|
||||
start_addr,
|
||||
fw_size,
|
||||
drv_size);
|
||||
|
||||
if ((start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
|
||||
(u32)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
|
||||
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
|
||||
/* Firmware request VRAM reservation for SR-IOV */
|
||||
adev->mman.fw_vram_usage_start_offset = (start_addr &
|
||||
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
|
||||
adev->mman.fw_vram_usage_size = fw_size << 10;
|
||||
/* Use the default scratch size */
|
||||
*usage_bytes = 0;
|
||||
} else {
|
||||
*usage_bytes = drv_size << 10;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_atomfirmware_allocate_fb_v2_2(struct amdgpu_device *adev,
|
||||
struct vram_usagebyfirmware_v2_2 *fw_usage, int *usage_bytes)
|
||||
{
|
||||
u32 fw_start_addr, fw_size, drv_start_addr, drv_size;
|
||||
|
||||
fw_start_addr = le32_to_cpu(fw_usage->fw_region_start_address_in_kb);
|
||||
fw_size = le16_to_cpu(fw_usage->used_by_firmware_in_kb);
|
||||
|
||||
drv_start_addr = le32_to_cpu(fw_usage->driver_region0_start_address_in_kb);
|
||||
drv_size = le32_to_cpu(fw_usage->used_by_driver_region0_in_kb);
|
||||
|
||||
DRM_DEBUG("atom requested fw start at %08x %dkb and drv start at %08x %dkb\n",
|
||||
fw_start_addr,
|
||||
fw_size,
|
||||
drv_start_addr,
|
||||
drv_size);
|
||||
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
((fw_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION <<
|
||||
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) == 0)) {
|
||||
/* Firmware request VRAM reservation for SR-IOV */
|
||||
adev->mman.fw_vram_usage_start_offset = (fw_start_addr &
|
||||
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
|
||||
adev->mman.fw_vram_usage_size = fw_size << 10;
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
((drv_start_addr & (ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION <<
|
||||
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) == 0)) {
|
||||
/* driver request VRAM reservation for SR-IOV */
|
||||
adev->mman.drv_vram_usage_start_offset = (drv_start_addr &
|
||||
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
|
||||
adev->mman.drv_vram_usage_size = drv_size << 10;
|
||||
}
|
||||
|
||||
*usage_bytes = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
|
||||
{
|
||||
struct atom_context *ctx = adev->mode_info.atom_context;
|
||||
int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
|
||||
vram_usagebyfirmware);
|
||||
struct vram_usagebyfirmware_v2_1 *firmware_usage;
|
||||
uint32_t start_addr, size;
|
||||
uint16_t data_offset;
|
||||
struct vram_usagebyfirmware_v2_1 *fw_usage_v2_1;
|
||||
struct vram_usagebyfirmware_v2_2 *fw_usage_v2_2;
|
||||
u16 data_offset;
|
||||
u8 frev, crev;
|
||||
int usage_bytes = 0;
|
||||
|
||||
if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
|
||||
firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
|
||||
DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n",
|
||||
le32_to_cpu(firmware_usage->start_address_in_kb),
|
||||
le16_to_cpu(firmware_usage->used_by_firmware_in_kb),
|
||||
le16_to_cpu(firmware_usage->used_by_driver_in_kb));
|
||||
|
||||
start_addr = le32_to_cpu(firmware_usage->start_address_in_kb);
|
||||
size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb);
|
||||
|
||||
if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
|
||||
(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
|
||||
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
|
||||
/* Firmware request VRAM reservation for SR-IOV */
|
||||
adev->mman.fw_vram_usage_start_offset = (start_addr &
|
||||
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
|
||||
adev->mman.fw_vram_usage_size = size << 10;
|
||||
/* Use the default scratch size */
|
||||
usage_bytes = 0;
|
||||
} else {
|
||||
usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10;
|
||||
if (amdgpu_atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) {
|
||||
if (frev == 2 && crev == 1) {
|
||||
fw_usage_v2_1 =
|
||||
(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
|
||||
amdgpu_atomfirmware_allocate_fb_v2_1(adev,
|
||||
fw_usage_v2_1,
|
||||
&usage_bytes);
|
||||
} else if (frev >= 2 && crev >= 2) {
|
||||
fw_usage_v2_2 =
|
||||
(struct vram_usagebyfirmware_v2_2 *)(ctx->bios + data_offset);
|
||||
amdgpu_atomfirmware_allocate_fb_v2_2(adev,
|
||||
fw_usage_v2_2,
|
||||
&usage_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
ctx->scratch_size_bytes = 0;
|
||||
if (usage_bytes == 0)
|
||||
usage_bytes = 20 * 1024;
|
||||
|
||||
@@ -317,6 +317,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
|
||||
|
||||
if (!found)
|
||||
return false;
|
||||
pci_dev_put(pdev);
|
||||
|
||||
adev->bios = kmalloc(size, GFP_KERNEL);
|
||||
if (!adev->bios) {
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <drm/display/drm_dp_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/amdgpu_drm.h>
|
||||
#include "amdgpu.h"
|
||||
|
||||
@@ -294,12 +294,8 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
|
||||
}
|
||||
|
||||
for (i = 0; i < p->gang_size; ++i) {
|
||||
ret = amdgpu_job_alloc(p->adev, num_ibs[i], &p->jobs[i], vm);
|
||||
if (ret)
|
||||
goto free_all_kdata;
|
||||
|
||||
ret = drm_sched_job_init(&p->jobs[i]->base, p->entities[i],
|
||||
&fpriv->vm);
|
||||
ret = amdgpu_job_alloc(p->adev, vm, p->entities[i], vm,
|
||||
num_ibs[i], &p->jobs[i]);
|
||||
if (ret)
|
||||
goto free_all_kdata;
|
||||
}
|
||||
@@ -433,7 +429,7 @@ static int amdgpu_cs_p2_dependencies(struct amdgpu_cs_parser *p,
|
||||
dma_fence_put(old);
|
||||
}
|
||||
|
||||
r = amdgpu_sync_fence(&p->gang_leader->sync, fence);
|
||||
r = amdgpu_sync_fence(&p->sync, fence);
|
||||
dma_fence_put(fence);
|
||||
if (r)
|
||||
return r;
|
||||
@@ -455,9 +451,20 @@ static int amdgpu_syncobj_lookup_and_add(struct amdgpu_cs_parser *p,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_sync_fence(&p->gang_leader->sync, fence);
|
||||
dma_fence_put(fence);
|
||||
r = amdgpu_sync_fence(&p->sync, fence);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
/*
|
||||
* When we have an explicit dependency it might be necessary to insert a
|
||||
* pipeline sync to make sure that all caches etc are flushed and the
|
||||
* next job actually sees the results from the previous one.
|
||||
*/
|
||||
if (fence->context == p->gang_leader->base.entity->fence_context)
|
||||
r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence);
|
||||
|
||||
error:
|
||||
dma_fence_put(fence);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1106,7 +1113,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_sync_fence(&job->sync, fpriv->prt_va->last_pt_update);
|
||||
r = amdgpu_sync_fence(&p->sync, fpriv->prt_va->last_pt_update);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -1117,7 +1124,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_sync_fence(&job->sync, bo_va->last_pt_update);
|
||||
r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
@@ -1136,7 +1143,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_sync_fence(&job->sync, bo_va->last_pt_update);
|
||||
r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
@@ -1149,7 +1156,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_sync_fence(&job->sync, vm->last_update);
|
||||
r = amdgpu_sync_fence(&p->sync, vm->last_update);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -1181,7 +1188,6 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
|
||||
static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
|
||||
{
|
||||
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
|
||||
struct amdgpu_job *leader = p->gang_leader;
|
||||
struct amdgpu_bo_list_entry *e;
|
||||
unsigned int i;
|
||||
int r;
|
||||
@@ -1193,17 +1199,14 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
|
||||
|
||||
sync_mode = amdgpu_bo_explicit_sync(bo) ?
|
||||
AMDGPU_SYNC_EXPLICIT : AMDGPU_SYNC_NE_OWNER;
|
||||
r = amdgpu_sync_resv(p->adev, &leader->sync, resv, sync_mode,
|
||||
r = amdgpu_sync_resv(p->adev, &p->sync, resv, sync_mode,
|
||||
&fpriv->vm);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 0; i < p->gang_size; ++i) {
|
||||
if (p->jobs[i] == leader)
|
||||
continue;
|
||||
|
||||
r = amdgpu_sync_clone(&leader->sync, &p->jobs[i]->sync);
|
||||
r = amdgpu_sync_push_to_job(&p->sync, p->jobs[i]);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
@@ -1251,7 +1254,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
||||
continue;
|
||||
|
||||
fence = &p->jobs[i]->base.s_fence->scheduled;
|
||||
r = amdgpu_sync_fence(&leader->sync, fence);
|
||||
r = drm_sched_job_add_dependency(&leader->base, fence);
|
||||
if (r)
|
||||
goto error_cleanup;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ struct amdgpu_cs_parser {
|
||||
|
||||
unsigned num_post_deps;
|
||||
struct amdgpu_cs_post_dep *post_deps;
|
||||
|
||||
struct amdgpu_sync sync;
|
||||
};
|
||||
|
||||
int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
|
||||
|
||||
@@ -1969,7 +1969,7 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
|
||||
amdgpu_ta_if_debugfs_init(adev);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
if (amdgpu_device_has_dc_support(adev))
|
||||
if (adev->dc_enabled)
|
||||
dtn_debugfs_init(adev);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <linux/pci-p2pdma.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/amdgpu_drm.h>
|
||||
#include <linux/vgaarb.h>
|
||||
@@ -1568,7 +1569,7 @@ static int amdgpu_device_check_arguments(struct amdgpu_device *adev)
|
||||
* @pdev: pci dev pointer
|
||||
* @state: vga_switcheroo state
|
||||
*
|
||||
* Callback for the switcheroo driver. Suspends or resumes the
|
||||
* Callback for the switcheroo driver. Suspends or resumes
|
||||
* the asics before or after it is powered up using ACPI methods.
|
||||
*/
|
||||
static void amdgpu_switcheroo_set_state(struct pci_dev *pdev,
|
||||
@@ -1915,6 +1916,16 @@ static void amdgpu_device_enable_virtual_display(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_device_set_sriov_virtual_display(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev) && !adev->enable_virtual_display) {
|
||||
adev->mode_info.num_crtc = 1;
|
||||
adev->enable_virtual_display = true;
|
||||
DRM_INFO("virtual_display:%d, num_crtc:%d\n",
|
||||
adev->enable_virtual_display, adev->mode_info.num_crtc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_parse_gpu_info_fw - parse gpu info firmware
|
||||
*
|
||||
@@ -2397,7 +2408,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
||||
adev->ip_blocks[i].status.hw = true;
|
||||
|
||||
/* right after GMC hw init, we create CSA */
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
|
||||
if (amdgpu_mcbp) {
|
||||
r = amdgpu_allocate_static_csa(adev, &adev->virt.csa_obj,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_CSA_SIZE);
|
||||
@@ -2462,6 +2473,11 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(adev);
|
||||
|
||||
if (WARN_ON(!hive)) {
|
||||
r = -ENOENT;
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
if (!hive->reset_domain ||
|
||||
!amdgpu_reset_get_reset_domain(hive->reset_domain)) {
|
||||
r = -ENOENT;
|
||||
@@ -3347,8 +3363,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) ||
|
||||
adev->enable_virtual_display ||
|
||||
if (adev->enable_virtual_display ||
|
||||
(adev->harvest_ip_mask & AMD_HARVEST_IP_DMU_MASK))
|
||||
return false;
|
||||
|
||||
@@ -4171,21 +4186,15 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
|
||||
r = amdgpu_device_ip_resume(adev);
|
||||
|
||||
/* no matter what r is, always need to properly release full GPU */
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_virt_init_data_exchange(adev);
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
}
|
||||
|
||||
if (r) {
|
||||
dev_err(adev->dev, "amdgpu_device_ip_resume failed (%d).\n", r);
|
||||
return r;
|
||||
goto exit;
|
||||
}
|
||||
amdgpu_fence_driver_hw_init(adev);
|
||||
|
||||
r = amdgpu_device_ip_late_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
goto exit;
|
||||
|
||||
queue_delayed_work(system_wq, &adev->delayed_init_work,
|
||||
msecs_to_jiffies(AMDGPU_RESUME_MS));
|
||||
@@ -4193,9 +4202,18 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
if (!adev->in_s0ix) {
|
||||
r = amdgpu_amdkfd_resume(adev, adev->in_runpm);
|
||||
if (r)
|
||||
return r;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_virt_init_data_exchange(adev);
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
}
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Make sure IB tests flushed */
|
||||
flush_delayed_work(&adev->delayed_init_work);
|
||||
|
||||
@@ -4213,25 +4231,27 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
||||
|
||||
amdgpu_ras_resume(adev);
|
||||
|
||||
/*
|
||||
* Most of the connector probing functions try to acquire runtime pm
|
||||
* refs to ensure that the GPU is powered on when connector polling is
|
||||
* performed. Since we're calling this from a runtime PM callback,
|
||||
* trying to acquire rpm refs will cause us to deadlock.
|
||||
*
|
||||
* Since we're guaranteed to be holding the rpm lock, it's safe to
|
||||
* temporarily disable the rpm helpers so this doesn't deadlock us.
|
||||
*/
|
||||
if (adev->mode_info.num_crtc) {
|
||||
/*
|
||||
* Most of the connector probing functions try to acquire runtime pm
|
||||
* refs to ensure that the GPU is powered on when connector polling is
|
||||
* performed. Since we're calling this from a runtime PM callback,
|
||||
* trying to acquire rpm refs will cause us to deadlock.
|
||||
*
|
||||
* Since we're guaranteed to be holding the rpm lock, it's safe to
|
||||
* temporarily disable the rpm helpers so this doesn't deadlock us.
|
||||
*/
|
||||
#ifdef CONFIG_PM
|
||||
dev->dev->power.disable_depth++;
|
||||
dev->dev->power.disable_depth++;
|
||||
#endif
|
||||
if (!amdgpu_device_has_dc_support(adev))
|
||||
drm_helper_hpd_irq_event(dev);
|
||||
else
|
||||
drm_kms_helper_hotplug_event(dev);
|
||||
if (!adev->dc_enabled)
|
||||
drm_helper_hpd_irq_event(dev);
|
||||
else
|
||||
drm_kms_helper_hotplug_event(dev);
|
||||
#ifdef CONFIG_PM
|
||||
dev->dev->power.disable_depth--;
|
||||
dev->dev->power.disable_depth--;
|
||||
#endif
|
||||
}
|
||||
adev->in_suspend = false;
|
||||
|
||||
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0))
|
||||
@@ -4580,6 +4600,10 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
|
||||
if (amdgpu_gpu_recovery == 0)
|
||||
goto disabled;
|
||||
|
||||
/* Skip soft reset check in fatal error mode */
|
||||
if (!amdgpu_ras_is_poison_mode_supported(adev))
|
||||
return true;
|
||||
|
||||
if (!amdgpu_device_ip_check_soft_reset(adev)) {
|
||||
dev_info(adev->dev,"Timeout, but no hardware hang detected.\n");
|
||||
return false;
|
||||
@@ -5027,6 +5051,8 @@ static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev)
|
||||
pm_runtime_enable(&(p->dev));
|
||||
pm_runtime_resume(&(p->dev));
|
||||
}
|
||||
|
||||
pci_dev_put(p);
|
||||
}
|
||||
|
||||
static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
|
||||
@@ -5065,6 +5091,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
|
||||
|
||||
if (expires < ktime_get_mono_fast_ns()) {
|
||||
dev_warn(adev->dev, "failed to suspend display audio\n");
|
||||
pci_dev_put(p);
|
||||
/* TODO: abort the succeeding gpu reset? */
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@@ -5072,97 +5099,10 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
|
||||
|
||||
pm_runtime_disable(&(p->dev));
|
||||
|
||||
pci_dev_put(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_device_recheck_guilty_jobs(
|
||||
struct amdgpu_device *adev, struct list_head *device_list_handle,
|
||||
struct amdgpu_reset_context *reset_context)
|
||||
{
|
||||
int i, r = 0;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
int ret = 0;
|
||||
struct drm_sched_job *s_job;
|
||||
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
s_job = list_first_entry_or_null(&ring->sched.pending_list,
|
||||
struct drm_sched_job, list);
|
||||
if (s_job == NULL)
|
||||
continue;
|
||||
|
||||
/* clear job's guilty and depend the folowing step to decide the real one */
|
||||
drm_sched_reset_karma(s_job);
|
||||
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);
|
||||
amdgpu_reset_prepare_hwcontext(adev, reset_context);
|
||||
retry:
|
||||
/* do hw reset */
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_virt_fini_data_exchange(adev);
|
||||
r = amdgpu_device_reset_sriov(adev, false);
|
||||
if (r)
|
||||
adev->asic_reset_res = r;
|
||||
} else {
|
||||
clear_bit(AMDGPU_SKIP_HW_RESET,
|
||||
&reset_context->flags);
|
||||
r = amdgpu_do_asic_reset(device_list_handle,
|
||||
reset_context);
|
||||
if (r && r == -EAGAIN)
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/*
|
||||
* add reset counter so that the following
|
||||
* resubmitted job could flush vmid
|
||||
*/
|
||||
atomic_inc(&adev->gpu_reset_counter);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* got the hw fence, signal finished fence */
|
||||
atomic_dec(ring->sched.score);
|
||||
dma_fence_get(&s_job->s_fence->finished);
|
||||
dma_fence_signal(&s_job->s_fence->finished);
|
||||
dma_fence_put(&s_job->s_fence->finished);
|
||||
|
||||
/* remove node from list and free the job */
|
||||
spin_lock(&ring->sched.job_list_lock);
|
||||
list_del_init(&s_job->list);
|
||||
spin_unlock(&ring->sched.job_list_lock);
|
||||
ring->sched.ops->free_job(s_job);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
|
||||
@@ -5183,7 +5123,6 @@ static inline void amdgpu_device_stop_pending_resets(struct amdgpu_device *adev)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* amdgpu_device_gpu_recover - reset the asic and recover scheduler
|
||||
*
|
||||
@@ -5206,7 +5145,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
int i, r = 0;
|
||||
bool need_emergency_restart = false;
|
||||
bool audio_suspended = false;
|
||||
int tmp_vram_lost_counter;
|
||||
bool gpu_reset_for_dev_remove = false;
|
||||
|
||||
gpu_reset_for_dev_remove =
|
||||
@@ -5352,7 +5290,6 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */
|
||||
amdgpu_device_stop_pending_resets(tmp_adev);
|
||||
}
|
||||
|
||||
tmp_vram_lost_counter = atomic_read(&((adev)->vram_lost_counter));
|
||||
/* Actual ASIC resets if needed.*/
|
||||
/* Host driver will handle XGMI hive reset for SRIOV */
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
@@ -5377,29 +5314,13 @@ skip_hw_reset:
|
||||
/* Post ASIC reset for all devs .*/
|
||||
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
|
||||
|
||||
/*
|
||||
* Sometimes a later bad compute job can block a good gfx job as gfx
|
||||
* and compute ring share internal GC HW mutually. We add an additional
|
||||
* guilty jobs recheck step to find the real guilty job, it synchronously
|
||||
* submits and pends for the first job being signaled. If it gets timeout,
|
||||
* we identify it as a real guilty job.
|
||||
*/
|
||||
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);
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = tmp_adev->rings[i];
|
||||
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
/* No point to resubmit jobs if we didn't HW reset*/
|
||||
if (!tmp_adev->asic_reset_res && !job_signaled)
|
||||
drm_sched_resubmit_jobs(&ring->sched);
|
||||
|
||||
drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
|
||||
drm_sched_start(&ring->sched, true);
|
||||
}
|
||||
|
||||
if (adev->enable_mes && adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3))
|
||||
@@ -5441,6 +5362,8 @@ skip_sched_resume:
|
||||
amdgpu_device_resume_display_audio(tmp_adev);
|
||||
|
||||
amdgpu_device_unset_mp1_state(tmp_adev);
|
||||
|
||||
amdgpu_ras_set_error_query_ready(tmp_adev, true);
|
||||
}
|
||||
|
||||
recover_end:
|
||||
@@ -5852,8 +5775,6 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
|
||||
drm_sched_resubmit_jobs(&ring->sched);
|
||||
drm_sched_start(&ring->sched, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -305,8 +305,13 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!amdgpu_discovery_verify_binary_signature(adev->mman.discovery_bin)) {
|
||||
dev_warn(adev->dev, "get invalid ip discovery binary signature from vram\n");
|
||||
if (!amdgpu_discovery_verify_binary_signature(adev->mman.discovery_bin) || amdgpu_discovery == 2) {
|
||||
/* ignore the discovery binary from vram if discovery=2 in kernel module parameter */
|
||||
if (amdgpu_discovery == 2)
|
||||
dev_info(adev->dev,"force read ip discovery binary from file");
|
||||
else
|
||||
dev_warn(adev->dev, "get invalid ip discovery binary signature from vram\n");
|
||||
|
||||
/* retry read ip discovery binary from file */
|
||||
r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin);
|
||||
if (r) {
|
||||
@@ -1507,6 +1512,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1551,6 +1557,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1636,6 +1643,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
case IP_VERSION(13, 0, 11):
|
||||
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||
break;
|
||||
case IP_VERSION(13, 0, 4):
|
||||
@@ -1686,6 +1694,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(13, 0, 7):
|
||||
case IP_VERSION(13, 0, 8):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
case IP_VERSION(13, 0, 11):
|
||||
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1697,9 +1706,17 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
static void amdgpu_discovery_set_sriov_display(struct amdgpu_device *adev)
|
||||
{
|
||||
amdgpu_device_set_sriov_virtual_display(adev);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) {
|
||||
if (adev->enable_virtual_display) {
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
return 0;
|
||||
}
|
||||
@@ -1727,7 +1744,10 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||
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);
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_discovery_set_sriov_display(adev);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
@@ -1740,7 +1760,10 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(12, 0, 0):
|
||||
case IP_VERSION(12, 0, 1):
|
||||
case IP_VERSION(12, 1, 0):
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_discovery_set_sriov_display(adev);
|
||||
else
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
break;
|
||||
default:
|
||||
dev_err(adev->dev,
|
||||
@@ -1785,6 +1808,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);
|
||||
break;
|
||||
default:
|
||||
@@ -1948,6 +1972,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 2):
|
||||
case IP_VERSION(11, 0, 3):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);
|
||||
adev->enable_mes = true;
|
||||
adev->enable_mes_kiq = true;
|
||||
@@ -2161,6 +2186,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
break;
|
||||
case IP_VERSION(10, 3, 1):
|
||||
adev->family = AMDGPU_FAMILY_VGH;
|
||||
adev->apu_flags |= AMD_APU_IS_VANGOGH;
|
||||
break;
|
||||
case IP_VERSION(10, 3, 3):
|
||||
adev->family = AMDGPU_FAMILY_YC;
|
||||
@@ -2177,6 +2203,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
adev->family = AMDGPU_FAMILY_GC_11_0_0;
|
||||
break;
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
adev->family = AMDGPU_FAMILY_GC_11_0_1;
|
||||
break;
|
||||
default:
|
||||
@@ -2194,6 +2221,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
case IP_VERSION(10, 3, 6):
|
||||
case IP_VERSION(10, 3, 7):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
adev->flags |= AMD_IS_APU;
|
||||
break;
|
||||
default:
|
||||
@@ -2250,6 +2278,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
|
||||
adev->nbio.hdp_flush_reg = &nbio_v4_3_hdp_flush_reg;
|
||||
break;
|
||||
case IP_VERSION(7, 7, 0):
|
||||
case IP_VERSION(7, 7, 1):
|
||||
adev->nbio.funcs = &nbio_v7_7_funcs;
|
||||
adev->nbio.hdp_flush_reg = &nbio_v7_7_hdp_flush_reg;
|
||||
break;
|
||||
|
||||
@@ -39,11 +39,46 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
/**
|
||||
* amdgpu_display_hotplug_work_func - work handler for display hotplug event
|
||||
*
|
||||
* @work: work struct pointer
|
||||
*
|
||||
* This is the hotplug event work handler (all ASICs).
|
||||
* The work gets scheduled from the IRQ handler if there
|
||||
* was a hotplug interrupt. It walks through the connector table
|
||||
* and calls hotplug handler for each connector. After this, it sends
|
||||
* a DRM hotplug event to alert userspace.
|
||||
*
|
||||
* This design approach is required in order to defer hotplug event handling
|
||||
* from the IRQ handler to a work handler because hotplug handler has to use
|
||||
* mutexes which cannot be locked in an IRQ handler (since &mutex_lock may
|
||||
* sleep).
|
||||
*/
|
||||
void amdgpu_display_hotplug_work_func(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
|
||||
hotplug_work);
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
|
||||
mutex_lock(&mode_config->mutex);
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
amdgpu_connector_hotplug(connector);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
mutex_unlock(&mode_config->mutex);
|
||||
/* Just fire off a uevent and let userspace tell us what to do */
|
||||
drm_helper_hpd_irq_event(dev);
|
||||
}
|
||||
|
||||
static int amdgpu_display_framebuffer_init(struct drm_device *dev,
|
||||
struct amdgpu_framebuffer *rfb,
|
||||
const struct drm_mode_fb_cmd2 *mode_cmd,
|
||||
@@ -514,7 +549,7 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
|
||||
*/
|
||||
if ((bo_flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC) &&
|
||||
amdgpu_bo_support_uswc(bo_flags) &&
|
||||
amdgpu_device_asic_has_dc_support(adev->asic_type) &&
|
||||
adev->dc_enabled &&
|
||||
adev->mode_info.gpu_vm_support)
|
||||
domain |= AMDGPU_GEM_DOMAIN_GTT;
|
||||
#endif
|
||||
@@ -1214,7 +1249,6 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
|
||||
|
||||
const struct drm_mode_config_funcs amdgpu_mode_funcs = {
|
||||
.fb_create = amdgpu_display_user_framebuffer_create,
|
||||
.output_poll_changed = drm_fb_helper_output_poll_changed,
|
||||
};
|
||||
|
||||
static const struct drm_prop_enum_list amdgpu_underscan_enum_list[] =
|
||||
@@ -1281,7 +1315,7 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
|
||||
"dither",
|
||||
amdgpu_dither_enum_list, sz);
|
||||
|
||||
if (amdgpu_device_has_dc_support(adev)) {
|
||||
if (adev->dc_enabled) {
|
||||
adev->mode_info.abm_level_property =
|
||||
drm_property_create_range(adev_to_drm(adev), 0,
|
||||
"abm level", 0, 4);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#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))
|
||||
|
||||
void amdgpu_display_hotplug_work_func(struct work_struct *work);
|
||||
void amdgpu_display_update_priority(struct amdgpu_device *adev);
|
||||
uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
|
||||
uint64_t bo_flags);
|
||||
|
||||
@@ -328,7 +328,9 @@ amdgpu_dma_buf_create_obj(struct drm_device *dev, struct dma_buf *dma_buf)
|
||||
if (dma_buf->ops == &amdgpu_dmabuf_ops) {
|
||||
struct amdgpu_bo *other = gem_to_amdgpu_bo(dma_buf->priv);
|
||||
|
||||
flags |= other->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC;
|
||||
flags |= other->flags & (AMDGPU_GEM_CREATE_CPU_GTT_USWC |
|
||||
AMDGPU_GEM_CREATE_COHERENT |
|
||||
AMDGPU_GEM_CREATE_UNCACHED);
|
||||
}
|
||||
|
||||
ret = amdgpu_gem_object_create(adev, dma_buf->size, PAGE_SIZE,
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <drm/amdgpu_drm.h>
|
||||
#include <drm/drm_aperture.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_fbdev_generic.h>
|
||||
#include <drm/drm_gem.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/drm_managed.h>
|
||||
@@ -230,17 +231,18 @@ module_param_named(vis_vramlimit, amdgpu_vis_vram_limit, int, 0444);
|
||||
|
||||
/**
|
||||
* DOC: gartsize (uint)
|
||||
* Restrict the size of GART in Mib (32, 64, etc.) for testing. The default is -1 (The size depends on asic).
|
||||
* Restrict the size of GART (for kernel use) in Mib (32, 64, etc.) for testing.
|
||||
* The default is -1 (The size depends on asic).
|
||||
*/
|
||||
MODULE_PARM_DESC(gartsize, "Size of GART to setup in megabytes (32, 64, etc., -1=auto)");
|
||||
MODULE_PARM_DESC(gartsize, "Size of kernel GART to setup in megabytes (32, 64, etc., -1=auto)");
|
||||
module_param_named(gartsize, amdgpu_gart_size, uint, 0600);
|
||||
|
||||
/**
|
||||
* DOC: gttsize (int)
|
||||
* Restrict the size of GTT domain in MiB for testing. The default is -1 (It's VRAM size if 3GB < VRAM < 3/4 RAM,
|
||||
* otherwise 3/4 RAM size).
|
||||
* Restrict the size of GTT domain (for userspace use) in MiB for testing.
|
||||
* The default is -1 (Use 1/2 RAM, minimum value is 3GB).
|
||||
*/
|
||||
MODULE_PARM_DESC(gttsize, "Size of the GTT domain in megabytes (-1 = auto)");
|
||||
MODULE_PARM_DESC(gttsize, "Size of the GTT userspace domain in megabytes (-1 = auto)");
|
||||
module_param_named(gttsize, amdgpu_gtt_size, int, 0600);
|
||||
|
||||
/**
|
||||
@@ -533,7 +535,7 @@ module_param_named(compute_multipipe, amdgpu_compute_multipipe, int, 0444);
|
||||
* DOC: gpu_recovery (int)
|
||||
* Set to enable GPU recovery mechanism (1 = enable, 0 = disable). The default is -1 (auto, disabled except SRIOV).
|
||||
*/
|
||||
MODULE_PARM_DESC(gpu_recovery, "Enable GPU recovery mechanism, (2 = advanced tdr mode, 1 = enable, 0 = disable, -1 = auto)");
|
||||
MODULE_PARM_DESC(gpu_recovery, "Enable GPU recovery mechanism, (1 = enable, 0 = disable, -1 = auto)");
|
||||
module_param_named(gpu_recovery, amdgpu_gpu_recovery, int, 0444);
|
||||
|
||||
/**
|
||||
@@ -1924,9 +1926,6 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x73AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
{0x1002, 0x73BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID},
|
||||
|
||||
/* Van Gogh */
|
||||
{0x1002, 0x163F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VANGOGH|AMD_IS_APU},
|
||||
|
||||
/* Yellow Carp */
|
||||
{0x1002, 0x164D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_YELLOW_CARP|AMD_IS_APU},
|
||||
{0x1002, 0x1681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_YELLOW_CARP|AMD_IS_APU},
|
||||
@@ -2471,7 +2470,7 @@ static int amdgpu_runtime_idle_check_display(struct device *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (amdgpu_device_has_dc_support(adev)) {
|
||||
if (adev->dc_enabled) {
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
drm_for_each_crtc(crtc, drm_dev) {
|
||||
@@ -2572,6 +2571,8 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
|
||||
amdgpu_device_baco_enter(drm_dev);
|
||||
}
|
||||
|
||||
dev_dbg(&pdev->dev, "asic/device is runtime suspended\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,13 +79,15 @@
|
||||
* That is, for an I2C EEPROM driver everything is controlled by
|
||||
* the "eeprom_addr".
|
||||
*
|
||||
* See also top of amdgpu_ras_eeprom.c.
|
||||
*
|
||||
* P.S. If you need to write, lock and read the Identification Page,
|
||||
* (M24M02-DR device only, which we do not use), change the "7" to
|
||||
* "0xF" in the macro below, and let the client set bit 20 to 1 in
|
||||
* "eeprom_addr", and set A10 to 0 to write into it, and A10 and A1 to
|
||||
* 1 to lock it permanently.
|
||||
*/
|
||||
#define MAKE_I2C_ADDR(_aa) ((0xA << 3) | (((_aa) >> 16) & 7))
|
||||
#define MAKE_I2C_ADDR(_aa) ((0xA << 3) | (((_aa) >> 16) & 0xF))
|
||||
|
||||
static int __amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr,
|
||||
u8 *eeprom_buf, u16 buf_size, bool read)
|
||||
|
||||
@@ -55,6 +55,7 @@ struct amdgpu_fence {
|
||||
|
||||
/* RB, DMA, etc. */
|
||||
struct amdgpu_ring *ring;
|
||||
ktime_t start_timestamp;
|
||||
};
|
||||
|
||||
static struct kmem_cache *amdgpu_fence_slab;
|
||||
@@ -199,6 +200,8 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, struct amd
|
||||
}
|
||||
}
|
||||
|
||||
to_amdgpu_fence(fence)->start_timestamp = ktime_get();
|
||||
|
||||
/* This function can't be called concurrently anyway, otherwise
|
||||
* emitting the fence would mess up the hardware ring buffer.
|
||||
*/
|
||||
@@ -406,6 +409,57 @@ unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring)
|
||||
return lower_32_bits(emitted);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_last_unsignaled_time_us - the time fence emitted until now
|
||||
* @ring: ring the fence is associated with
|
||||
*
|
||||
* Find the earliest fence unsignaled until now, calculate the time delta
|
||||
* between the time fence emitted and now.
|
||||
*/
|
||||
u64 amdgpu_fence_last_unsignaled_time_us(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_fence_driver *drv = &ring->fence_drv;
|
||||
struct dma_fence *fence;
|
||||
uint32_t last_seq, sync_seq;
|
||||
|
||||
last_seq = atomic_read(&ring->fence_drv.last_seq);
|
||||
sync_seq = READ_ONCE(ring->fence_drv.sync_seq);
|
||||
if (last_seq == sync_seq)
|
||||
return 0;
|
||||
|
||||
++last_seq;
|
||||
last_seq &= drv->num_fences_mask;
|
||||
fence = drv->fences[last_seq];
|
||||
if (!fence)
|
||||
return 0;
|
||||
|
||||
return ktime_us_delta(ktime_get(),
|
||||
to_amdgpu_fence(fence)->start_timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_update_start_timestamp - update the timestamp of the fence
|
||||
* @ring: ring the fence is associated with
|
||||
* @seq: the fence seq number to update.
|
||||
* @timestamp: the start timestamp to update.
|
||||
*
|
||||
* The function called at the time the fence and related ib is about to
|
||||
* resubmit to gpu in MCBP scenario. Thus we do not consider race condition
|
||||
* with amdgpu_fence_process to modify the same fence.
|
||||
*/
|
||||
void amdgpu_fence_update_start_timestamp(struct amdgpu_ring *ring, uint32_t seq, ktime_t timestamp)
|
||||
{
|
||||
struct amdgpu_fence_driver *drv = &ring->fence_drv;
|
||||
struct dma_fence *fence;
|
||||
|
||||
seq &= drv->num_fences_mask;
|
||||
fence = drv->fences[seq];
|
||||
if (!fence)
|
||||
return;
|
||||
|
||||
to_amdgpu_fence(fence)->start_timestamp = timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_driver_start_ring - make the fence driver
|
||||
* ready for use on the requested ring.
|
||||
|
||||
@@ -29,9 +29,10 @@
|
||||
#include "amdgpu_fru_eeprom.h"
|
||||
#include "amdgpu_eeprom.h"
|
||||
|
||||
#define FRU_EEPROM_MADDR 0x60000
|
||||
#define FRU_EEPROM_MADDR_6 0x60000
|
||||
#define FRU_EEPROM_MADDR_8 0x80000
|
||||
|
||||
static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
|
||||
static bool is_fru_eeprom_supported(struct amdgpu_device *adev, u32 *fru_addr)
|
||||
{
|
||||
/* Only server cards have the FRU EEPROM
|
||||
* TODO: See if we can figure this out dynamically instead of
|
||||
@@ -45,6 +46,11 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return false;
|
||||
|
||||
/* The default I2C EEPROM address of the FRU.
|
||||
*/
|
||||
if (fru_addr)
|
||||
*fru_addr = FRU_EEPROM_MADDR_8;
|
||||
|
||||
/* VBIOS is of the format ###-DXXXYYYY-##. For SKU identification,
|
||||
* we can use just the "DXXX" portion. If there were more models, we
|
||||
* could convert the 3 characters to a hex integer and use a switch
|
||||
@@ -57,21 +63,29 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
|
||||
if (strnstr(atom_ctx->vbios_version, "D161",
|
||||
sizeof(atom_ctx->vbios_version)) ||
|
||||
strnstr(atom_ctx->vbios_version, "D163",
|
||||
sizeof(atom_ctx->vbios_version)))
|
||||
sizeof(atom_ctx->vbios_version))) {
|
||||
*fru_addr = FRU_EEPROM_MADDR_6;
|
||||
return true;
|
||||
else
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case CHIP_ALDEBARAN:
|
||||
/* All Aldebaran SKUs have the FRU */
|
||||
/* All Aldebaran SKUs have an FRU */
|
||||
if (!strnstr(atom_ctx->vbios_version, "D673",
|
||||
sizeof(atom_ctx->vbios_version)))
|
||||
if (fru_addr)
|
||||
*fru_addr = FRU_EEPROM_MADDR_6;
|
||||
return true;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
if (strnstr(atom_ctx->vbios_version, "D603",
|
||||
sizeof(atom_ctx->vbios_version))) {
|
||||
sizeof(atom_ctx->vbios_version))) {
|
||||
if (strnstr(atom_ctx->vbios_version, "D603GLXE",
|
||||
sizeof(atom_ctx->vbios_version)))
|
||||
sizeof(atom_ctx->vbios_version))) {
|
||||
return false;
|
||||
else
|
||||
} else {
|
||||
*fru_addr = FRU_EEPROM_MADDR_6;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -80,41 +94,14 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr,
|
||||
unsigned char *buf, size_t buf_size)
|
||||
{
|
||||
int ret;
|
||||
u8 size;
|
||||
|
||||
ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr, buf, 1);
|
||||
if (ret < 1) {
|
||||
DRM_WARN("FRU: Failed to get size field");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The size returned by the i2c requires subtraction of 0xC0 since the
|
||||
* size apparently always reports as 0xC0+actual size.
|
||||
*/
|
||||
size = buf[0] & 0x3F;
|
||||
size = min_t(size_t, size, buf_size);
|
||||
|
||||
ret = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addrptr + 1,
|
||||
buf, size);
|
||||
if (ret < 1) {
|
||||
DRM_WARN("FRU: Failed to get data field");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned char buf[AMDGPU_PRODUCT_NAME_LEN];
|
||||
u32 addrptr;
|
||||
unsigned char buf[8], *pia;
|
||||
u32 addr, fru_addr;
|
||||
int size, len;
|
||||
u8 csum;
|
||||
|
||||
if (!is_fru_eeprom_supported(adev))
|
||||
if (!is_fru_eeprom_supported(adev, &fru_addr))
|
||||
return 0;
|
||||
|
||||
/* If algo exists, it means that the i2c_adapter's initialized */
|
||||
@@ -123,88 +110,102 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* There's a lot of repetition here. This is due to the FRU having
|
||||
* variable-length fields. To get the information, we have to find the
|
||||
* size of each field, and then keep reading along and reading along
|
||||
* until we get all of the data that we want. We use addrptr to track
|
||||
* the address as we go
|
||||
/* Read the IPMI Common header */
|
||||
len = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, fru_addr, buf,
|
||||
sizeof(buf));
|
||||
if (len != 8) {
|
||||
DRM_ERROR("Couldn't read the IPMI Common Header: %d", len);
|
||||
return len < 0 ? len : -EIO;
|
||||
}
|
||||
|
||||
if (buf[0] != 1) {
|
||||
DRM_ERROR("Bad IPMI Common Header version: 0x%02x", buf[0]);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
for (csum = 0; len > 0; len--)
|
||||
csum += buf[len - 1];
|
||||
if (csum) {
|
||||
DRM_ERROR("Bad IPMI Common Header checksum: 0x%02x", csum);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Get the offset to the Product Info Area (PIA). */
|
||||
addr = buf[4] * 8;
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
/* Get the absolute address to the PIA. */
|
||||
addr += fru_addr;
|
||||
|
||||
/* Read the header of the PIA. */
|
||||
len = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addr, buf, 3);
|
||||
if (len != 3) {
|
||||
DRM_ERROR("Couldn't read the Product Info Area header: %d", len);
|
||||
return len < 0 ? len : -EIO;
|
||||
}
|
||||
|
||||
if (buf[0] != 1) {
|
||||
DRM_ERROR("Bad IPMI Product Info Area version: 0x%02x", buf[0]);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
size = buf[1] * 8;
|
||||
pia = kzalloc(size, GFP_KERNEL);
|
||||
if (!pia)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Read the whole PIA. */
|
||||
len = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addr, pia, size);
|
||||
if (len != size) {
|
||||
kfree(pia);
|
||||
DRM_ERROR("Couldn't read the Product Info Area: %d", len);
|
||||
return len < 0 ? len : -EIO;
|
||||
}
|
||||
|
||||
for (csum = 0; size > 0; size--)
|
||||
csum += pia[size - 1];
|
||||
if (csum) {
|
||||
DRM_ERROR("Bad Product Info Area checksum: 0x%02x", csum);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Now extract useful information from the PIA.
|
||||
*
|
||||
* Skip the Manufacturer Name at [3] and go directly to
|
||||
* the Product Name field.
|
||||
*/
|
||||
addr = 3 + 1 + (pia[3] & 0x3F);
|
||||
if (addr + 1 >= len)
|
||||
goto Out;
|
||||
memcpy(adev->product_name, pia + addr + 1,
|
||||
min_t(size_t,
|
||||
sizeof(adev->product_name),
|
||||
pia[addr] & 0x3F));
|
||||
adev->product_name[sizeof(adev->product_name) - 1] = '\0';
|
||||
|
||||
/* The first fields are all of size 1-byte, from 0-7 are offsets that
|
||||
* contain information that isn't useful to us.
|
||||
* Bytes 8-a are all 1-byte and refer to the size of the entire struct,
|
||||
* and the language field, so just start from 0xb, manufacturer size
|
||||
*/
|
||||
addrptr = FRU_EEPROM_MADDR + 0xb;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Go to the Product Part/Model Number field. */
|
||||
addr += 1 + (pia[addr] & 0x3F);
|
||||
if (addr + 1 >= len)
|
||||
goto Out;
|
||||
memcpy(adev->product_number, pia + addr + 1,
|
||||
min_t(size_t,
|
||||
sizeof(adev->product_number),
|
||||
pia[addr] & 0x3F));
|
||||
adev->product_number[sizeof(adev->product_number) - 1] = '\0';
|
||||
|
||||
/* Increment the addrptr by the size of the field, and 1 due to the
|
||||
* size field being 1 byte. This pattern continues below.
|
||||
*/
|
||||
addrptr += size + 1;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU product name, ret:%d", size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
len = size;
|
||||
if (len >= AMDGPU_PRODUCT_NAME_LEN) {
|
||||
DRM_WARN("FRU Product Name is larger than %d characters. This is likely a mistake",
|
||||
AMDGPU_PRODUCT_NAME_LEN);
|
||||
len = AMDGPU_PRODUCT_NAME_LEN - 1;
|
||||
}
|
||||
memcpy(adev->product_name, buf, len);
|
||||
adev->product_name[len] = '\0';
|
||||
|
||||
addrptr += size + 1;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU product number, ret:%d", size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
len = size;
|
||||
/* Product number should only be 16 characters. Any more,
|
||||
* and something could be wrong. Cap it at 16 to be safe
|
||||
*/
|
||||
if (len >= sizeof(adev->product_number)) {
|
||||
DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake");
|
||||
len = sizeof(adev->product_number) - 1;
|
||||
}
|
||||
memcpy(adev->product_number, buf, len);
|
||||
adev->product_number[len] = '\0';
|
||||
|
||||
addrptr += size + 1;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
|
||||
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU product version, ret:%d", size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
addrptr += size + 1;
|
||||
size = amdgpu_fru_read_eeprom(adev, addrptr, buf, sizeof(buf));
|
||||
|
||||
if (size < 1) {
|
||||
DRM_ERROR("Failed to read FRU serial number, ret:%d", size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
len = size;
|
||||
/* Serial number should only be 16 characters. Any more,
|
||||
* and something could be wrong. Cap it at 16 to be safe
|
||||
*/
|
||||
if (len >= sizeof(adev->serial)) {
|
||||
DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake");
|
||||
len = sizeof(adev->serial) - 1;
|
||||
}
|
||||
memcpy(adev->serial, buf, len);
|
||||
adev->serial[len] = '\0';
|
||||
/* Go to the Product Version field. */
|
||||
addr += 1 + (pia[addr] & 0x3F);
|
||||
|
||||
/* Go to the Product Serial Number field. */
|
||||
addr += 1 + (pia[addr] & 0x3F);
|
||||
if (addr + 1 >= len)
|
||||
goto Out;
|
||||
memcpy(adev->serial, pia + addr + 1, min_t(size_t,
|
||||
sizeof(adev->serial),
|
||||
pia[addr] & 0x3F));
|
||||
adev->serial[sizeof(adev->serial) - 1] = '\0';
|
||||
Out:
|
||||
kfree(pia);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_display.h"
|
||||
#include "amdgpu_dma_buf.h"
|
||||
#include "amdgpu_hmm.h"
|
||||
#include "amdgpu_xgmi.h"
|
||||
|
||||
static const struct drm_gem_object_funcs amdgpu_gem_object_funcs;
|
||||
@@ -87,7 +88,7 @@ static void amdgpu_gem_object_free(struct drm_gem_object *gobj)
|
||||
struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
|
||||
|
||||
if (robj) {
|
||||
amdgpu_mn_unregister(robj);
|
||||
amdgpu_hmm_unregister(robj);
|
||||
amdgpu_bo_unref(&robj);
|
||||
}
|
||||
}
|
||||
@@ -112,7 +113,7 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
|
||||
bp.resv = resv;
|
||||
bp.preferred_domain = initial_domain;
|
||||
bp.flags = flags;
|
||||
bp.domain = initial_domain;
|
||||
bp.domain = initial_domain | AMDGPU_GEM_DOMAIN_CPU;
|
||||
bp.bo_ptr_size = sizeof(struct amdgpu_bo);
|
||||
|
||||
r = amdgpu_bo_create_user(adev, &bp, &ubo);
|
||||
@@ -331,20 +332,10 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
|
||||
}
|
||||
|
||||
initial_domain = (u32)(0xffffffff & args->in.domains);
|
||||
retry:
|
||||
r = amdgpu_gem_object_create(adev, size, args->in.alignment,
|
||||
initial_domain,
|
||||
flags, ttm_bo_type_device, resv, &gobj);
|
||||
initial_domain, flags, ttm_bo_type_device,
|
||||
resv, &gobj);
|
||||
if (r && r != -ERESTARTSYS) {
|
||||
if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {
|
||||
flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
|
||||
initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
|
||||
goto retry;
|
||||
}
|
||||
DRM_DEBUG("Failed to allocate GEM object (%llu, %d, %llu, %d)\n",
|
||||
size, initial_domain, args->in.alignment, r);
|
||||
}
|
||||
@@ -414,7 +405,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
|
||||
if (r)
|
||||
goto release_object;
|
||||
|
||||
r = amdgpu_mn_register(bo, args->addr);
|
||||
r = amdgpu_hmm_register(bo, args->addr);
|
||||
if (r)
|
||||
goto release_object;
|
||||
|
||||
|
||||
@@ -583,10 +583,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
||||
if (adev->gfx.gfx_off_req_count == 0 &&
|
||||
!adev->gfx.gfx_off_state) {
|
||||
/* If going to s2idle, no need to wait */
|
||||
if (adev->in_s0ix)
|
||||
delay = GFX_OFF_NO_DELAY;
|
||||
schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
|
||||
if (adev->in_s0ix) {
|
||||
if (!amdgpu_dpm_set_powergating_by_smu(adev,
|
||||
AMD_IP_BLOCK_TYPE_GFX, true))
|
||||
adev->gfx.gfx_off_state = true;
|
||||
} else {
|
||||
schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
|
||||
delay);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (adev->gfx.gfx_off_req_count == 0) {
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "amdgpu_imu.h"
|
||||
#include "soc15.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_ring_mux.h"
|
||||
|
||||
/* GFX current status */
|
||||
#define AMDGPU_GFX_NORMAL_MODE 0x00000000L
|
||||
@@ -352,6 +353,9 @@ struct amdgpu_gfx {
|
||||
struct amdgpu_gfx_ras *ras;
|
||||
|
||||
bool is_poweron;
|
||||
|
||||
struct amdgpu_ring sw_gfx_ring[AMDGPU_MAX_SW_GFX_RINGS];
|
||||
struct amdgpu_ring_mux muxer;
|
||||
};
|
||||
|
||||
#define amdgpu_gfx_get_gpu_clock_counter(adev) (adev)->gfx.funcs->get_gpu_clock_counter((adev))
|
||||
|
||||
@@ -548,6 +548,8 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
|
||||
case IP_VERSION(10, 3, 1):
|
||||
/* YELLOW_CARP*/
|
||||
case IP_VERSION(10, 3, 3):
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
/* Don't enable it by default yet.
|
||||
*/
|
||||
if (amdgpu_tmz < 1) {
|
||||
|
||||
@@ -144,7 +144,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
|
||||
node->base.start = node->mm_nodes[0].start;
|
||||
} else {
|
||||
node->mm_nodes[0].start = 0;
|
||||
node->mm_nodes[0].size = node->base.num_pages;
|
||||
node->mm_nodes[0].size = PFN_UP(node->base.size);
|
||||
node->base.start = AMDGPU_BO_INVALID_OFFSET;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,9 +49,12 @@
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "amdgpu_hmm.h"
|
||||
|
||||
#define MAX_WALK_BYTE (2UL << 30)
|
||||
|
||||
/**
|
||||
* amdgpu_mn_invalidate_gfx - callback to notify about mm change
|
||||
* amdgpu_hmm_invalidate_gfx - callback to notify about mm change
|
||||
*
|
||||
* @mni: the range (mm) is about to update
|
||||
* @range: details on the invalidation
|
||||
@@ -60,9 +63,9 @@
|
||||
* Block for operations on BOs to finish and mark pages as accessed and
|
||||
* potentially dirty.
|
||||
*/
|
||||
static bool amdgpu_mn_invalidate_gfx(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
static bool amdgpu_hmm_invalidate_gfx(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
{
|
||||
struct amdgpu_bo *bo = container_of(mni, struct amdgpu_bo, notifier);
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
@@ -83,12 +86,12 @@ static bool amdgpu_mn_invalidate_gfx(struct mmu_interval_notifier *mni,
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct mmu_interval_notifier_ops amdgpu_mn_gfx_ops = {
|
||||
.invalidate = amdgpu_mn_invalidate_gfx,
|
||||
static const struct mmu_interval_notifier_ops amdgpu_hmm_gfx_ops = {
|
||||
.invalidate = amdgpu_hmm_invalidate_gfx,
|
||||
};
|
||||
|
||||
/**
|
||||
* amdgpu_mn_invalidate_hsa - callback to notify about mm change
|
||||
* amdgpu_hmm_invalidate_hsa - callback to notify about mm change
|
||||
*
|
||||
* @mni: the range (mm) is about to update
|
||||
* @range: details on the invalidation
|
||||
@@ -97,9 +100,9 @@ static const struct mmu_interval_notifier_ops amdgpu_mn_gfx_ops = {
|
||||
* We temporarily evict the BO attached to this range. This necessitates
|
||||
* evicting all user-mode queues of the process.
|
||||
*/
|
||||
static bool amdgpu_mn_invalidate_hsa(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
static bool amdgpu_hmm_invalidate_hsa(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
{
|
||||
struct amdgpu_bo *bo = container_of(mni, struct amdgpu_bo, notifier);
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
@@ -117,12 +120,12 @@ static bool amdgpu_mn_invalidate_hsa(struct mmu_interval_notifier *mni,
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct mmu_interval_notifier_ops amdgpu_mn_hsa_ops = {
|
||||
.invalidate = amdgpu_mn_invalidate_hsa,
|
||||
static const struct mmu_interval_notifier_ops amdgpu_hmm_hsa_ops = {
|
||||
.invalidate = amdgpu_hmm_invalidate_hsa,
|
||||
};
|
||||
|
||||
/**
|
||||
* amdgpu_mn_register - register a BO for notifier updates
|
||||
* amdgpu_hmm_register - register a BO for notifier updates
|
||||
*
|
||||
* @bo: amdgpu buffer object
|
||||
* @addr: userptr addr we should monitor
|
||||
@@ -130,25 +133,25 @@ static const struct mmu_interval_notifier_ops amdgpu_mn_hsa_ops = {
|
||||
* Registers a mmu_notifier for the given BO at the specified address.
|
||||
* Returns 0 on success, -ERRNO if anything goes wrong.
|
||||
*/
|
||||
int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
|
||||
int amdgpu_hmm_register(struct amdgpu_bo *bo, unsigned long addr)
|
||||
{
|
||||
if (bo->kfd_bo)
|
||||
return mmu_interval_notifier_insert(&bo->notifier, current->mm,
|
||||
addr, amdgpu_bo_size(bo),
|
||||
&amdgpu_mn_hsa_ops);
|
||||
&amdgpu_hmm_hsa_ops);
|
||||
return mmu_interval_notifier_insert(&bo->notifier, current->mm, addr,
|
||||
amdgpu_bo_size(bo),
|
||||
&amdgpu_mn_gfx_ops);
|
||||
&amdgpu_hmm_gfx_ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_mn_unregister - unregister a BO for notifier updates
|
||||
* amdgpu_hmm_unregister - unregister a BO for notifier updates
|
||||
*
|
||||
* @bo: amdgpu buffer object
|
||||
*
|
||||
* Remove any registration of mmu notifier updates from the buffer object.
|
||||
*/
|
||||
void amdgpu_mn_unregister(struct amdgpu_bo *bo)
|
||||
void amdgpu_hmm_unregister(struct amdgpu_bo *bo)
|
||||
{
|
||||
if (!bo->notifier.mm)
|
||||
return;
|
||||
@@ -157,12 +160,12 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo)
|
||||
}
|
||||
|
||||
int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
|
||||
struct mm_struct *mm, struct page **pages,
|
||||
uint64_t start, uint64_t npages,
|
||||
struct hmm_range **phmm_range, bool readonly,
|
||||
bool mmap_locked, void *owner)
|
||||
uint64_t start, uint64_t npages, bool readonly,
|
||||
void *owner, struct page **pages,
|
||||
struct hmm_range **phmm_range)
|
||||
{
|
||||
struct hmm_range *hmm_range;
|
||||
unsigned long end;
|
||||
unsigned long timeout;
|
||||
unsigned long i;
|
||||
unsigned long *pfns;
|
||||
@@ -184,32 +187,42 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
|
||||
hmm_range->default_flags |= HMM_PFN_REQ_WRITE;
|
||||
hmm_range->hmm_pfns = pfns;
|
||||
hmm_range->start = start;
|
||||
hmm_range->end = start + npages * PAGE_SIZE;
|
||||
end = start + npages * PAGE_SIZE;
|
||||
hmm_range->dev_private_owner = owner;
|
||||
|
||||
/* Assuming 512MB takes maxmium 1 second to fault page address */
|
||||
timeout = max(npages >> 17, 1ULL) * HMM_RANGE_DEFAULT_TIMEOUT;
|
||||
timeout = jiffies + msecs_to_jiffies(timeout);
|
||||
do {
|
||||
hmm_range->end = min(hmm_range->start + MAX_WALK_BYTE, end);
|
||||
|
||||
pr_debug("hmm range: start = 0x%lx, end = 0x%lx",
|
||||
hmm_range->start, hmm_range->end);
|
||||
|
||||
/* Assuming 512MB takes maxmium 1 second to fault page address */
|
||||
timeout = max((hmm_range->end - hmm_range->start) >> 29, 1UL);
|
||||
timeout *= HMM_RANGE_DEFAULT_TIMEOUT;
|
||||
timeout = jiffies + msecs_to_jiffies(timeout);
|
||||
|
||||
retry:
|
||||
hmm_range->notifier_seq = mmu_interval_read_begin(notifier);
|
||||
hmm_range->notifier_seq = mmu_interval_read_begin(notifier);
|
||||
r = hmm_range_fault(hmm_range);
|
||||
if (unlikely(r)) {
|
||||
/*
|
||||
* FIXME: This timeout should encompass the retry from
|
||||
* mmu_interval_read_retry() as well.
|
||||
*/
|
||||
if (r == -EBUSY && !time_after(jiffies, timeout))
|
||||
goto retry;
|
||||
goto out_free_pfns;
|
||||
}
|
||||
|
||||
if (likely(!mmap_locked))
|
||||
mmap_read_lock(mm);
|
||||
if (hmm_range->end == end)
|
||||
break;
|
||||
hmm_range->hmm_pfns += MAX_WALK_BYTE >> PAGE_SHIFT;
|
||||
hmm_range->start = hmm_range->end;
|
||||
schedule();
|
||||
} while (hmm_range->end < end);
|
||||
|
||||
r = hmm_range_fault(hmm_range);
|
||||
|
||||
if (likely(!mmap_locked))
|
||||
mmap_read_unlock(mm);
|
||||
if (unlikely(r)) {
|
||||
/*
|
||||
* FIXME: This timeout should encompass the retry from
|
||||
* mmu_interval_read_retry() as well.
|
||||
*/
|
||||
if (r == -EBUSY && !time_after(jiffies, timeout))
|
||||
goto retry;
|
||||
goto out_free_pfns;
|
||||
}
|
||||
hmm_range->start = start;
|
||||
hmm_range->hmm_pfns = pfns;
|
||||
|
||||
/*
|
||||
* Due to default_flags, all pages are HMM_PFN_VALID or
|
||||
@@ -31,23 +31,22 @@
|
||||
#include <linux/interval_tree.h>
|
||||
|
||||
int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
|
||||
struct mm_struct *mm, struct page **pages,
|
||||
uint64_t start, uint64_t npages,
|
||||
struct hmm_range **phmm_range, bool readonly,
|
||||
bool mmap_locked, void *owner);
|
||||
uint64_t start, uint64_t npages, bool readonly,
|
||||
void *owner, struct page **pages,
|
||||
struct hmm_range **phmm_range);
|
||||
int amdgpu_hmm_range_get_pages_done(struct hmm_range *hmm_range);
|
||||
|
||||
#if defined(CONFIG_HMM_MIRROR)
|
||||
int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr);
|
||||
void amdgpu_mn_unregister(struct amdgpu_bo *bo);
|
||||
int amdgpu_hmm_register(struct amdgpu_bo *bo, unsigned long addr);
|
||||
void amdgpu_hmm_unregister(struct amdgpu_bo *bo);
|
||||
#else
|
||||
static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
|
||||
static inline int amdgpu_hmm_register(struct amdgpu_bo *bo, unsigned long addr)
|
||||
{
|
||||
DRM_WARN_ONCE("HMM_MIRROR kernel config option is not enabled, "
|
||||
"add CONFIG_ZONE_DEVICE=y in config file to fix this\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void amdgpu_mn_unregister(struct amdgpu_bo *bo) {}
|
||||
static inline void amdgpu_hmm_unregister(struct amdgpu_bo *bo) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -182,7 +182,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
||||
|
||||
need_ctx_switch = ring->current_ctx != fence_ctx;
|
||||
if (ring->funcs->emit_pipeline_sync && job &&
|
||||
((tmp = amdgpu_sync_get_fence(&job->sched_sync)) ||
|
||||
((tmp = amdgpu_sync_get_fence(&job->explicit_sync)) ||
|
||||
(amdgpu_sriov_vf(adev) && need_ctx_switch) ||
|
||||
amdgpu_vm_need_pipeline_sync(ring, job))) {
|
||||
need_pipe_sync = true;
|
||||
@@ -211,6 +211,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_ring_ib_begin(ring);
|
||||
if (job && ring->funcs->init_cond_exec)
|
||||
patch_offset = amdgpu_ring_init_cond_exec(ring);
|
||||
|
||||
@@ -285,6 +286,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
||||
ring->hw_prio == AMDGPU_GFX_PIPE_PRIO_HIGH)
|
||||
ring->funcs->emit_wave_limit(ring, false);
|
||||
|
||||
amdgpu_ring_ib_end(ring);
|
||||
amdgpu_ring_commit(ring);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -170,26 +170,27 @@ bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
|
||||
*
|
||||
* @vm: vm to allocate id for
|
||||
* @ring: ring we want to submit job to
|
||||
* @sync: sync object where we add dependencies
|
||||
* @idle: resulting idle VMID
|
||||
* @fence: fence to wait for if no id could be grabbed
|
||||
*
|
||||
* Try to find an idle VMID, if none is idle add a fence to wait to the sync
|
||||
* object. Returns -ENOMEM when we are out of memory.
|
||||
*/
|
||||
static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
|
||||
struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync,
|
||||
struct amdgpu_vmid **idle)
|
||||
struct amdgpu_vmid **idle,
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct dma_fence **fences;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
if (!dma_fence_is_signaled(ring->vmid_wait))
|
||||
return amdgpu_sync_fence(sync, ring->vmid_wait);
|
||||
if (!dma_fence_is_signaled(ring->vmid_wait)) {
|
||||
*fence = dma_fence_get(ring->vmid_wait);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fences = kmalloc_array(id_mgr->num_ids, sizeof(void *), GFP_KERNEL);
|
||||
if (!fences)
|
||||
@@ -228,10 +229,10 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
r = amdgpu_sync_fence(sync, &array->base);
|
||||
*fence = dma_fence_get(&array->base);
|
||||
dma_fence_put(ring->vmid_wait);
|
||||
ring->vmid_wait = &array->base;
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
kfree(fences);
|
||||
|
||||
@@ -243,19 +244,17 @@ static int amdgpu_vmid_grab_idle(struct amdgpu_vm *vm,
|
||||
*
|
||||
* @vm: vm to allocate id for
|
||||
* @ring: ring we want to submit job to
|
||||
* @sync: sync object where we add dependencies
|
||||
* @fence: fence protecting ID from reuse
|
||||
* @job: job who wants to use the VMID
|
||||
* @id: resulting VMID
|
||||
* @fence: fence to wait for if no id could be grabbed
|
||||
*
|
||||
* Try to assign a reserved VMID.
|
||||
*/
|
||||
static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
|
||||
struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync,
|
||||
struct dma_fence *fence,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_vmid **id)
|
||||
struct amdgpu_vmid **id,
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
@@ -282,7 +281,8 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
|
||||
tmp = amdgpu_sync_peek_fence(&(*id)->active, ring);
|
||||
if (tmp) {
|
||||
*id = NULL;
|
||||
return amdgpu_sync_fence(sync, tmp);
|
||||
*fence = dma_fence_get(tmp);
|
||||
return 0;
|
||||
}
|
||||
needs_flush = true;
|
||||
}
|
||||
@@ -290,7 +290,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
|
||||
/* Good we can use this VMID. Remember this submission as
|
||||
* user of the VMID.
|
||||
*/
|
||||
r = amdgpu_sync_fence(&(*id)->active, fence);
|
||||
r = amdgpu_sync_fence(&(*id)->active, &job->base.s_fence->finished);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -304,19 +304,17 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
|
||||
*
|
||||
* @vm: vm to allocate id for
|
||||
* @ring: ring we want to submit job to
|
||||
* @sync: sync object where we add dependencies
|
||||
* @fence: fence protecting ID from reuse
|
||||
* @job: job who wants to use the VMID
|
||||
* @id: resulting VMID
|
||||
* @fence: fence to wait for if no id could be grabbed
|
||||
*
|
||||
* Try to reuse a VMID for this submission.
|
||||
*/
|
||||
static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
|
||||
struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync,
|
||||
struct dma_fence *fence,
|
||||
struct amdgpu_job *job,
|
||||
struct amdgpu_vmid **id)
|
||||
struct amdgpu_vmid **id,
|
||||
struct dma_fence **fence)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
@@ -352,7 +350,8 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
|
||||
/* Good, we can use this VMID. Remember this submission as
|
||||
* user of the VMID.
|
||||
*/
|
||||
r = amdgpu_sync_fence(&(*id)->active, fence);
|
||||
r = amdgpu_sync_fence(&(*id)->active,
|
||||
&job->base.s_fence->finished);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -370,15 +369,13 @@ static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
|
||||
*
|
||||
* @vm: vm to allocate id for
|
||||
* @ring: ring we want to submit job to
|
||||
* @sync: sync object where we add dependencies
|
||||
* @fence: fence protecting ID from reuse
|
||||
* @job: job who wants to use the VMID
|
||||
* @fence: fence to wait for if no id could be grabbed
|
||||
*
|
||||
* Allocate an id for the vm, adding fences to the sync obj as necessary.
|
||||
*/
|
||||
int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync, struct dma_fence *fence,
|
||||
struct amdgpu_job *job)
|
||||
struct amdgpu_job *job, struct dma_fence **fence)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
@@ -388,16 +385,16 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
int r = 0;
|
||||
|
||||
mutex_lock(&id_mgr->lock);
|
||||
r = amdgpu_vmid_grab_idle(vm, ring, sync, &idle);
|
||||
r = amdgpu_vmid_grab_idle(vm, ring, &idle, fence);
|
||||
if (r || !idle)
|
||||
goto error;
|
||||
|
||||
if (vm->reserved_vmid[vmhub]) {
|
||||
r = amdgpu_vmid_grab_reserved(vm, ring, sync, fence, job, &id);
|
||||
r = amdgpu_vmid_grab_reserved(vm, ring, job, &id, fence);
|
||||
if (r || !id)
|
||||
goto error;
|
||||
} else {
|
||||
r = amdgpu_vmid_grab_used(vm, ring, sync, fence, job, &id);
|
||||
r = amdgpu_vmid_grab_used(vm, ring, job, &id, fence);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
@@ -406,7 +403,8 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
id = idle;
|
||||
|
||||
/* Remember this submission as user of the VMID */
|
||||
r = amdgpu_sync_fence(&id->active, fence);
|
||||
r = amdgpu_sync_fence(&id->active,
|
||||
&job->base.s_fence->finished);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@ void amdgpu_vmid_free_reserved(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
unsigned vmhub);
|
||||
int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync, struct dma_fence *fence,
|
||||
struct amdgpu_job *job);
|
||||
struct amdgpu_job *job, struct dma_fence **fence);
|
||||
void amdgpu_vmid_reset(struct amdgpu_device *adev, unsigned vmhub,
|
||||
unsigned vmid);
|
||||
void amdgpu_vmid_reset_all(struct amdgpu_device *adev);
|
||||
|
||||
@@ -100,41 +100,6 @@ const char *soc15_ih_clientid_name[] = {
|
||||
"MP1"
|
||||
};
|
||||
|
||||
/**
|
||||
* amdgpu_hotplug_work_func - work handler for display hotplug event
|
||||
*
|
||||
* @work: work struct pointer
|
||||
*
|
||||
* This is the hotplug event work handler (all ASICs).
|
||||
* The work gets scheduled from the IRQ handler if there
|
||||
* was a hotplug interrupt. It walks through the connector table
|
||||
* and calls hotplug handler for each connector. After this, it sends
|
||||
* a DRM hotplug event to alert userspace.
|
||||
*
|
||||
* This design approach is required in order to defer hotplug event handling
|
||||
* from the IRQ handler to a work handler because hotplug handler has to use
|
||||
* mutexes which cannot be locked in an IRQ handler (since &mutex_lock may
|
||||
* sleep).
|
||||
*/
|
||||
static void amdgpu_hotplug_work_func(struct work_struct *work)
|
||||
{
|
||||
struct amdgpu_device *adev = container_of(work, struct amdgpu_device,
|
||||
hotplug_work);
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
|
||||
mutex_lock(&mode_config->mutex);
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter)
|
||||
amdgpu_connector_hotplug(connector);
|
||||
drm_connector_list_iter_end(&iter);
|
||||
mutex_unlock(&mode_config->mutex);
|
||||
/* Just fire off a uevent and let userspace tell us what to do */
|
||||
drm_helper_hpd_irq_event(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_irq_disable_all - disable *all* interrupts
|
||||
*
|
||||
@@ -317,21 +282,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
if (!amdgpu_device_has_dc_support(adev)) {
|
||||
if (!adev->enable_virtual_display)
|
||||
/* Disable vblank IRQs aggressively for power-saving */
|
||||
/* XXX: can this be enabled for DC? */
|
||||
adev_to_drm(adev)->vblank_disable_immediate = true;
|
||||
|
||||
r = drm_vblank_init(adev_to_drm(adev), adev->mode_info.num_crtc);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Pre-DCE11 */
|
||||
INIT_WORK(&adev->hotplug_work,
|
||||
amdgpu_hotplug_work_func);
|
||||
}
|
||||
|
||||
INIT_WORK(&adev->irq.ih1_work, amdgpu_irq_handle_ih1);
|
||||
INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2);
|
||||
INIT_WORK(&adev->irq.ih_soft_work, amdgpu_irq_handle_ih_soft);
|
||||
@@ -345,11 +295,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
|
||||
/* PCI devices require shared interrupts. */
|
||||
r = request_irq(irq, amdgpu_irq_handler, IRQF_SHARED, adev_to_drm(adev)->driver->name,
|
||||
adev_to_drm(adev));
|
||||
if (r) {
|
||||
if (!amdgpu_device_has_dc_support(adev))
|
||||
flush_work(&adev->hotplug_work);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
adev->irq.installed = true;
|
||||
adev->irq.irq = irq;
|
||||
adev_to_drm(adev)->max_vblank_count = 0x00ffffff;
|
||||
@@ -366,9 +313,6 @@ void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
|
||||
adev->irq.installed = false;
|
||||
if (adev->irq.msi_enabled)
|
||||
pci_free_irq_vectors(adev->pdev);
|
||||
|
||||
if (!amdgpu_device_has_dc_support(adev))
|
||||
flush_work(&adev->hotplug_work);
|
||||
}
|
||||
|
||||
amdgpu_ih_ring_fini(adev, &adev->irq.ih_soft);
|
||||
|
||||
@@ -88,8 +88,9 @@ exit:
|
||||
return DRM_GPU_SCHED_STAT_NOMINAL;
|
||||
}
|
||||
|
||||
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
struct amdgpu_job **job, struct amdgpu_vm *vm)
|
||||
int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct drm_sched_entity *entity, void *owner,
|
||||
unsigned int num_ibs, struct amdgpu_job **job)
|
||||
{
|
||||
if (num_ibs == 0)
|
||||
return -EINVAL;
|
||||
@@ -105,28 +106,34 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
(*job)->base.sched = &adev->rings[0]->sched;
|
||||
(*job)->vm = vm;
|
||||
|
||||
amdgpu_sync_create(&(*job)->sync);
|
||||
amdgpu_sync_create(&(*job)->sched_sync);
|
||||
amdgpu_sync_create(&(*job)->explicit_sync);
|
||||
(*job)->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
|
||||
(*job)->vm_pd_addr = AMDGPU_BO_INVALID_OFFSET;
|
||||
|
||||
return 0;
|
||||
if (!entity)
|
||||
return 0;
|
||||
|
||||
return drm_sched_job_init(&(*job)->base, entity, owner);
|
||||
}
|
||||
|
||||
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
|
||||
enum amdgpu_ib_pool_type pool_type,
|
||||
struct amdgpu_job **job)
|
||||
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
|
||||
struct drm_sched_entity *entity, void *owner,
|
||||
size_t size, enum amdgpu_ib_pool_type pool_type,
|
||||
struct amdgpu_job **job)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = amdgpu_job_alloc(adev, 1, job, NULL);
|
||||
r = amdgpu_job_alloc(adev, NULL, entity, owner, 1, job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
(*job)->num_ibs = 1;
|
||||
r = amdgpu_ib_get(adev, NULL, size, pool_type, &(*job)->ibs[0]);
|
||||
if (r)
|
||||
if (r) {
|
||||
if (entity)
|
||||
drm_sched_job_cleanup(&(*job)->base);
|
||||
kfree(*job);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -166,8 +173,7 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
|
||||
|
||||
drm_sched_job_cleanup(s_job);
|
||||
|
||||
amdgpu_sync_free(&job->sync);
|
||||
amdgpu_sync_free(&job->sched_sync);
|
||||
amdgpu_sync_free(&job->explicit_sync);
|
||||
|
||||
/* only put the hw fence if has embedded fence */
|
||||
if (!job->hw_fence.ops)
|
||||
@@ -194,9 +200,11 @@ void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
|
||||
|
||||
void amdgpu_job_free(struct amdgpu_job *job)
|
||||
{
|
||||
if (job->base.entity)
|
||||
drm_sched_job_cleanup(&job->base);
|
||||
|
||||
amdgpu_job_free_resources(job);
|
||||
amdgpu_sync_free(&job->sync);
|
||||
amdgpu_sync_free(&job->sched_sync);
|
||||
amdgpu_sync_free(&job->explicit_sync);
|
||||
if (job->gang_submit != &job->base.s_fence->scheduled)
|
||||
dma_fence_put(job->gang_submit);
|
||||
|
||||
@@ -206,25 +214,16 @@ void amdgpu_job_free(struct amdgpu_job *job)
|
||||
dma_fence_put(&job->hw_fence);
|
||||
}
|
||||
|
||||
int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
|
||||
void *owner, struct dma_fence **f)
|
||||
struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!f)
|
||||
return -EINVAL;
|
||||
|
||||
r = drm_sched_job_init(&job->base, entity, owner);
|
||||
if (r)
|
||||
return r;
|
||||
struct dma_fence *f;
|
||||
|
||||
drm_sched_job_arm(&job->base);
|
||||
|
||||
*f = dma_fence_get(&job->base.s_fence->finished);
|
||||
f = dma_fence_get(&job->base.s_fence->finished);
|
||||
amdgpu_job_free_resources(job);
|
||||
drm_sched_entity_push_job(&job->base);
|
||||
|
||||
return 0;
|
||||
return f;
|
||||
}
|
||||
|
||||
int amdgpu_job_submit_direct(struct amdgpu_job *job, struct amdgpu_ring *ring,
|
||||
@@ -242,33 +241,22 @@ int amdgpu_job_submit_direct(struct amdgpu_job *job, struct amdgpu_ring *ring,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job,
|
||||
struct drm_sched_entity *s_entity)
|
||||
static struct dma_fence *
|
||||
amdgpu_job_prepare_job(struct drm_sched_job *sched_job,
|
||||
struct drm_sched_entity *s_entity)
|
||||
{
|
||||
struct amdgpu_ring *ring = to_amdgpu_ring(s_entity->rq->sched);
|
||||
struct amdgpu_job *job = to_amdgpu_job(sched_job);
|
||||
struct amdgpu_vm *vm = job->vm;
|
||||
struct dma_fence *fence;
|
||||
struct dma_fence *fence = NULL;
|
||||
int r;
|
||||
|
||||
fence = amdgpu_sync_get_fence(&job->sync);
|
||||
if (fence && drm_sched_dependency_optimized(fence, s_entity)) {
|
||||
r = amdgpu_sync_fence(&job->sched_sync, fence);
|
||||
if (r)
|
||||
DRM_ERROR("Error adding fence (%d)\n", r);
|
||||
}
|
||||
|
||||
if (!fence && job->gang_submit)
|
||||
fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit);
|
||||
|
||||
while (fence == NULL && vm && !job->vmid) {
|
||||
r = amdgpu_vmid_grab(vm, ring, &job->sync,
|
||||
&job->base.s_fence->finished,
|
||||
job);
|
||||
while (!fence && job->vm && !job->vmid) {
|
||||
r = amdgpu_vmid_grab(job->vm, ring, job, &fence);
|
||||
if (r)
|
||||
DRM_ERROR("Error getting VM ID (%d)\n", r);
|
||||
|
||||
fence = amdgpu_sync_get_fence(&job->sync);
|
||||
}
|
||||
|
||||
return fence;
|
||||
@@ -285,8 +273,6 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
||||
job = to_amdgpu_job(sched_job);
|
||||
finished = &job->base.s_fence->finished;
|
||||
|
||||
BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL));
|
||||
|
||||
trace_amdgpu_sched_run_job(job);
|
||||
|
||||
/* Skip job if VRAM is lost and never resubmit gangs */
|
||||
@@ -345,7 +331,7 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
|
||||
}
|
||||
|
||||
const struct drm_sched_backend_ops amdgpu_sched_ops = {
|
||||
.dependency = amdgpu_job_dependency,
|
||||
.prepare_job = amdgpu_job_prepare_job,
|
||||
.run_job = amdgpu_job_run,
|
||||
.timedout_job = amdgpu_job_timedout,
|
||||
.free_job = amdgpu_job_free_cb
|
||||
|
||||
@@ -47,8 +47,7 @@ enum amdgpu_ib_pool_type;
|
||||
struct amdgpu_job {
|
||||
struct drm_sched_job base;
|
||||
struct amdgpu_vm *vm;
|
||||
struct amdgpu_sync sync;
|
||||
struct amdgpu_sync sched_sync;
|
||||
struct amdgpu_sync explicit_sync;
|
||||
struct dma_fence hw_fence;
|
||||
struct dma_fence *gang_submit;
|
||||
uint32_t preamble_status;
|
||||
@@ -78,18 +77,20 @@ static inline struct amdgpu_ring *amdgpu_job_ring(struct amdgpu_job *job)
|
||||
return to_amdgpu_ring(job->base.entity->rq->sched);
|
||||
}
|
||||
|
||||
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
struct amdgpu_job **job, struct amdgpu_vm *vm);
|
||||
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
|
||||
enum amdgpu_ib_pool_type pool, struct amdgpu_job **job);
|
||||
int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct drm_sched_entity *entity, void *owner,
|
||||
unsigned int num_ibs, struct amdgpu_job **job);
|
||||
int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev,
|
||||
struct drm_sched_entity *entity, void *owner,
|
||||
size_t size, enum amdgpu_ib_pool_type pool_type,
|
||||
struct amdgpu_job **job);
|
||||
void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds,
|
||||
struct amdgpu_bo *gws, struct amdgpu_bo *oa);
|
||||
void amdgpu_job_free_resources(struct amdgpu_job *job);
|
||||
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
|
||||
struct amdgpu_job *leader);
|
||||
void amdgpu_job_free(struct amdgpu_job *job);
|
||||
int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
|
||||
void *owner, struct dma_fence **f);
|
||||
struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job);
|
||||
int amdgpu_job_submit_direct(struct amdgpu_job *job, struct amdgpu_ring *ring,
|
||||
struct dma_fence **fence);
|
||||
|
||||
|
||||
@@ -150,14 +150,15 @@ static int amdgpu_jpeg_dec_set_reg(struct amdgpu_ring *ring, uint32_t handle,
|
||||
const unsigned ib_size_dw = 16;
|
||||
int i, r;
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, ib_size_dw * 4,
|
||||
AMDGPU_IB_POOL_DIRECT, &job);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ib = &job->ibs[0];
|
||||
|
||||
ib->ptr[0] = PACKETJ(adev->jpeg.internal.jpeg_pitch, 0, 0, PACKETJ_TYPE0);
|
||||
ib->ptr[0] = PACKETJ(adev->jpeg.internal.jpeg_pitch, 0, 0,
|
||||
PACKETJ_TYPE0);
|
||||
ib->ptr[1] = 0xDEADBEEF;
|
||||
for (i = 2; i < 16; i += 2) {
|
||||
ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
|
||||
@@ -234,3 +235,20 @@ int amdgpu_jpeg_process_poison_irq(struct amdgpu_device *adev,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void jpeg_set_ras_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (!adev->jpeg.ras)
|
||||
return;
|
||||
|
||||
amdgpu_ras_register_ras_block(adev, &adev->jpeg.ras->ras_block);
|
||||
|
||||
strcpy(adev->jpeg.ras->ras_block.ras_comm.name, "jpeg");
|
||||
adev->jpeg.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__JPEG;
|
||||
adev->jpeg.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__POISON;
|
||||
adev->jpeg.ras_if = &adev->jpeg.ras->ras_block.ras_comm;
|
||||
|
||||
/* If don't define special ras_late_init function, use default ras_late_init */
|
||||
if (!adev->jpeg.ras->ras_block.ras_late_init)
|
||||
adev->jpeg.ras->ras_block.ras_late_init = amdgpu_ras_block_late_init;
|
||||
}
|
||||
|
||||
@@ -72,5 +72,6 @@ int amdgpu_jpeg_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout);
|
||||
int amdgpu_jpeg_process_poison_irq(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry);
|
||||
void jpeg_set_ras_funcs(struct amdgpu_device *adev);
|
||||
|
||||
#endif /*__AMDGPU_JPEG_H__*/
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "amdgpu.h"
|
||||
#include <drm/amdgpu_drm.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include "amdgpu_uvd.h"
|
||||
#include "amdgpu_vce.h"
|
||||
#include "atom.h"
|
||||
@@ -430,7 +431,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
|
||||
case AMDGPU_HW_IP_VCN_DEC:
|
||||
type = AMD_IP_BLOCK_TYPE_VCN;
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
if (adev->uvd.harvest_config & (1 << i))
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
if (adev->vcn.inst[i].ring_dec.sched.ready)
|
||||
@@ -442,7 +443,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
|
||||
case AMDGPU_HW_IP_VCN_ENC:
|
||||
type = AMD_IP_BLOCK_TYPE_VCN;
|
||||
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
|
||||
if (adev->uvd.harvest_config & (1 << i))
|
||||
if (adev->vcn.harvest_config & (1 << i))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < adev->vcn.num_enc_rings; j++)
|
||||
@@ -796,7 +797,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
dev_info->ids_flags = 0;
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
dev_info->ids_flags |= AMDGPU_IDS_FLAGS_FUSION;
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev))
|
||||
if (amdgpu_mcbp)
|
||||
dev_info->ids_flags |= AMDGPU_IDS_FLAGS_PREEMPTION;
|
||||
if (amdgpu_is_tmz(adev))
|
||||
dev_info->ids_flags |= AMDGPU_IDS_FLAGS_TMZ;
|
||||
@@ -1172,7 +1173,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
|
||||
goto error_vm;
|
||||
}
|
||||
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
|
||||
if (amdgpu_mcbp) {
|
||||
uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK;
|
||||
|
||||
r = amdgpu_map_static_csa(adev, &fpriv->vm, adev->virt.csa_obj,
|
||||
@@ -1236,7 +1237,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
|
||||
if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE) != NULL)
|
||||
amdgpu_vce_free_handles(adev, file_priv);
|
||||
|
||||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
|
||||
if (amdgpu_mcbp) {
|
||||
/* TODO: how to handle reserve failure */
|
||||
BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, true));
|
||||
amdgpu_vm_bo_del(adev, fpriv->csa_va);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user