Commit afd6dbfd authored by Dmitry Baryshkov's avatar Dmitry Baryshkov

Merge branch 'msm-next-lumag' into HEAD

Merge display-related changes targeting Qualcomm DRM MSM driver.

Notable changes:

DPU, DSI, MDSS:
- Support for SM8350, SM8450 SM8550 and SC8280XP platform

Core:
- Added bindings for SM8150 (driver support already present)

DPU:
- Partial support for DSC on SM8150 and SM8250
- Fixed color transformation matrix being lost on suspend/resume

DP:
- Support for DP on SDM845 and SC8280XP platforms
- HPD fixes
- Support for limiting DP link rate via DT property, this enables
  support for HBR3 rates.

DSI:
- Validate display modes according to the DSI OPP table
- DSI PHY support for the SM6375 platform
- Fixed byte intf clock selection for 14nm PHYs

MDP5:
- Schema conversion to YAML

Misc fixes as usual
Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
parents 33f868db 82461ab8
......@@ -21,6 +21,9 @@ properties:
- qcom,sc7280-edp
- qcom,sc8180x-dp
- qcom,sc8180x-edp
- qcom,sc8280xp-dp
- qcom,sc8280xp-edp
- qcom,sdm845-dp
- qcom,sm8350-dp
reg:
......@@ -81,6 +84,7 @@ properties:
data-lanes:
$ref: /schemas/types.yaml#/definitions/uint32-array
deprecated: true
minItems: 1
maxItems: 4
items:
......@@ -102,8 +106,28 @@ properties:
description: Input endpoint of the controller
port@1:
$ref: /schemas/graph.yaml#/properties/port
$ref: /schemas/graph.yaml#/$defs/port-base
description: Output endpoint of the controller
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
data-lanes:
minItems: 1
maxItems: 4
items:
enum: [ 0, 1, 2, 3 ]
link-frequencies:
minItems: 1
maxItems: 4
items:
enum: [ 1620000000, 2700000000, 5400000000, 8100000000 ]
required:
- port@0
- port@1
required:
- compatible
......@@ -127,11 +151,10 @@ allOf:
enum:
- qcom,sc7280-edp
- qcom,sc8180x-edp
- qcom,sc8280xp-edp
then:
properties:
"#sound-dai-cells": false
reg:
maxItems: 4
else:
properties:
aux-bus: false
......@@ -193,6 +216,8 @@ examples:
reg = <1>;
endpoint {
remote-endpoint = <&typec>;
data-lanes = <0 1>;
link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
};
};
};
......
......@@ -13,7 +13,15 @@ maintainers:
description: |
Common properties for QCom DPU display controller.
# Do not select this by default, otherwise it is also selected for all
# display-controller@ nodes
select:
false
properties:
$nodename:
pattern: '^display-controller@[0-9a-f]+$'
interrupts:
maxItems: 1
......@@ -40,10 +48,6 @@ properties:
- port@0
required:
- compatible
- reg
- reg-names
- clocks
- interrupts
- power-domains
- operating-points-v2
......
......@@ -32,7 +32,7 @@ properties:
- description: Display byte clock
- description: Display byte interface clock
- description: Display pixel clock
- description: Display escape clock
- description: Display core clock
- description: Display AHB clock
- description: Display AXI clock
......@@ -127,6 +127,18 @@ properties:
- port@0
- port@1
vdd-supply:
description:
VDD regulator
vddio-supply:
description:
VDD-IO regulator
vdda-supply:
description:
VDDA regulator
required:
- compatible
- reg
......@@ -137,8 +149,6 @@ required:
- phys
- assigned-clocks
- assigned-clock-parents
- power-domains
- operating-points-v2
- ports
additionalProperties: false
......
......@@ -69,7 +69,6 @@ required:
- compatible
- reg
- reg-names
- vdds-supply
unevaluatedProperties: false
......
......@@ -39,7 +39,6 @@ required:
- compatible
- reg
- reg-names
- vcca-supply
unevaluatedProperties: false
......
......@@ -16,6 +16,7 @@ properties:
compatible:
enum:
- qcom,dsi-phy-28nm-hpm
- qcom,dsi-phy-28nm-hpm-fam-b
- qcom,dsi-phy-28nm-lp
- qcom,dsi-phy-28nm-8960
......@@ -34,6 +35,10 @@ properties:
vddio-supply:
description: Phandle to vdd-io regulator device node.
qcom,dsi-phy-regulator-ldo-mode:
type: boolean
description: Indicates if the LDO mode PHY regulator is wanted.
required:
- compatible
- reg
......
......@@ -18,6 +18,10 @@ properties:
- qcom,dsi-phy-7nm
- qcom,dsi-phy-7nm-8150
- qcom,sc7280-dsi-phy-7nm
- qcom,sm6375-dsi-phy-7nm
- qcom,sm8350-dsi-phy-5nm
- qcom,sm8450-dsi-phy-5nm
- qcom,sm8550-dsi-phy-4nm
reg:
items:
......@@ -44,7 +48,6 @@ required:
- compatible
- reg
- reg-names
- vdds-supply
unevaluatedProperties: false
......
......@@ -4,14 +4,13 @@
$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
title: Qualcomm Display DSI PHY Common Properties
maintainers:
- Krishna Manikandan <quic_mkrishn@quicinc.com>
description: |
This defines the DSI PHY dt properties which are common for all
dsi phy versions.
description:
Common properties for Qualcomm Display DSI PHY.
properties:
"#clock-cells":
......
......@@ -149,6 +149,8 @@ allOf:
description: GPU 3D engine clock
- const: rbbmtimer
description: GPU RBBM Timer for Adreno 5xx series
- const: rbcpr
description: GPU RB Core Power Reduction clock
minItems: 2
maxItems: 7
......
Qualcomm adreno/snapdragon MDP5 display controller
Description:
This is the bindings documentation for the MDP5 display
controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and MSM8996.
MDP5:
Required properties:
- compatible:
* "qcom,mdp5" - MDP5
- reg: Physical base address and length of the controller's registers.
- reg-names: The names of register regions. The following regions are required:
* "mdp_phys"
- interrupts: Interrupt line from MDP5 to MDSS interrupt controller.
- clocks: device clocks. See ../clocks/clock-bindings.txt for details.
- clock-names: the following clocks are required.
- * "bus"
- * "iface"
- * "core"
- * "vsync"
- ports: contains the list of output ports from MDP. These connect to interfaces
that are external to the MDP hardware, such as HDMI, DSI, EDP etc (LVDS is a
special case since it is a part of the MDP block itself).
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
The availability of output ports can vary across SoC revisions:
For MSM8974 and APQ8084:
Port 0 -> MDP_INTF0 (eDP)
Port 1 -> MDP_INTF1 (DSI1)
Port 2 -> MDP_INTF2 (DSI2)
Port 3 -> MDP_INTF3 (HDMI)
For MSM8916:
Port 0 -> MDP_INTF1 (DSI1)
For MSM8994 and MSM8996:
Port 0 -> MDP_INTF1 (DSI1)
Port 1 -> MDP_INTF2 (DSI2)
Port 2 -> MDP_INTF3 (HDMI)
Optional properties:
- clock-names: the following clocks are optional:
* "lut"
* "tbu"
* "tbu_rt"
Example:
/ {
...
mdss: mdss@1a00000 {
compatible = "qcom,mdss";
reg = <0x1a00000 0x1000>,
<0x1ac8000 0x3000>;
reg-names = "mdss_phys", "vbif_phys";
power-domains = <&gcc MDSS_GDSC>;
clocks = <&gcc GCC_MDSS_AHB_CLK>,
<&gcc GCC_MDSS_AXI_CLK>,
<&gcc GCC_MDSS_VSYNC_CLK>;
clock-names = "iface",
"bus",
"vsync"
interrupts = <0 72 0>;
interrupt-controller;
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
mdp: mdp@1a01000 {
compatible = "qcom,mdp5";
reg = <0x1a01000 0x90000>;
reg-names = "mdp_phys";
interrupt-parent = <&mdss>;
interrupts = <0 0>;
clocks = <&gcc GCC_MDSS_AHB_CLK>,
<&gcc GCC_MDSS_AXI_CLK>,
<&gcc GCC_MDSS_MDP_CLK>,
<&gcc GCC_MDSS_VSYNC_CLK>;
clock-names = "iface",
"bus",
"core",
"vsync";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
mdp5_intf1_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
};
};
dsi0: dsi@1a98000 {
...
ports {
...
port@0 {
reg = <0>;
dsi0_in: endpoint {
remote-endpoint = <&mdp5_intf1_out>;
};
};
...
};
...
};
dsi_phy0: dsi-phy@1a98300 {
...
};
};
};
......@@ -15,7 +15,15 @@ description:
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
sub-blocks like DPU display controller, DSI and DP interfaces etc.
# Do not select this by default, otherwise it is also selected for qcom,mdss
# devices.
select:
false
properties:
$nodename:
pattern: "^display-subsystem@[0-9a-f]+$"
reg:
maxItems: 1
......@@ -70,7 +78,6 @@ properties:
- description: MDSS_CORE reset
required:
- compatible
- reg
- reg-names
- power-domains
......
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,mdp5.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Adreno/Snapdragon Mobile Display controller (MDP5)
description:
MDP5 display controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994
and MSM8996.
maintainers:
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
- Rob Clark <robdclark@gmail.com>
properties:
compatible:
oneOf:
- const: qcom,mdp5
deprecated: true
- items:
- enum:
- qcom,apq8084-mdp5
- qcom,msm8916-mdp5
- qcom,msm8917-mdp5
- qcom,msm8953-mdp5
- qcom,msm8974-mdp5
- qcom,msm8976-mdp5
- qcom,msm8994-mdp5
- qcom,msm8996-mdp5
- qcom,sdm630-mdp5
- qcom,sdm660-mdp5
- const: qcom,mdp5
$nodename:
pattern: '^display-controller@[0-9a-f]+$'
reg:
maxItems: 1
reg-names:
items:
- const: mdp_phys
interrupts:
maxItems: 1
clocks:
minItems: 4
maxItems: 7
clock-names:
oneOf:
- minItems: 4
items:
- const: iface
- const: bus
- const: core
- const: vsync
- const: lut
- const: tbu
- const: tbu_rt
#MSM8996 has additional iommu clock
- items:
- const: iface
- const: bus
- const: core
- const: iommu
- const: vsync
interconnects:
minItems: 1
items:
- description: Interconnect path from mdp0 (or a single mdp) port to the data bus
- description: Interconnect path from mdp1 port to the data bus
- description: Interconnect path from rotator port to the data bus
interconnect-names:
minItems: 1
items:
- const: mdp0-mem
- const: mdp1-mem
- const: rotator-mem
iommus:
items:
- description: apps SMMU with the Stream-ID mask for Hard-Fail port0
power-domains:
maxItems: 1
operating-points-v2: true
opp-table:
type: object
ports:
$ref: /schemas/graph.yaml#/properties/ports
description: >
Contains the list of output ports from DPU device. These ports
connect to interfaces that are external to the DPU hardware,
such as DSI, DP etc. MDP5 devices support up to 4 ports:
one or two DSI ports, HDMI and eDP.
patternProperties:
"^port@[0-3]+$":
$ref: /schemas/graph.yaml#/properties/port
# at least one port is required
required:
- port@0
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
- ports
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-msm8916.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
display-controller@1a01000 {
compatible = "qcom,mdp5";
reg = <0x1a01000 0x90000>;
reg-names = "mdp_phys";
interrupt-parent = <&mdss>;
interrupts = <0>;
clocks = <&gcc GCC_MDSS_AHB_CLK>,
<&gcc GCC_MDSS_AXI_CLK>,
<&gcc GCC_MDSS_MDP_CLK>,
<&gcc GCC_MDSS_VSYNC_CLK>;
clock-names = "iface",
"bus",
"core",
"vsync";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
endpoint {
remote-endpoint = <&dsi0_in>;
};
};
};
};
...
......@@ -15,6 +15,9 @@ description:
encapsulates sub-blocks like MDP5, DSI, HDMI, eDP, etc.
properties:
$nodename:
pattern: "^display-subsystem@[0-9a-f]+$"
compatible:
enum:
- qcom,mdss
......@@ -44,18 +47,30 @@ properties:
The MDSS power domain provided by GCC
clocks:
minItems: 1
items:
- description: Display abh clock
- description: Display axi clock
- description: Display vsync clock
oneOf:
- minItems: 3
items:
- description: Display abh clock
- description: Display axi clock
- description: Display vsync clock
- description: Display core clock
- minItems: 1
items:
- description: Display abh clock
- description: Display core clock
clock-names:
minItems: 1
items:
- const: iface
- const: bus
- const: vsync
oneOf:
- minItems: 3
items:
- const: iface
- const: bus
- const: vsync
- const: core
- minItems: 1
items:
- const: iface
- const: core
"#address-cells":
const: 1
......@@ -84,11 +99,12 @@ required:
- ranges
patternProperties:
"^mdp@[1-9a-f][0-9a-f]*$":
"^display-controller@[1-9a-f][0-9a-f]*$":
type: object
properties:
compatible:
const: qcom,mdp5
contains:
const: qcom,mdp5
"^dsi@[1-9a-f][0-9a-f]*$":
type: object
......@@ -107,12 +123,6 @@ patternProperties:
- qcom,dsi-phy-20nm
- qcom,dsi-phy-28nm-hpm
- qcom,dsi-phy-28nm-lp
"^hdmi-phy@[1-9a-f][0-9a-f]*$":
type: object
properties:
compatible:
enum:
- qcom,hdmi-phy-8084
- qcom,hdmi-phy-8660
- qcom,hdmi-phy-8960
......@@ -137,7 +147,7 @@ examples:
- |
#include <dt-bindings/clock/qcom,gcc-msm8916.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
mdss@1a00000 {
display-subsystem@1a00000 {
compatible = "qcom,mdss";
reg = <0x1a00000 0x1000>,
<0x1ac8000 0x3000>;
......@@ -161,8 +171,8 @@ examples:
#size-cells = <1>;
ranges;
mdp@1a01000 {
compatible = "qcom,mdp5";
display-controller@1a01000 {
compatible = "qcom,msm8916-mdp5", "qcom,mdp5";
reg = <0x01a01000 0x89000>;
reg-names = "mdp_phys";
......
......@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,msm8998-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DPU dt properties for MSM8998 target
title: Qualcomm Display DPU on MSM8998
maintainers:
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
......@@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
items:
- const: qcom,msm8998-dpu
const: qcom,msm8998-dpu
reg:
items:
......@@ -46,6 +45,13 @@ properties:
- const: core
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
......
......@@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
items:
- const: qcom,msm8998-mdss
const: qcom,msm8998-mdss
clocks:
items:
......@@ -55,6 +54,9 @@ patternProperties:
compatible:
const: qcom,dsi-phy-10nm-8998
required:
- compatible
unevaluatedProperties: false
examples:
......
......@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DPU dt properties for QCM2290 target
title: Qualcomm Display DPU on QCM2290
maintainers:
- Loic Poulain <loic.poulain@linaro.org>
......@@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
items:
- const: qcom,qcm2290-dpu
const: qcom,qcm2290-dpu
reg:
items:
......@@ -42,6 +41,13 @@ properties:
- const: lut
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
......
......@@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
items:
- const: qcom,qcm2290-mdss
const: qcom,qcm2290-mdss
clocks:
items:
......@@ -61,6 +60,9 @@ patternProperties:
compatible:
const: qcom,dsi-phy-14nm-2290
required:
- compatible
unevaluatedProperties: false
examples:
......@@ -72,7 +74,7 @@ examples:
#include <dt-bindings/interconnect/qcom,qcm2290.h>
#include <dt-bindings/power/qcom-rpmpd.h>
mdss@5e00000 {
display-subsystem@5e00000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "qcom,qcm2290-mdss";
......
......@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,sc7180-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DPU dt properties for SC7180 target
title: Qualcomm Display DPU on SC7180
maintainers:
- Krishna Manikandan <quic_mkrishn@quicinc.com>
......@@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
items:
- const: qcom,sc7180-dpu
const: qcom,sc7180-dpu
reg:
items:
......@@ -44,6 +43,13 @@ properties:
- const: core
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
......
......@@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
items:
- const: qcom,sc7180-mdss
const: qcom,sc7180-mdss
clocks:
items:
......@@ -67,6 +66,9 @@ patternProperties:
compatible:
const: qcom,dsi-phy-10nm
required:
- compatible
unevaluatedProperties: false
examples:
......
......@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,sc7280-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DPU dt properties for SC7280
title: Qualcomm Display DPU on SC7280
maintainers:
- Krishna Manikandan <quic_mkrishn@quicinc.com>
......@@ -43,6 +43,13 @@ properties:
- const: core
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
......
......@@ -74,6 +74,9 @@ patternProperties:
- qcom,sc7280-dsi-phy-7nm
- qcom,sc7280-edp-phy
required:
- compatible
unevaluatedProperties: false
examples:
......
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sc8280xp-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SC8280XP Display Processing Unit
maintainers:
- Bjorn Andersson <andersson@kernel.org>
description:
Device tree bindings for SC8280XP Display Processing Unit.
$ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
const: qcom,sc8280xp-dpu
reg:
items:
- description: Address offset and size for mdp register set
- description: Address offset and size for vbif register set
reg-names:
items:
- const: mdp
- const: vbif
clocks:
items:
- description: Display hf axi clock
- description: Display sf axi clock
- description: Display ahb clock
- description: Display lut clock
- description: Display core clock
- description: Display vsync clock
clock-names:
items:
- const: bus
- const: nrt_bus
- const: iface
- const: lut
- const: core
- const: vsync
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sc8280xp.h>
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sc8280xp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-controller@ae01000 {
compatible = "qcom,sc8280xp-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
<&gcc GCC_DISP_SF_AXI_CLK>,
<&dispcc0 DISP_CC_MDSS_AHB_CLK>,
<&dispcc0 DISP_CC_MDSS_MDP_LUT_CLK>,
<&dispcc0 DISP_CC_MDSS_MDP_CLK>,
<&dispcc0 DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "bus",
"nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc0 DISP_CC_MDSS_MDP_CLK>,
<&dispcc0 DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <460000000>,
<19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SC8280XP_MMCX>;
interrupt-parent = <&mdss0>;
interrupts = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
endpoint {
remote-endpoint = <&mdss0_dp0_in>;
};
};
port@4 {
reg = <4>;
endpoint {
remote-endpoint = <&mdss0_dp1_in>;
};
};
port@5 {
reg = <5>;
endpoint {
remote-endpoint = <&mdss0_dp3_in>;
};
};
port@6 {
reg = <6>;
endpoint {
remote-endpoint = <&mdss0_dp2_in>;
};
};
};
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sc8280xp-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SC8280XP Mobile Display Subsystem
maintainers:
- Bjorn Andersson <andersson@kernel.org>
description:
Device tree bindings for MSM Mobile Display Subsystem (MDSS) that encapsulates
sub-blocks like DPU display controller, DSI and DP interfaces etc.
$ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
const: qcom,sc8280xp-mdss
clocks:
items:
- description: Display AHB clock from gcc
- description: Display AHB clock from dispcc
- description: Display core clock
clock-names:
items:
- const: iface
- const: ahb
- const: core
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,sc8280xp-dpu
"^displayport-controller@[0-9a-f]+$":
type: object
properties:
compatible:
enum:
- qcom,sc8280xp-dp
- qcom,sc8280xp-edp
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sc8280xp.h>
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sc8280xp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sc8280xp-mdss";
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
power-domains = <&dispcc0 MDSS_GDSC>;
clocks = <&gcc GCC_DISP_AHB_CLK>,
<&dispcc0 DISP_CC_MDSS_AHB_CLK>,
<&dispcc0 DISP_CC_MDSS_MDP_CLK>;
clock-names = "iface",
"ahb",
"core";
resets = <&dispcc0 DISP_CC_MDSS_CORE_BCR>;
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;
interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>,
<&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>;
interconnect-names = "mdp0-mem", "mdp1-mem";
iommus = <&apps_smmu 0x1000 0x402>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
display-controller@ae01000 {
compatible = "qcom,sc8280xp-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
<&gcc GCC_DISP_SF_AXI_CLK>,
<&dispcc0 DISP_CC_MDSS_AHB_CLK>,
<&dispcc0 DISP_CC_MDSS_MDP_LUT_CLK>,
<&dispcc0 DISP_CC_MDSS_MDP_CLK>,
<&dispcc0 DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "bus",
"nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc0 DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdss0_mdp_opp_table>;
power-domains = <&rpmhpd SC8280XP_MMCX>;
interrupt-parent = <&mdss0>;
interrupts = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
endpoint {
remote-endpoint = <&mdss0_dp0_in>;
};
};
port@4 {
reg = <4>;
endpoint {
remote-endpoint = <&mdss0_dp1_in>;
};
};
port@5 {
reg = <5>;
endpoint {
remote-endpoint = <&mdss0_dp3_in>;
};
};
port@6 {
reg = <6>;
endpoint {
remote-endpoint = <&mdss0_dp2_in>;
};
};
};
};
};
...
......@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,sdm845-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DPU dt properties for SDM845 target
title: Qualcomm Display DPU on SDM845
maintainers:
- Krishna Manikandan <quic_mkrishn@quicinc.com>
......@@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
items:
- const: qcom,sdm845-dpu
const: qcom,sdm845-dpu
reg:
items:
......@@ -42,6 +41,13 @@ properties:
- const: core
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
......
......@@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
items:
- const: qcom,sdm845-mdss
const: qcom,sdm845-mdss
clocks:
items:
......@@ -47,6 +46,12 @@ patternProperties:
compatible:
const: qcom,sdm845-dpu
"^displayport-controller@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,sdm845-dp
"^dsi@[0-9a-f]+$":
type: object
properties:
......@@ -59,6 +64,9 @@ patternProperties:
compatible:
const: qcom,dsi-phy-10nm
required:
- compatible
unevaluatedProperties: false
examples:
......
......@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,sm6115-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DPU dt properties for SM6115 target
title: Qualcomm Display DPU on SM6115
maintainers:
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
......@@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
items:
- const: qcom,sm6115-dpu
const: qcom,sm6115-dpu
reg:
items:
......
......@@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
items:
- const: qcom,sm6115-mdss
const: qcom,sm6115-mdss
clocks:
items:
......@@ -62,7 +61,7 @@ examples:
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom-rpmpd.h>
mdss@5e00000 {
display-subsystem@5e00000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "qcom,sm6115-mdss";
......
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8150-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8150 Display DPU
maintainers:
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
$ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
const: qcom,sm8150-dpu
reg:
items:
- description: Address offset and size for mdp register set
- description: Address offset and size for vbif register set
reg-names:
items:
- const: mdp
- const: vbif
clocks:
items:
- description: Display ahb clock
- description: Display hf axi clock
- description: Display core clock
- description: Display vsync clock
clock-names:
items:
- const: iface
- const: bus
- const: core
- const: vsync
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sm8150.h>
#include <dt-bindings/clock/qcom,gcc-sm8150.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8150.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8150-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>,
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "iface", "bus", "core", "vsync";
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8150_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
endpoint {
remote-endpoint = <&dsi0_in>;
};
};
port@1 {
reg = <1>;
endpoint {
remote-endpoint = <&dsi1_in>;
};
};
};
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8150-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8150 Display MDSS
maintainers:
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
description:
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
bindings of MDSS are mentioned for SM8150 target.
$ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
items:
- const: qcom,sm8150-mdss
clocks:
items:
- description: Display AHB clock from gcc
- description: Display hf axi clock
- description: Display sf axi clock
- description: Display core clock
clock-names:
items:
- const: iface
- const: bus
- const: nrt_bus
- const: core
iommus:
maxItems: 1
interconnects:
maxItems: 2
interconnect-names:
maxItems: 2
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,sm8150-dpu
"^dsi@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,mdss-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,dsi-phy-7nm
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sm8150.h>
#include <dt-bindings/clock/qcom,gcc-sm8150.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8150.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8150-mdss";
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
interconnects = <&mmss_noc MASTER_MDP_PORT0 &mc_virt SLAVE_EBI_CH0>,
<&mmss_noc MASTER_MDP_PORT1 &mc_virt SLAVE_EBI_CH0>;
interconnect-names = "mdp0-mem", "mdp1-mem";
power-domains = <&dispcc MDSS_GDSC>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>,
<&gcc GCC_DISP_SF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>;
clock-names = "iface", "bus", "nrt_bus", "core";
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;
iommus = <&apps_smmu 0x800 0x420>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
display-controller@ae01000 {
compatible = "qcom,sm8150-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>,
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "iface", "bus", "core", "vsync";
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8150_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpu_intf1_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
port@1 {
reg = <1>;
dpu_intf2_out: endpoint {
remote-endpoint = <&dsi1_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-171428571 {
opp-hz = /bits/ 64 <171428571>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-345000000 {
opp-hz = /bits/ 64 <345000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-460000000 {
opp-hz = /bits/ 64 <460000000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
};
dsi@ae94000 {
compatible = "qcom,mdss-dsi-ctrl";
reg = <0x0ae94000 0x400>;
reg-names = "dsi_ctrl";
interrupt-parent = <&mdss>;
interrupts = <4>;
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>;
clock-names = "byte",
"byte_intf",
"pixel",
"core",
"iface",
"bus";
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8150_MMCX>;
phys = <&dsi0_phy>;
phy-names = "dsi";
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi0_in: endpoint {
remote-endpoint = <&dpu_intf1_out>;
};
};
port@1 {
reg = <1>;
dsi0_out: endpoint {
};
};
};
dsi_opp_table: opp-table {
compatible = "operating-points-v2";
opp-187500000 {
opp-hz = /bits/ 64 <187500000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-358000000 {
opp-hz = /bits/ 64 <358000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
};
};
dsi0_phy: phy@ae94400 {
compatible = "qcom,dsi-phy-7nm";
reg = <0x0ae94400 0x200>,
<0x0ae94600 0x280>,
<0x0ae94900 0x260>;
reg-names = "dsi_phy",
"dsi_phy_lane",
"dsi_pll";
#clock-cells = <1>;
#phy-cells = <0>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
vdds-supply = <&vreg_dsi_phy>;
};
dsi@ae96000 {
compatible = "qcom,mdss-dsi-ctrl";
reg = <0x0ae96000 0x400>;
reg-names = "dsi_ctrl";
interrupt-parent = <&mdss>;
interrupts = <5>;
clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>,
<&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>,
<&dispcc DISP_CC_MDSS_PCLK1_CLK>,
<&dispcc DISP_CC_MDSS_ESC1_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>;
clock-names = "byte",
"byte_intf",
"pixel",
"core",
"iface",
"bus";
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>,
<&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>;
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8150_MMCX>;
phys = <&dsi1_phy>;
phy-names = "dsi";
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi1_in: endpoint {
remote-endpoint = <&dpu_intf2_out>;
};
};
port@1 {
reg = <1>;
dsi1_out: endpoint {
};
};
};
};
dsi1_phy: phy@ae96400 {
compatible = "qcom,dsi-phy-7nm";
reg = <0x0ae96400 0x200>,
<0x0ae96600 0x280>,
<0x0ae96900 0x260>;
reg-names = "dsi_phy",
"dsi_phy_lane",
"dsi_pll";
#clock-cells = <1>;
#phy-cells = <0>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
vdds-supply = <&vreg_dsi_phy>;
};
};
...
......@@ -39,6 +39,13 @@ properties:
- const: core
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
......
......@@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
items:
- const: qcom,sm8250-mdss
const: qcom,sm8250-mdss
clocks:
items:
......@@ -63,6 +62,9 @@ patternProperties:
compatible:
const: qcom,dsi-phy-7nm
required:
- compatible
unevaluatedProperties: false
examples:
......
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8350-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8350 Display DPU
maintainers:
- Robert Foss <robert.foss@linaro.org>
$ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
const: qcom,sm8350-dpu
reg:
items:
- description: Address offset and size for mdp register set
- description: Address offset and size for vbif register set
reg-names:
items:
- const: mdp
- const: vbif
clocks:
items:
- description: Display hf axi clock
- description: Display sf axi clock
- description: Display ahb clock
- description: Display lut clock
- description: Display core clock
- description: Display vsync clock
clock-names:
items:
- const: bus
- const: nrt_bus
- const: iface
- const: lut
- const: core
- const: vsync
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sm8350.h>
#include <dt-bindings/clock/qcom,gcc-sm8350.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8350.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8350-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
<&gcc GCC_DISP_SF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>,
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "bus",
"nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8350_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpu_intf1_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-345000000 {
opp-hz = /bits/ 64 <345000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-460000000 {
opp-hz = /bits/ 64 <460000000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8350-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8350 Display MDSS
maintainers:
- Robert Foss <robert.foss@linaro.org>
description:
MSM Mobile Display Subsystem(MDSS) that encapsulates sub-blocks like
DPU display controller, DSI and DP interfaces etc.
$ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
items:
- const: qcom,sm8350-mdss
clocks:
items:
- description: Display AHB clock from gcc
- description: Display hf axi clock
- description: Display sf axi clock
- description: Display core clock
clock-names:
items:
- const: iface
- const: bus
- const: nrt_bus
- const: core
iommus:
maxItems: 1
interconnects:
maxItems: 2
interconnect-names:
items:
- const: mdp0-mem
- const: mdp1-mem
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,sm8350-dpu
"^dsi@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,mdss-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,dsi-phy-5nm-8350
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sm8350.h>
#include <dt-bindings/clock/qcom,gcc-sm8350.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8350.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8350-mdss";
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>,
<&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>;
interconnect-names = "mdp0-mem", "mdp1-mem";
power-domains = <&dispcc MDSS_GDSC>;
resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>,
<&gcc GCC_DISP_SF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>;
clock-names = "iface", "bus", "nrt_bus", "core";
iommus = <&apps_smmu 0x820 0x402>;
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
display-controller@ae01000 {
compatible = "qcom,sm8350-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
<&gcc GCC_DISP_SF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>,
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "bus",
"nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8350_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpu_intf1_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-345000000 {
opp-hz = /bits/ 64 <345000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-460000000 {
opp-hz = /bits/ 64 <460000000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
};
dsi0: dsi@ae94000 {
compatible = "qcom,mdss-dsi-ctrl";
reg = <0x0ae94000 0x400>;
reg-names = "dsi_ctrl";
interrupt-parent = <&mdss>;
interrupts = <4>;
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>;
clock-names = "byte",
"byte_intf",
"pixel",
"core",
"iface",
"bus";
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
assigned-clock-parents = <&mdss_dsi0_phy 0>,
<&mdss_dsi0_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8350_MMCX>;
phys = <&mdss_dsi0_phy>;
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 {
};
};
};
};
};
...
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8450-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8450 Display DPU
maintainers:
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
$ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
const: qcom,sm8450-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
- description: Display sf axi
- description: Display ahb
- description: Display lut
- description: Display core
- description: Display vsync
clock-names:
items:
- const: bus
- const: nrt_bus
- const: iface
- const: lut
- const: core
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,sm8450-dispcc.h>
#include <dt-bindings/clock/qcom,gcc-sm8450.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8450.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8450-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
<&gcc GCC_DISP_SF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>,
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "bus",
"nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8450_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpu_intf1_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
port@1 {
reg = <1>;
dpu_intf2_out: endpoint {
remote-endpoint = <&dsi1_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-172000000{
opp-hz = /bits/ 64 <172000000>;
required-opps = <&rpmhpd_opp_low_svs_d1>;
};
opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-325000000 {
opp-hz = /bits/ 64 <325000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-375000000 {
opp-hz = /bits/ 64 <375000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-500000000 {
opp-hz = /bits/ 64 <500000000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
};
...
......@@ -141,12 +141,12 @@ config DRM_MSM_DSI_10NM_PHY
Choose this option if DSI PHY on SDM845 is used on the platform.
config DRM_MSM_DSI_7NM_PHY
bool "Enable DSI 7nm PHY driver in MSM DRM"
bool "Enable DSI 7nm/5nm/4nm PHY driver in MSM DRM"
depends on DRM_MSM_DSI
default y
help
Choose this option if DSI PHY on SM8150/SM8250/SC7280 is used on
the platform.
Choose this option if DSI PHY on SM8150/SM8250/SM8350/SM8450/SM8550/SC7280
is used on the platform.
config DRM_MSM_HDMI
bool "Enable HDMI support in MSM DRM driver"
......
......@@ -876,7 +876,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
#define GBIF_CLIENT_HALT_MASK BIT(0)
#define GBIF_ARB_HALT_MASK BIT(1)
static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu)
static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu,
bool gx_off)
{
struct msm_gpu *gpu = &adreno_gpu->base;
......@@ -889,9 +890,11 @@ static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu)
return;
}
/* Halt the gx side of GBIF */
gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1);
spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1);
if (gx_off) {
/* Halt the gx side of GBIF */
gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1);
spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1);
}
/* Halt new client requests on GBIF */
gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_CLIENT_HALT_MASK);
......@@ -929,7 +932,7 @@ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu)
/* Halt the gmu cm3 core */
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
a6xx_bus_clear_pending_transactions(adreno_gpu);
a6xx_bus_clear_pending_transactions(adreno_gpu, true);
/* Reset GPU core blocks */
gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, 1);
......@@ -1083,7 +1086,7 @@ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu)
return;
}
a6xx_bus_clear_pending_transactions(adreno_gpu);
a6xx_bus_clear_pending_transactions(adreno_gpu, a6xx_gpu->hung);
/* tell the GMU we want to slumber */
ret = a6xx_gmu_notify_slumber(gmu);
......
......@@ -1270,6 +1270,12 @@ static void a6xx_recover(struct msm_gpu *gpu)
if (hang_debug)
a6xx_dump(gpu);
/*
* To handle recovery specific sequences during the rpm suspend we are
* about to trigger
*/
a6xx_gpu->hung = true;
/* Halt SQE first */
gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3);
......@@ -1312,6 +1318,7 @@ static void a6xx_recover(struct msm_gpu *gpu)
mutex_unlock(&gpu->active_lock);
msm_gpu_hw_init(gpu);
a6xx_gpu->hung = false;
}
static const char *a6xx_uche_fault_block(struct msm_gpu *gpu, u32 mid)
......
......@@ -32,6 +32,7 @@ struct a6xx_gpu {
void *llc_slice;
void *htw_llc_slice;
bool have_mmu500;
bool hung;
};
#define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base)
......
......@@ -29,11 +29,9 @@ enum {
ADRENO_FW_MAX,
};
enum adreno_quirks {
ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
ADRENO_QUIRK_LMLOADKILL_DISABLE = 3,
};
#define ADRENO_QUIRK_TWO_PASS_USE_WFI BIT(0)
#define ADRENO_QUIRK_FAULT_DETECT_MASK BIT(1)
#define ADRENO_QUIRK_LMLOADKILL_DISABLE BIT(2)
struct adreno_rev {
uint8_t core;
......@@ -65,7 +63,7 @@ struct adreno_info {
const char *name;
const char *fw[ADRENO_FW_MAX];
uint32_t gmem;
enum adreno_quirks quirks;
u64 quirks;
struct msm_gpu *(*init)(struct drm_device *dev);
const char *zapfw;
u32 inactive_period;
......
......@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
int i;
if (!state->color_mgmt_changed)
if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
return;
for (i = 0; i < cstate->num_mixers; i++) {
......@@ -1517,16 +1517,12 @@ DEFINE_SHOW_ATTRIBUTE(dpu_crtc_debugfs_state);
static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc)
{
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dentry *debugfs_root;
debugfs_root = debugfs_create_dir(dpu_crtc->name,
crtc->dev->primary->debugfs_root);
debugfs_create_file("status", 0400,
debugfs_root,
crtc->debugfs_entry,
dpu_crtc, &_dpu_debugfs_status_fops);
debugfs_create_file("state", 0600,
debugfs_root,
crtc->debugfs_entry,
&dpu_crtc->base,
&dpu_crtc_debugfs_state_fops);
......
......@@ -162,6 +162,7 @@ enum dpu_enc_rc_states {
* @vsync_event_work: worker to handle vsync event for autorefresh
* @topology: topology of the display
* @idle_timeout: idle timeout duration in milliseconds
* @wide_bus_en: wide bus is enabled on this interface
* @dsc: drm_dsc_config pointer, for DSC-enabled encoders
*/
struct dpu_encoder_virt {
......@@ -340,9 +341,7 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
phys_enc->intf_idx - INTF_0, phys_enc->wb_idx - WB_0,
phys_enc->hw_pp->idx - PINGPONG_0, intr_idx);
if (phys_enc->parent_ops->handle_frame_done)
phys_enc->parent_ops->handle_frame_done(
phys_enc->parent, phys_enc,
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
DPU_ENCODER_FRAME_EVENT_ERROR);
}
......@@ -579,19 +578,18 @@ static struct msm_display_topology dpu_encoder_get_topology(
topology.num_dspp = topology.num_lm;
}
topology.num_enc = 0;
topology.num_intf = intf_count;
if (dpu_enc->dsc) {
/* In case of Display Stream Compression (DSC), we would use
* 2 encoders, 2 layer mixers and 1 interface
/*
* In case of Display Stream Compression (DSC), we would use
* 2 DSC encoders, 2 layer mixers and 1 interface
* this is power optimal and can drive up to (including) 4k
* screens
*/
topology.num_enc = 2;
topology.num_dsc = 2;
topology.num_intf = 1;
topology.num_lm = 2;
topology.num_intf = 1;
}
return topology;
......@@ -1284,7 +1282,7 @@ static enum dpu_wb dpu_encoder_get_wb(const struct dpu_mdss_cfg *catalog,
return WB_MAX;
}
static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phy_enc)
{
struct dpu_encoder_virt *dpu_enc = NULL;
......@@ -1306,7 +1304,7 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
DPU_ATRACE_END("encoder_vblank_callback");
}
static void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phy_enc)
{
if (!phy_enc)
......@@ -1382,7 +1380,7 @@ void dpu_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
}
static void dpu_encoder_frame_done_callback(
void dpu_encoder_frame_done_callback(
struct drm_encoder *drm_enc,
struct dpu_encoder_phys *ready_phys, u32 event)
{
......@@ -1830,6 +1828,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
if (hw_pp->ops.setup_dsc)
hw_pp->ops.setup_dsc(hw_pp);
if (hw_dsc->ops.dsc_bind_pingpong_blk)
hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, true, hw_pp->idx);
if (hw_pp->ops.enable_dsc)
hw_pp->ops.enable_dsc(hw_pp);
}
......@@ -2233,12 +2234,6 @@ static int dpu_encoder_virt_add_phys_encs(
return 0;
}
static const struct dpu_encoder_virt_ops dpu_encoder_parent_ops = {
.handle_vblank_virt = dpu_encoder_vblank_callback,
.handle_underrun_virt = dpu_encoder_underrun_callback,
.handle_frame_done = dpu_encoder_frame_done_callback,
};
static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms,
struct msm_display_info *disp_info)
......@@ -2258,7 +2253,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
memset(&phys_params, 0, sizeof(phys_params));
phys_params.dpu_kms = dpu_kms;
phys_params.parent = &dpu_enc->base;
phys_params.parent_ops = &dpu_encoder_parent_ops;
phys_params.enc_spinlock = &dpu_enc->enc_spinlock;
switch (disp_info->intf_type) {
......
......@@ -60,25 +60,6 @@ enum dpu_enc_enable_state {
struct dpu_encoder_phys;
/**
* struct dpu_encoder_virt_ops - Interface the containing virtual encoder
* provides for the physical encoders to use to callback.
* @handle_vblank_virt: Notify virtual encoder of vblank IRQ reception
* Note: This is called from IRQ handler context.
* @handle_underrun_virt: Notify virtual encoder of underrun IRQ reception
* Note: This is called from IRQ handler context.
* @handle_frame_done: Notify virtual encoder that this phys encoder
* completes last request frame.
*/
struct dpu_encoder_virt_ops {
void (*handle_vblank_virt)(struct drm_encoder *,
struct dpu_encoder_phys *phys);
void (*handle_underrun_virt)(struct drm_encoder *,
struct dpu_encoder_phys *phys);
void (*handle_frame_done)(struct drm_encoder *,
struct dpu_encoder_phys *phys, u32 event);
};
/**
* struct dpu_encoder_phys_ops - Interface the physical encoders provide to
* the containing virtual encoder.
......@@ -199,7 +180,6 @@ enum dpu_intr_idx {
struct dpu_encoder_phys {
struct drm_encoder *parent;
struct dpu_encoder_phys_ops ops;
const struct dpu_encoder_virt_ops *parent_ops;
struct dpu_hw_mdp *hw_mdptop;
struct dpu_hw_ctl *hw_ctl;
struct dpu_hw_pingpong *hw_pp;
......@@ -283,7 +263,6 @@ struct dpu_encoder_phys_cmd {
struct dpu_enc_phys_init_params {
struct dpu_kms *dpu_kms;
struct drm_encoder *parent;
const struct dpu_encoder_virt_ops *parent_ops;
enum dpu_enc_split_role split_role;
enum dpu_intf intf_idx;
enum dpu_wb wb_idx;
......@@ -400,4 +379,30 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
*/
void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
/**
* dpu_encoder_vblank_callback - Notify virtual encoder of vblank IRQ reception
* @drm_enc: Pointer to drm encoder structure
* @phys_enc: Pointer to physical encoder
* Note: This is called from IRQ handler context.
*/
void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phy_enc);
/** dpu_encoder_underrun_callback - Notify virtual encoder of underrun IRQ reception
* @drm_enc: Pointer to drm encoder structure
* @phys_enc: Pointer to physical encoder
* Note: This is called from IRQ handler context.
*/
void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
struct dpu_encoder_phys *phy_enc);
/** dpu_encoder_frame_done_callback -- Notify virtual encoder that this phys encoder completes last request frame
* @drm_enc: Pointer to drm encoder structure
* @phys_enc: Pointer to physical encoder
* @event: Event to process
*/
void dpu_encoder_frame_done_callback(
struct drm_encoder *drm_enc,
struct dpu_encoder_phys *ready_phys, u32 event);
#endif /* __dpu_encoder_phys_H__ */
......@@ -61,6 +61,7 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg(
intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD;
intf_cfg.stream_sel = cmd_enc->stream_sel;
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
ctl->ops.setup_intf_cfg(ctl, &intf_cfg);
/* setup which pp blk will connect to this intf */
......@@ -83,9 +84,7 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
DPU_ATRACE_BEGIN("pp_done_irq");
/* notify all synchronous clients first, then asynchronous clients */
if (phys_enc->parent_ops->handle_frame_done)
phys_enc->parent_ops->handle_frame_done(phys_enc->parent,
phys_enc, event);
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
......@@ -111,9 +110,7 @@ static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
DPU_ATRACE_BEGIN("rd_ptr_irq");
cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
if (phys_enc->parent_ops->handle_vblank_virt)
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
phys_enc);
dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
atomic_add_unless(&cmd_enc->pending_vblank_cnt, -1, 0);
wake_up_all(&cmd_enc->pending_vblank_wq);
......@@ -137,9 +134,7 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)
{
struct dpu_encoder_phys *phys_enc = arg;
if (phys_enc->parent_ops->handle_underrun_virt)
phys_enc->parent_ops->handle_underrun_virt(phys_enc->parent,
phys_enc);
dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
}
static void dpu_encoder_phys_cmd_atomic_mode_set(
......@@ -202,9 +197,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
/* request a ctl reset before the next kickoff */
phys_enc->enable_state = DPU_ENC_ERR_NEEDS_HW_RESET;
if (phys_enc->parent_ops->handle_frame_done)
phys_enc->parent_ops->handle_frame_done(
drm_enc, phys_enc, frame_event);
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
return -ETIMEDOUT;
}
......@@ -780,7 +773,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent;
phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_CMD;
......
......@@ -274,6 +274,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID;
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);
intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
if (phys_enc->hw_pp->merge_3d)
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
......@@ -308,9 +309,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
DPU_ATRACE_BEGIN("vblank_irq");
if (phys_enc->parent_ops->handle_vblank_virt)
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
phys_enc);
dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
atomic_read(&phys_enc->pending_kickoff_cnt);
......@@ -330,7 +329,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
/* Signal any waiting atomic commit thread */
wake_up_all(&phys_enc->pending_kickoff_wq);
phys_enc->parent_ops->handle_frame_done(phys_enc->parent, phys_enc,
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
DPU_ENCODER_FRAME_EVENT_DONE);
DPU_ATRACE_END("vblank_irq");
......@@ -340,9 +339,7 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
{
struct dpu_encoder_phys *phys_enc = arg;
if (phys_enc->parent_ops->handle_underrun_virt)
phys_enc->parent_ops->handle_underrun_virt(phys_enc->parent,
phys_enc);
dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
}
static bool dpu_encoder_phys_vid_needs_single_flush(
......@@ -700,7 +697,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent;
phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_VIDEO;
......
......@@ -26,6 +26,7 @@
/**
* dpu_encoder_phys_wb_is_master - report wb always as master encoder
* @phys_enc: Pointer to physical encoder
*/
static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys *phys_enc)
{
......@@ -132,7 +133,6 @@ static void dpu_encoder_phys_wb_set_qos(struct dpu_encoder_phys *phys_enc)
* dpu_encoder_phys_wb_setup_fb - setup output framebuffer
* @phys_enc: Pointer to physical encoder
* @fb: Pointer to output framebuffer
* @wb_roi: Pointer to output region of interest
*/
static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc,
struct drm_framebuffer *fb)
......@@ -365,13 +365,9 @@ static void _dpu_encoder_phys_wb_frame_done_helper(void *arg)
DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
if (phys_enc->parent_ops->handle_frame_done)
phys_enc->parent_ops->handle_frame_done(phys_enc->parent,
phys_enc, event);
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
if (phys_enc->parent_ops->handle_vblank_virt)
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
phys_enc);
dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
......@@ -441,9 +437,7 @@ static void _dpu_encoder_phys_wb_handle_wbdone_timeout(
if (wb_enc->wb_conn)
drm_writeback_signal_completion(wb_enc->wb_conn, 0);
if (phys_enc->parent_ops->handle_frame_done)
phys_enc->parent_ops->handle_frame_done(
phys_enc->parent, phys_enc, frame_event);
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
}
/**
......@@ -692,7 +686,7 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops)
/**
* dpu_encoder_phys_wb_init - initialize writeback encoder
* @init: Pointer to init info structure with initialization params
* @p: Pointer to init info structure with initialization params
*/
struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
struct dpu_enc_phys_init_params *p)
......@@ -723,7 +717,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
dpu_encoder_phys_wb_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent;
phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_WB_LINE;
......
......@@ -46,7 +46,11 @@
#define DPU_HW_VER_620 DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */
#define DPU_HW_VER_630 DPU_HW_VER(6, 3, 0) /* sm6115|sm4250 */
#define DPU_HW_VER_650 DPU_HW_VER(6, 5, 0) /* qcm2290|sm4125 */
#define DPU_HW_VER_700 DPU_HW_VER(7, 0, 0) /* sm8350 */
#define DPU_HW_VER_720 DPU_HW_VER(7, 2, 0) /* sc7280 */
#define DPU_HW_VER_800 DPU_HW_VER(8, 0, 0) /* sc8280xp */
#define DPU_HW_VER_810 DPU_HW_VER(8, 1, 0) /* sm8450 */
#define DPU_HW_VER_900 DPU_HW_VER(9, 0, 0) /* sm8550 */
#define IS_MSM8996_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_170)
#define IS_MSM8998_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_300)
......@@ -83,6 +87,8 @@ enum {
* @DPU_MDP_UBWC_1_0, This chipsets supports Universal Bandwidth
* compression initial revision
* @DPU_MDP_UBWC_1_5, Universal Bandwidth compression version 1.5
* @DPU_MDP_PERIPH_0_REMOVED Indicates that access to periph top0 block results
* in a failure
* @DPU_MDP_MAX Maximum value
*/
......@@ -93,6 +99,7 @@ enum {
DPU_MDP_UBWC_1_0,
DPU_MDP_UBWC_1_5,
DPU_MDP_AUDIO_SELECT,
DPU_MDP_PERIPH_0_REMOVED,
DPU_MDP_MAX
};
......@@ -192,6 +199,7 @@ enum {
* @DPU_CTL_SPLIT_DISPLAY: CTL supports video mode split display
* @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs)
* @DPU_CTL_VM_CFG: CTL config to support multiple VMs
* @DPU_CTL_HAS_LAYER_EXT4: CTL has the CTL_LAYER_EXT4 register
* @DPU_CTL_MAX
*/
enum {
......@@ -199,6 +207,7 @@ enum {
DPU_CTL_ACTIVE_CFG,
DPU_CTL_FETCH_ACTIVE,
DPU_CTL_VM_CFG,
DPU_CTL_HAS_LAYER_EXT4,
DPU_CTL_MAX
};
......@@ -266,6 +275,15 @@ enum {
DPU_VBIF_MAX
};
/**
* DSC features
* @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets
* the pixel output from this DSC.
*/
enum {
DPU_DSC_OUTPUT_CTRL = 0x1,
};
/**
* MACRO DPU_HW_BLK_INFO - information of HW blocks inside DPU
* @name: string name for debug purposes
......
......@@ -17,6 +17,8 @@
(0x70 + (((lm) - LM_0) * 0x004))
#define CTL_LAYER_EXT3(lm) \
(0xA0 + (((lm) - LM_0) * 0x004))
#define CTL_LAYER_EXT4(lm) \
(0xB8 + (((lm) - LM_0) * 0x004))
#define CTL_TOP 0x014
#define CTL_FLUSH 0x018
#define CTL_START 0x01C
......@@ -377,12 +379,37 @@ static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx)
DPU_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0);
}
struct ctl_blend_config {
int idx, shift, ext_shift;
};
static const struct ctl_blend_config ctl_blend_config[][2] = {
[SSPP_NONE] = { { -1 }, { -1 } },
[SSPP_MAX] = { { -1 }, { -1 } },
[SSPP_VIG0] = { { 0, 0, 0 }, { 3, 0 } },
[SSPP_VIG1] = { { 0, 3, 2 }, { 3, 4 } },
[SSPP_VIG2] = { { 0, 6, 4 }, { 3, 8 } },
[SSPP_VIG3] = { { 0, 26, 6 }, { 3, 12 } },
[SSPP_RGB0] = { { 0, 9, 8 }, { -1 } },
[SSPP_RGB1] = { { 0, 12, 10 }, { -1 } },
[SSPP_RGB2] = { { 0, 15, 12 }, { -1 } },
[SSPP_RGB3] = { { 0, 29, 14 }, { -1 } },
[SSPP_DMA0] = { { 0, 18, 16 }, { 2, 8 } },
[SSPP_DMA1] = { { 0, 21, 18 }, { 2, 12 } },
[SSPP_DMA2] = { { 2, 0 }, { 2, 16 } },
[SSPP_DMA3] = { { 2, 4 }, { 2, 20 } },
[SSPP_DMA4] = { { 4, 0 }, { 4, 8 } },
[SSPP_DMA5] = { { 4, 4 }, { 4, 12 } },
[SSPP_CURSOR0] = { { 1, 20 }, { -1 } },
[SSPP_CURSOR1] = { { 1, 26 }, { -1 } },
};
static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
{
struct dpu_hw_blk_reg_map *c = &ctx->hw;
u32 mixercfg = 0, mixercfg_ext = 0, mix, ext;
u32 mixercfg_ext2 = 0, mixercfg_ext3 = 0;
u32 mix, ext, mix_ext;
u32 mixercfg[5] = { 0 };
int i, j;
int stages;
int pipes_per_stage;
......@@ -397,7 +424,7 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
else
pipes_per_stage = 1;
mixercfg = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */
mixercfg[0] = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */
if (!stage_cfg)
goto exit;
......@@ -406,109 +433,35 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
/* overflow to ext register if 'i + 1 > 7' */
mix = (i + 1) & 0x7;
ext = i >= 7;
mix_ext = (i + 1) & 0xf;
for (j = 0 ; j < pipes_per_stage; j++) {
enum dpu_sspp_multirect_index rect_index =
stage_cfg->multirect_index[i][j];
switch (stage_cfg->stage[i][j]) {
case SSPP_VIG0:
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext3 |= ((i + 1) & 0xF) << 0;
} else {
mixercfg |= mix << 0;
mixercfg_ext |= ext << 0;
}
break;
case SSPP_VIG1:
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext3 |= ((i + 1) & 0xF) << 4;
} else {
mixercfg |= mix << 3;
mixercfg_ext |= ext << 2;
}
break;
case SSPP_VIG2:
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext3 |= ((i + 1) & 0xF) << 8;
} else {
mixercfg |= mix << 6;
mixercfg_ext |= ext << 4;
}
break;
case SSPP_VIG3:
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext3 |= ((i + 1) & 0xF) << 12;
} else {
mixercfg |= mix << 26;
mixercfg_ext |= ext << 6;
}
break;
case SSPP_RGB0:
mixercfg |= mix << 9;
mixercfg_ext |= ext << 8;
break;
case SSPP_RGB1:
mixercfg |= mix << 12;
mixercfg_ext |= ext << 10;
break;
case SSPP_RGB2:
mixercfg |= mix << 15;
mixercfg_ext |= ext << 12;
break;
case SSPP_RGB3:
mixercfg |= mix << 29;
mixercfg_ext |= ext << 14;
break;
case SSPP_DMA0:
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext2 |= ((i + 1) & 0xF) << 8;
} else {
mixercfg |= mix << 18;
mixercfg_ext |= ext << 16;
}
break;
case SSPP_DMA1:
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext2 |= ((i + 1) & 0xF) << 12;
} else {
mixercfg |= mix << 21;
mixercfg_ext |= ext << 18;
}
break;
case SSPP_DMA2:
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext2 |= ((i + 1) & 0xF) << 16;
} else {
mix |= (i + 1) & 0xF;
mixercfg_ext2 |= mix << 0;
}
break;
case SSPP_DMA3:
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext2 |= ((i + 1) & 0xF) << 20;
} else {
mix |= (i + 1) & 0xF;
mixercfg_ext2 |= mix << 4;
}
break;
case SSPP_CURSOR0:
mixercfg_ext |= ((i + 1) & 0xF) << 20;
break;
case SSPP_CURSOR1:
mixercfg_ext |= ((i + 1) & 0xF) << 26;
break;
default:
break;
enum dpu_sspp pipe = stage_cfg->stage[i][j];
const struct ctl_blend_config *cfg =
&ctl_blend_config[pipe][rect_index == DPU_SSPP_RECT_1];
/*
* CTL_LAYER has 3-bit field (and extra bits in EXT register),
* all EXT registers has 4-bit fields.
*/
if (cfg->idx == 0) {
mixercfg[0] |= mix << cfg->shift;
mixercfg[1] |= ext << cfg->ext_shift;
} else {
mixercfg[cfg->idx] |= mix_ext << cfg->shift;
}
}
}
exit:
DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg);
DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext);
DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg_ext2);
DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3);
DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg[0]);
DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg[1]);
DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg[2]);
DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg[3]);
if ((test_bit(DPU_CTL_HAS_LAYER_EXT4, &ctx->caps->features)))
DPU_REG_WRITE(c, CTL_LAYER_EXT4(lm), mixercfg[4]);
}
......
......@@ -29,6 +29,8 @@
#define DSC_RANGE_MAX_QP 0x0B0
#define DSC_RANGE_BPG_OFFSET 0x0EC
#define DSC_CTL(m) (0x1800 - 0x3FC * (m - DSC_0))
static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc)
{
struct dpu_hw_blk_reg_map *c = &dsc->hw;
......@@ -150,6 +152,29 @@ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc,
}
}
static void dpu_hw_dsc_bind_pingpong_blk(
struct dpu_hw_dsc *hw_dsc,
bool enable,
const enum dpu_pingpong pp)
{
struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
int mux_cfg = 0xF;
u32 dsc_ctl_offset;
dsc_ctl_offset = DSC_CTL(hw_dsc->idx);
if (enable)
mux_cfg = (pp - PINGPONG_0) & 0x7;
DRM_DEBUG_KMS("%s dsc:%d %s pp:%d\n",
enable ? "Binding" : "Unbinding",
hw_dsc->idx - DSC_0,
enable ? "to" : "from",
pp - PINGPONG_0);
DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg);
}
static struct dpu_dsc_cfg *_dsc_offset(enum dpu_dsc dsc,
const struct dpu_mdss_cfg *m,
void __iomem *addr,
......@@ -174,6 +199,8 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops,
ops->dsc_disable = dpu_hw_dsc_disable;
ops->dsc_config = dpu_hw_dsc_config;
ops->dsc_config_thresh = dpu_hw_dsc_config_thresh;
if (cap & BIT(DPU_DSC_OUTPUT_CTRL))
ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk;
};
struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr,
......
......@@ -42,6 +42,10 @@ struct dpu_hw_dsc_ops {
*/
void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc,
struct drm_dsc_config *dsc);
void (*dsc_bind_pingpong_blk)(struct dpu_hw_dsc *hw_dsc,
bool enable,
enum dpu_pingpong pp);
};
struct dpu_hw_dsc {
......
......@@ -35,6 +35,9 @@
#define MDP_INTF_3_OFF_REV_7xxx 0x37000
#define MDP_INTF_4_OFF_REV_7xxx 0x38000
#define MDP_INTF_5_OFF_REV_7xxx 0x39000
#define MDP_INTF_6_OFF_REV_7xxx 0x3a000
#define MDP_INTF_7_OFF_REV_7xxx 0x3b000
#define MDP_INTF_8_OFF_REV_7xxx 0x3c000
/**
* struct dpu_intr_reg - array of DPU register sets
......@@ -139,6 +142,21 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_EN,
MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_STATUS
},
[MDP_INTF6_7xxx_INTR] = {
MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_CLEAR,
MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_EN,
MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_STATUS
},
[MDP_INTF7_7xxx_INTR] = {
MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_CLEAR,
MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_EN,
MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_STATUS
},
[MDP_INTF8_7xxx_INTR] = {
MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_CLEAR,
MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_EN,
MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_STATUS
},
};
#define DPU_IRQ_REG(irq_idx) (irq_idx / 32)
......@@ -252,9 +270,9 @@ static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
cache_irq_mask = intr->cache_irq_mask[reg_idx];
if (cache_irq_mask & DPU_IRQ_MASK(irq_idx)) {
dbgstr = "DPU IRQ already set:";
dbgstr = "already ";
} else {
dbgstr = "DPU IRQ enabled:";
dbgstr = "";
cache_irq_mask |= DPU_IRQ_MASK(irq_idx);
/* Cleaning any pending interrupt */
......@@ -268,7 +286,7 @@ static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
intr->cache_irq_mask[reg_idx] = cache_irq_mask;
}
pr_debug("%s MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", dbgstr,
pr_debug("DPU IRQ %d %senabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", irq_idx, dbgstr,
DPU_IRQ_MASK(irq_idx), cache_irq_mask);
return 0;
......@@ -301,9 +319,9 @@ static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
cache_irq_mask = intr->cache_irq_mask[reg_idx];
if ((cache_irq_mask & DPU_IRQ_MASK(irq_idx)) == 0) {
dbgstr = "DPU IRQ is already cleared:";
dbgstr = "already ";
} else {
dbgstr = "DPU IRQ mask disable:";
dbgstr = "";
cache_irq_mask &= ~DPU_IRQ_MASK(irq_idx);
/* Disable interrupts based on the new mask */
......@@ -317,7 +335,7 @@ static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
intr->cache_irq_mask[reg_idx] = cache_irq_mask;
}
pr_debug("%s MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", dbgstr,
pr_debug("DPU IRQ %d %sdisabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", irq_idx, dbgstr,
DPU_IRQ_MASK(irq_idx), cache_irq_mask);
return 0;
......
......@@ -31,6 +31,9 @@ enum dpu_hw_intr_reg {
MDP_INTF3_7xxx_INTR,
MDP_INTF4_7xxx_INTR,
MDP_INTF5_7xxx_INTR,
MDP_INTF6_7xxx_INTR,
MDP_INTF7_7xxx_INTR,
MDP_INTF8_7xxx_INTR,
MDP_INTR_MAX,
};
......
......@@ -120,6 +120,8 @@ enum dpu_sspp {
SSPP_DMA1,
SSPP_DMA2,
SSPP_DMA3,
SSPP_DMA4,
SSPP_DMA5,
SSPP_CURSOR0,
SSPP_CURSOR1,
SSPP_MAX
......@@ -195,6 +197,8 @@ enum dpu_pingpong {
PINGPONG_3,
PINGPONG_4,
PINGPONG_5,
PINGPONG_6,
PINGPONG_7,
PINGPONG_S0,
PINGPONG_MAX
};
......@@ -203,6 +207,7 @@ enum dpu_merge_3d {
MERGE_3D_0 = 1,
MERGE_3D_1,
MERGE_3D_2,
MERGE_3D_3,
MERGE_3D_MAX
};
......@@ -214,6 +219,8 @@ enum dpu_intf {
INTF_4,
INTF_5,
INTF_6,
INTF_7,
INTF_8,
INTF_MAX
};
......
......@@ -7,40 +7,17 @@
#include "dpu_hw_top.h"
#include "dpu_kms.h"
#define SSPP_SPARE 0x28
#define FLD_SPLIT_DISPLAY_CMD BIT(1)
#define FLD_SMART_PANEL_FREE_RUN BIT(2)
#define FLD_INTF_1_SW_TRG_MUX BIT(4)
#define FLD_INTF_2_SW_TRG_MUX BIT(8)
#define FLD_TE_LINE_INTER_WATERLEVEL_MASK 0xFFFF
#define DANGER_STATUS 0x360
#define SAFE_STATUS 0x364
#define TE_LINE_INTERVAL 0x3F4
#define TRAFFIC_SHAPER_EN BIT(31)
#define TRAFFIC_SHAPER_RD_CLIENT(num) (0x030 + (num * 4))
#define TRAFFIC_SHAPER_WR_CLIENT(num) (0x060 + (num * 4))
#define TRAFFIC_SHAPER_FIXPOINT_FACTOR 4
#define MDP_WD_TIMER_0_CTL 0x380
#define MDP_WD_TIMER_0_CTL2 0x384
#define MDP_WD_TIMER_0_LOAD_VALUE 0x388
#define MDP_WD_TIMER_1_CTL 0x390
#define MDP_WD_TIMER_1_CTL2 0x394
#define MDP_WD_TIMER_1_LOAD_VALUE 0x398
#define MDP_WD_TIMER_2_CTL 0x420
#define MDP_WD_TIMER_2_CTL2 0x424
#define MDP_WD_TIMER_2_LOAD_VALUE 0x428
#define MDP_WD_TIMER_3_CTL 0x430
#define MDP_WD_TIMER_3_CTL2 0x434
#define MDP_WD_TIMER_3_LOAD_VALUE 0x438
#define MDP_WD_TIMER_4_CTL 0x440
#define MDP_WD_TIMER_4_CTL2 0x444
#define MDP_WD_TIMER_4_LOAD_VALUE 0x448
#define MDP_TICK_COUNT 16
#define XO_CLK_RATE 19200
#define MS_TICKS_IN_SEC 1000
......@@ -48,8 +25,6 @@
#define CALCULATE_WD_LOAD_VALUE(fps) \
((uint32_t)((MS_TICKS_IN_SEC * XO_CLK_RATE)/(MDP_TICK_COUNT * fps)))
#define DCE_SEL 0x450
static void dpu_hw_setup_split_pipe(struct dpu_hw_mdp *mdp,
struct split_pipe_cfg *cfg)
{
......
......@@ -16,6 +16,7 @@
#define INTR_CLEAR 0x018
#define INTR2_EN 0x008
#define INTR2_STATUS 0x00c
#define SSPP_SPARE 0x028
#define INTR2_CLEAR 0x02c
#define HIST_INTR_EN 0x01c
#define HIST_INTR_STATUS 0x020
......@@ -28,7 +29,15 @@
#define DSPP_IGC_COLOR0_RAM_LUTN 0x300
#define DSPP_IGC_COLOR1_RAM_LUTN 0x304
#define DSPP_IGC_COLOR2_RAM_LUTN 0x308
#define DANGER_STATUS 0x360
#define SAFE_STATUS 0x364
#define HW_EVENTS_CTL 0x37C
#define MDP_WD_TIMER_0_CTL 0x380
#define MDP_WD_TIMER_0_CTL2 0x384
#define MDP_WD_TIMER_0_LOAD_VALUE 0x388
#define MDP_WD_TIMER_1_CTL 0x390
#define MDP_WD_TIMER_1_CTL2 0x394
#define MDP_WD_TIMER_1_LOAD_VALUE 0x398
#define CLK_CTRL3 0x3A8
#define CLK_STATUS3 0x3AC
#define CLK_CTRL4 0x3B0
......@@ -43,6 +52,18 @@
#define HDMI_DP_CORE_SELECT 0x408
#define MDP_OUT_CTL_0 0x410
#define MDP_VSYNC_SEL 0x414
#define MDP_WD_TIMER_2_CTL 0x420
#define MDP_WD_TIMER_2_CTL2 0x424
#define MDP_WD_TIMER_2_LOAD_VALUE 0x428
#define MDP_WD_TIMER_3_CTL 0x430
#define MDP_WD_TIMER_3_CTL2 0x434
#define MDP_WD_TIMER_3_LOAD_VALUE 0x438
#define MDP_WD_TIMER_4_CTL 0x440
#define MDP_WD_TIMER_4_CTL2 0x444
#define MDP_WD_TIMER_4_LOAD_VALUE 0x448
#define DCE_SEL 0x450
#define MDP_PERIPH_TOP0 MDP_WD_TIMER_0_CTL
#define MDP_PERIPH_TOP0_END CLK_CTRL3
#endif /*_DPU_HWIO_H */
......@@ -927,8 +927,15 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k
msm_disp_snapshot_add_block(disp_state, cat->wb[i].len,
dpu_kms->mmio + cat->wb[i].base, "wb_%d", i);
msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len,
dpu_kms->mmio + cat->mdp[0].base, "top");
if (cat->mdp[0].features & BIT(DPU_MDP_PERIPH_0_REMOVED)) {
msm_disp_snapshot_add_block(disp_state, MDP_PERIPH_TOP0,
dpu_kms->mmio + cat->mdp[0].base, "top");
msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len - MDP_PERIPH_TOP0_END,
dpu_kms->mmio + cat->mdp[0].base + MDP_PERIPH_TOP0_END, "top_2");
} else {
msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len,
dpu_kms->mmio + cat->mdp[0].base, "top");
}
pm_runtime_put_sync(&dpu_kms->pdev->dev);
}
......@@ -1292,9 +1299,13 @@ static const struct of_device_id dpu_dt_match[] = {
{ .compatible = "qcom,sc7180-dpu", },
{ .compatible = "qcom,sc7280-dpu", },
{ .compatible = "qcom,sc8180x-dpu", },
{ .compatible = "qcom,sc8280xp-dpu", },
{ .compatible = "qcom,sm6115-dpu", },
{ .compatible = "qcom,sm8150-dpu", },
{ .compatible = "qcom,sm8250-dpu", },
{ .compatible = "qcom,sm8350-dpu", },
{ .compatible = "qcom,sm8450-dpu", },
{ .compatible = "qcom,sm8550-dpu", },
{}
};
MODULE_DEVICE_TABLE(of, dpu_dt_match);
......
......@@ -496,6 +496,11 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
/* check if DSC required are allocated or not */
for (i = 0; i < num_dsc; i++) {
if (!rm->dsc_blks[i]) {
DPU_ERROR("DSC %d does not exist\n", i);
return -EIO;
}
if (global_state->dsc_to_enc_id[i]) {
DPU_ERROR("DSC %d is already allocated\n", i);
return -EIO;
......@@ -543,8 +548,8 @@ static int _dpu_rm_populate_requirements(
{
reqs->topology = req_topology;
DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n",
reqs->topology.num_lm, reqs->topology.num_enc,
DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
reqs->topology.num_lm, reqs->topology.num_dsc,
reqs->topology.num_intf);
return 0;
......@@ -660,6 +665,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
blks_size, enc_id);
break;
}
if (!hw_blks[i]) {
DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n",
type, enc_id);
break;
}
blks[num_blks++] = hw_blks[i];
}
......
......@@ -70,6 +70,8 @@ int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
int rc = 0;
dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), GFP_KERNEL);
if (!dpu_wb_conn)
return -ENOMEM;
drm_connector_helper_add(&dpu_wb_conn->base.base, &dpu_wb_conn_helper_funcs);
......
......@@ -69,8 +69,7 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms);
struct drm_device *dev = mdp4_kms->dev;
struct msm_drm_private *priv = dev->dev_private;
unsigned int id;
struct drm_crtc *crtc;
uint32_t status, enable;
enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE);
......@@ -81,9 +80,9 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
mdp_dispatch_irqs(mdp_kms, status);
for (id = 0; id < priv->num_crtcs; id++)
if (status & mdp4_crtc_vblank(priv->crtcs[id]))
drm_handle_vblank(dev, id);
drm_for_each_crtc(crtc, dev)
if (status & mdp4_crtc_vblank(crtc))
drm_crtc_handle_vblank(crtc);
return IRQ_HANDLED;
}
......
......@@ -82,8 +82,7 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
struct drm_device *dev = mdp5_kms->dev;
struct msm_drm_private *priv = dev->dev_private;
unsigned int id;
struct drm_crtc *crtc;
uint32_t status, enable;
enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN);
......@@ -94,9 +93,9 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
mdp_dispatch_irqs(mdp_kms, status);
for (id = 0; id < priv->num_crtcs; id++)
if (status & mdp5_crtc_vblank(priv->crtcs[id]))
drm_handle_vblank(dev, id);
drm_for_each_crtc(crtc, dev)
if (status & mdp5_crtc_vblank(crtc))
drm_crtc_handle_vblank(crtc);
return IRQ_HANDLED;
}
......
......@@ -423,6 +423,10 @@ void dp_aux_isr(struct drm_dp_aux *dp_aux)
isr = dp_catalog_aux_get_irq(aux->catalog);
/* no interrupts pending, return immediately */
if (!isr)
return;
if (!aux->cmd_busy)
return;
......
This diff is collapsed.
......@@ -21,6 +21,7 @@ struct msm_dp {
bool power_on;
unsigned int connector_type;
bool is_edp;
bool internal_hpd;
hdmi_codec_plugged_cb plugged_cb;
......
......@@ -102,6 +102,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
.get_modes = dp_bridge_get_modes,
.detect = dp_bridge_detect,
.atomic_check = dp_bridge_atomic_check,
.hpd_enable = dp_bridge_hpd_enable,
.hpd_disable = dp_bridge_hpd_disable,
.hpd_notify = dp_bridge_hpd_notify,
};
struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
......
......@@ -32,5 +32,9 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode);
void dp_bridge_hpd_enable(struct drm_bridge *bridge);
void dp_bridge_hpd_disable(struct drm_bridge *bridge);
void dp_bridge_hpd_notify(struct drm_bridge *bridge,
enum drm_connector_status status);
#endif /* _DP_DRM_H_ */
......@@ -75,12 +75,13 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel)
link_info->rate = drm_dp_bw_code_to_link_rate(dpcd[DP_MAX_LINK_RATE]);
link_info->num_lanes = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
/* Limit data lanes from data-lanes of endpoint property of dtsi */
if (link_info->num_lanes > dp_panel->max_dp_lanes)
link_info->num_lanes = dp_panel->max_dp_lanes;
/* Limit support upto HBR2 until HBR3 support is added */
if (link_info->rate >= (drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4)))
link_info->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4);
/* Limit link rate from link-frequencies of endpoint property of dtsi */
if (link_info->rate > dp_panel->max_dp_link_rate)
link_info->rate = dp_panel->max_dp_link_rate;
drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
......
......@@ -50,6 +50,7 @@ struct dp_panel {
u32 vic;
u32 max_dp_lanes;
u32 max_dp_link_rate;
u32 max_bw_code;
};
......
......@@ -91,19 +91,53 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
return 0;
}
static u32 dp_parser_link_frequencies(struct device_node *of_node)
{
struct device_node *endpoint;
u64 frequency = 0;
int cnt;
endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */
if (!endpoint)
return 0;
cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
if (cnt > 0)
of_property_read_u64_index(endpoint, "link-frequencies",
cnt - 1, &frequency);
of_node_put(endpoint);
do_div(frequency,
10 * /* from symbol rate to link rate */
1000); /* kbytes */
return frequency;
}
static int dp_parser_misc(struct dp_parser *parser)
{
struct device_node *of_node = parser->pdev->dev.of_node;
int len;
len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
if (len < 0) {
DRM_WARN("Invalid property \"data-lanes\", default max DP lanes = %d\n",
DP_MAX_NUM_DP_LANES);
len = DP_MAX_NUM_DP_LANES;
int cnt;
/*
* data-lanes is the property of dp_out endpoint
*/
cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
if (cnt < 0) {
/* legacy code, data-lanes is the property of mdss_dp node */
cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
}
parser->max_dp_lanes = len;
if (cnt > 0)
parser->max_dp_lanes = cnt;
else
parser->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
parser->max_dp_link_rate = dp_parser_link_frequencies(of_node);
if (!parser->max_dp_link_rate)
parser->max_dp_link_rate = DP_LINK_RATE_HBR2;
return 0;
}
......
......@@ -15,6 +15,7 @@
#define DP_LABEL "MDSS DP DISPLAY"
#define DP_MAX_PIXEL_CLK_KHZ 675000
#define DP_MAX_NUM_DP_LANES 4
#define DP_LINK_RATE_HBR2 540000 /* kbytes */
enum dp_pm_type {
DP_CORE_PM,
......@@ -119,6 +120,7 @@ struct dp_parser {
struct dp_io io;
struct dp_display_data disp_data;
u32 max_dp_lanes;
u32 max_dp_link_rate;
struct drm_bridge *next_bridge;
int (*parse)(struct dp_parser *parser);
......
......@@ -118,6 +118,8 @@ int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_dsi,
const struct drm_display_mode *mode);
int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
......@@ -139,6 +141,7 @@ struct msm_dsi_phy_shared_timings {
u32 clk_post;
u32 clk_pre;
bool clk_pre_inc_by_2;
bool byte_intf_clk_div_2;
};
struct msm_dsi_phy_clk_request {
......
......@@ -181,6 +181,20 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
.num_dsi = 2,
};
static const struct regulator_bulk_data sm8550_dsi_regulators[] = {
{ .supply = "vdda", .init_load_uA = 16800 }, /* 1.2 V */
};
static const struct msm_dsi_config sm8550_dsi_cfg = {
.io_offset = DSI_6G_REG_SHIFT,
.regulator_data = sm8550_dsi_regulators,
.num_regulators = ARRAY_SIZE(sm8550_dsi_regulators),
.bus_clk_names = dsi_sdm845_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sdm845_bus_clk_names),
.io_start = { 0xae94000, 0xae96000 },
.num_dsi = 2,
};
static const struct regulator_bulk_data sc7180_dsi_regulators[] = {
{ .supply = "vdda", .init_load_uA = 21800 }, /* 1.2 V */
};
......@@ -209,8 +223,8 @@ static const struct msm_dsi_config sc7280_dsi_cfg = {
.num_regulators = ARRAY_SIZE(sc7280_dsi_regulators),
.bus_clk_names = dsi_sc7280_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sc7280_bus_clk_names),
.io_start = { 0xae94000 },
.num_dsi = 1,
.io_start = { 0xae94000, 0xae96000 },
.num_dsi = 2,
};
static const char * const dsi_qcm2290_bus_clk_names[] = {
......@@ -300,6 +314,10 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
&sc7180_dsi_cfg, &msm_dsi_6g_v2_host_ops},
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_0,
&sc7280_dsi_cfg, &msm_dsi_6g_v2_host_ops},
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_6_0,
&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0,
&sm8550_dsi_cfg, &msm_dsi_6g_v2_host_ops},
};
const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
......
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