Commit 334200bf authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-msm-next-2021-06-23b' of https://gitlab.freedesktop.org/drm/msm into drm-next

* devcoredump support for display errors
* dpu: irq cleanup/refactor
* dpu: dt bindings conversion to yaml
* dsi: dt bindings conversion to yaml
* mdp5: alpha/blend_mode/zpos support
* a6xx: cached coherent buffer support
* a660 support
* gpu iova fault improvements:
   - info about which block triggered the fault, etc
   - generation of gpu devcoredump on fault
* assortment of other cleanups and fixes
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGs4=qsGBBbyn-4JWqW4-YUSTKh67X3DsPQ=T2D9aXKqNA@mail.gmail.com
parents 61c0cb8a e88bbc91
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/dp-controller.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MSM Display Port Controller
maintainers:
- Kuogee Hsieh <khsieh@codeaurora.org>
description: |
Device tree bindings for DisplayPort host controller for MSM targets
that are compatible with VESA DisplayPort interface specification.
properties:
compatible:
enum:
- qcom,sc7180-dp
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: AHB clock to enable register access
- description: Display Port AUX clock
- description: Display Port Link clock
- description: Link interface clock between DP and PHY
- description: Display Port Pixel clock
clock-names:
items:
- const: core_iface
- const: core_aux
- const: ctrl_link
- const: ctrl_link_iface
- const: stream_pixel
assigned-clocks:
items:
- description: link clock source
- description: pixel clock source
assigned-clock-parents:
items:
- description: phy 0 parent
- description: phy 1 parent
phys:
maxItems: 1
phy-names:
items:
- const: dp
operating-points-v2:
maxItems: 1
power-domains:
maxItems: 1
"#sound-dai-cells":
const: 0
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
description: Input endpoint of the controller
port@1:
$ref: /schemas/graph.yaml#/properties/port
description: Output endpoint of the controller
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- phys
- phy-names
- "#sound-dai-cells"
- power-domains
- ports
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,dispcc-sc7180.h>
#include <dt-bindings/power/qcom-aoss-qmp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
displayport-controller@ae90000 {
compatible = "qcom,sc7180-dp";
reg = <0xae90000 0x1400>;
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";
#sound-dai-cells = <0>;
power-domains = <&rpmhpd SC7180_CX>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
endpoint {
remote-endpoint = <&dpu_intf0_out>;
};
};
port@1 {
reg = <1>;
endpoint {
remote-endpoint = <&typec>;
};
};
};
};
...
# 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 <mkrishn@codeaurora.org>
description: |
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
bindings of MDSS and DPU are mentioned for 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
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
description: Node containing the properties of DPU.
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
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>;
};
};
};
};
};
...
# 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 <mkrishn@codeaurora.org>
description: |
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
bindings of MDSS and DPU are mentioned for 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 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
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
description: Node containing the properties of DPU.
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
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>,
<&gcc GCC_DISP_AXI_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>;
clock-names = "iface", "bus", "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>;
};
};
};
};
};
...
Qualcomm Technologies, Inc. DPU KMS
Description:
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
sub-blocks like DPU display controller, DSI and DP interfaces etc.
The DPU display controller is found in SDM845 SoC.
MDSS:
Required properties:
- compatible: "qcom,sdm845-mdss", "qcom,sc7180-mdss"
- reg: physical base address and length of controller's registers.
- reg-names: register region names. The following region is required:
* "mdss"
- power-domains: a power domain consumer specifier according to
Documentation/devicetree/bindings/power/power_domain.txt
- clocks: list of clock specifiers for clocks needed by the device.
- clock-names: device clock names, must be in same order as clocks property.
The following clocks are required:
* "iface"
* "bus"
* "core"
- interrupts: 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.
- iommus: phandle of iommu device node.
- #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.
- interconnects : interconnect path specifier for MDSS according to
Documentation/devicetree/bindings/interconnect/interconnect.txt. Should be
2 paths corresponding to 2 AXI ports.
- interconnect-names : MDSS will have 2 port names to differentiate between the
2 interconnect paths defined with interconnect specifier.
Optional properties:
- assigned-clocks: list of clock specifiers for clocks needing rate assignment
- assigned-clock-rates: list of clock frequencies sorted in the same order as
the assigned-clocks property.
MDP:
Required properties:
- compatible: "qcom,sdm845-dpu", "qcom,sc7180-dpu"
- reg: physical base address and length of controller's registers.
- reg-names : register region names. The following region is required:
* "mdp"
* "vbif"
- clocks: list of clock specifiers for clocks needed by the device.
- clock-names: device clock names, must be in same order as clocks property.
The following clocks are required.
* "bus"
* "iface"
* "core"
* "vsync"
- interrupts: interrupt line from DPU to MDSS.
- ports: 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. These are described by the standard properties documented
here:
Documentation/devicetree/bindings/graph.txt
Documentation/devicetree/bindings/media/video-interfaces.txt
Port 0 -> DPU_INTF1 (DSI1)
Port 1 -> DPU_INTF2 (DSI2)
Optional properties:
- assigned-clocks: list of clock specifiers for clocks needing rate assignment
- assigned-clock-rates: list of clock frequencies sorted in the same order as
the assigned-clocks property.
Example:
mdss: mdss@ae00000 {
compatible = "qcom,sdm845-mdss";
reg = <0xae00000 0x1000>;
reg-names = "mdss";
power-domains = <&clock_dispcc 0>;
clocks = <&gcc GCC_DISP_AHB_CLK>, <&gcc GCC_DISP_AXI_CLK>,
<&clock_dispcc DISP_CC_MDSS_MDP_CLK>;
clock-names = "iface", "bus", "core";
assigned-clocks = <&clock_dispcc DISP_CC_MDSS_MDP_CLK>;
assigned-clock-rates = <300000000>;
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;
interconnects = <&rsc_hlos MASTER_MDP0 &rsc_hlos SLAVE_EBI1>,
<&rsc_hlos MASTER_MDP1 &rsc_hlos SLAVE_EBI1>;
interconnect-names = "mdp0-mem", "mdp1-mem";
iommus = <&apps_iommu 0>;
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0xae00000 0xb2008>;
mdss_mdp: mdp@ae01000 {
compatible = "qcom,sdm845-dpu";
reg = <0 0x1000 0x8f000>, <0 0xb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&clock_dispcc DISP_CC_MDSS_AHB_CLK>,
<&clock_dispcc DISP_CC_MDSS_AXI_CLK>,
<&clock_dispcc DISP_CC_MDSS_MDP_CLK>,
<&clock_dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "iface", "bus", "core", "vsync";
assigned-clocks = <&clock_dispcc DISP_CC_MDSS_MDP_CLK>,
<&clock_dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <0 0 300000000 19200000>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
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>;
};
};
};
};
};
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/dsi-controller-main.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DSI controller
maintainers:
- Krishna Manikandan <mkrishn@codeaurora.org>
allOf:
- $ref: "../dsi-controller.yaml#"
properties:
compatible:
items:
- const: qcom,mdss-dsi-ctrl
reg:
maxItems: 1
reg-names:
const: dsi_ctrl
interrupts:
maxItems: 1
clocks:
items:
- description: Display byte clock
- description: Display byte interface clock
- description: Display pixel clock
- description: Display escape clock
- description: Display AHB clock
- description: Display AXI clock
clock-names:
items:
- const: byte
- const: byte_intf
- const: pixel
- const: core
- const: iface
- const: bus
phys:
maxItems: 1
phy-names:
const: dsi
"#address-cells": true
"#size-cells": true
syscon-sfpb:
description: A phandle to mmss_sfpb syscon node (only for DSIv2).
$ref: "/schemas/types.yaml#/definitions/phandle"
qcom,dual-dsi-mode:
type: boolean
description: |
Indicates if the DSI controller is driving a panel which needs
2 DSI links.
power-domains:
maxItems: 1
operating-points-v2: true
ports:
$ref: "/schemas/graph.yaml#/properties/ports"
description: |
Contains DSI controller input and output ports as children, each
containing one endpoint subnode.
properties:
port@0:
$ref: "/schemas/graph.yaml#/properties/port"
description: |
Input endpoints of the controller.
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
data-lanes:
maxItems: 4
minItems: 4
items:
enum: [ 0, 1, 2, 3 ]
port@1:
$ref: "/schemas/graph.yaml#/properties/port"
description: |
Output endpoints of the controller.
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
data-lanes:
maxItems: 4
minItems: 4
items:
enum: [ 0, 1, 2, 3 ]
required:
- port@0
- port@1
required:
- compatible
- reg
- reg-names
- interrupts
- clocks
- clock-names
- phys
- phy-names
- power-domains
- operating-points-v2
- ports
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
#include <dt-bindings/power/qcom-rpmpd.h>
dsi@ae94000 {
compatible = "qcom,mdss-dsi-ctrl";
reg = <0x0ae94000 0x400>;
reg-names = "dsi_ctrl";
#address-cells = <1>;
#size-cells = <0>;
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";
phys = <&dsi0_phy>;
phy-names = "dsi";
power-domains = <&rpmhpd SC7180_CX>;
operating-points-v2 = <&dsi_opp_table>;
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 {
remote-endpoint = <&sn65dsi86_in>;
data-lanes = <0 1 2 3>;
};
};
};
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/dsi-phy-10nm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DSI 10nm PHY
maintainers:
- Krishna Manikandan <mkrishn@codeaurora.org>
allOf:
- $ref: dsi-phy-common.yaml#
properties:
compatible:
oneOf:
- const: qcom,dsi-phy-10nm
- const: qcom,dsi-phy-10nm-8998
reg:
items:
- description: dsi phy register set
- description: dsi phy lane register set
- description: dsi pll register set
reg-names:
items:
- const: dsi_phy
- const: dsi_phy_lane
- const: dsi_pll
vdds-supply:
description: |
Connected to DSI0_MIPI_DSI_PLL_VDDA0P9 pin for sc7180 target and
connected to VDDA_MIPI_DSI_0_PLL_0P9 pin for sdm845 target
required:
- compatible
- reg
- reg-names
- vdds-supply
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
dsi-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>;
vdds-supply = <&vdda_mipi_dsi0_pll>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/dsi-phy-14nm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DSI 14nm PHY
maintainers:
- Krishna Manikandan <mkrishn@codeaurora.org>
allOf:
- $ref: dsi-phy-common.yaml#
properties:
compatible:
oneOf:
- const: qcom,dsi-phy-14nm
- const: qcom,dsi-phy-14nm-660
reg:
items:
- description: dsi phy register set
- description: dsi phy lane register set
- description: dsi pll register set
reg-names:
items:
- const: dsi_phy
- const: dsi_phy_lane
- const: dsi_pll
vcca-supply:
description: Phandle to vcca regulator device node.
required:
- compatible
- reg
- reg-names
- vcca-supply
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
dsi-phy@ae94400 {
compatible = "qcom,dsi-phy-14nm";
reg = <0x0ae94400 0x200>,
<0x0ae94600 0x280>,
<0x0ae94a00 0x1e0>;
reg-names = "dsi_phy",
"dsi_phy_lane",
"dsi_pll";
#clock-cells = <1>;
#phy-cells = <0>;
vcca-supply = <&vcca_reg>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/dsi-phy-20nm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DSI 20nm PHY
maintainers:
- Krishna Manikandan <mkrishn@codeaurora.org>
allOf:
- $ref: dsi-phy-common.yaml#
properties:
compatible:
oneOf:
- const: qcom,dsi-phy-20nm
reg:
items:
- description: dsi pll register set
- description: dsi phy register set
- description: dsi phy regulator register set
reg-names:
items:
- const: dsi_pll
- const: dsi_phy
- const: dsi_phy_regulator
vcca-supply:
description: Phandle to vcca regulator device node.
vddio-supply:
description: Phandle to vdd-io regulator device node.
required:
- compatible
- reg
- reg-names
- vddio-supply
- vcca-supply
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
dsi-phy@fd922a00 {
compatible = "qcom,dsi-phy-20nm";
reg = <0xfd922a00 0xd4>,
<0xfd922b00 0x2b0>,
<0xfd922d80 0x7b>;
reg-names = "dsi_pll",
"dsi_phy",
"dsi_phy_regulator";
#clock-cells = <1>;
#phy-cells = <0>;
vcca-supply = <&vcca_reg>;
vddio-supply = <&vddio_reg>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/dsi-phy-28nm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DSI 28nm PHY
maintainers:
- Krishna Manikandan <mkrishn@codeaurora.org>
allOf:
- $ref: dsi-phy-common.yaml#
properties:
compatible:
oneOf:
- const: qcom,dsi-phy-28nm-hpm
- const: qcom,dsi-phy-28nm-lp
- const: qcom,dsi-phy-28nm-8960
reg:
items:
- description: dsi pll register set
- description: dsi phy register set
- description: dsi phy regulator register set
reg-names:
items:
- const: dsi_pll
- const: dsi_phy
- const: dsi_phy_regulator
vddio-supply:
description: Phandle to vdd-io regulator device node.
required:
- compatible
- reg
- reg-names
- vddio-supply
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
dsi-phy@fd922a00 {
compatible = "qcom,dsi-phy-28nm-lp";
reg = <0xfd922a00 0xd4>,
<0xfd922b00 0x2b0>,
<0xfd922d80 0x7b>;
reg-names = "dsi_pll",
"dsi_phy",
"dsi_phy_regulator";
#clock-cells = <1>;
#phy-cells = <0>;
vddio-supply = <&vddio_reg>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/dsi-phy-common.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Description of Qualcomm Display DSI PHY common dt properties
maintainers:
- Krishna Manikandan <mkrishn@codeaurora.org>
description: |
This defines the DSI PHY dt properties which are common for all
dsi phy versions.
properties:
"#clock-cells":
const: 1
"#phy-cells":
const: 0
clocks:
items:
- description: Display AHB clock
- description: Board XO source
clock-names:
items:
- const: iface
- const: ref
required:
- clocks
- clock-names
- "#clock-cells"
- "#phy-cells"
additionalProperties: true
...
Qualcomm Technologies Inc. adreno/snapdragon DSI output
DSI Controller:
Required properties:
- compatible:
* "qcom,mdss-dsi-ctrl"
- reg: Physical base address and length of the registers of controller
- reg-names: The names of register regions. The following regions are required:
* "dsi_ctrl"
- interrupts: The interrupt signal from the DSI block.
- power-domains: Should be <&mmcc MDSS_GDSC>.
- clocks: Phandles to device clocks.
- clock-names: the following clocks are required:
* "mdp_core"
* "iface"
* "bus"
* "core_mmss"
* "byte"
* "pixel"
* "core"
For DSIv2, we need an additional clock:
* "src"
For DSI6G v2.0 onwards, we need also need the clock:
* "byte_intf"
- assigned-clocks: Parents of "byte" and "pixel" for the given platform.
- assigned-clock-parents: The Byte clock and Pixel clock PLL outputs provided
by a DSI PHY block. See [1] for details on clock bindings.
- vdd-supply: phandle to vdd regulator device node
- vddio-supply: phandle to vdd-io regulator device node
- vdda-supply: phandle to vdda regulator device node
- phys: phandle to DSI PHY device node
- phy-names: the name of the corresponding PHY device
- syscon-sfpb: A phandle to mmss_sfpb syscon node (only for DSIv2)
- ports: Contains 2 DSI controller ports as child nodes. Each port contains
an endpoint subnode as defined in [2] and [3].
Optional properties:
- panel@0: Node of panel connected to this DSI controller.
See files in [4] for each supported panel.
- qcom,dual-dsi-mode: Boolean value indicating if the DSI controller is
driving a panel which needs 2 DSI links.
- qcom,master-dsi: Boolean value indicating if the DSI controller is driving
the master link of the 2-DSI panel.
- qcom,sync-dual-dsi: Boolean value indicating if the DSI controller is
driving a 2-DSI panel whose 2 links need receive command simultaneously.
- pinctrl-names: the pin control state names; should contain "default"
- pinctrl-0: the default pinctrl state (active)
- pinctrl-n: the "sleep" pinctrl state
- ports: contains DSI controller input and output ports as children, each
containing one endpoint subnode.
DSI Endpoint properties:
- remote-endpoint: For port@0, set to phandle of the connected panel/bridge's
input endpoint. For port@1, set to the MDP interface output. See [2] for
device graph info.
- data-lanes: this describes how the physical DSI data lanes are mapped
to the logical lanes on the given platform. The value contained in
index n describes what physical lane is mapped to the logical lane n
(DATAn, where n lies between 0 and 3). The clock lane position is fixed
and can't be changed. Hence, they aren't a part of the DT bindings. See
[3] for more info on the data-lanes property.
For example:
data-lanes = <3 0 1 2>;
The above mapping describes that the logical data lane DATA0 is mapped to
the physical data lane DATA3, logical DATA1 to physical DATA0, logic DATA2
to phys DATA1 and logic DATA3 to phys DATA2.
There are only a limited number of physical to logical mappings possible:
<0 1 2 3>
<1 2 3 0>
<2 3 0 1>
<3 0 1 2>
<0 3 2 1>
<1 0 3 2>
<2 1 0 3>
<3 2 1 0>
DSI PHY:
Required properties:
- compatible: Could be the following
* "qcom,dsi-phy-28nm-hpm"
* "qcom,dsi-phy-28nm-lp"
* "qcom,dsi-phy-20nm"
* "qcom,dsi-phy-28nm-8960"
* "qcom,dsi-phy-14nm"
* "qcom,dsi-phy-14nm-660"
* "qcom,dsi-phy-10nm"
* "qcom,dsi-phy-10nm-8998"
* "qcom,dsi-phy-7nm"
* "qcom,dsi-phy-7nm-8150"
- reg: Physical base address and length of the registers of PLL, PHY. Some
revisions require the PHY regulator base address, whereas others require the
PHY lane base address. See below for each PHY revision.
- reg-names: The names of register regions. The following regions are required:
For DSI 28nm HPM/LP/8960 PHYs and 20nm PHY:
* "dsi_pll"
* "dsi_phy"
* "dsi_phy_regulator"
For DSI 14nm, 10nm and 7nm PHYs:
* "dsi_pll"
* "dsi_phy"
* "dsi_phy_lane"
- clock-cells: Must be 1. The DSI PHY block acts as a clock provider, creating
2 clocks: A byte clock (index 0), and a pixel clock (index 1).
- power-domains: Should be <&mmcc MDSS_GDSC>.
- clocks: Phandles to device clocks. See [1] for details on clock bindings.
- clock-names: the following clocks are required:
* "iface"
* "ref" (only required for new DTS files/entries)
For 28nm HPM/LP, 28nm 8960 PHYs:
- vddio-supply: phandle to vdd-io regulator device node
For 20nm PHY:
- vddio-supply: phandle to vdd-io regulator device node
- vcca-supply: phandle to vcca regulator device node
For 14nm PHY:
- vcca-supply: phandle to vcca regulator device node
For 10nm and 7nm PHY:
- vdds-supply: phandle to vdds regulator device node
Optional properties:
- qcom,dsi-phy-regulator-ldo-mode: Boolean value indicating if the LDO mode PHY
regulator is wanted.
- qcom,mdss-mdp-transfer-time-us: Specifies the dsi transfer time for command mode
panels in microseconds. Driver uses this number to adjust
the clock rate according to the expected transfer time.
Increasing this value would slow down the mdp processing
and can result in slower performance.
Decreasing this value can speed up the mdp processing,
but this can also impact power consumption.
As a rule this time should not be higher than the time
that would be expected with the processing at the
dsi link rate since anyways this would be the maximum
transfer time that could be achieved.
If ping pong split is enabled, this time should not be higher
than two times the dsi link rate time.
If the property is not specified, then the default value is 14000 us.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/graph.txt
[3] Documentation/devicetree/bindings/media/video-interfaces.txt
[4] Documentation/devicetree/bindings/display/panel/
Example:
dsi0: dsi@fd922800 {
compatible = "qcom,mdss-dsi-ctrl";
qcom,dsi-host-index = <0>;
interrupt-parent = <&mdp>;
interrupts = <4 0>;
reg-names = "dsi_ctrl";
reg = <0xfd922800 0x200>;
power-domains = <&mmcc MDSS_GDSC>;
clock-names =
"bus",
"byte",
"core",
"core_mmss",
"iface",
"mdp_core",
"pixel";
clocks =
<&mmcc MDSS_AXI_CLK>,
<&mmcc MDSS_BYTE0_CLK>,
<&mmcc MDSS_ESC0_CLK>,
<&mmcc MMSS_MISC_AHB_CLK>,
<&mmcc MDSS_AHB_CLK>,
<&mmcc MDSS_MDP_CLK>,
<&mmcc MDSS_PCLK0_CLK>;
assigned-clocks =
<&mmcc BYTE0_CLK_SRC>,
<&mmcc PCLK0_CLK_SRC>;
assigned-clock-parents =
<&dsi_phy0 0>,
<&dsi_phy0 1>;
vdda-supply = <&pma8084_l2>;
vdd-supply = <&pma8084_l22>;
vddio-supply = <&pma8084_l12>;
phys = <&dsi_phy0>;
phy-names ="dsi-phy";
qcom,dual-dsi-mode;
qcom,master-dsi;
qcom,sync-dual-dsi;
qcom,mdss-mdp-transfer-time-us = <12000>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&dsi_active>;
pinctrl-1 = <&dsi_suspend>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi0_in: endpoint {
remote-endpoint = <&mdp_intf1_out>;
};
};
port@1 {
reg = <1>;
dsi0_out: endpoint {
remote-endpoint = <&panel_in>;
data-lanes = <0 1 2 3>;
};
};
};
panel: panel@0 {
compatible = "sharp,lq101r1sx01";
reg = <0>;
link2 = <&secondary>;
power-supply = <...>;
backlight = <...>;
port {
panel_in: endpoint {
remote-endpoint = <&dsi0_out>;
};
};
};
};
dsi_phy0: dsi-phy@fd922a00 {
compatible = "qcom,dsi-phy-28nm-hpm";
qcom,dsi-phy-index = <0>;
reg-names =
"dsi_pll",
"dsi_phy",
"dsi_phy_regulator";
reg = <0xfd922a00 0xd4>,
<0xfd922b00 0x2b0>,
<0xfd922d80 0x7b>;
clock-names = "iface";
clocks = <&mmcc MDSS_AHB_CLK>;
#clock-cells = <1>;
vddio-supply = <&pma8084_l12>;
qcom,dsi-phy-regulator-ldo-mode;
};
/*
* Copyright (C) 2014 Red Hat
* Copyright (C) 2014 Intel Corp.
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
......@@ -1609,9 +1610,20 @@ int __drm_atomic_helper_set_config(struct drm_mode_set *set,
}
EXPORT_SYMBOL(__drm_atomic_helper_set_config);
void drm_atomic_print_state(const struct drm_atomic_state *state)
/**
* drm_atomic_print_new_state - prints drm atomic state
* @state: atomic configuration to check
* @p: drm printer
*
* This functions prints the drm atomic state snapshot using the drm printer
* which is passed to it. This snapshot can be used for debugging purposes.
*
* Note that this function looks into the new state objects and hence its not
* safe to be used after the call to drm_atomic_helper_commit_hw_done().
*/
void drm_atomic_print_new_state(const struct drm_atomic_state *state,
struct drm_printer *p)
{
struct drm_printer p = drm_info_printer(state->dev->dev);
struct drm_plane *plane;
struct drm_plane_state *plane_state;
struct drm_crtc *crtc;
......@@ -1620,17 +1632,23 @@ void drm_atomic_print_state(const struct drm_atomic_state *state)
struct drm_connector_state *connector_state;
int i;
if (!p) {
DRM_ERROR("invalid drm printer\n");
return;
}
DRM_DEBUG_ATOMIC("checking %p\n", state);
for_each_new_plane_in_state(state, plane, plane_state, i)
drm_atomic_plane_print_state(&p, plane_state);
drm_atomic_plane_print_state(p, plane_state);
for_each_new_crtc_in_state(state, crtc, crtc_state, i)
drm_atomic_crtc_print_state(&p, crtc_state);
drm_atomic_crtc_print_state(p, crtc_state);
for_each_new_connector_in_state(state, connector, connector_state, i)
drm_atomic_connector_print_state(&p, connector_state);
drm_atomic_connector_print_state(p, connector_state);
}
EXPORT_SYMBOL(drm_atomic_print_new_state);
static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
bool take_locks)
......
......@@ -2,6 +2,7 @@
* Copyright (C) 2014 Red Hat
* Copyright (C) 2014 Intel Corp.
* Copyright (C) 2018 Intel Corp.
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
......@@ -1321,6 +1322,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
struct drm_out_fence_state *fence_state;
int ret = 0;
unsigned int i, j, num_fences;
struct drm_printer p = drm_info_printer(dev->dev);
/* disallow for drivers not supporting atomic: */
if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
......@@ -1453,7 +1455,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
ret = drm_atomic_nonblocking_commit(state);
} else {
if (drm_debug_enabled(DRM_UT_STATE))
drm_atomic_print_state(state);
drm_atomic_print_new_state(state, &p);
ret = drm_atomic_commit(state);
}
......
......@@ -5,6 +5,7 @@
* Jesse Barnes <jesse.barnes@intel.com>
* Copyright © 2014 Intel Corporation
* Daniel Vetter <daniel.vetter@ffwll.ch>
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
......@@ -236,7 +237,8 @@ int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
int __drm_atomic_helper_set_config(struct drm_mode_set *set,
struct drm_atomic_state *state);
void drm_atomic_print_state(const struct drm_atomic_state *state);
void drm_atomic_print_new_state(const struct drm_atomic_state *state,
struct drm_printer *p);
/* drm_atomic_uapi.c */
int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
......
......@@ -58,7 +58,6 @@ msm-y := \
disp/dpu1/dpu_encoder_phys_cmd.o \
disp/dpu1/dpu_encoder_phys_vid.o \
disp/dpu1/dpu_formats.o \
disp/dpu1/dpu_hw_blk.o \
disp/dpu1/dpu_hw_catalog.o \
disp/dpu1/dpu_hw_ctl.o \
disp/dpu1/dpu_hw_interrupts.o \
......@@ -77,6 +76,8 @@ msm-y := \
disp/dpu1/dpu_plane.o \
disp/dpu1/dpu_rm.o \
disp/dpu1/dpu_vbif.o \
disp/msm_disp_snapshot.o \
disp/msm_disp_snapshot_util.o \
msm_atomic.o \
msm_atomic_tracepoints.o \
msm_debugfs.o \
......
......@@ -8,21 +8,21 @@ This file was generated by the rules-ng-ng headergen tool in this git repository
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/envytools/rnndb/adreno.xml ( 594 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 90159 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14386 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 65048 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 84226 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112556 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 149461 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 184695 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 11218 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_control_regs.xml ( 4559 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pipe_regs.xml ( 2872 bytes, from 2020-07-23 21:58:14)
Copyright (C) 2013-2020 by the following authors:
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13)
Copyright (C) 2013-2021 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
......@@ -1258,11 +1258,17 @@ static inline uint32_t A2XX_MH_MMU_VA_RANGE_VA_BASE(uint32_t val)
#define REG_A2XX_NQWAIT_UNTIL 0x00000394
#define REG_A2XX_RBBM_PERFCOUNTER1_SELECT 0x00000395
#define REG_A2XX_RBBM_PERFCOUNTER0_SELECT 0x00000395
#define REG_A2XX_RBBM_PERFCOUNTER1_LO 0x00000397
#define REG_A2XX_RBBM_PERFCOUNTER1_SELECT 0x00000396
#define REG_A2XX_RBBM_PERFCOUNTER1_HI 0x00000398
#define REG_A2XX_RBBM_PERFCOUNTER0_LO 0x00000397
#define REG_A2XX_RBBM_PERFCOUNTER0_HI 0x00000398
#define REG_A2XX_RBBM_PERFCOUNTER1_LO 0x00000399
#define REG_A2XX_RBBM_PERFCOUNTER1_HI 0x0000039a
#define REG_A2XX_RBBM_DEBUG 0x0000039b
......@@ -2922,10 +2928,28 @@ static inline uint32_t A2XX_RB_COPY_DEST_OFFSET_Y(uint32_t val)
#define REG_A2XX_RB_PERFCOUNTER0_SELECT 0x00000f04
#define REG_A2XX_RB_PERFCOUNTER1_SELECT 0x00000f05
#define REG_A2XX_RB_PERFCOUNTER2_SELECT 0x00000f06
#define REG_A2XX_RB_PERFCOUNTER3_SELECT 0x00000f07
#define REG_A2XX_RB_PERFCOUNTER0_LOW 0x00000f08
#define REG_A2XX_RB_PERFCOUNTER0_HI 0x00000f09
#define REG_A2XX_RB_PERFCOUNTER1_LOW 0x00000f0a
#define REG_A2XX_RB_PERFCOUNTER1_HI 0x00000f0b
#define REG_A2XX_RB_PERFCOUNTER2_LOW 0x00000f0c
#define REG_A2XX_RB_PERFCOUNTER2_HI 0x00000f0d
#define REG_A2XX_RB_PERFCOUNTER3_LOW 0x00000f0e
#define REG_A2XX_RB_PERFCOUNTER3_HI 0x00000f0f
#define REG_A2XX_SQ_TEX_0 0x00000000
#define A2XX_SQ_TEX_0_TYPE__MASK 0x00000003
#define A2XX_SQ_TEX_0_TYPE__SHIFT 0
......
......@@ -8,21 +8,21 @@ This file was generated by the rules-ng-ng headergen tool in this git repository
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/envytools/rnndb/adreno.xml ( 594 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 90159 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14386 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 65048 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 84226 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112556 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 149461 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 184695 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 11218 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_control_regs.xml ( 4559 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pipe_regs.xml ( 2872 bytes, from 2020-07-23 21:58:14)
Copyright (C) 2013-2020 by the following authors:
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13)
Copyright (C) 2013-2021 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
......@@ -1215,7 +1215,7 @@ static inline uint32_t A3XX_RB_ALPHA_REF_UINT(uint32_t val)
#define A3XX_RB_ALPHA_REF_FLOAT__SHIFT 16
static inline uint32_t A3XX_RB_ALPHA_REF_FLOAT(float val)
{
return ((util_float_to_half(val)) << A3XX_RB_ALPHA_REF_FLOAT__SHIFT) & A3XX_RB_ALPHA_REF_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A3XX_RB_ALPHA_REF_FLOAT__SHIFT) & A3XX_RB_ALPHA_REF_FLOAT__MASK;
}
static inline uint32_t REG_A3XX_RB_MRT(uint32_t i0) { return 0x000020c4 + 0x4*i0; }
......@@ -1328,7 +1328,7 @@ static inline uint32_t A3XX_RB_BLEND_RED_UINT(uint32_t val)
#define A3XX_RB_BLEND_RED_FLOAT__SHIFT 16
static inline uint32_t A3XX_RB_BLEND_RED_FLOAT(float val)
{
return ((util_float_to_half(val)) << A3XX_RB_BLEND_RED_FLOAT__SHIFT) & A3XX_RB_BLEND_RED_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A3XX_RB_BLEND_RED_FLOAT__SHIFT) & A3XX_RB_BLEND_RED_FLOAT__MASK;
}
#define REG_A3XX_RB_BLEND_GREEN 0x000020e5
......@@ -1342,7 +1342,7 @@ static inline uint32_t A3XX_RB_BLEND_GREEN_UINT(uint32_t val)
#define A3XX_RB_BLEND_GREEN_FLOAT__SHIFT 16
static inline uint32_t A3XX_RB_BLEND_GREEN_FLOAT(float val)
{
return ((util_float_to_half(val)) << A3XX_RB_BLEND_GREEN_FLOAT__SHIFT) & A3XX_RB_BLEND_GREEN_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A3XX_RB_BLEND_GREEN_FLOAT__SHIFT) & A3XX_RB_BLEND_GREEN_FLOAT__MASK;
}
#define REG_A3XX_RB_BLEND_BLUE 0x000020e6
......@@ -1356,7 +1356,7 @@ static inline uint32_t A3XX_RB_BLEND_BLUE_UINT(uint32_t val)
#define A3XX_RB_BLEND_BLUE_FLOAT__SHIFT 16
static inline uint32_t A3XX_RB_BLEND_BLUE_FLOAT(float val)
{
return ((util_float_to_half(val)) << A3XX_RB_BLEND_BLUE_FLOAT__SHIFT) & A3XX_RB_BLEND_BLUE_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A3XX_RB_BLEND_BLUE_FLOAT__SHIFT) & A3XX_RB_BLEND_BLUE_FLOAT__MASK;
}
#define REG_A3XX_RB_BLEND_ALPHA 0x000020e7
......@@ -1370,7 +1370,7 @@ static inline uint32_t A3XX_RB_BLEND_ALPHA_UINT(uint32_t val)
#define A3XX_RB_BLEND_ALPHA_FLOAT__SHIFT 16
static inline uint32_t A3XX_RB_BLEND_ALPHA_FLOAT(float val)
{
return ((util_float_to_half(val)) << A3XX_RB_BLEND_ALPHA_FLOAT__SHIFT) & A3XX_RB_BLEND_ALPHA_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A3XX_RB_BLEND_ALPHA_FLOAT__SHIFT) & A3XX_RB_BLEND_ALPHA_FLOAT__MASK;
}
#define REG_A3XX_RB_CLEAR_COLOR_DW0 0x000020e8
......
......@@ -8,21 +8,21 @@ This file was generated by the rules-ng-ng headergen tool in this git repository
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/envytools/rnndb/adreno.xml ( 594 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 90159 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14386 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 65048 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 84226 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112556 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 149461 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 184695 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 11218 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_control_regs.xml ( 4559 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pipe_regs.xml ( 2872 bytes, from 2020-07-23 21:58:14)
Copyright (C) 2013-2020 by the following authors:
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13)
Copyright (C) 2013-2021 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
......@@ -1085,7 +1085,7 @@ static inline uint32_t A4XX_RB_BLEND_RED_SINT(uint32_t val)
#define A4XX_RB_BLEND_RED_FLOAT__SHIFT 16
static inline uint32_t A4XX_RB_BLEND_RED_FLOAT(float val)
{
return ((util_float_to_half(val)) << A4XX_RB_BLEND_RED_FLOAT__SHIFT) & A4XX_RB_BLEND_RED_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A4XX_RB_BLEND_RED_FLOAT__SHIFT) & A4XX_RB_BLEND_RED_FLOAT__MASK;
}
#define REG_A4XX_RB_BLEND_RED_F32 0x000020f1
......@@ -1113,7 +1113,7 @@ static inline uint32_t A4XX_RB_BLEND_GREEN_SINT(uint32_t val)
#define A4XX_RB_BLEND_GREEN_FLOAT__SHIFT 16
static inline uint32_t A4XX_RB_BLEND_GREEN_FLOAT(float val)
{
return ((util_float_to_half(val)) << A4XX_RB_BLEND_GREEN_FLOAT__SHIFT) & A4XX_RB_BLEND_GREEN_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A4XX_RB_BLEND_GREEN_FLOAT__SHIFT) & A4XX_RB_BLEND_GREEN_FLOAT__MASK;
}
#define REG_A4XX_RB_BLEND_GREEN_F32 0x000020f3
......@@ -1141,7 +1141,7 @@ static inline uint32_t A4XX_RB_BLEND_BLUE_SINT(uint32_t val)
#define A4XX_RB_BLEND_BLUE_FLOAT__SHIFT 16
static inline uint32_t A4XX_RB_BLEND_BLUE_FLOAT(float val)
{
return ((util_float_to_half(val)) << A4XX_RB_BLEND_BLUE_FLOAT__SHIFT) & A4XX_RB_BLEND_BLUE_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A4XX_RB_BLEND_BLUE_FLOAT__SHIFT) & A4XX_RB_BLEND_BLUE_FLOAT__MASK;
}
#define REG_A4XX_RB_BLEND_BLUE_F32 0x000020f5
......@@ -1169,7 +1169,7 @@ static inline uint32_t A4XX_RB_BLEND_ALPHA_SINT(uint32_t val)
#define A4XX_RB_BLEND_ALPHA_FLOAT__SHIFT 16
static inline uint32_t A4XX_RB_BLEND_ALPHA_FLOAT(float val)
{
return ((util_float_to_half(val)) << A4XX_RB_BLEND_ALPHA_FLOAT__SHIFT) & A4XX_RB_BLEND_ALPHA_FLOAT__MASK;
return ((_mesa_float_to_half(val)) << A4XX_RB_BLEND_ALPHA_FLOAT__SHIFT) & A4XX_RB_BLEND_ALPHA_FLOAT__MASK;
}
#define REG_A4XX_RB_BLEND_ALPHA_F32 0x000020f7
......
This diff is collapsed.
......@@ -902,7 +902,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
if (!a5xx_gpu->shadow_bo) {
a5xx_gpu->shadow = msm_gem_kernel_new(gpu->dev,
sizeof(u32) * gpu->nr_rings,
MSM_BO_UNCACHED | MSM_BO_MAP_PRIV,
MSM_BO_WC | MSM_BO_MAP_PRIV,
gpu->aspace, &a5xx_gpu->shadow_bo,
&a5xx_gpu->shadow_iova);
......@@ -1075,7 +1075,7 @@ bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
return true;
}
static int a5xx_fault_handler(void *arg, unsigned long iova, int flags)
static int a5xx_fault_handler(void *arg, unsigned long iova, int flags, void *data)
{
struct msm_gpu *gpu = arg;
pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d (%u,%u,%u,%u)\n",
......@@ -1085,7 +1085,7 @@ static int a5xx_fault_handler(void *arg, unsigned long iova, int flags)
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)),
gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7)));
return -EFAULT;
return 0;
}
static void a5xx_cp_err_irq(struct msm_gpu *gpu)
......@@ -1200,6 +1200,15 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu)
struct drm_device *dev = gpu->dev;
struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu);
/*
* If stalled on SMMU fault, we could trip the GPU's hang detection,
* but the fault handler will trigger the devcore dump, and we want
* to otherwise resume normally rather than killing the submit, so
* just bail.
*/
if (gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24))
return;
DRM_DEV_ERROR(dev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
ring ? ring->id : -1, ring ? ring->seqno : 0,
gpu_read(gpu, REG_A5XX_RBBM_STATUS),
......@@ -1407,7 +1416,7 @@ static int a5xx_crashdumper_init(struct msm_gpu *gpu,
struct a5xx_crashdumper *dumper)
{
dumper->ptr = msm_gem_kernel_new_locked(gpu->dev,
SZ_1M, MSM_BO_UNCACHED, gpu->aspace,
SZ_1M, MSM_BO_WC, gpu->aspace,
&dumper->bo, &dumper->iova);
if (!IS_ERR(dumper->ptr))
......@@ -1523,6 +1532,7 @@ static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
{
struct a5xx_gpu_state *a5xx_state = kzalloc(sizeof(*a5xx_state),
GFP_KERNEL);
bool stalled = !!(gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24));
if (!a5xx_state)
return ERR_PTR(-ENOMEM);
......@@ -1535,8 +1545,13 @@ static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
a5xx_state->base.rbbm_status = gpu_read(gpu, REG_A5XX_RBBM_STATUS);
/* Get the HLSQ regs with the help of the crashdumper */
a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state);
/*
* Get the HLSQ regs with the help of the crashdumper, but only if
* we are not stalled in an iommu fault (in which case the crashdumper
* would not have access to memory)
*/
if (!stalled)
a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state);
a5xx_set_hwcg(gpu, true);
......@@ -1705,7 +1720,7 @@ static void check_speed_bin(struct device *dev)
nvmem_cell_put(cell);
}
dev_pm_opp_set_supported_hw(dev, &val, 1);
devm_pm_opp_set_supported_hw(dev, &val, 1);
}
struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
......
......@@ -363,7 +363,7 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
bosize = (cmds_size + (cmds_size / TYPE4_MAX_PAYLOAD) + 1) << 2;
ptr = msm_gem_kernel_new_locked(drm, bosize,
MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace,
MSM_BO_WC | MSM_BO_GPU_READONLY, gpu->aspace,
&a5xx_gpu->gpmu_bo, &a5xx_gpu->gpmu_iova);
if (IS_ERR(ptr))
return;
......
......@@ -230,7 +230,7 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,
ptr = msm_gem_kernel_new(gpu->dev,
A5XX_PREEMPT_RECORD_SIZE + A5XX_PREEMPT_COUNTER_SIZE,
MSM_BO_UNCACHED | MSM_BO_MAP_PRIV, gpu->aspace, &bo, &iova);
MSM_BO_WC | MSM_BO_MAP_PRIV, gpu->aspace, &bo, &iova);
if (IS_ERR(ptr))
return PTR_ERR(ptr);
......@@ -238,7 +238,7 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,
/* The buffer to store counters needs to be unprivileged */
counters = msm_gem_kernel_new(gpu->dev,
A5XX_PREEMPT_COUNTER_SIZE,
MSM_BO_UNCACHED, gpu->aspace, &counters_bo, &counters_iova);
MSM_BO_WC, gpu->aspace, &counters_bo, &counters_iova);
if (IS_ERR(counters)) {
msm_gem_kernel_put(bo, gpu->aspace, true);
return PTR_ERR(counters);
......
This diff is collapsed.
......@@ -512,19 +512,26 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
struct platform_device *pdev = to_platform_device(gmu->dev);
void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");
void __iomem *seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
void __iomem *seqptr;
uint32_t pdc_address_offset;
bool pdc_in_aop = false;
if (!pdcptr || !seqptr)
if (!pdcptr)
goto err;
if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu))
if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
pdc_in_aop = true;
else if (adreno_is_a618(adreno_gpu) || adreno_is_a640(adreno_gpu))
pdc_address_offset = 0x30090;
else if (adreno_is_a650(adreno_gpu))
pdc_address_offset = 0x300a0;
else
pdc_address_offset = 0x30080;
if (!pdc_in_aop) {
seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
if (!seqptr)
goto err;
}
/* Disable SDE clock gating */
gmu_write_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
......@@ -542,7 +549,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
/* Load RSC sequencer uCode for sleep and wakeup */
if (adreno_is_a650(adreno_gpu)) {
if (adreno_is_a650_family(adreno_gpu)) {
gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xeaaae5a0);
gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xe1a1ebab);
gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e0a581);
......@@ -556,6 +563,9 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);
}
if (pdc_in_aop)
goto setup_pdc;
/* Load PDC sequencer uCode for power up and power down sequence */
pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1);
pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 1, 0xa5a4a3a2);
......@@ -587,7 +597,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108);
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x30000);
if (adreno_is_a618(adreno_gpu) || adreno_is_a650(adreno_gpu))
if (adreno_is_a618(adreno_gpu) || adreno_is_a650_family(adreno_gpu))
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2);
else
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3);
......@@ -596,6 +606,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3);
/* Setup GPU PDC */
setup_pdc:
pdc_write(pdcptr, REG_A6XX_PDC_GPU_SEQ_START_ADDR, 0);
pdc_write(pdcptr, REG_A6XX_PDC_GPU_ENABLE_PDC, 0x80000001);
......@@ -687,7 +698,7 @@ static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)
u32 itcm_base = 0x00000000;
u32 dtcm_base = 0x00040000;
if (adreno_is_a650(adreno_gpu))
if (adreno_is_a650_family(adreno_gpu))
dtcm_base = 0x10004000;
if (gmu->legacy) {
......@@ -740,8 +751,10 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
int ret;
u32 chipid;
if (adreno_is_a650(adreno_gpu))
if (adreno_is_a650_family(adreno_gpu)) {
gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FALNEXT_INTF, 1);
gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF, 1);
}
if (state == GMU_WARM_BOOT) {
ret = a6xx_rpmh_start(gmu);
......@@ -1346,7 +1359,7 @@ static int a6xx_gmu_pwrlevels_probe(struct a6xx_gmu *gmu)
* The GMU handles its own frequency switching so build a list of
* available frequencies to send during initialization
*/
ret = dev_pm_opp_of_add_table(gmu->dev);
ret = devm_pm_opp_of_add_table(gmu->dev);
if (ret) {
DRM_DEV_ERROR(gmu->dev, "Unable to set the OPP table for the GMU\n");
return ret;
......@@ -1483,12 +1496,28 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
if (ret)
goto err_put_device;
/* A660 now requires handling "prealloc requests" in GMU firmware
* For now just hardcode allocations based on the known firmware.
* note: there is no indication that these correspond to "dummy" or
* "debug" regions, but this "guess" allows reusing these BOs which
* are otherwise unused by a660.
*/
gmu->dummy.size = SZ_4K;
if (adreno_is_a660(adreno_gpu)) {
ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7, 0x60400000);
if (ret)
goto err_memory;
gmu->dummy.size = SZ_8K;
}
/* Allocate memory for the GMU dummy page */
ret = a6xx_gmu_memory_alloc(gmu, &gmu->dummy, SZ_4K, 0x60000000);
ret = a6xx_gmu_memory_alloc(gmu, &gmu->dummy, gmu->dummy.size, 0x60000000);
if (ret)
goto err_memory;
if (adreno_is_a650(adreno_gpu)) {
if (adreno_is_a650_family(adreno_gpu)) {
ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,
SZ_16M - SZ_16K, 0x04000);
if (ret)
......@@ -1530,7 +1559,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
goto err_memory;
}
if (adreno_is_a650(adreno_gpu)) {
if (adreno_is_a650_family(adreno_gpu)) {
gmu->rscc = a6xx_gmu_get_mmio(pdev, "rscc");
if (IS_ERR(gmu->rscc))
goto err_mmio;
......
......@@ -8,21 +8,21 @@ This file was generated by the rules-ng-ng headergen tool in this git repository
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/envytools/rnndb/adreno.xml ( 594 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 90159 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14386 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 65048 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 84226 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112556 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 149461 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 184695 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 11218 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_control_regs.xml ( 4559 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pipe_regs.xml ( 2872 bytes, from 2020-07-23 21:58:14)
Copyright (C) 2013-2020 by the following authors:
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13)
Copyright (C) 2013-2021 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
......@@ -292,6 +292,8 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val)
#define REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF 0x000050f0
#define REG_A6XX_GPU_GMU_CX_GMU_CX_FALNEXT_INTF 0x000050f1
#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG 0x00005100
#define REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP 0x00005101
......@@ -439,6 +441,8 @@ static inline uint32_t A6XX_GMU_GPU_NAP_CTRL_SID(uint32_t val)
#define REG_A6XX_GPU_CC_GX_DOMAIN_MISC 0x00009d42
#define REG_A6XX_GPU_CPR_FSM_CTL 0x0000c001
#define REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0 0x00000004
#define REG_A6XX_RSCC_PDC_SEQ_START_ADDR 0x00000008
......
This diff is collapsed.
......@@ -33,8 +33,6 @@ struct a6xx_gpu {
void *llc_slice;
void *htw_llc_slice;
bool have_mmu500;
struct opp_table *opp_table;
};
#define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base)
......
......@@ -113,7 +113,7 @@ static int a6xx_crashdumper_init(struct msm_gpu *gpu,
struct a6xx_crashdumper *dumper)
{
dumper->ptr = msm_gem_kernel_new_locked(gpu->dev,
SZ_1M, MSM_BO_UNCACHED, gpu->aspace,
SZ_1M, MSM_BO_WC, gpu->aspace,
&dumper->bo, &dumper->iova);
if (!IS_ERR(dumper->ptr))
......@@ -832,6 +832,20 @@ static void a6xx_get_registers(struct msm_gpu *gpu,
a6xx_get_ahb_gpu_registers(gpu,
a6xx_state, &a6xx_vbif_reglist,
&a6xx_state->registers[index++]);
if (!dumper) {
/*
* We can't use the crashdumper when the SMMU is stalled,
* because the GPU has no memory access until we resume
* translation (but we don't want to do that until after
* we have captured as much useful GPU state as possible).
* So instead collect registers via the CPU:
*/
for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++)
a6xx_get_ahb_gpu_registers(gpu,
a6xx_state, &a6xx_reglist[i],
&a6xx_state->registers[index++]);
return;
}
for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++)
a6xx_get_crashdumper_registers(gpu,
......@@ -905,11 +919,13 @@ static void a6xx_get_indexed_registers(struct msm_gpu *gpu,
struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu)
{
struct a6xx_crashdumper dumper = { 0 };
struct a6xx_crashdumper _dumper = { 0 }, *dumper = NULL;
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
struct a6xx_gpu_state *a6xx_state = kzalloc(sizeof(*a6xx_state),
GFP_KERNEL);
bool stalled = !!(gpu_read(gpu, REG_A6XX_RBBM_STATUS3) &
A6XX_RBBM_STATUS3_SMMU_STALLED_ON_FAULT);
if (!a6xx_state)
return ERR_PTR(-ENOMEM);
......@@ -928,14 +944,24 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu)
/* Get the banks of indexed registers */
a6xx_get_indexed_registers(gpu, a6xx_state);
/* Try to initialize the crashdumper */
if (!a6xx_crashdumper_init(gpu, &dumper)) {
a6xx_get_registers(gpu, a6xx_state, &dumper);
a6xx_get_shaders(gpu, a6xx_state, &dumper);
a6xx_get_clusters(gpu, a6xx_state, &dumper);
a6xx_get_dbgahb_clusters(gpu, a6xx_state, &dumper);
/*
* Try to initialize the crashdumper, if we are not dumping state
* with the SMMU stalled. The crashdumper needs memory access to
* write out GPU state, so we need to skip this when the SMMU is
* stalled in response to an iova fault
*/
if (!stalled && !a6xx_crashdumper_init(gpu, &_dumper)) {
dumper = &_dumper;
}
a6xx_get_registers(gpu, a6xx_state, dumper);
if (dumper) {
a6xx_get_shaders(gpu, a6xx_state, dumper);
a6xx_get_clusters(gpu, a6xx_state, dumper);
a6xx_get_dbgahb_clusters(gpu, a6xx_state, dumper);
msm_gem_kernel_put(dumper.bo, gpu->aspace, true);
msm_gem_kernel_put(dumper->bo, gpu->aspace, true);
}
if (snapshot_debugbus)
......
......@@ -351,6 +351,37 @@ static void a650_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
msg->cnoc_cmds_data[1][0] = 0x60000001;
}
static void a660_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
{
/*
* Send a single "off" entry just to get things running
* TODO: bus scaling
*/
msg->bw_level_num = 1;
msg->ddr_cmds_num = 3;
msg->ddr_wait_bitmask = 0x01;
msg->ddr_cmds_addrs[0] = 0x50004;
msg->ddr_cmds_addrs[1] = 0x500a0;
msg->ddr_cmds_addrs[2] = 0x50000;
msg->ddr_cmds_data[0][0] = 0x40000000;
msg->ddr_cmds_data[0][1] = 0x40000000;
msg->ddr_cmds_data[0][2] = 0x40000000;
/*
* These are the CX (CNOC) votes - these are used by the GMU but the
* votes are known and fixed for the target
*/
msg->cnoc_cmds_num = 1;
msg->cnoc_wait_bitmask = 0x01;
msg->cnoc_cmds_addrs[0] = 0x50070;
msg->cnoc_cmds_data[0][0] = 0x40000000;
msg->cnoc_cmds_data[1][0] = 0x60000001;
}
static void a6xx_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
{
/* Send a single "off" entry since the 630 GMU doesn't do bus scaling */
......@@ -401,6 +432,8 @@ static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu)
a640_build_bw_table(&msg);
else if (adreno_is_a650(adreno_gpu))
a650_build_bw_table(&msg);
else if (adreno_is_a660(adreno_gpu))
a660_build_bw_table(&msg);
else
a6xx_build_bw_table(&msg);
......
......@@ -8,21 +8,21 @@ This file was generated by the rules-ng-ng headergen tool in this git repository
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/envytools/rnndb/adreno.xml ( 594 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 90159 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14386 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 65048 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 84226 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112556 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 149461 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 184695 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 11218 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_control_regs.xml ( 4559 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pipe_regs.xml ( 2872 bytes, from 2020-07-23 21:58:14)
Copyright (C) 2013-2020 by the following authors:
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13)
Copyright (C) 2013-2021 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
......
......@@ -287,6 +287,19 @@ static const struct adreno_info gpulist[] = {
.init = a6xx_gpu_init,
.zapfw = "a650_zap.mdt",
.hwcg = a650_hwcg,
}, {
.rev = ADRENO_REV(6, 6, 0, ANY_ID),
.revn = 660,
.name = "A660",
.fw = {
[ADRENO_FW_SQE] = "a660_sqe.fw",
[ADRENO_FW_GMU] = "a660_gmu.bin",
},
.gmem = SZ_1M + SZ_512K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a6xx_gpu_init,
.zapfw = "a660_zap.mdt",
.hwcg = a660_hwcg,
},
};
......@@ -466,6 +479,7 @@ static int adreno_bind(struct device *dev, struct device *master, void *data)
config.rev.minor, config.rev.patchid);
priv->is_a2xx = config.rev.core == 2;
priv->has_cached_coherent = config.rev.core >= 6;
gpu = info->init(drm);
if (IS_ERR(gpu)) {
......
......@@ -239,7 +239,7 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
*value = adreno_gpu->gmem;
return 0;
case MSM_PARAM_GMEM_BASE:
*value = !adreno_is_a650(adreno_gpu) ? 0x100000 : 0;
*value = !adreno_is_a650_family(adreno_gpu) ? 0x100000 : 0;
return 0;
case MSM_PARAM_CHIP_ID:
*value = adreno_gpu->rev.patchid |
......@@ -391,7 +391,7 @@ struct drm_gem_object *adreno_fw_create_bo(struct msm_gpu *gpu,
void *ptr;
ptr = msm_gem_kernel_new_locked(gpu->dev, fw->size - 4,
MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace, &bo, iova);
MSM_BO_WC | MSM_BO_GPU_READONLY, gpu->aspace, &bo, iova);
if (IS_ERR(ptr))
return ERR_CAST(ptr);
......@@ -408,7 +408,7 @@ int adreno_hw_init(struct msm_gpu *gpu)
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
int ret, i;
DBG("%s", gpu->name);
VERB("%s", gpu->name);
ret = adreno_load_fw(adreno_gpu);
if (ret)
......@@ -684,6 +684,21 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
adreno_gpu->info->revn, adreno_gpu->rev.core,
adreno_gpu->rev.major, adreno_gpu->rev.minor,
adreno_gpu->rev.patchid);
/*
* If this is state collected due to iova fault, so fault related info
*
* TTBR0 would not be zero, so this is a good way to distinguish
*/
if (state->fault_info.ttbr0) {
const struct msm_gpu_fault_info *info = &state->fault_info;
drm_puts(p, "fault-info:\n");
drm_printf(p, " - ttbr0=%.16llx\n", info->ttbr0);
drm_printf(p, " - iova=%.16lx\n", info->iova);
drm_printf(p, " - dir=%s\n", info->flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ");
drm_printf(p, " - type=%s\n", info->type);
drm_printf(p, " - source=%s\n", info->block);
}
drm_printf(p, "rbbm-status: 0x%08x\n", state->rbbm_status);
......@@ -841,7 +856,7 @@ static void adreno_get_pwrlevels(struct device *dev,
if (!of_find_property(dev->of_node, "operating-points-v2", NULL))
ret = adreno_get_legacy_pwrlevels(dev);
else {
ret = dev_pm_opp_of_add_table(dev);
ret = devm_pm_opp_of_add_table(dev);
if (ret)
DRM_DEV_ERROR(dev, "Unable to set the OPP table\n");
}
......@@ -946,7 +961,4 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
pm_runtime_disable(&priv->gpu_pdev->dev);
msm_gpu_cleanup(&adreno_gpu->base);
icc_put(gpu->icc_path);
icc_put(gpu->ocmem_icc_path);
}
......@@ -55,7 +55,7 @@ struct adreno_reglist {
u32 value;
};
extern const struct adreno_reglist a630_hwcg[], a640_hwcg[], a650_hwcg[];
extern const struct adreno_reglist a630_hwcg[], a640_hwcg[], a650_hwcg[], a660_hwcg[];
struct adreno_info {
struct adreno_rev rev;
......@@ -247,6 +247,17 @@ static inline int adreno_is_a650(struct adreno_gpu *gpu)
return gpu->revn == 650;
}
static inline int adreno_is_a660(struct adreno_gpu *gpu)
{
return gpu->revn == 660;
}
/* check for a650, a660, or any derivatives */
static inline int adreno_is_a650_family(struct adreno_gpu *gpu)
{
return gpu->revn == 650 || gpu->revn == 620 || gpu->revn == 660;
}
int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu,
const char *fwname);
......
......@@ -8,21 +8,21 @@ This file was generated by the rules-ng-ng headergen tool in this git repository
git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/envytools/rnndb/adreno.xml ( 594 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 90159 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14386 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 65048 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 84226 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112556 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 149461 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 184695 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 11218 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_control_regs.xml ( 4559 bytes, from 2020-07-23 21:58:14)
- /home/robclark/src/envytools/rnndb/adreno/adreno_pipe_regs.xml ( 2872 bytes, from 2020-07-23 21:58:14)
Copyright (C) 2013-2020 by the following authors:
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno.xml ( 594 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml ( 1572 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a2xx.xml ( 90810 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_common.xml ( 14386 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pm4.xml ( 67699 bytes, from 2021-05-31 20:21:57)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a3xx.xml ( 84226 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a4xx.xml ( 112551 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a5xx.xml ( 150713 bytes, from 2021-06-10 22:34:02)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx.xml ( 180049 bytes, from 2021-06-02 21:44:19)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/a6xx_gmu.xml ( 11331 bytes, from 2021-05-21 19:18:08)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/ocmem.xml ( 1773 bytes, from 2021-02-18 16:45:44)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_control_regs.xml ( 6038 bytes, from 2021-05-27 20:22:36)
- /home/robclark/src/mesa/mesa/src/freedreno/registers/adreno/adreno_pipe_regs.xml ( 2924 bytes, from 2021-05-27 20:18:13)
Copyright (C) 2013-2021 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
......@@ -247,9 +247,9 @@ enum adreno_pm4_type3_packets {
CP_DRAW_INDX_INDIRECT = 41,
CP_DRAW_INDIRECT_MULTI = 42,
CP_DRAW_AUTO = 36,
CP_UNKNOWN_19 = 25,
CP_UNKNOWN_1A = 26,
CP_UNKNOWN_4E = 78,
CP_DRAW_PRED_ENABLE_GLOBAL = 25,
CP_DRAW_PRED_ENABLE_LOCAL = 26,
CP_DRAW_PRED_SET = 78,
CP_WIDE_REG_WRITE = 116,
CP_SCRATCH_TO_REG = 77,
CP_REG_TO_SCRATCH = 74,
......@@ -267,6 +267,7 @@ enum adreno_pm4_type3_packets {
CP_SKIP_IB2_ENABLE_GLOBAL = 29,
CP_SKIP_IB2_ENABLE_LOCAL = 35,
CP_SET_SUBDRAW_SIZE = 53,
CP_WHERE_AM_I = 98,
CP_SET_VISIBILITY_OVERRIDE = 100,
CP_PREEMPT_ENABLE_GLOBAL = 105,
CP_PREEMPT_ENABLE_LOCAL = 106,
......@@ -298,7 +299,6 @@ enum adreno_pm4_type3_packets {
CP_SET_BIN_DATA5_OFFSET = 46,
CP_SET_CTXSWITCH_IB = 85,
CP_REG_WRITE = 109,
CP_WHERE_AM_I = 98,
};
enum adreno_state_block {
......@@ -400,6 +400,17 @@ enum a6xx_patch_type {
enum a6xx_draw_indirect_opcode {
INDIRECT_OP_NORMAL = 2,
INDIRECT_OP_INDEXED = 4,
INDIRECT_OP_INDIRECT_COUNT = 6,
INDIRECT_OP_INDIRECT_COUNT_INDEXED = 7,
};
enum cp_draw_pred_src {
PRED_SRC_MEM = 5,
};
enum cp_draw_pred_test {
NE_0_PASS = 0,
EQ_0_PASS = 1,
};
enum cp_cond_function {
......@@ -1040,33 +1051,61 @@ static inline uint32_t A6XX_CP_DRAW_INDIRECT_MULTI_1_DST_OFF(uint32_t val)
return ((val) << A6XX_CP_DRAW_INDIRECT_MULTI_1_DST_OFF__SHIFT) & A6XX_CP_DRAW_INDIRECT_MULTI_1_DST_OFF__MASK;
}
#define REG_A6XX_CP_DRAW_INDIRECT_MULTI_2 0x00000002
#define A6XX_CP_DRAW_INDIRECT_MULTI_2_DRAW_COUNT__MASK 0xffffffff
#define A6XX_CP_DRAW_INDIRECT_MULTI_2_DRAW_COUNT__SHIFT 0
static inline uint32_t A6XX_CP_DRAW_INDIRECT_MULTI_2_DRAW_COUNT(uint32_t val)
{
return ((val) << A6XX_CP_DRAW_INDIRECT_MULTI_2_DRAW_COUNT__SHIFT) & A6XX_CP_DRAW_INDIRECT_MULTI_2_DRAW_COUNT__MASK;
}
#define REG_A6XX_CP_DRAW_INDIRECT_MULTI_DRAW_COUNT 0x00000002
#define REG_A6XX_CP_DRAW_INDIRECT_MULTI_ADDRESS_0 0x00000003
#define REG_A6XX_CP_DRAW_INDIRECT_MULTI_5 0x00000005
#define A6XX_CP_DRAW_INDIRECT_MULTI_5_PARAM_0__MASK 0xffffffff
#define A6XX_CP_DRAW_INDIRECT_MULTI_5_PARAM_0__SHIFT 0
static inline uint32_t A6XX_CP_DRAW_INDIRECT_MULTI_5_PARAM_0(uint32_t val)
{
return ((val) << A6XX_CP_DRAW_INDIRECT_MULTI_5_PARAM_0__SHIFT) & A6XX_CP_DRAW_INDIRECT_MULTI_5_PARAM_0__MASK;
}
#define REG_A6XX_CP_DRAW_INDIRECT_MULTI_INDIRECT 0x00000003
#define REG_A6XX_CP_DRAW_INDIRECT_MULTI_STRIDE 0x00000005
#define REG_CP_DRAW_INDIRECT_MULTI_INDEX_INDEXED 0x00000003
#define REG_CP_DRAW_INDIRECT_MULTI_MAX_INDICES_INDEXED 0x00000005
#define REG_CP_DRAW_INDIRECT_MULTI_INDIRECT_INDEXED 0x00000006
#define REG_A6XX_CP_DRAW_INDIRECT_MULTI_INDIRECT 0x00000006
#define REG_CP_DRAW_INDIRECT_MULTI_STRIDE_INDEXED 0x00000008
#define REG_A6XX_CP_DRAW_INDIRECT_MULTI_8 0x00000008
#define A6XX_CP_DRAW_INDIRECT_MULTI_8_STRIDE__MASK 0xffffffff
#define A6XX_CP_DRAW_INDIRECT_MULTI_8_STRIDE__SHIFT 0
static inline uint32_t A6XX_CP_DRAW_INDIRECT_MULTI_8_STRIDE(uint32_t val)
#define REG_CP_DRAW_INDIRECT_MULTI_INDIRECT_INDIRECT 0x00000003
#define REG_CP_DRAW_INDIRECT_MULTI_INDIRECT_COUNT_INDIRECT 0x00000005
#define REG_CP_DRAW_INDIRECT_MULTI_STRIDE_INDIRECT 0x00000007
#define REG_CP_DRAW_INDIRECT_MULTI_INDEX_INDIRECT_INDEXED 0x00000003
#define REG_CP_DRAW_INDIRECT_MULTI_MAX_INDICES_INDIRECT_INDEXED 0x00000005
#define REG_CP_DRAW_INDIRECT_MULTI_INDIRECT_INDIRECT_INDEXED 0x00000006
#define REG_CP_DRAW_INDIRECT_MULTI_INDIRECT_COUNT_INDIRECT_INDEXED 0x00000008
#define REG_CP_DRAW_INDIRECT_MULTI_STRIDE_INDIRECT_INDEXED 0x0000000a
#define REG_CP_DRAW_PRED_ENABLE_GLOBAL_0 0x00000000
#define CP_DRAW_PRED_ENABLE_GLOBAL_0_ENABLE 0x00000001
#define REG_CP_DRAW_PRED_ENABLE_LOCAL_0 0x00000000
#define CP_DRAW_PRED_ENABLE_LOCAL_0_ENABLE 0x00000001
#define REG_CP_DRAW_PRED_SET_0 0x00000000
#define CP_DRAW_PRED_SET_0_SRC__MASK 0x000000f0
#define CP_DRAW_PRED_SET_0_SRC__SHIFT 4
static inline uint32_t CP_DRAW_PRED_SET_0_SRC(enum cp_draw_pred_src val)
{
return ((val) << A6XX_CP_DRAW_INDIRECT_MULTI_8_STRIDE__SHIFT) & A6XX_CP_DRAW_INDIRECT_MULTI_8_STRIDE__MASK;
return ((val) << CP_DRAW_PRED_SET_0_SRC__SHIFT) & CP_DRAW_PRED_SET_0_SRC__MASK;
}
#define CP_DRAW_PRED_SET_0_TEST__MASK 0x00000100
#define CP_DRAW_PRED_SET_0_TEST__SHIFT 8
static inline uint32_t CP_DRAW_PRED_SET_0_TEST(enum cp_draw_pred_test val)
{
return ((val) << CP_DRAW_PRED_SET_0_TEST__SHIFT) & CP_DRAW_PRED_SET_0_TEST__MASK;
}
#define REG_CP_DRAW_PRED_SET_MEM_ADDR 0x00000001
static inline uint32_t REG_CP_SET_DRAW_STATE_(uint32_t i0) { return 0x00000000 + 0x3*i0; }
......
......@@ -29,49 +29,6 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms);
*/
irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms);
/**
* dpu_core_irq_idx_lookup - IRQ helper function for lookup irq_idx from HW
* interrupt mapping table.
* @dpu_kms: DPU handle
* @intr_type: DPU HW interrupt type for lookup
* @instance_idx: DPU HW block instance defined in dpu_hw_mdss.h
* @return: irq_idx or -EINVAL when fail to lookup
*/
int dpu_core_irq_idx_lookup(
struct dpu_kms *dpu_kms,
enum dpu_intr_type intr_type,
uint32_t instance_idx);
/**
* dpu_core_irq_enable - IRQ helper function for enabling one or more IRQs
* @dpu_kms: DPU handle
* @irq_idxs: Array of irq index
* @irq_count: Number of irq_idx provided in the array
* @return: 0 for success enabling IRQ, otherwise failure
*
* This function increments count on each enable and decrements on each
* disable. Interrupts is enabled if count is 0 before increment.
*/
int dpu_core_irq_enable(
struct dpu_kms *dpu_kms,
int *irq_idxs,
uint32_t irq_count);
/**
* dpu_core_irq_disable - IRQ helper function for disabling one of more IRQs
* @dpu_kms: DPU handle
* @irq_idxs: Array of irq index
* @irq_count: Number of irq_idx provided in the array
* @return: 0 for success disabling IRQ, otherwise failure
*
* This function increments count on each enable and decrements on each
* disable. Interrupts is disabled if count is 0 after decrement.
*/
int dpu_core_irq_disable(
struct dpu_kms *dpu_kms,
int *irq_idxs,
uint32_t irq_count);
/**
* dpu_core_irq_read - IRQ helper function for reading IRQ status
* @dpu_kms: DPU handle
......
......@@ -132,7 +132,7 @@ static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms,
perf->core_clk_rate = _dpu_core_perf_calc_clk(kms, crtc, state);
}
DPU_DEBUG(
DRM_DEBUG_ATOMIC(
"crtc=%d clk_rate=%llu core_ib=%llu core_ab=%llu\n",
crtc->base.id, perf->core_clk_rate,
perf->max_per_pipe_ib, perf->bw_ctl);
......@@ -178,7 +178,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
struct dpu_crtc_state *tmp_cstate =
to_dpu_crtc_state(tmp_crtc->state);
DPU_DEBUG("crtc:%d bw:%llu ctrl:%d\n",
DRM_DEBUG_ATOMIC("crtc:%d bw:%llu ctrl:%d\n",
tmp_crtc->base.id, tmp_cstate->new_perf.bw_ctl,
tmp_cstate->bw_control);
......@@ -187,11 +187,11 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
/* convert bandwidth to kb */
bw = DIV_ROUND_UP_ULL(bw_sum_of_intfs, 1000);
DPU_DEBUG("calculated bandwidth=%uk\n", bw);
DRM_DEBUG_ATOMIC("calculated bandwidth=%uk\n", bw);
threshold = kms->catalog->perf.max_bw_high;
DPU_DEBUG("final threshold bw limit = %d\n", threshold);
DRM_DEBUG_ATOMIC("final threshold bw limit = %d\n", threshold);
if (!threshold) {
DPU_ERROR("no bandwidth limits specified\n");
......@@ -228,7 +228,7 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
perf.bw_ctl += dpu_cstate->new_perf.bw_ctl;
DPU_DEBUG("crtc=%d bw=%llu paths:%d\n",
DRM_DEBUG_ATOMIC("crtc=%d bw=%llu paths:%d\n",
tmp_crtc->base.id,
dpu_cstate->new_perf.bw_ctl, kms->num_paths);
}
......@@ -278,7 +278,7 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
/* Release the bandwidth */
if (kms->perf.enable_bw_release) {
trace_dpu_cmd_release_bw(crtc->base.id);
DPU_DEBUG("Release BW crtc=%d\n", crtc->base.id);
DRM_DEBUG_ATOMIC("Release BW crtc=%d\n", crtc->base.id);
dpu_crtc->cur_perf.bw_ctl = 0;
_dpu_core_perf_crtc_update_bus(kms, crtc);
}
......@@ -314,7 +314,7 @@ static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
if (kms->perf.perf_tune.mode == DPU_PERF_MODE_FIXED)
clk_rate = kms->perf.fix_core_clk_rate;
DPU_DEBUG("clk:%llu\n", clk_rate);
DRM_DEBUG_ATOMIC("clk:%llu\n", clk_rate);
return clk_rate;
}
......@@ -344,7 +344,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
dpu_crtc = to_dpu_crtc(crtc);
dpu_cstate = to_dpu_crtc_state(crtc->state);
DPU_DEBUG("crtc:%d stop_req:%d core_clk:%llu\n",
DRM_DEBUG_ATOMIC("crtc:%d stop_req:%d core_clk:%llu\n",
crtc->base.id, stop_req, kms->perf.core_clk_rate);
old = &dpu_crtc->cur_perf;
......@@ -362,7 +362,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
(new->max_per_pipe_ib > old->max_per_pipe_ib))) ||
(!params_changed && ((new->bw_ctl < old->bw_ctl) ||
(new->max_per_pipe_ib < old->max_per_pipe_ib)))) {
DPU_DEBUG("crtc=%d p=%d new_bw=%llu,old_bw=%llu\n",
DRM_DEBUG_ATOMIC("crtc=%d p=%d new_bw=%llu,old_bw=%llu\n",
crtc->base.id, params_changed,
new->bw_ctl, old->bw_ctl);
old->bw_ctl = new->bw_ctl;
......@@ -378,7 +378,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
update_clk = true;
}
} else {
DPU_DEBUG("crtc=%d disable\n", crtc->base.id);
DRM_DEBUG_ATOMIC("crtc=%d disable\n", crtc->base.id);
memset(old, 0, sizeof(*old));
update_bus = true;
update_clk = true;
......@@ -413,7 +413,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
}
kms->perf.core_clk_rate = clk_rate;
DPU_DEBUG("update clk rate = %lld HZ\n", clk_rate);
DRM_DEBUG_ATOMIC("update clk rate = %lld HZ\n", clk_rate);
}
return 0;
}
......
......@@ -57,8 +57,6 @@ static void dpu_crtc_destroy(struct drm_crtc *crtc)
{
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
DPU_DEBUG("\n");
if (!crtc)
return;
......@@ -163,7 +161,7 @@ static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer,
lm->ops.setup_blend_config(lm, pstate->stage,
0xFF, 0, blend_op);
DPU_DEBUG("format:%p4cc, alpha_en:%u blend_op:0x%x\n",
DRM_DEBUG_ATOMIC("format:%p4cc, alpha_en:%u blend_op:0x%x\n",
&format->base.pixel_format, format->alpha_enable, blend_op);
}
......@@ -220,7 +218,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
dpu_plane_get_ctl_flush(plane, ctl, &flush_mask);
set_bit(dpu_plane_pipe(plane), fetch_active);
DPU_DEBUG("crtc %d stage:%d - plane %d sspp %d fb %d\n",
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
crtc->base.id,
pstate->stage,
plane->base.id,
......@@ -278,7 +277,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
struct dpu_hw_mixer *lm;
int i;
DPU_DEBUG("%s\n", dpu_crtc->name);
DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
for (i = 0; i < cstate->num_mixers; i++) {
mixer[i].mixer_op_mode = 0;
......@@ -305,7 +304,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
/* stage config flush mask */
ctl->ops.update_pending_flush(ctl, mixer[i].flush_mask);
DPU_DEBUG("lm %d, op_mode 0x%X, ctl %d, flush mask 0x%x\n",
DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d, flush mask 0x%x\n",
mixer[i].hw_lm->idx - LM_0,
mixer[i].mixer_op_mode,
ctl->idx - CTL_0,
......@@ -388,7 +387,7 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work)
DPU_ATRACE_BEGIN("crtc_frame_event");
DRM_DEBUG_KMS("crtc%d event:%u ts:%lld\n", crtc->base.id, fevent->event,
DRM_DEBUG_ATOMIC("crtc%d event:%u ts:%lld\n", crtc->base.id, fevent->event,
ktime_to_ns(fevent->ts));
if (fevent->event & (DPU_ENCODER_FRAME_EVENT_DONE
......@@ -407,9 +406,6 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work)
fevent->event);
}
if (fevent->event & DPU_ENCODER_FRAME_EVENT_DONE)
dpu_core_perf_crtc_update(crtc, 0, false);
if (fevent->event & (DPU_ENCODER_FRAME_EVENT_DONE
| DPU_ENCODER_FRAME_EVENT_ERROR))
frame_done = true;
......@@ -477,6 +473,7 @@ static void dpu_crtc_frame_event_cb(void *data, u32 event)
void dpu_crtc_complete_commit(struct drm_crtc *crtc)
{
trace_dpu_crtc_complete_commit(DRMID(crtc));
dpu_core_perf_crtc_update(crtc, 0, false);
_dpu_crtc_complete_flip(crtc);
}
......@@ -558,7 +555,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
/* stage config flush mask */
ctl->ops.update_pending_flush(ctl, mixer[i].flush_mask);
DPU_DEBUG("lm %d, ctl %d, flush mask 0x%x\n",
DRM_DEBUG_ATOMIC("lm %d, ctl %d, flush mask 0x%x\n",
mixer[i].hw_lm->idx - DSPP_0,
ctl->idx - CTL_0,
mixer[i].flush_mask);
......@@ -572,12 +569,12 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_encoder *encoder;
if (!crtc->state->enable) {
DPU_DEBUG("crtc%d -> enable %d, skip atomic_begin\n",
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, skip atomic_begin\n",
crtc->base.id, crtc->state->enable);
return;
}
DPU_DEBUG("crtc%d\n", crtc->base.id);
DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
_dpu_crtc_setup_lm_bounds(crtc, crtc->state);
......@@ -617,12 +614,12 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
struct dpu_crtc_state *cstate;
if (!crtc->state->enable) {
DPU_DEBUG("crtc%d -> enable %d, skip atomic_flush\n",
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, skip atomic_flush\n",
crtc->base.id, crtc->state->enable);
return;
}
DPU_DEBUG("crtc%d\n", crtc->base.id);
DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
dpu_crtc = to_dpu_crtc(crtc);
cstate = to_dpu_crtc_state(crtc->state);
......@@ -675,7 +672,7 @@ static void dpu_crtc_destroy_state(struct drm_crtc *crtc,
{
struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
DPU_DEBUG("crtc%d\n", crtc->base.id);
DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
__drm_atomic_helper_crtc_destroy_state(state);
......@@ -688,7 +685,7 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc)
int ret, rc = 0;
if (!atomic_read(&dpu_crtc->frame_pending)) {
DPU_DEBUG("no frames pending\n");
DRM_DEBUG_ATOMIC("no frames pending\n");
return 0;
}
......@@ -731,9 +728,9 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) {
/* acquire bandwidth and other resources */
DPU_DEBUG("crtc%d first commit\n", crtc->base.id);
DRM_DEBUG_ATOMIC("crtc%d first commit\n", crtc->base.id);
} else
DPU_DEBUG("crtc%d commit\n", crtc->base.id);
DRM_DEBUG_ATOMIC("crtc%d commit\n", crtc->base.id);
dpu_crtc->play_count++;
......@@ -908,7 +905,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
if (!crtc_state->enable || !crtc_state->active) {
DPU_DEBUG("crtc%d -> enable %d, active %d, skip atomic_check\n",
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
crtc->base.id, crtc_state->enable,
crtc_state->active);
memset(&cstate->new_perf, 0, sizeof(cstate->new_perf));
......@@ -916,7 +913,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
}
mode = &crtc_state->adjusted_mode;
DPU_DEBUG("%s: check\n", dpu_crtc->name);
DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
/* force a full mode set if active state changed */
if (crtc_state->active_changed)
......@@ -1024,7 +1021,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
}
pstates[i].dpu_pstate->stage = z_pos + DPU_STAGE_0;
DPU_DEBUG("%s: zpos %d\n", dpu_crtc->name, z_pos);
DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
}
for (i = 0; i < multirect_count; i++) {
......@@ -1376,6 +1373,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
/* initialize event handling */
spin_lock_init(&dpu_crtc->event_lock);
DPU_DEBUG("%s: successfully initialized crtc\n", dpu_crtc->name);
DRM_DEBUG_KMS("%s: successfully initialized crtc\n", dpu_crtc->name);
return crtc;
}
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*/
......@@ -26,14 +26,15 @@
#include "dpu_crtc.h"
#include "dpu_trace.h"
#include "dpu_core_irq.h"
#include "disp/msm_disp_snapshot.h"
#define DPU_DEBUG_ENC(e, fmt, ...) DPU_DEBUG("enc%d " fmt,\
#define DPU_DEBUG_ENC(e, fmt, ...) DRM_DEBUG_ATOMIC("enc%d " fmt,\
(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
#define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\
(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
#define DPU_DEBUG_PHYS(p, fmt, ...) DPU_DEBUG("enc%d intf%d pp%d " fmt,\
#define DPU_DEBUG_PHYS(p, fmt, ...) DRM_DEBUG_ATOMIC("enc%d intf%d pp%d " fmt,\
(p) ? (p)->parent->base.id : -1, \
(p) ? (p)->intf_idx - INTF_0 : -1, \
(p) ? ((p)->hw_pp ? (p)->hw_pp->idx - PINGPONG_0 : -1) : -1, \
......@@ -253,7 +254,7 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
}
static int dpu_encoder_helper_wait_event_timeout(int32_t drm_id,
int32_t hw_id, struct dpu_encoder_wait_info *info);
u32 irq_idx, struct dpu_encoder_wait_info *info);
int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
enum dpu_intr_idx intr_idx,
......@@ -273,27 +274,27 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
/* return EWOULDBLOCK since we know the wait isn't necessary */
if (phys_enc->enable_state == DPU_ENC_DISABLED) {
DRM_ERROR("encoder is disabled id=%u, intr=%d, hw=%d, irq=%d",
DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
DRM_ERROR("encoder is disabled id=%u, intr=%d, irq=%d",
DRMID(phys_enc->parent), intr_idx,
irq->irq_idx);
return -EWOULDBLOCK;
}
if (irq->irq_idx < 0) {
DRM_DEBUG_KMS("skip irq wait id=%u, intr=%d, hw=%d, irq=%s",
DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
DRM_DEBUG_KMS("skip irq wait id=%u, intr=%d, irq=%s",
DRMID(phys_enc->parent), intr_idx,
irq->name);
return 0;
}
DRM_DEBUG_KMS("id=%u, intr=%d, hw=%d, irq=%d, pp=%d, pending_cnt=%d",
DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
DRM_DEBUG_KMS("id=%u, intr=%d, irq=%d, pp=%d, pending_cnt=%d",
DRMID(phys_enc->parent), intr_idx,
irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
atomic_read(wait_info->atomic_cnt));
ret = dpu_encoder_helper_wait_event_timeout(
DRMID(phys_enc->parent),
irq->hw_idx,
irq->irq_idx,
wait_info);
if (ret <= 0) {
......@@ -303,9 +304,9 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
unsigned long flags;
DRM_DEBUG_KMS("irq not triggered id=%u, intr=%d, "
"hw=%d, irq=%d, pp=%d, atomic_cnt=%d",
"irq=%d, pp=%d, atomic_cnt=%d",
DRMID(phys_enc->parent), intr_idx,
irq->hw_idx, irq->irq_idx,
irq->irq_idx,
phys_enc->hw_pp->idx - PINGPONG_0,
atomic_read(wait_info->atomic_cnt));
local_irq_save(flags);
......@@ -315,16 +316,16 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
} else {
ret = -ETIMEDOUT;
DRM_DEBUG_KMS("irq timeout id=%u, intr=%d, "
"hw=%d, irq=%d, pp=%d, atomic_cnt=%d",
"irq=%d, pp=%d, atomic_cnt=%d",
DRMID(phys_enc->parent), intr_idx,
irq->hw_idx, irq->irq_idx,
irq->irq_idx,
phys_enc->hw_pp->idx - PINGPONG_0,
atomic_read(wait_info->atomic_cnt));
}
} else {
ret = 0;
trace_dpu_enc_irq_wait_success(DRMID(phys_enc->parent),
intr_idx, irq->hw_idx, irq->irq_idx,
intr_idx, irq->irq_idx,
phys_enc->hw_pp->idx - PINGPONG_0,
atomic_read(wait_info->atomic_cnt));
}
......@@ -344,19 +345,9 @@ int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc,
}
irq = &phys_enc->irq[intr_idx];
if (irq->irq_idx >= 0) {
DPU_DEBUG_PHYS(phys_enc,
"skipping already registered irq %s type %d\n",
irq->name, irq->intr_type);
return 0;
}
irq->irq_idx = dpu_core_irq_idx_lookup(phys_enc->dpu_kms,
irq->intr_type, irq->hw_idx);
if (irq->irq_idx < 0) {
DPU_ERROR_PHYS(phys_enc,
"failed to lookup IRQ index for %s type:%d\n",
irq->name, irq->intr_type);
"invalid IRQ index:%d\n", irq->irq_idx);
return -EINVAL;
}
......@@ -370,19 +361,8 @@ int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc,
return ret;
}
ret = dpu_core_irq_enable(phys_enc->dpu_kms, &irq->irq_idx, 1);
if (ret) {
DRM_ERROR("enable failed id=%u, intr=%d, hw=%d, irq=%d",
DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
irq->irq_idx);
dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
irq->irq_idx, &irq->cb);
irq->irq_idx = -EINVAL;
return ret;
}
trace_dpu_enc_irq_register_success(DRMID(phys_enc->parent), intr_idx,
irq->hw_idx, irq->irq_idx);
irq->irq_idx);
return ret;
}
......@@ -397,31 +377,22 @@ int dpu_encoder_helper_unregister_irq(struct dpu_encoder_phys *phys_enc,
/* silently skip irqs that weren't registered */
if (irq->irq_idx < 0) {
DRM_ERROR("duplicate unregister id=%u, intr=%d, hw=%d, irq=%d",
DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
DRM_ERROR("duplicate unregister id=%u, intr=%d, irq=%d",
DRMID(phys_enc->parent), intr_idx,
irq->irq_idx);
return 0;
}
ret = dpu_core_irq_disable(phys_enc->dpu_kms, &irq->irq_idx, 1);
if (ret) {
DRM_ERROR("disable failed id=%u, intr=%d, hw=%d, irq=%d ret=%d",
DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
irq->irq_idx, ret);
}
ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, irq->irq_idx,
&irq->cb);
if (ret) {
DRM_ERROR("unreg cb fail id=%u, intr=%d, hw=%d, irq=%d ret=%d",
DRMID(phys_enc->parent), intr_idx, irq->hw_idx,
DRM_ERROR("unreg cb fail id=%u, intr=%d, irq=%d ret=%d",
DRMID(phys_enc->parent), intr_idx,
irq->irq_idx, ret);
}
trace_dpu_enc_irq_unregister_success(DRMID(phys_enc->parent), intr_idx,
irq->hw_idx, irq->irq_idx);
irq->irq_idx = -EINVAL;
irq->irq_idx);
return 0;
}
......@@ -820,13 +791,13 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc,
/* return if the resource control is already in ON state */
if (dpu_enc->rc_state == DPU_ENC_RC_STATE_ON) {
DRM_DEBUG_KMS("id;%u, sw_event:%d, rc in ON state\n",
DRM_DEBUG_ATOMIC("id;%u, sw_event:%d, rc in ON state\n",
DRMID(drm_enc), sw_event);
mutex_unlock(&dpu_enc->rc_lock);
return 0;
} else if (dpu_enc->rc_state != DPU_ENC_RC_STATE_OFF &&
dpu_enc->rc_state != DPU_ENC_RC_STATE_IDLE) {
DRM_DEBUG_KMS("id;%u, sw_event:%d, rc in state %d\n",
DRM_DEBUG_ATOMIC("id;%u, sw_event:%d, rc in state %d\n",
DRMID(drm_enc), sw_event,
dpu_enc->rc_state);
mutex_unlock(&dpu_enc->rc_lock);
......@@ -1336,6 +1307,11 @@ static void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
DPU_ATRACE_BEGIN("encoder_underrun_callback");
atomic_inc(&phy_enc->underrun_cnt);
/* trigger dump only on the first underrun */
if (atomic_read(&phy_enc->underrun_cnt) == 1)
msm_disp_snapshot_state(drm_enc->dev);
trace_dpu_enc_underrun_cb(DRMID(drm_enc),
atomic_read(&phy_enc->underrun_cnt));
DPU_ATRACE_END("encoder_underrun_callback");
......@@ -1453,11 +1429,6 @@ static void dpu_encoder_off_work(struct work_struct *work)
struct dpu_encoder_virt *dpu_enc = container_of(work,
struct dpu_encoder_virt, delayed_off_work.work);
if (!dpu_enc) {
DPU_ERROR("invalid dpu encoder\n");
return;
}
dpu_encoder_resource_control(&dpu_enc->base,
DPU_ENC_RC_EVENT_ENTER_IDLE);
......@@ -1537,7 +1508,7 @@ void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc)
static int dpu_encoder_helper_wait_event_timeout(
int32_t drm_id,
int32_t hw_id,
u32 irq_idx,
struct dpu_encoder_wait_info *info)
{
int rc = 0;
......@@ -1550,7 +1521,7 @@ static int dpu_encoder_helper_wait_event_timeout(
atomic_read(info->atomic_cnt) == 0, jiffies);
time = ktime_to_ms(ktime_get());
trace_dpu_enc_wait_event_timeout(drm_id, hw_id, rc, time,
trace_dpu_enc_wait_event_timeout(drm_id, irq_idx, rc, time,
expected_time,
atomic_read(info->atomic_cnt));
/* If we timed out, counter is valid and time is less, wait again */
......@@ -1565,19 +1536,23 @@ static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc)
struct dpu_encoder_virt *dpu_enc;
struct dpu_hw_ctl *ctl;
int rc;
struct drm_encoder *drm_enc;
dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
ctl = phys_enc->hw_ctl;
drm_enc = phys_enc->parent;
if (!ctl->ops.reset)
return;
DRM_DEBUG_KMS("id:%u ctl %d reset\n", DRMID(phys_enc->parent),
DRM_DEBUG_KMS("id:%u ctl %d reset\n", DRMID(drm_enc),
ctl->idx);
rc = ctl->ops.reset(ctl);
if (rc)
if (rc) {
DPU_ERROR_ENC(dpu_enc, "ctl %d reset failure\n", ctl->idx);
msm_disp_snapshot_state(drm_enc->dev);
}
phys_enc->enable_state = DPU_ENC_ENABLED;
}
......@@ -1797,11 +1772,6 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work)
struct dpu_encoder_virt, vsync_event_work);
ktime_t wakeup_time;
if (!dpu_enc) {
DPU_ERROR("invalid dpu encoder\n");
return;
}
if (dpu_encoder_vsync_time(&dpu_enc->base, &wakeup_time))
return;
......@@ -2068,8 +2038,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
phys_params.parent_ops = &dpu_encoder_parent_ops;
phys_params.enc_spinlock = &dpu_enc->enc_spinlock;
DPU_DEBUG("\n");
switch (disp_info->intf_type) {
case DRM_MODE_ENCODER_DSI:
intf_type = INTF_DSI;
......
......@@ -165,18 +165,14 @@ enum dpu_intr_idx {
/**
* dpu_encoder_irq - tracking structure for interrupts
* @name: string name of interrupt
* @intr_type: Encoder interrupt type
* @intr_idx: Encoder interrupt enumeration
* @hw_idx: HW Block ID
* @irq_idx: IRQ interface lookup index from DPU IRQ framework
* will be -EINVAL if IRQ is not registered
* @irq_cb: interrupt callback
*/
struct dpu_encoder_irq {
const char *name;
enum dpu_intr_type intr_type;
enum dpu_intr_idx intr_idx;
int hw_idx;
int irq_idx;
struct dpu_irq_callback cb;
};
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2018, 2020-2021 The Linux Foundation. All rights reserved.
*/
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
......@@ -11,6 +11,7 @@
#include "dpu_core_irq.h"
#include "dpu_formats.h"
#include "dpu_trace.h"
#include "disp/msm_disp_snapshot.h"
#define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
(e) && (e)->base.parent ? \
......@@ -143,28 +144,6 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)
phys_enc);
}
static void _dpu_encoder_phys_cmd_setup_irq_hw_idx(
struct dpu_encoder_phys *phys_enc)
{
struct dpu_encoder_irq *irq;
irq = &phys_enc->irq[INTR_IDX_CTL_START];
irq->hw_idx = phys_enc->hw_ctl->idx;
irq->irq_idx = -EINVAL;
irq = &phys_enc->irq[INTR_IDX_PINGPONG];
irq->hw_idx = phys_enc->hw_pp->idx;
irq->irq_idx = -EINVAL;
irq = &phys_enc->irq[INTR_IDX_RDPTR];
irq->hw_idx = phys_enc->hw_pp->idx;
irq->irq_idx = -EINVAL;
irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
irq->hw_idx = phys_enc->intf_idx;
irq->irq_idx = -EINVAL;
}
static void dpu_encoder_phys_cmd_mode_set(
struct dpu_encoder_phys *phys_enc,
struct drm_display_mode *mode,
......@@ -172,6 +151,7 @@ static void dpu_encoder_phys_cmd_mode_set(
{
struct dpu_encoder_phys_cmd *cmd_enc =
to_dpu_encoder_phys_cmd(phys_enc);
struct dpu_encoder_irq *irq;
if (!mode || !adj_mode) {
DPU_ERROR("invalid args\n");
......@@ -181,7 +161,17 @@ static void dpu_encoder_phys_cmd_mode_set(
DPU_DEBUG_CMDENC(cmd_enc, "caching mode:\n");
drm_mode_debug_printmodeline(adj_mode);
_dpu_encoder_phys_cmd_setup_irq_hw_idx(phys_enc);
irq = &phys_enc->irq[INTR_IDX_CTL_START];
irq->irq_idx = phys_enc->hw_ctl->caps->intr_start;
irq = &phys_enc->irq[INTR_IDX_PINGPONG];
irq->irq_idx = phys_enc->hw_pp->caps->intr_done;
irq = &phys_enc->irq[INTR_IDX_RDPTR];
irq->irq_idx = phys_enc->hw_pp->caps->intr_rdptr;
irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
irq->irq_idx = phys_enc->hw_intf->cap->intr_underrun;
}
static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
......@@ -191,10 +181,13 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
to_dpu_encoder_phys_cmd(phys_enc);
u32 frame_event = DPU_ENCODER_FRAME_EVENT_ERROR;
bool do_log = false;
struct drm_encoder *drm_enc;
if (!phys_enc->hw_pp)
return -EINVAL;
drm_enc = phys_enc->parent;
cmd_enc->pp_timeout_report_cnt++;
if (cmd_enc->pp_timeout_report_cnt == PP_TIMEOUT_MAX_TRIALS) {
frame_event |= DPU_ENCODER_FRAME_EVENT_PANEL_DEAD;
......@@ -203,7 +196,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
do_log = true;
}
trace_dpu_enc_phys_cmd_pdone_timeout(DRMID(phys_enc->parent),
trace_dpu_enc_phys_cmd_pdone_timeout(DRMID(drm_enc),
phys_enc->hw_pp->idx - PINGPONG_0,
cmd_enc->pp_timeout_report_cnt,
atomic_read(&phys_enc->pending_kickoff_cnt),
......@@ -212,12 +205,12 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
/* to avoid flooding, only log first time, and "dead" time */
if (do_log) {
DRM_ERROR("id:%d pp:%d kickoff timeout %d cnt %d koff_cnt %d\n",
DRMID(phys_enc->parent),
DRMID(drm_enc),
phys_enc->hw_pp->idx - PINGPONG_0,
phys_enc->hw_ctl->idx - CTL_0,
cmd_enc->pp_timeout_report_cnt,
atomic_read(&phys_enc->pending_kickoff_cnt));
msm_disp_snapshot_state(drm_enc->dev);
dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR);
}
......@@ -228,7 +221,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
if (phys_enc->parent_ops->handle_frame_done)
phys_enc->parent_ops->handle_frame_done(
phys_enc->parent, phys_enc, frame_event);
drm_enc, phys_enc, frame_event);
return -ETIMEDOUT;
}
......@@ -685,10 +678,6 @@ static int dpu_encoder_phys_cmd_wait_for_tx_complete(
static int dpu_encoder_phys_cmd_wait_for_commit_done(
struct dpu_encoder_phys *phys_enc)
{
struct dpu_encoder_phys_cmd *cmd_enc;
cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
/* only required for master controller */
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
return 0;
......@@ -795,31 +784,26 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
irq = &phys_enc->irq[i];
INIT_LIST_HEAD(&irq->cb.list);
irq->irq_idx = -EINVAL;
irq->hw_idx = -EINVAL;
irq->cb.arg = phys_enc;
}
irq = &phys_enc->irq[INTR_IDX_CTL_START];
irq->name = "ctl_start";
irq->intr_type = DPU_IRQ_TYPE_CTL_START;
irq->intr_idx = INTR_IDX_CTL_START;
irq->cb.func = dpu_encoder_phys_cmd_ctl_start_irq;
irq = &phys_enc->irq[INTR_IDX_PINGPONG];
irq->name = "pp_done";
irq->intr_type = DPU_IRQ_TYPE_PING_PONG_COMP;
irq->intr_idx = INTR_IDX_PINGPONG;
irq->cb.func = dpu_encoder_phys_cmd_pp_tx_done_irq;
irq = &phys_enc->irq[INTR_IDX_RDPTR];
irq->name = "pp_rd_ptr";
irq->intr_type = DPU_IRQ_TYPE_PING_PONG_RD_PTR;
irq->intr_idx = INTR_IDX_RDPTR;
irq->cb.func = dpu_encoder_phys_cmd_pp_rd_ptr_irq;
irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
irq->name = "underrun";
irq->intr_type = DPU_IRQ_TYPE_INTF_UNDER_RUN;
irq->intr_idx = INTR_IDX_UNDERRUN;
irq->cb.func = dpu_encoder_phys_cmd_underrun_irq;
......
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, 2020-2021 The Linux Foundation. All rights reserved.
*/
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
......@@ -9,6 +9,7 @@
#include "dpu_core_irq.h"
#include "dpu_formats.h"
#include "dpu_trace.h"
#include "disp/msm_disp_snapshot.h"
#define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
(e) && (e)->parent ? \
......@@ -284,7 +285,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
intf_cfg.stream_sel = 0; /* Don't care value for video mode */
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
if (phys_enc->hw_pp->merge_3d)
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->id;
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf,
......@@ -298,11 +299,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
true,
phys_enc->hw_pp->idx);
if (phys_enc->hw_pp->merge_3d) {
struct dpu_hw_merge_3d *merge_3d = to_dpu_hw_merge_3d(phys_enc->hw_pp->merge_3d);
merge_3d->ops.setup_3d_mode(merge_3d, intf_cfg.mode_3d);
}
if (phys_enc->hw_pp->merge_3d)
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, intf_cfg.mode_3d);
spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
......@@ -363,38 +361,24 @@ static bool dpu_encoder_phys_vid_needs_single_flush(
return phys_enc->split_role != ENC_ROLE_SOLO;
}
static void _dpu_encoder_phys_vid_setup_irq_hw_idx(
struct dpu_encoder_phys *phys_enc)
{
struct dpu_encoder_irq *irq;
/*
* Initialize irq->hw_idx only when irq is not registered.
* Prevent invalidating irq->irq_idx as modeset may be
* called many times during dfps.
*/
irq = &phys_enc->irq[INTR_IDX_VSYNC];
if (irq->irq_idx < 0)
irq->hw_idx = phys_enc->intf_idx;
irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
if (irq->irq_idx < 0)
irq->hw_idx = phys_enc->intf_idx;
}
static void dpu_encoder_phys_vid_mode_set(
struct dpu_encoder_phys *phys_enc,
struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
{
struct dpu_encoder_irq *irq;
if (adj_mode) {
phys_enc->cached_mode = *adj_mode;
drm_mode_debug_printmodeline(adj_mode);
DPU_DEBUG_VIDENC(phys_enc, "caching mode:\n");
}
_dpu_encoder_phys_vid_setup_irq_hw_idx(phys_enc);
irq = &phys_enc->irq[INTR_IDX_VSYNC];
irq->irq_idx = phys_enc->hw_intf->cap->intr_vsync;
irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
irq->irq_idx = phys_enc->hw_intf->cap->intr_underrun;
}
static int dpu_encoder_phys_vid_control_vblank_irq(
......@@ -416,7 +400,7 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
goto end;
}
DRM_DEBUG_KMS("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
atomic_read(&phys_enc->vblank_refcount));
if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
......@@ -461,13 +445,14 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d)
ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->id);
ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx);
skip_flush:
DPU_DEBUG_VIDENC(phys_enc,
"update pending flush ctl %d intf %d\n",
ctl->idx - CTL_0, phys_enc->hw_intf->idx);
atomic_set(&phys_enc->underrun_cnt, 0);
/* ctl_flush & timing engine enable will be triggered by framework */
if (phys_enc->enable_state == DPU_ENC_DISABLED)
......@@ -537,6 +522,9 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
{
struct dpu_hw_ctl *ctl;
int rc;
struct drm_encoder *drm_enc;
drm_enc = phys_enc->parent;
ctl = phys_enc->hw_ctl;
if (!ctl->ops.wait_reset_status)
......@@ -550,6 +538,7 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff(
if (rc) {
DPU_ERROR_VIDENC(phys_enc, "ctl %d reset failure: %d\n",
ctl->idx, rc);
msm_disp_snapshot_state(drm_enc->dev);
dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_VSYNC);
}
}
......@@ -636,7 +625,7 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
if (enable) {
ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true);
if (ret)
if (WARN_ON(ret))
return;
dpu_encoder_helper_register_irq(phys_enc, INTR_IDX_UNDERRUN);
......@@ -738,19 +727,16 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
irq = &phys_enc->irq[i];
INIT_LIST_HEAD(&irq->cb.list);
irq->irq_idx = -EINVAL;
irq->hw_idx = -EINVAL;
irq->cb.arg = phys_enc;
}
irq = &phys_enc->irq[INTR_IDX_VSYNC];
irq->name = "vsync_irq";
irq->intr_type = DPU_IRQ_TYPE_INTF_VSYNC;
irq->intr_idx = INTR_IDX_VSYNC;
irq->cb.func = dpu_encoder_phys_vid_vblank_irq;
irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
irq->name = "underrun";
irq->intr_type = DPU_IRQ_TYPE_INTF_UNDER_RUN;
irq->intr_idx = INTR_IDX_UNDERRUN;
irq->cb.func = dpu_encoder_phys_vid_underrun_irq;
......
......@@ -992,7 +992,7 @@ const struct dpu_format *dpu_get_dpu_format_ext(
* Currently only support exactly zero or one modifier.
* All planes use the same modifier.
*/
DPU_DEBUG("plane format modifier 0x%llX\n", modifier);
DRM_DEBUG_ATOMIC("plane format modifier 0x%llX\n", modifier);
switch (modifier) {
case 0:
......@@ -1002,7 +1002,7 @@ const struct dpu_format *dpu_get_dpu_format_ext(
case DRM_FORMAT_MOD_QCOM_COMPRESSED:
map = dpu_format_map_ubwc;
map_size = ARRAY_SIZE(dpu_format_map_ubwc);
DPU_DEBUG("found fmt: %4.4s DRM_FORMAT_MOD_QCOM_COMPRESSED\n",
DRM_DEBUG_ATOMIC("found fmt: %4.4s DRM_FORMAT_MOD_QCOM_COMPRESSED\n",
(char *)&format);
break;
default:
......@@ -1021,7 +1021,7 @@ const struct dpu_format *dpu_get_dpu_format_ext(
DPU_ERROR("unsupported fmt: %4.4s modifier 0x%llX\n",
(char *)&format, modifier);
else
DPU_DEBUG("fmt %4.4s mod 0x%llX ubwc %d yuv %d\n",
DRM_DEBUG_ATOMIC("fmt %4.4s mod 0x%llX ubwc %d yuv %d\n",
(char *)&format, modifier,
DPU_FORMAT_IS_UBWC(fmt),
DPU_FORMAT_IS_YUV(fmt));
......
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*/
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
#include <linux/mutex.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include "dpu_hw_mdss.h"
#include "dpu_hw_blk.h"
/* Serialization lock for dpu_hw_blk_list */
static DEFINE_MUTEX(dpu_hw_blk_lock);
/* List of all hw block objects */
static LIST_HEAD(dpu_hw_blk_list);
/**
* dpu_hw_blk_init - initialize hw block object
* @hw_blk: pointer to hw block object
* @type: hw block type - enum dpu_hw_blk_type
* @id: instance id of the hw block
* @ops: Pointer to block operations
*/
void dpu_hw_blk_init(struct dpu_hw_blk *hw_blk, u32 type, int id,
struct dpu_hw_blk_ops *ops)
{
INIT_LIST_HEAD(&hw_blk->list);
hw_blk->type = type;
hw_blk->id = id;
atomic_set(&hw_blk->refcount, 0);
if (ops)
hw_blk->ops = *ops;
mutex_lock(&dpu_hw_blk_lock);
list_add(&hw_blk->list, &dpu_hw_blk_list);
mutex_unlock(&dpu_hw_blk_lock);
}
/**
* dpu_hw_blk_destroy - destroy hw block object.
* @hw_blk: pointer to hw block object
* return: none
*/
void dpu_hw_blk_destroy(struct dpu_hw_blk *hw_blk)
{
if (!hw_blk) {
pr_err("invalid parameters\n");
return;
}
if (atomic_read(&hw_blk->refcount))
pr_err("hw_blk:%d.%d invalid refcount\n", hw_blk->type,
hw_blk->id);
mutex_lock(&dpu_hw_blk_lock);
list_del(&hw_blk->list);
mutex_unlock(&dpu_hw_blk_lock);
}
/**
* dpu_hw_blk_get - get hw_blk from free pool
* @hw_blk: if specified, increment reference count only
* @type: if hw_blk is not specified, allocate the next available of this type
* @id: if specified (>= 0), allocate the given instance of the above type
* return: pointer to hw block object
*/
struct dpu_hw_blk *dpu_hw_blk_get(struct dpu_hw_blk *hw_blk, u32 type, int id)
{
struct dpu_hw_blk *curr;
int rc, refcount;
if (!hw_blk) {
mutex_lock(&dpu_hw_blk_lock);
list_for_each_entry(curr, &dpu_hw_blk_list, list) {
if ((curr->type != type) ||
(id >= 0 && curr->id != id) ||
(id < 0 &&
atomic_read(&curr->refcount)))
continue;
hw_blk = curr;
break;
}
mutex_unlock(&dpu_hw_blk_lock);
}
if (!hw_blk) {
pr_debug("no hw_blk:%d\n", type);
return NULL;
}
refcount = atomic_inc_return(&hw_blk->refcount);
if (refcount == 1 && hw_blk->ops.start) {
rc = hw_blk->ops.start(hw_blk);
if (rc) {
pr_err("failed to start hw_blk:%d rc:%d\n", type, rc);
goto error_start;
}
}
pr_debug("hw_blk:%d.%d refcount:%d\n", hw_blk->type,
hw_blk->id, refcount);
return hw_blk;
error_start:
dpu_hw_blk_put(hw_blk);
return ERR_PTR(rc);
}
/**
* dpu_hw_blk_put - put hw_blk to free pool if decremented refcount is zero
* @hw_blk: hw block to be freed
*/
void dpu_hw_blk_put(struct dpu_hw_blk *hw_blk)
{
if (!hw_blk) {
pr_err("invalid parameters\n");
return;
}
pr_debug("hw_blk:%d.%d refcount:%d\n", hw_blk->type, hw_blk->id,
atomic_read(&hw_blk->refcount));
if (!atomic_read(&hw_blk->refcount)) {
pr_err("hw_blk:%d.%d invalid put\n", hw_blk->type, hw_blk->id);
return;
}
if (atomic_dec_return(&hw_blk->refcount))
return;
if (hw_blk->ops.stop)
hw_blk->ops.stop(hw_blk);
}
......@@ -7,19 +7,9 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/atomic.h>
struct dpu_hw_blk;
/**
* struct dpu_hw_blk_ops - common hardware block operations
* @start: start operation on first get
* @stop: stop operation on last put
*/
struct dpu_hw_blk_ops {
int (*start)(struct dpu_hw_blk *);
void (*stop)(struct dpu_hw_blk *);
};
/**
* struct dpu_hw_blk - definition of hardware block object
......@@ -29,17 +19,7 @@ struct dpu_hw_blk_ops {
* @refcount: reference/usage count
*/
struct dpu_hw_blk {
struct list_head list;
u32 type;
int id;
atomic_t refcount;
struct dpu_hw_blk_ops ops;
/* opaque */
};
void dpu_hw_blk_init(struct dpu_hw_blk *hw_blk, u32 type, int id,
struct dpu_hw_blk_ops *ops);
void dpu_hw_blk_destroy(struct dpu_hw_blk *hw_blk);
struct dpu_hw_blk *dpu_hw_blk_get(struct dpu_hw_blk *hw_blk, u32 type, int id);
void dpu_hw_blk_put(struct dpu_hw_blk *hw_blk);
#endif /*_DPU_HW_BLK_H */
......@@ -589,8 +589,6 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
};
static struct dpu_hw_blk_ops dpu_hw_ops;
struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx,
void __iomem *addr,
const struct dpu_mdss_cfg *m)
......@@ -615,14 +613,10 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx,
c->mixer_count = m->mixer_count;
c->mixer_hw_caps = m->mixer;
dpu_hw_blk_init(&c->base, DPU_HW_BLK_CTL, idx, &dpu_hw_ops);
return c;
}
void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx)
{
if (ctx)
dpu_hw_blk_destroy(&ctx->base);
kfree(ctx);
}
This diff is collapsed.
......@@ -299,8 +299,6 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops,
ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk;
}
static struct dpu_hw_blk_ops dpu_hw_ops;
struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx,
void __iomem *addr,
const struct dpu_mdss_cfg *m)
......@@ -327,15 +325,11 @@ struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx,
c->mdss = m;
_setup_intf_ops(&c->ops, c->cap->features);
dpu_hw_blk_init(&c->base, DPU_HW_BLK_INTF, idx, &dpu_hw_ops);
return c;
}
void dpu_hw_intf_destroy(struct dpu_hw_intf *intf)
{
if (intf)
dpu_hw_blk_destroy(&intf->base);
kfree(intf);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment