Commit 82461ab8 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov

Merge branches 'msm-next-lumag-core', 'msm-next-lumag-dpu',...

Merge branches 'msm-next-lumag-core', 'msm-next-lumag-dpu', 'msm-next-lumag-dp', 'msm-next-lumag-dsi', 'msm-next-lumag-hdmi', 'msm-next-lumag-mdp5' and 'msm-next-lumag-mdp4' into msm-next-lumag

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>
...@@ -21,6 +21,9 @@ properties: ...@@ -21,6 +21,9 @@ properties:
- qcom,sc7280-edp - qcom,sc7280-edp
- qcom,sc8180x-dp - qcom,sc8180x-dp
- qcom,sc8180x-edp - qcom,sc8180x-edp
- qcom,sc8280xp-dp
- qcom,sc8280xp-edp
- qcom,sdm845-dp
- qcom,sm8350-dp - qcom,sm8350-dp
reg: reg:
...@@ -81,6 +84,7 @@ properties: ...@@ -81,6 +84,7 @@ properties:
data-lanes: data-lanes:
$ref: /schemas/types.yaml#/definitions/uint32-array $ref: /schemas/types.yaml#/definitions/uint32-array
deprecated: true
minItems: 1 minItems: 1
maxItems: 4 maxItems: 4
items: items:
...@@ -102,8 +106,28 @@ properties: ...@@ -102,8 +106,28 @@ properties:
description: Input endpoint of the controller description: Input endpoint of the controller
port@1: port@1:
$ref: /schemas/graph.yaml#/properties/port $ref: /schemas/graph.yaml#/$defs/port-base
description: Output endpoint of the controller 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: required:
- compatible - compatible
...@@ -127,11 +151,10 @@ allOf: ...@@ -127,11 +151,10 @@ allOf:
enum: enum:
- qcom,sc7280-edp - qcom,sc7280-edp
- qcom,sc8180x-edp - qcom,sc8180x-edp
- qcom,sc8280xp-edp
then: then:
properties: properties:
"#sound-dai-cells": false "#sound-dai-cells": false
reg:
maxItems: 4
else: else:
properties: properties:
aux-bus: false aux-bus: false
...@@ -193,6 +216,8 @@ examples: ...@@ -193,6 +216,8 @@ examples:
reg = <1>; reg = <1>;
endpoint { endpoint {
remote-endpoint = <&typec>; remote-endpoint = <&typec>;
data-lanes = <0 1>;
link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
}; };
}; };
}; };
......
...@@ -48,10 +48,6 @@ properties: ...@@ -48,10 +48,6 @@ properties:
- port@0 - port@0
required: required:
- compatible
- reg
- reg-names
- clocks
- interrupts - interrupts
- power-domains - power-domains
- operating-points-v2 - operating-points-v2
......
...@@ -127,6 +127,18 @@ properties: ...@@ -127,6 +127,18 @@ properties:
- port@0 - port@0
- port@1 - port@1
vdd-supply:
description:
VDD regulator
vddio-supply:
description:
VDD-IO regulator
vdda-supply:
description:
VDDA regulator
required: required:
- compatible - compatible
- reg - reg
......
...@@ -16,6 +16,7 @@ properties: ...@@ -16,6 +16,7 @@ properties:
compatible: compatible:
enum: enum:
- qcom,dsi-phy-28nm-hpm - qcom,dsi-phy-28nm-hpm
- qcom,dsi-phy-28nm-hpm-fam-b
- qcom,dsi-phy-28nm-lp - qcom,dsi-phy-28nm-lp
- qcom,dsi-phy-28nm-8960 - qcom,dsi-phy-28nm-8960
......
...@@ -18,6 +18,10 @@ properties: ...@@ -18,6 +18,10 @@ properties:
- qcom,dsi-phy-7nm - qcom,dsi-phy-7nm
- qcom,dsi-phy-7nm-8150 - qcom,dsi-phy-7nm-8150
- qcom,sc7280-dsi-phy-7nm - 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: reg:
items: items:
...@@ -44,7 +48,6 @@ required: ...@@ -44,7 +48,6 @@ required:
- compatible - compatible
- reg - reg
- reg-names - reg-names
- vdds-supply
unevaluatedProperties: false unevaluatedProperties: false
......
...@@ -4,14 +4,13 @@ ...@@ -4,14 +4,13 @@
$id: http://devicetree.org/schemas/display/msm/dsi-phy-common.yaml# $id: http://devicetree.org/schemas/display/msm/dsi-phy-common.yaml#
$schema: http://devicetree.org/meta-schemas/core.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: maintainers:
- Krishna Manikandan <quic_mkrishn@quicinc.com> - Krishna Manikandan <quic_mkrishn@quicinc.com>
description: | description:
This defines the DSI PHY dt properties which are common for all Common properties for Qualcomm Display DSI PHY.
dsi phy versions.
properties: properties:
"#clock-cells": "#clock-cells":
......
...@@ -123,12 +123,6 @@ patternProperties: ...@@ -123,12 +123,6 @@ patternProperties:
- qcom,dsi-phy-20nm - qcom,dsi-phy-20nm
- qcom,dsi-phy-28nm-hpm - qcom,dsi-phy-28nm-hpm
- qcom,dsi-phy-28nm-lp - 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-8084
- qcom,hdmi-phy-8660 - qcom,hdmi-phy-8660
- qcom,hdmi-phy-8960 - qcom,hdmi-phy-8960
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,msm8998-dpu.yaml# $id: http://devicetree.org/schemas/display/msm/qcom,msm8998-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.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: maintainers:
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org> - AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
...@@ -45,6 +45,13 @@ properties: ...@@ -45,6 +45,13 @@ properties:
- const: core - const: core
- const: vsync - const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-dpu.yaml# $id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.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: maintainers:
- Loic Poulain <loic.poulain@linaro.org> - Loic Poulain <loic.poulain@linaro.org>
...@@ -41,6 +41,13 @@ properties: ...@@ -41,6 +41,13 @@ properties:
- const: lut - const: lut
- const: vsync - const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,sc7180-dpu.yaml# $id: http://devicetree.org/schemas/display/msm/qcom,sc7180-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.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: maintainers:
- Krishna Manikandan <quic_mkrishn@quicinc.com> - Krishna Manikandan <quic_mkrishn@quicinc.com>
...@@ -43,6 +43,13 @@ properties: ...@@ -43,6 +43,13 @@ properties:
- const: core - const: core
- const: vsync - const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,sc7280-dpu.yaml# $id: http://devicetree.org/schemas/display/msm/qcom,sc7280-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display DPU dt properties for SC7280 title: Qualcomm Display DPU on SC7280
maintainers: maintainers:
- Krishna Manikandan <quic_mkrishn@quicinc.com> - Krishna Manikandan <quic_mkrishn@quicinc.com>
...@@ -43,6 +43,13 @@ properties: ...@@ -43,6 +43,13 @@ properties:
- const: core - const: core
- const: vsync - const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false unevaluatedProperties: false
examples: 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 @@ ...@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,sdm845-dpu.yaml# $id: http://devicetree.org/schemas/display/msm/qcom,sdm845-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.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: maintainers:
- Krishna Manikandan <quic_mkrishn@quicinc.com> - Krishna Manikandan <quic_mkrishn@quicinc.com>
...@@ -41,6 +41,13 @@ properties: ...@@ -41,6 +41,13 @@ properties:
- const: core - const: core
- const: vsync - const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false unevaluatedProperties: false
examples: examples:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/display/msm/qcom,sm6115-dpu.yaml# $id: http://devicetree.org/schemas/display/msm/qcom,sm6115-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.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: maintainers:
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org> - Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
......
...@@ -39,6 +39,13 @@ properties: ...@@ -39,6 +39,13 @@ properties:
- const: core - const: core
- const: vsync - const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false unevaluatedProperties: false
examples: 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>;
};
};
};
...
...@@ -140,12 +140,12 @@ config DRM_MSM_DSI_10NM_PHY ...@@ -140,12 +140,12 @@ config DRM_MSM_DSI_10NM_PHY
Choose this option if DSI PHY on SDM845 is used on the platform. Choose this option if DSI PHY on SDM845 is used on the platform.
config DRM_MSM_DSI_7NM_PHY 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 depends on DRM_MSM_DSI
default y default y
help help
Choose this option if DSI PHY on SM8150/SM8250/SC7280 is used on Choose this option if DSI PHY on SM8150/SM8250/SM8350/SM8450/SM8550/SC7280
the platform. is used on the platform.
config DRM_MSM_HDMI config DRM_MSM_HDMI
bool "Enable HDMI support in MSM DRM driver" bool "Enable HDMI support in MSM DRM driver"
......
...@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc) ...@@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
int i; int i;
if (!state->color_mgmt_changed) if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
return; return;
for (i = 0; i < cstate->num_mixers; i++) { for (i = 0; i < cstate->num_mixers; i++) {
...@@ -1517,16 +1517,12 @@ DEFINE_SHOW_ATTRIBUTE(dpu_crtc_debugfs_state); ...@@ -1517,16 +1517,12 @@ DEFINE_SHOW_ATTRIBUTE(dpu_crtc_debugfs_state);
static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc) static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc)
{ {
struct dpu_crtc *dpu_crtc = to_dpu_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_create_file("status", 0400,
debugfs_root, crtc->debugfs_entry,
dpu_crtc, &_dpu_debugfs_status_fops); dpu_crtc, &_dpu_debugfs_status_fops);
debugfs_create_file("state", 0600, debugfs_create_file("state", 0600,
debugfs_root, crtc->debugfs_entry,
&dpu_crtc->base, &dpu_crtc->base,
&dpu_crtc_debugfs_state_fops); &dpu_crtc_debugfs_state_fops);
......
...@@ -162,6 +162,7 @@ enum dpu_enc_rc_states { ...@@ -162,6 +162,7 @@ enum dpu_enc_rc_states {
* @vsync_event_work: worker to handle vsync event for autorefresh * @vsync_event_work: worker to handle vsync event for autorefresh
* @topology: topology of the display * @topology: topology of the display
* @idle_timeout: idle timeout duration in milliseconds * @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 * @dsc: drm_dsc_config pointer, for DSC-enabled encoders
*/ */
struct dpu_encoder_virt { struct dpu_encoder_virt {
...@@ -340,9 +341,7 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc, ...@@ -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->intf_idx - INTF_0, phys_enc->wb_idx - WB_0,
phys_enc->hw_pp->idx - PINGPONG_0, intr_idx); phys_enc->hw_pp->idx - PINGPONG_0, intr_idx);
if (phys_enc->parent_ops->handle_frame_done) dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
phys_enc->parent_ops->handle_frame_done(
phys_enc->parent, phys_enc,
DPU_ENCODER_FRAME_EVENT_ERROR); DPU_ENCODER_FRAME_EVENT_ERROR);
} }
...@@ -579,19 +578,18 @@ static struct msm_display_topology dpu_encoder_get_topology( ...@@ -579,19 +578,18 @@ static struct msm_display_topology dpu_encoder_get_topology(
topology.num_dspp = topology.num_lm; topology.num_dspp = topology.num_lm;
} }
topology.num_enc = 0;
topology.num_intf = intf_count; topology.num_intf = intf_count;
if (dpu_enc->dsc) { 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 * this is power optimal and can drive up to (including) 4k
* screens * screens
*/ */
topology.num_enc = 2;
topology.num_dsc = 2; topology.num_dsc = 2;
topology.num_intf = 1;
topology.num_lm = 2; topology.num_lm = 2;
topology.num_intf = 1;
} }
return topology; return topology;
...@@ -1284,7 +1282,7 @@ static enum dpu_wb dpu_encoder_get_wb(const struct dpu_mdss_cfg *catalog, ...@@ -1284,7 +1282,7 @@ static enum dpu_wb dpu_encoder_get_wb(const struct dpu_mdss_cfg *catalog,
return WB_MAX; 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_phys *phy_enc)
{ {
struct dpu_encoder_virt *dpu_enc = NULL; struct dpu_encoder_virt *dpu_enc = NULL;
...@@ -1306,7 +1304,7 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, ...@@ -1306,7 +1304,7 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
DPU_ATRACE_END("encoder_vblank_callback"); 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) struct dpu_encoder_phys *phy_enc)
{ {
if (!phy_enc) if (!phy_enc)
...@@ -1382,7 +1380,7 @@ void dpu_encoder_register_frame_event_callback(struct drm_encoder *drm_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); 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 drm_encoder *drm_enc,
struct dpu_encoder_phys *ready_phys, u32 event) 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, ...@@ -1830,6 +1828,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
if (hw_pp->ops.setup_dsc) if (hw_pp->ops.setup_dsc)
hw_pp->ops.setup_dsc(hw_pp); 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) if (hw_pp->ops.enable_dsc)
hw_pp->ops.enable_dsc(hw_pp); hw_pp->ops.enable_dsc(hw_pp);
} }
...@@ -2233,12 +2234,6 @@ static int dpu_encoder_virt_add_phys_encs( ...@@ -2233,12 +2234,6 @@ static int dpu_encoder_virt_add_phys_encs(
return 0; 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, static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms, struct dpu_kms *dpu_kms,
struct msm_display_info *disp_info) struct msm_display_info *disp_info)
...@@ -2258,7 +2253,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, ...@@ -2258,7 +2253,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
memset(&phys_params, 0, sizeof(phys_params)); memset(&phys_params, 0, sizeof(phys_params));
phys_params.dpu_kms = dpu_kms; phys_params.dpu_kms = dpu_kms;
phys_params.parent = &dpu_enc->base; phys_params.parent = &dpu_enc->base;
phys_params.parent_ops = &dpu_encoder_parent_ops;
phys_params.enc_spinlock = &dpu_enc->enc_spinlock; phys_params.enc_spinlock = &dpu_enc->enc_spinlock;
switch (disp_info->intf_type) { switch (disp_info->intf_type) {
......
...@@ -60,25 +60,6 @@ enum dpu_enc_enable_state { ...@@ -60,25 +60,6 @@ enum dpu_enc_enable_state {
struct dpu_encoder_phys; 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 * struct dpu_encoder_phys_ops - Interface the physical encoders provide to
* the containing virtual encoder. * the containing virtual encoder.
...@@ -199,7 +180,6 @@ enum dpu_intr_idx { ...@@ -199,7 +180,6 @@ enum dpu_intr_idx {
struct dpu_encoder_phys { struct dpu_encoder_phys {
struct drm_encoder *parent; struct drm_encoder *parent;
struct dpu_encoder_phys_ops ops; struct dpu_encoder_phys_ops ops;
const struct dpu_encoder_virt_ops *parent_ops;
struct dpu_hw_mdp *hw_mdptop; struct dpu_hw_mdp *hw_mdptop;
struct dpu_hw_ctl *hw_ctl; struct dpu_hw_ctl *hw_ctl;
struct dpu_hw_pingpong *hw_pp; struct dpu_hw_pingpong *hw_pp;
...@@ -283,7 +263,6 @@ struct dpu_encoder_phys_cmd { ...@@ -283,7 +263,6 @@ struct dpu_encoder_phys_cmd {
struct dpu_enc_phys_init_params { struct dpu_enc_phys_init_params {
struct dpu_kms *dpu_kms; struct dpu_kms *dpu_kms;
struct drm_encoder *parent; struct drm_encoder *parent;
const struct dpu_encoder_virt_ops *parent_ops;
enum dpu_enc_split_role split_role; enum dpu_enc_split_role split_role;
enum dpu_intf intf_idx; enum dpu_intf intf_idx;
enum dpu_wb wb_idx; enum dpu_wb wb_idx;
...@@ -400,4 +379,30 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, ...@@ -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); 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__ */ #endif /* __dpu_encoder_phys_H__ */
...@@ -61,6 +61,7 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( ...@@ -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.intf_mode_sel = DPU_CTL_MODE_SEL_CMD;
intf_cfg.stream_sel = cmd_enc->stream_sel; intf_cfg.stream_sel = cmd_enc->stream_sel;
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); 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); ctl->ops.setup_intf_cfg(ctl, &intf_cfg);
/* setup which pp blk will connect to this intf */ /* 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) ...@@ -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"); DPU_ATRACE_BEGIN("pp_done_irq");
/* notify all synchronous clients first, then asynchronous clients */ /* notify all synchronous clients first, then asynchronous clients */
if (phys_enc->parent_ops->handle_frame_done) dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
phys_enc->parent_ops->handle_frame_done(phys_enc->parent,
phys_enc, event);
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); 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) ...@@ -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"); DPU_ATRACE_BEGIN("rd_ptr_irq");
cmd_enc = to_dpu_encoder_phys_cmd(phys_enc); cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
if (phys_enc->parent_ops->handle_vblank_virt) dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
phys_enc);
atomic_add_unless(&cmd_enc->pending_vblank_cnt, -1, 0); atomic_add_unless(&cmd_enc->pending_vblank_cnt, -1, 0);
wake_up_all(&cmd_enc->pending_vblank_wq); 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) ...@@ -137,9 +134,7 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)
{ {
struct dpu_encoder_phys *phys_enc = arg; struct dpu_encoder_phys *phys_enc = arg;
if (phys_enc->parent_ops->handle_underrun_virt) dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
phys_enc->parent_ops->handle_underrun_virt(phys_enc->parent,
phys_enc);
} }
static void dpu_encoder_phys_cmd_atomic_mode_set( static void dpu_encoder_phys_cmd_atomic_mode_set(
...@@ -202,9 +197,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout( ...@@ -202,9 +197,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
/* request a ctl reset before the next kickoff */ /* request a ctl reset before the next kickoff */
phys_enc->enable_state = DPU_ENC_ERR_NEEDS_HW_RESET; phys_enc->enable_state = DPU_ENC_ERR_NEEDS_HW_RESET;
if (phys_enc->parent_ops->handle_frame_done) dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
phys_enc->parent_ops->handle_frame_done(
drm_enc, phys_enc, frame_event);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -780,7 +773,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( ...@@ -780,7 +773,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
dpu_encoder_phys_cmd_init_ops(&phys_enc->ops); dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent; phys_enc->parent = p->parent;
phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms; phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role; phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_CMD; phys_enc->intf_mode = INTF_MODE_CMD;
......
...@@ -273,6 +273,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine( ...@@ -273,6 +273,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID; intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID;
intf_cfg.stream_sel = 0; /* Don't care value for video mode */ 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.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) if (phys_enc->hw_pp->merge_3d)
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
...@@ -307,9 +308,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) ...@@ -307,9 +308,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
DPU_ATRACE_BEGIN("vblank_irq"); DPU_ATRACE_BEGIN("vblank_irq");
if (phys_enc->parent_ops->handle_vblank_virt) dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
phys_enc);
atomic_read(&phys_enc->pending_kickoff_cnt); atomic_read(&phys_enc->pending_kickoff_cnt);
...@@ -329,7 +328,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) ...@@ -329,7 +328,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
/* Signal any waiting atomic commit thread */ /* Signal any waiting atomic commit thread */
wake_up_all(&phys_enc->pending_kickoff_wq); 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_ENCODER_FRAME_EVENT_DONE);
DPU_ATRACE_END("vblank_irq"); DPU_ATRACE_END("vblank_irq");
...@@ -339,9 +338,7 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx) ...@@ -339,9 +338,7 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
{ {
struct dpu_encoder_phys *phys_enc = arg; struct dpu_encoder_phys *phys_enc = arg;
if (phys_enc->parent_ops->handle_underrun_virt) dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
phys_enc->parent_ops->handle_underrun_virt(phys_enc->parent,
phys_enc);
} }
static bool dpu_encoder_phys_vid_needs_single_flush( static bool dpu_encoder_phys_vid_needs_single_flush(
...@@ -697,7 +694,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( ...@@ -697,7 +694,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
dpu_encoder_phys_vid_init_ops(&phys_enc->ops); dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent; phys_enc->parent = p->parent;
phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms; phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role; phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_VIDEO; phys_enc->intf_mode = INTF_MODE_VIDEO;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
/** /**
* dpu_encoder_phys_wb_is_master - report wb always as master encoder * 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) static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys *phys_enc)
{ {
...@@ -364,13 +365,9 @@ static void _dpu_encoder_phys_wb_frame_done_helper(void *arg) ...@@ -364,13 +365,9 @@ static void _dpu_encoder_phys_wb_frame_done_helper(void *arg)
DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
if (phys_enc->parent_ops->handle_frame_done) dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
phys_enc->parent_ops->handle_frame_done(phys_enc->parent,
phys_enc, event);
if (phys_enc->parent_ops->handle_vblank_virt) dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
phys_enc);
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
...@@ -440,9 +437,7 @@ static void _dpu_encoder_phys_wb_handle_wbdone_timeout( ...@@ -440,9 +437,7 @@ static void _dpu_encoder_phys_wb_handle_wbdone_timeout(
if (wb_enc->wb_conn) if (wb_enc->wb_conn)
drm_writeback_signal_completion(wb_enc->wb_conn, 0); drm_writeback_signal_completion(wb_enc->wb_conn, 0);
if (phys_enc->parent_ops->handle_frame_done) dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
phys_enc->parent_ops->handle_frame_done(
phys_enc->parent, phys_enc, frame_event);
} }
/** /**
...@@ -722,7 +717,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init( ...@@ -722,7 +717,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
dpu_encoder_phys_wb_init_ops(&phys_enc->ops); dpu_encoder_phys_wb_init_ops(&phys_enc->ops);
phys_enc->parent = p->parent; phys_enc->parent = p->parent;
phys_enc->parent_ops = p->parent_ops;
phys_enc->dpu_kms = p->dpu_kms; phys_enc->dpu_kms = p->dpu_kms;
phys_enc->split_role = p->split_role; phys_enc->split_role = p->split_role;
phys_enc->intf_mode = INTF_MODE_WB_LINE; phys_enc->intf_mode = INTF_MODE_WB_LINE;
......
...@@ -46,7 +46,11 @@ ...@@ -46,7 +46,11 @@
#define DPU_HW_VER_620 DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */ #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_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_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_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_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) #define IS_MSM8998_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_300)
...@@ -83,6 +87,8 @@ enum { ...@@ -83,6 +87,8 @@ enum {
* @DPU_MDP_UBWC_1_0, This chipsets supports Universal Bandwidth * @DPU_MDP_UBWC_1_0, This chipsets supports Universal Bandwidth
* compression initial revision * compression initial revision
* @DPU_MDP_UBWC_1_5, Universal Bandwidth compression version 1.5 * @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 * @DPU_MDP_MAX Maximum value
*/ */
...@@ -93,6 +99,7 @@ enum { ...@@ -93,6 +99,7 @@ enum {
DPU_MDP_UBWC_1_0, DPU_MDP_UBWC_1_0,
DPU_MDP_UBWC_1_5, DPU_MDP_UBWC_1_5,
DPU_MDP_AUDIO_SELECT, DPU_MDP_AUDIO_SELECT,
DPU_MDP_PERIPH_0_REMOVED,
DPU_MDP_MAX DPU_MDP_MAX
}; };
...@@ -192,6 +199,7 @@ enum { ...@@ -192,6 +199,7 @@ enum {
* @DPU_CTL_SPLIT_DISPLAY: CTL supports video mode split display * @DPU_CTL_SPLIT_DISPLAY: CTL supports video mode split display
* @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs) * @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs)
* @DPU_CTL_VM_CFG: CTL config to support multiple VMs * @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 * @DPU_CTL_MAX
*/ */
enum { enum {
...@@ -199,6 +207,7 @@ enum { ...@@ -199,6 +207,7 @@ enum {
DPU_CTL_ACTIVE_CFG, DPU_CTL_ACTIVE_CFG,
DPU_CTL_FETCH_ACTIVE, DPU_CTL_FETCH_ACTIVE,
DPU_CTL_VM_CFG, DPU_CTL_VM_CFG,
DPU_CTL_HAS_LAYER_EXT4,
DPU_CTL_MAX DPU_CTL_MAX
}; };
...@@ -266,6 +275,15 @@ enum { ...@@ -266,6 +275,15 @@ enum {
DPU_VBIF_MAX 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 * MACRO DPU_HW_BLK_INFO - information of HW blocks inside DPU
* @name: string name for debug purposes * @name: string name for debug purposes
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
(0x70 + (((lm) - LM_0) * 0x004)) (0x70 + (((lm) - LM_0) * 0x004))
#define CTL_LAYER_EXT3(lm) \ #define CTL_LAYER_EXT3(lm) \
(0xA0 + (((lm) - LM_0) * 0x004)) (0xA0 + (((lm) - LM_0) * 0x004))
#define CTL_LAYER_EXT4(lm) \
(0xB8 + (((lm) - LM_0) * 0x004))
#define CTL_TOP 0x014 #define CTL_TOP 0x014
#define CTL_FLUSH 0x018 #define CTL_FLUSH 0x018
#define CTL_START 0x01C #define CTL_START 0x01C
...@@ -377,12 +379,37 @@ static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx) ...@@ -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); 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, static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg) enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
{ {
struct dpu_hw_blk_reg_map *c = &ctx->hw; struct dpu_hw_blk_reg_map *c = &ctx->hw;
u32 mixercfg = 0, mixercfg_ext = 0, mix, ext; u32 mix, ext, mix_ext;
u32 mixercfg_ext2 = 0, mixercfg_ext3 = 0; u32 mixercfg[5] = { 0 };
int i, j; int i, j;
int stages; int stages;
int pipes_per_stage; int pipes_per_stage;
...@@ -397,7 +424,7 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx, ...@@ -397,7 +424,7 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
else else
pipes_per_stage = 1; 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) if (!stage_cfg)
goto exit; goto exit;
...@@ -406,109 +433,35 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx, ...@@ -406,109 +433,35 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
/* overflow to ext register if 'i + 1 > 7' */ /* overflow to ext register if 'i + 1 > 7' */
mix = (i + 1) & 0x7; mix = (i + 1) & 0x7;
ext = i >= 7; ext = i >= 7;
mix_ext = (i + 1) & 0xf;
for (j = 0 ; j < pipes_per_stage; j++) { for (j = 0 ; j < pipes_per_stage; j++) {
enum dpu_sspp_multirect_index rect_index = enum dpu_sspp_multirect_index rect_index =
stage_cfg->multirect_index[i][j]; stage_cfg->multirect_index[i][j];
enum dpu_sspp pipe = stage_cfg->stage[i][j];
switch (stage_cfg->stage[i][j]) { const struct ctl_blend_config *cfg =
case SSPP_VIG0: &ctl_blend_config[pipe][rect_index == DPU_SSPP_RECT_1];
if (rect_index == DPU_SSPP_RECT_1) {
mixercfg_ext3 |= ((i + 1) & 0xF) << 0; /*
} else { * CTL_LAYER has 3-bit field (and extra bits in EXT register),
mixercfg |= mix << 0; * all EXT registers has 4-bit fields.
mixercfg_ext |= ext << 0; */
} if (cfg->idx == 0) {
break; mixercfg[0] |= mix << cfg->shift;
case SSPP_VIG1: mixercfg[1] |= ext << cfg->ext_shift;
if (rect_index == DPU_SSPP_RECT_1) { } else {
mixercfg_ext3 |= ((i + 1) & 0xF) << 4; mixercfg[cfg->idx] |= mix_ext << cfg->shift;
} 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;
} }
} }
} }
exit: exit:
DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg); DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg[0]);
DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext); DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg[1]);
DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg_ext2); DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg[2]);
DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3); 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 @@ ...@@ -29,6 +29,8 @@
#define DSC_RANGE_MAX_QP 0x0B0 #define DSC_RANGE_MAX_QP 0x0B0
#define DSC_RANGE_BPG_OFFSET 0x0EC #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) static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc)
{ {
struct dpu_hw_blk_reg_map *c = &dsc->hw; 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, ...@@ -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, static struct dpu_dsc_cfg *_dsc_offset(enum dpu_dsc dsc,
const struct dpu_mdss_cfg *m, const struct dpu_mdss_cfg *m,
void __iomem *addr, void __iomem *addr,
...@@ -174,6 +199,8 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops, ...@@ -174,6 +199,8 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops,
ops->dsc_disable = dpu_hw_dsc_disable; ops->dsc_disable = dpu_hw_dsc_disable;
ops->dsc_config = dpu_hw_dsc_config; ops->dsc_config = dpu_hw_dsc_config;
ops->dsc_config_thresh = dpu_hw_dsc_config_thresh; 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, struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr,
......
...@@ -42,6 +42,10 @@ struct dpu_hw_dsc_ops { ...@@ -42,6 +42,10 @@ struct dpu_hw_dsc_ops {
*/ */
void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc, void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc,
struct drm_dsc_config *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 { struct dpu_hw_dsc {
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#define MDP_INTF_3_OFF_REV_7xxx 0x37000 #define MDP_INTF_3_OFF_REV_7xxx 0x37000
#define MDP_INTF_4_OFF_REV_7xxx 0x38000 #define MDP_INTF_4_OFF_REV_7xxx 0x38000
#define MDP_INTF_5_OFF_REV_7xxx 0x39000 #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 * struct dpu_intr_reg - array of DPU register sets
...@@ -139,6 +142,21 @@ static const struct dpu_intr_reg dpu_intr_set[] = { ...@@ -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_EN,
MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_STATUS 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) #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) ...@@ -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]; cache_irq_mask = intr->cache_irq_mask[reg_idx];
if (cache_irq_mask & DPU_IRQ_MASK(irq_idx)) { if (cache_irq_mask & DPU_IRQ_MASK(irq_idx)) {
dbgstr = "DPU IRQ already set:"; dbgstr = "already ";
} else { } else {
dbgstr = "DPU IRQ enabled:"; dbgstr = "";
cache_irq_mask |= DPU_IRQ_MASK(irq_idx); cache_irq_mask |= DPU_IRQ_MASK(irq_idx);
/* Cleaning any pending interrupt */ /* Cleaning any pending interrupt */
...@@ -268,7 +286,7 @@ static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx) ...@@ -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; 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); DPU_IRQ_MASK(irq_idx), cache_irq_mask);
return 0; return 0;
...@@ -301,9 +319,9 @@ static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, int irq_idx) ...@@ -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]; cache_irq_mask = intr->cache_irq_mask[reg_idx];
if ((cache_irq_mask & DPU_IRQ_MASK(irq_idx)) == 0) { if ((cache_irq_mask & DPU_IRQ_MASK(irq_idx)) == 0) {
dbgstr = "DPU IRQ is already cleared:"; dbgstr = "already ";
} else { } else {
dbgstr = "DPU IRQ mask disable:"; dbgstr = "";
cache_irq_mask &= ~DPU_IRQ_MASK(irq_idx); cache_irq_mask &= ~DPU_IRQ_MASK(irq_idx);
/* Disable interrupts based on the new mask */ /* 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) ...@@ -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; 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); DPU_IRQ_MASK(irq_idx), cache_irq_mask);
return 0; return 0;
......
...@@ -31,6 +31,9 @@ enum dpu_hw_intr_reg { ...@@ -31,6 +31,9 @@ enum dpu_hw_intr_reg {
MDP_INTF3_7xxx_INTR, MDP_INTF3_7xxx_INTR,
MDP_INTF4_7xxx_INTR, MDP_INTF4_7xxx_INTR,
MDP_INTF5_7xxx_INTR, MDP_INTF5_7xxx_INTR,
MDP_INTF6_7xxx_INTR,
MDP_INTF7_7xxx_INTR,
MDP_INTF8_7xxx_INTR,
MDP_INTR_MAX, MDP_INTR_MAX,
}; };
......
...@@ -120,6 +120,8 @@ enum dpu_sspp { ...@@ -120,6 +120,8 @@ enum dpu_sspp {
SSPP_DMA1, SSPP_DMA1,
SSPP_DMA2, SSPP_DMA2,
SSPP_DMA3, SSPP_DMA3,
SSPP_DMA4,
SSPP_DMA5,
SSPP_CURSOR0, SSPP_CURSOR0,
SSPP_CURSOR1, SSPP_CURSOR1,
SSPP_MAX SSPP_MAX
...@@ -195,6 +197,8 @@ enum dpu_pingpong { ...@@ -195,6 +197,8 @@ enum dpu_pingpong {
PINGPONG_3, PINGPONG_3,
PINGPONG_4, PINGPONG_4,
PINGPONG_5, PINGPONG_5,
PINGPONG_6,
PINGPONG_7,
PINGPONG_S0, PINGPONG_S0,
PINGPONG_MAX PINGPONG_MAX
}; };
...@@ -203,6 +207,7 @@ enum dpu_merge_3d { ...@@ -203,6 +207,7 @@ enum dpu_merge_3d {
MERGE_3D_0 = 1, MERGE_3D_0 = 1,
MERGE_3D_1, MERGE_3D_1,
MERGE_3D_2, MERGE_3D_2,
MERGE_3D_3,
MERGE_3D_MAX MERGE_3D_MAX
}; };
...@@ -214,6 +219,8 @@ enum dpu_intf { ...@@ -214,6 +219,8 @@ enum dpu_intf {
INTF_4, INTF_4,
INTF_5, INTF_5,
INTF_6, INTF_6,
INTF_7,
INTF_8,
INTF_MAX INTF_MAX
}; };
......
...@@ -7,40 +7,17 @@ ...@@ -7,40 +7,17 @@
#include "dpu_hw_top.h" #include "dpu_hw_top.h"
#include "dpu_kms.h" #include "dpu_kms.h"
#define SSPP_SPARE 0x28
#define FLD_SPLIT_DISPLAY_CMD BIT(1) #define FLD_SPLIT_DISPLAY_CMD BIT(1)
#define FLD_SMART_PANEL_FREE_RUN BIT(2) #define FLD_SMART_PANEL_FREE_RUN BIT(2)
#define FLD_INTF_1_SW_TRG_MUX BIT(4) #define FLD_INTF_1_SW_TRG_MUX BIT(4)
#define FLD_INTF_2_SW_TRG_MUX BIT(8) #define FLD_INTF_2_SW_TRG_MUX BIT(8)
#define FLD_TE_LINE_INTER_WATERLEVEL_MASK 0xFFFF #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_EN BIT(31)
#define TRAFFIC_SHAPER_RD_CLIENT(num) (0x030 + (num * 4)) #define TRAFFIC_SHAPER_RD_CLIENT(num) (0x030 + (num * 4))
#define TRAFFIC_SHAPER_WR_CLIENT(num) (0x060 + (num * 4)) #define TRAFFIC_SHAPER_WR_CLIENT(num) (0x060 + (num * 4))
#define TRAFFIC_SHAPER_FIXPOINT_FACTOR 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 MDP_TICK_COUNT 16
#define XO_CLK_RATE 19200 #define XO_CLK_RATE 19200
#define MS_TICKS_IN_SEC 1000 #define MS_TICKS_IN_SEC 1000
...@@ -48,8 +25,6 @@ ...@@ -48,8 +25,6 @@
#define CALCULATE_WD_LOAD_VALUE(fps) \ #define CALCULATE_WD_LOAD_VALUE(fps) \
((uint32_t)((MS_TICKS_IN_SEC * XO_CLK_RATE)/(MDP_TICK_COUNT * 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, static void dpu_hw_setup_split_pipe(struct dpu_hw_mdp *mdp,
struct split_pipe_cfg *cfg) struct split_pipe_cfg *cfg)
{ {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#define INTR_CLEAR 0x018 #define INTR_CLEAR 0x018
#define INTR2_EN 0x008 #define INTR2_EN 0x008
#define INTR2_STATUS 0x00c #define INTR2_STATUS 0x00c
#define SSPP_SPARE 0x028
#define INTR2_CLEAR 0x02c #define INTR2_CLEAR 0x02c
#define HIST_INTR_EN 0x01c #define HIST_INTR_EN 0x01c
#define HIST_INTR_STATUS 0x020 #define HIST_INTR_STATUS 0x020
...@@ -28,7 +29,15 @@ ...@@ -28,7 +29,15 @@
#define DSPP_IGC_COLOR0_RAM_LUTN 0x300 #define DSPP_IGC_COLOR0_RAM_LUTN 0x300
#define DSPP_IGC_COLOR1_RAM_LUTN 0x304 #define DSPP_IGC_COLOR1_RAM_LUTN 0x304
#define DSPP_IGC_COLOR2_RAM_LUTN 0x308 #define DSPP_IGC_COLOR2_RAM_LUTN 0x308
#define DANGER_STATUS 0x360
#define SAFE_STATUS 0x364
#define HW_EVENTS_CTL 0x37C #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_CTRL3 0x3A8
#define CLK_STATUS3 0x3AC #define CLK_STATUS3 0x3AC
#define CLK_CTRL4 0x3B0 #define CLK_CTRL4 0x3B0
...@@ -43,6 +52,18 @@ ...@@ -43,6 +52,18 @@
#define HDMI_DP_CORE_SELECT 0x408 #define HDMI_DP_CORE_SELECT 0x408
#define MDP_OUT_CTL_0 0x410 #define MDP_OUT_CTL_0 0x410
#define MDP_VSYNC_SEL 0x414 #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 DCE_SEL 0x450
#define MDP_PERIPH_TOP0 MDP_WD_TIMER_0_CTL
#define MDP_PERIPH_TOP0_END CLK_CTRL3
#endif /*_DPU_HWIO_H */ #endif /*_DPU_HWIO_H */
...@@ -927,8 +927,15 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k ...@@ -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, msm_disp_snapshot_add_block(disp_state, cat->wb[i].len,
dpu_kms->mmio + cat->wb[i].base, "wb_%d", i); dpu_kms->mmio + cat->wb[i].base, "wb_%d", i);
msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len, if (cat->mdp[0].features & BIT(DPU_MDP_PERIPH_0_REMOVED)) {
dpu_kms->mmio + cat->mdp[0].base, "top"); 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); pm_runtime_put_sync(&dpu_kms->pdev->dev);
} }
...@@ -1292,9 +1299,13 @@ static const struct of_device_id dpu_dt_match[] = { ...@@ -1292,9 +1299,13 @@ static const struct of_device_id dpu_dt_match[] = {
{ .compatible = "qcom,sc7180-dpu", }, { .compatible = "qcom,sc7180-dpu", },
{ .compatible = "qcom,sc7280-dpu", }, { .compatible = "qcom,sc7280-dpu", },
{ .compatible = "qcom,sc8180x-dpu", }, { .compatible = "qcom,sc8180x-dpu", },
{ .compatible = "qcom,sc8280xp-dpu", },
{ .compatible = "qcom,sm6115-dpu", }, { .compatible = "qcom,sm6115-dpu", },
{ .compatible = "qcom,sm8150-dpu", }, { .compatible = "qcom,sm8150-dpu", },
{ .compatible = "qcom,sm8250-dpu", }, { .compatible = "qcom,sm8250-dpu", },
{ .compatible = "qcom,sm8350-dpu", },
{ .compatible = "qcom,sm8450-dpu", },
{ .compatible = "qcom,sm8550-dpu", },
{} {}
}; };
MODULE_DEVICE_TABLE(of, dpu_dt_match); MODULE_DEVICE_TABLE(of, dpu_dt_match);
......
...@@ -496,6 +496,11 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, ...@@ -496,6 +496,11 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
/* check if DSC required are allocated or not */ /* check if DSC required are allocated or not */
for (i = 0; i < num_dsc; i++) { 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]) { if (global_state->dsc_to_enc_id[i]) {
DPU_ERROR("DSC %d is already allocated\n", i); DPU_ERROR("DSC %d is already allocated\n", i);
return -EIO; return -EIO;
...@@ -543,8 +548,8 @@ static int _dpu_rm_populate_requirements( ...@@ -543,8 +548,8 @@ static int _dpu_rm_populate_requirements(
{ {
reqs->topology = req_topology; reqs->topology = req_topology;
DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n", DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
reqs->topology.num_lm, reqs->topology.num_enc, reqs->topology.num_lm, reqs->topology.num_dsc,
reqs->topology.num_intf); reqs->topology.num_intf);
return 0; return 0;
...@@ -660,6 +665,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, ...@@ -660,6 +665,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
blks_size, enc_id); blks_size, enc_id);
break; 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]; blks[num_blks++] = hw_blks[i];
} }
......
...@@ -70,6 +70,8 @@ int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc, ...@@ -70,6 +70,8 @@ int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
int rc = 0; int rc = 0;
dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), GFP_KERNEL); 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); 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) ...@@ -69,8 +69,7 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms); struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms);
struct drm_device *dev = mdp4_kms->dev; struct drm_device *dev = mdp4_kms->dev;
struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc;
unsigned int id;
uint32_t status, enable; uint32_t status, enable;
enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE); enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE);
...@@ -81,9 +80,9 @@ irqreturn_t mdp4_irq(struct msm_kms *kms) ...@@ -81,9 +80,9 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
mdp_dispatch_irqs(mdp_kms, status); mdp_dispatch_irqs(mdp_kms, status);
for (id = 0; id < priv->num_crtcs; id++) drm_for_each_crtc(crtc, dev)
if (status & mdp4_crtc_vblank(priv->crtcs[id])) if (status & mdp4_crtc_vblank(crtc))
drm_handle_vblank(dev, id); drm_crtc_handle_vblank(crtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -82,8 +82,7 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) ...@@ -82,8 +82,7 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
struct drm_device *dev = mdp5_kms->dev; struct drm_device *dev = mdp5_kms->dev;
struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc;
unsigned int id;
uint32_t status, enable; uint32_t status, enable;
enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN); enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN);
...@@ -94,9 +93,9 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) ...@@ -94,9 +93,9 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
mdp_dispatch_irqs(mdp_kms, status); mdp_dispatch_irqs(mdp_kms, status);
for (id = 0; id < priv->num_crtcs; id++) drm_for_each_crtc(crtc, dev)
if (status & mdp5_crtc_vblank(priv->crtcs[id])) if (status & mdp5_crtc_vblank(crtc))
drm_handle_vblank(dev, id); drm_crtc_handle_vblank(crtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
This diff is collapsed.
...@@ -21,6 +21,7 @@ struct msm_dp { ...@@ -21,6 +21,7 @@ struct msm_dp {
bool power_on; bool power_on;
unsigned int connector_type; unsigned int connector_type;
bool is_edp; bool is_edp;
bool internal_hpd;
hdmi_codec_plugged_cb plugged_cb; hdmi_codec_plugged_cb plugged_cb;
......
...@@ -102,6 +102,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = { ...@@ -102,6 +102,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
.get_modes = dp_bridge_get_modes, .get_modes = dp_bridge_get_modes,
.detect = dp_bridge_detect, .detect = dp_bridge_detect,
.atomic_check = dp_bridge_atomic_check, .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, 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, ...@@ -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, void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
const struct drm_display_mode *mode, const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_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_ */ #endif /* _DP_DRM_H_ */
...@@ -75,12 +75,13 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel) ...@@ -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->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; 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) if (link_info->num_lanes > dp_panel->max_dp_lanes)
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 */ /* Limit link rate from link-frequencies of endpoint property of dtsi */
if (link_info->rate >= (drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4))) if (link_info->rate > dp_panel->max_dp_link_rate)
link_info->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4); 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, "version: %d.%d\n", major, minor);
drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate); drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
......
...@@ -50,6 +50,7 @@ struct dp_panel { ...@@ -50,6 +50,7 @@ struct dp_panel {
u32 vic; u32 vic;
u32 max_dp_lanes; u32 max_dp_lanes;
u32 max_dp_link_rate;
u32 max_bw_code; u32 max_bw_code;
}; };
......
...@@ -91,19 +91,53 @@ static int dp_parser_ctrl_res(struct dp_parser *parser) ...@@ -91,19 +91,53 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
return 0; 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) static int dp_parser_misc(struct dp_parser *parser)
{ {
struct device_node *of_node = parser->pdev->dev.of_node; struct device_node *of_node = parser->pdev->dev.of_node;
int len; int cnt;
len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES); /*
if (len < 0) { * data-lanes is the property of dp_out endpoint
DRM_WARN("Invalid property \"data-lanes\", default max DP lanes = %d\n", */
DP_MAX_NUM_DP_LANES); cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
len = 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; return 0;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#define DP_LABEL "MDSS DP DISPLAY" #define DP_LABEL "MDSS DP DISPLAY"
#define DP_MAX_PIXEL_CLK_KHZ 675000 #define DP_MAX_PIXEL_CLK_KHZ 675000
#define DP_MAX_NUM_DP_LANES 4 #define DP_MAX_NUM_DP_LANES 4
#define DP_LINK_RATE_HBR2 540000 /* kbytes */
enum dp_pm_type { enum dp_pm_type {
DP_CORE_PM, DP_CORE_PM,
...@@ -119,6 +120,7 @@ struct dp_parser { ...@@ -119,6 +120,7 @@ struct dp_parser {
struct dp_io io; struct dp_io io;
struct dp_display_data disp_data; struct dp_display_data disp_data;
u32 max_dp_lanes; u32 max_dp_lanes;
u32 max_dp_link_rate;
struct drm_bridge *next_bridge; struct drm_bridge *next_bridge;
int (*parse)(struct dp_parser *parser); int (*parse)(struct dp_parser *parser);
......
...@@ -118,6 +118,8 @@ int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host); ...@@ -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); 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_6g(struct msm_dsi_host *msm_host);
void dsi_link_clk_disable_v2(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_6g(struct msm_dsi_host *msm_host, int size);
int dsi_tx_buf_alloc_v2(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); void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
...@@ -139,6 +141,7 @@ struct msm_dsi_phy_shared_timings { ...@@ -139,6 +141,7 @@ struct msm_dsi_phy_shared_timings {
u32 clk_post; u32 clk_post;
u32 clk_pre; u32 clk_pre;
bool clk_pre_inc_by_2; bool clk_pre_inc_by_2;
bool byte_intf_clk_div_2;
}; };
struct msm_dsi_phy_clk_request { struct msm_dsi_phy_clk_request {
......
...@@ -181,6 +181,20 @@ static const struct msm_dsi_config sdm845_dsi_cfg = { ...@@ -181,6 +181,20 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
.num_dsi = 2, .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[] = { static const struct regulator_bulk_data sc7180_dsi_regulators[] = {
{ .supply = "vdda", .init_load_uA = 21800 }, /* 1.2 V */ { .supply = "vdda", .init_load_uA = 21800 }, /* 1.2 V */
}; };
...@@ -209,8 +223,8 @@ static const struct msm_dsi_config sc7280_dsi_cfg = { ...@@ -209,8 +223,8 @@ static const struct msm_dsi_config sc7280_dsi_cfg = {
.num_regulators = ARRAY_SIZE(sc7280_dsi_regulators), .num_regulators = ARRAY_SIZE(sc7280_dsi_regulators),
.bus_clk_names = dsi_sc7280_bus_clk_names, .bus_clk_names = dsi_sc7280_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sc7280_bus_clk_names), .num_bus_clks = ARRAY_SIZE(dsi_sc7280_bus_clk_names),
.io_start = { 0xae94000 }, .io_start = { 0xae94000, 0xae96000 },
.num_dsi = 1, .num_dsi = 2,
}; };
static const char * const dsi_qcm2290_bus_clk_names[] = { static const char * const dsi_qcm2290_bus_clk_names[] = {
...@@ -300,6 +314,10 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { ...@@ -300,6 +314,10 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
&sc7180_dsi_cfg, &msm_dsi_6g_v2_host_ops}, &sc7180_dsi_cfg, &msm_dsi_6g_v2_host_ops},
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_0, {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_0,
&sc7280_dsi_cfg, &msm_dsi_6g_v2_host_ops}, &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) const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#define MSM_DSI_6G_VER_MINOR_V2_4_0 0x20040000 #define MSM_DSI_6G_VER_MINOR_V2_4_0 0x20040000
#define MSM_DSI_6G_VER_MINOR_V2_4_1 0x20040001 #define MSM_DSI_6G_VER_MINOR_V2_4_1 0x20040001
#define MSM_DSI_6G_VER_MINOR_V2_5_0 0x20050000 #define MSM_DSI_6G_VER_MINOR_V2_5_0 0x20050000
#define MSM_DSI_6G_VER_MINOR_V2_6_0 0x20060000
#define MSM_DSI_6G_VER_MINOR_V2_7_0 0x20070000
#define MSM_DSI_V2_VER_MINOR_8064 0x0 #define MSM_DSI_V2_VER_MINOR_8064 0x0
......
...@@ -122,6 +122,7 @@ struct msm_dsi_host { ...@@ -122,6 +122,7 @@ struct msm_dsi_host {
struct clk *byte_intf_clk; struct clk *byte_intf_clk;
unsigned long byte_clk_rate; unsigned long byte_clk_rate;
unsigned long byte_intf_clk_rate;
unsigned long pixel_clk_rate; unsigned long pixel_clk_rate;
unsigned long esc_clk_rate; unsigned long esc_clk_rate;
...@@ -398,7 +399,6 @@ int msm_dsi_runtime_resume(struct device *dev) ...@@ -398,7 +399,6 @@ int msm_dsi_runtime_resume(struct device *dev)
int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host) int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
{ {
unsigned long byte_intf_rate;
int ret; int ret;
DBG("Set clk rates: pclk=%d, byteclk=%lu", DBG("Set clk rates: pclk=%d, byteclk=%lu",
...@@ -418,13 +418,7 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host) ...@@ -418,13 +418,7 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
} }
if (msm_host->byte_intf_clk) { if (msm_host->byte_intf_clk) {
/* For CPHY, byte_intf_clk is same as byte_clk */ ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);
if (msm_host->cphy_mode)
byte_intf_rate = msm_host->byte_clk_rate;
else
byte_intf_rate = msm_host->byte_clk_rate / 2;
ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_rate);
if (ret) { if (ret) {
pr_err("%s: Failed to set rate byte intf clk, %d\n", pr_err("%s: Failed to set rate byte intf clk, %d\n",
__func__, ret); __func__, ret);
...@@ -570,9 +564,8 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host) ...@@ -570,9 +564,8 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
clk_disable_unprepare(msm_host->byte_clk); clk_disable_unprepare(msm_host->byte_clk);
} }
static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi) static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool is_bonded_dsi)
{ {
struct drm_display_mode *mode = msm_host->mode;
unsigned long pclk_rate; unsigned long pclk_rate;
pclk_rate = mode->clock * 1000; pclk_rate = mode->clock * 1000;
...@@ -589,11 +582,13 @@ static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bo ...@@ -589,11 +582,13 @@ static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bo
return pclk_rate; return pclk_rate;
} }
static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_dsi,
const struct drm_display_mode *mode)
{ {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
u8 lanes = msm_host->lanes; u8 lanes = msm_host->lanes;
u32 bpp = dsi_get_bpp(msm_host->format); u32 bpp = dsi_get_bpp(msm_host->format);
unsigned long pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi); unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi);
u64 pclk_bpp = (u64)pclk_rate * bpp; u64 pclk_bpp = (u64)pclk_rate * bpp;
if (lanes == 0) { if (lanes == 0) {
...@@ -607,8 +602,14 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) ...@@ -607,8 +602,14 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
else else
do_div(pclk_bpp, (8 * lanes)); do_div(pclk_bpp, (8 * lanes));
msm_host->pixel_clk_rate = pclk_rate; return pclk_bpp;
msm_host->byte_clk_rate = pclk_bpp; }
static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
{
msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi);
msm_host->byte_clk_rate = dsi_byte_clk_get_rate(&msm_host->base, is_bonded_dsi,
msm_host->mode);
DBG("pclk=%lu, bclk=%lu", msm_host->pixel_clk_rate, DBG("pclk=%lu, bclk=%lu", msm_host->pixel_clk_rate,
msm_host->byte_clk_rate); msm_host->byte_clk_rate);
...@@ -636,7 +637,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi) ...@@ -636,7 +637,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
dsi_calc_pclk(msm_host, is_bonded_dsi); dsi_calc_pclk(msm_host, is_bonded_dsi);
pclk_bpp = (u64)dsi_get_pclk_rate(msm_host, is_bonded_dsi) * bpp; pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp;
do_div(pclk_bpp, 8); do_div(pclk_bpp, 8);
msm_host->src_clk_rate = pclk_bpp; msm_host->src_clk_rate = pclk_bpp;
...@@ -853,11 +854,12 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod ...@@ -853,11 +854,12 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
*/ */
slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width); slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width);
/* If slice_per_pkt is greater than slice_per_intf /*
* If slice_count is greater than slice_per_intf
* then default to 1. This can happen during partial * then default to 1. This can happen during partial
* update. * update.
*/ */
if (slice_per_intf > dsc->slice_count) if (dsc->slice_count > slice_per_intf)
dsc->slice_count = 1; dsc->slice_count = 1;
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
...@@ -987,7 +989,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) ...@@ -987,7 +989,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
if (!msm_host->dsc) if (!msm_host->dsc)
wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
else else
wc = mode->hdisplay / 2 + 1; wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1;
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
...@@ -1883,8 +1885,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) ...@@ -1883,8 +1885,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL); msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);
if (!msm_host) { if (!msm_host) {
ret = -ENOMEM; return -ENOMEM;
goto fail;
} }
msm_host->pdev = pdev; msm_host->pdev = pdev;
...@@ -1893,31 +1894,28 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) ...@@ -1893,31 +1894,28 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
ret = dsi_host_parse_dt(msm_host); ret = dsi_host_parse_dt(msm_host);
if (ret) { if (ret) {
pr_err("%s: failed to parse dt\n", __func__); pr_err("%s: failed to parse dt\n", __func__);
goto fail; return ret;
} }
msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", &msm_host->ctrl_size); msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", &msm_host->ctrl_size);
if (IS_ERR(msm_host->ctrl_base)) { if (IS_ERR(msm_host->ctrl_base)) {
pr_err("%s: unable to map Dsi ctrl base\n", __func__); pr_err("%s: unable to map Dsi ctrl base\n", __func__);
ret = PTR_ERR(msm_host->ctrl_base); return PTR_ERR(msm_host->ctrl_base);
goto fail;
} }
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
msm_host->cfg_hnd = dsi_get_config(msm_host); msm_host->cfg_hnd = dsi_get_config(msm_host);
if (!msm_host->cfg_hnd) { if (!msm_host->cfg_hnd) {
ret = -EINVAL;
pr_err("%s: get config failed\n", __func__); pr_err("%s: get config failed\n", __func__);
goto fail; return -EINVAL;
} }
cfg = msm_host->cfg_hnd->cfg; cfg = msm_host->cfg_hnd->cfg;
msm_host->id = dsi_host_get_id(msm_host); msm_host->id = dsi_host_get_id(msm_host);
if (msm_host->id < 0) { if (msm_host->id < 0) {
ret = msm_host->id;
pr_err("%s: unable to identify DSI host index\n", __func__); pr_err("%s: unable to identify DSI host index\n", __func__);
goto fail; return msm_host->id;
} }
/* fixup base address by io offset */ /* fixup base address by io offset */
...@@ -1927,19 +1925,18 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) ...@@ -1927,19 +1925,18 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
cfg->regulator_data, cfg->regulator_data,
&msm_host->supplies); &msm_host->supplies);
if (ret) if (ret)
goto fail; return ret;
ret = dsi_clk_init(msm_host); ret = dsi_clk_init(msm_host);
if (ret) { if (ret) {
pr_err("%s: unable to initialize dsi clks\n", __func__); pr_err("%s: unable to initialize dsi clks\n", __func__);
goto fail; return ret;
} }
msm_host->rx_buf = devm_kzalloc(&pdev->dev, SZ_4K, GFP_KERNEL); msm_host->rx_buf = devm_kzalloc(&pdev->dev, SZ_4K, GFP_KERNEL);
if (!msm_host->rx_buf) { if (!msm_host->rx_buf) {
ret = -ENOMEM;
pr_err("%s: alloc rx temp buf failed\n", __func__); pr_err("%s: alloc rx temp buf failed\n", __func__);
goto fail; return -ENOMEM;
} }
ret = devm_pm_opp_set_clkname(&pdev->dev, "byte"); ret = devm_pm_opp_set_clkname(&pdev->dev, "byte");
...@@ -1977,15 +1974,15 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) ...@@ -1977,15 +1974,15 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
/* setup workqueue */ /* setup workqueue */
msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0); msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
if (!msm_host->workqueue)
return -ENOMEM;
INIT_WORK(&msm_host->err_work, dsi_err_worker); INIT_WORK(&msm_host->err_work, dsi_err_worker);
msm_dsi->id = msm_host->id; msm_dsi->id = msm_host->id;
DBG("Dsi Host %d initialized", msm_host->id); DBG("Dsi Host %d initialized", msm_host->id);
return 0; return 0;
fail:
return ret;
} }
void msm_dsi_host_destroy(struct mipi_dsi_host *host) void msm_dsi_host_destroy(struct mipi_dsi_host *host)
...@@ -2391,6 +2388,10 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, ...@@ -2391,6 +2388,10 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
goto unlock_ret; goto unlock_ret;
} }
msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate;
if (phy_shared_timings->byte_intf_clk_div_2)
msm_host->byte_intf_clk_rate /= 2;
msm_dsi_sfpb_config(msm_host, true); msm_dsi_sfpb_config(msm_host, true);
ret = regulator_bulk_enable(msm_host->cfg_hnd->cfg->num_regulators, ret = regulator_bulk_enable(msm_host->cfg_hnd->cfg->num_regulators,
......
...@@ -450,6 +450,25 @@ static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge, ...@@ -450,6 +450,25 @@ static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
int id = dsi_mgr_bridge_get_id(bridge); int id = dsi_mgr_bridge_get_id(bridge);
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
struct mipi_dsi_host *host = msm_dsi->host; struct mipi_dsi_host *host = msm_dsi->host;
struct platform_device *pdev = msm_dsi->pdev;
struct dev_pm_opp *opp;
unsigned long byte_clk_rate;
byte_clk_rate = dsi_byte_clk_get_rate(host, IS_BONDED_DSI(), mode);
/*
* fail all errors except -ENODEV as that could mean that opp
* table is not yet implemented
*/
opp = dev_pm_opp_find_freq_ceil(&pdev->dev, &byte_clk_rate);
if (IS_ERR(opp)) {
if (PTR_ERR(opp) == -ERANGE)
return MODE_CLOCK_RANGE;
else if (PTR_ERR(opp) != -ENODEV)
return MODE_ERROR;
} else {
dev_pm_opp_put(opp);
}
return msm_dsi_host_check_dsc(host, mode); return msm_dsi_host_check_dsc(host, mode);
} }
......
...@@ -350,6 +350,8 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing, ...@@ -350,6 +350,8 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
timing->shared_timings.clk_pre_inc_by_2 = 0; timing->shared_timings.clk_pre_inc_by_2 = 0;
} }
timing->shared_timings.byte_intf_clk_div_2 = true;
timing->ta_go = 3; timing->ta_go = 3;
timing->ta_sure = 0; timing->ta_sure = 0;
timing->ta_get = 4; timing->ta_get = 4;
...@@ -454,6 +456,8 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, ...@@ -454,6 +456,8 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
tmax = 255; tmax = 255;
timing->shared_timings.clk_pre = DIV_ROUND_UP((tmax - tmin) * 125, 10000) + tmin; timing->shared_timings.clk_pre = DIV_ROUND_UP((tmax - tmin) * 125, 10000) + tmin;
timing->shared_timings.byte_intf_clk_div_2 = true;
DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d", DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
timing->shared_timings.clk_pre, timing->shared_timings.clk_post, timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
timing->clk_zero, timing->clk_trail, timing->clk_prepare, timing->hs_exit, timing->clk_zero, timing->clk_trail, timing->clk_prepare, timing->hs_exit,
...@@ -569,6 +573,14 @@ static const struct of_device_id dsi_phy_dt_match[] = { ...@@ -569,6 +573,14 @@ static const struct of_device_id dsi_phy_dt_match[] = {
.data = &dsi_phy_7nm_8150_cfgs }, .data = &dsi_phy_7nm_8150_cfgs },
{ .compatible = "qcom,sc7280-dsi-phy-7nm", { .compatible = "qcom,sc7280-dsi-phy-7nm",
.data = &dsi_phy_7nm_7280_cfgs }, .data = &dsi_phy_7nm_7280_cfgs },
{ .compatible = "qcom,sm6375-dsi-phy-7nm",
.data = &dsi_phy_7nm_6375_cfgs },
{ .compatible = "qcom,sm8350-dsi-phy-5nm",
.data = &dsi_phy_5nm_8350_cfgs },
{ .compatible = "qcom,sm8450-dsi-phy-5nm",
.data = &dsi_phy_5nm_8450_cfgs },
{ .compatible = "qcom,sm8550-dsi-phy-4nm",
.data = &dsi_phy_4nm_8550_cfgs },
#endif #endif
{} {}
}; };
......
...@@ -55,8 +55,12 @@ extern const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs; ...@@ -55,8 +55,12 @@ extern const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_7nm_6375_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs; extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs;
extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs;
struct msm_dsi_dphy_timing { struct msm_dsi_dphy_timing {
u32 clk_zero; u32 clk_zero;
......
This diff is collapsed.
...@@ -120,6 +120,10 @@ static int msm_hdmi_init(struct hdmi *hdmi) ...@@ -120,6 +120,10 @@ static int msm_hdmi_init(struct hdmi *hdmi)
int ret; int ret;
hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0); hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
if (!hdmi->workq) {
ret = -ENOMEM;
goto fail;
}
hdmi->i2c = msm_hdmi_i2c_init(hdmi); hdmi->i2c = msm_hdmi_i2c_init(hdmi);
if (IS_ERR(hdmi->i2c)) { if (IS_ERR(hdmi->i2c)) {
......
...@@ -61,6 +61,7 @@ enum msm_dp_controller { ...@@ -61,6 +61,7 @@ enum msm_dp_controller {
MSM_DP_CONTROLLER_0, MSM_DP_CONTROLLER_0,
MSM_DP_CONTROLLER_1, MSM_DP_CONTROLLER_1,
MSM_DP_CONTROLLER_2, MSM_DP_CONTROLLER_2,
MSM_DP_CONTROLLER_3,
MSM_DP_CONTROLLER_COUNT, MSM_DP_CONTROLLER_COUNT,
}; };
...@@ -82,14 +83,12 @@ enum msm_event_wait { ...@@ -82,14 +83,12 @@ enum msm_event_wait {
/** /**
* struct msm_display_topology - defines a display topology pipeline * struct msm_display_topology - defines a display topology pipeline
* @num_lm: number of layer mixers used * @num_lm: number of layer mixers used
* @num_enc: number of compression encoder blocks used
* @num_intf: number of interfaces the panel is mounted on * @num_intf: number of interfaces the panel is mounted on
* @num_dspp: number of dspp blocks used * @num_dspp: number of dspp blocks used
* @num_dsc: number of Display Stream Compression (DSC) blocks used * @num_dsc: number of Display Stream Compression (DSC) blocks used
*/ */
struct msm_display_topology { struct msm_display_topology {
u32 num_lm; u32 num_lm;
u32 num_enc;
u32 num_intf; u32 num_intf;
u32 num_dspp; u32 num_dspp;
u32 num_dsc; u32 num_dsc;
......
...@@ -286,9 +286,21 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) ...@@ -286,9 +286,21 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss)
/* UBWC_2_0 */ /* UBWC_2_0 */
msm_mdss_setup_ubwc_dec_20(msm_mdss, 0x11f); msm_mdss_setup_ubwc_dec_20(msm_mdss, 0x11f);
break; break;
case DPU_HW_VER_700:
/* TODO: highest_bank_bit = 2 for LP_DDR4 */
msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_4_0, 6, 1, 3, 1);
break;
case DPU_HW_VER_720: case DPU_HW_VER_720:
msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_3_0, 6, 1, 1, 1); msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_3_0, 6, 1, 1, 1);
break; break;
case DPU_HW_VER_800:
msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_4_0, 6, 1, 2, 1);
break;
case DPU_HW_VER_810:
case DPU_HW_VER_900:
/* TODO: highest_bank_bit = 2 for LP_DDR4 */
msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_4_0, 6, 1, 3, 1);
break;
} }
return ret; return ret;
...@@ -515,9 +527,13 @@ static const struct of_device_id mdss_dt_match[] = { ...@@ -515,9 +527,13 @@ static const struct of_device_id mdss_dt_match[] = {
{ .compatible = "qcom,sc7180-mdss" }, { .compatible = "qcom,sc7180-mdss" },
{ .compatible = "qcom,sc7280-mdss" }, { .compatible = "qcom,sc7280-mdss" },
{ .compatible = "qcom,sc8180x-mdss" }, { .compatible = "qcom,sc8180x-mdss" },
{ .compatible = "qcom,sc8280xp-mdss" },
{ .compatible = "qcom,sm6115-mdss" }, { .compatible = "qcom,sm6115-mdss" },
{ .compatible = "qcom,sm8150-mdss" }, { .compatible = "qcom,sm8150-mdss" },
{ .compatible = "qcom,sm8250-mdss" }, { .compatible = "qcom,sm8250-mdss" },
{ .compatible = "qcom,sm8350-mdss" },
{ .compatible = "qcom,sm8450-mdss" },
{ .compatible = "qcom,sm8550-mdss" },
{} {}
}; };
MODULE_DEVICE_TABLE(of, mdss_dt_match); MODULE_DEVICE_TABLE(of, mdss_dt_match);
......
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