mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Merge tag 'drm-msm-next-2023-01-30' of https://gitlab.freedesktop.org/drm/msm into drm-next
msm-next for v6.3 There is one devfreq patch, maintainer acked to land via msm-next to avoid a build break on platforms that do not support PM_DEVFREQ. And otherwise the usual assortment: GPU: - Add MSM_SUBMIT_BO_NO_IMPLICIT - a2xx: Support to load legacy firmware - a6xx: GPU devcore dump updates for a650/a660 - GPU devfreq tuning and fixes 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 - Include DSC blocks into register snapshot - Misc HW catalog fixes 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 - Fix the case of empty OPP tables (fixing db410c) - DT schema rework and fixes HDMI: - Turn 8960 HDMI PHY into clock provider, - Make 8960 HDMI PHY use PXO clock from DT MDP5: - Schema conversion to YAML Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rob Clark <robdclark@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGv6zQ-zsgS+NG+WuV=tk51q9vA2QdKqYhNgiXQddAdZjA@mail.gmail.com
This commit is contained in:
commit
535cd7104b
@ -21,6 +21,9 @@ properties:
|
||||
- qcom,sc7280-edp
|
||||
- qcom,sc8180x-dp
|
||||
- qcom,sc8180x-edp
|
||||
- qcom,sc8280xp-dp
|
||||
- qcom,sc8280xp-edp
|
||||
- qcom,sdm845-dp
|
||||
- qcom,sm8350-dp
|
||||
|
||||
reg:
|
||||
@ -81,6 +84,7 @@ properties:
|
||||
|
||||
data-lanes:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
deprecated: true
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
@ -102,8 +106,28 @@ properties:
|
||||
description: Input endpoint of the controller
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
description: Output endpoint of the controller
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
|
||||
link-frequencies:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
enum: [ 1620000000, 2700000000, 5400000000, 8100000000 ]
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -127,11 +151,10 @@ allOf:
|
||||
enum:
|
||||
- qcom,sc7280-edp
|
||||
- qcom,sc8180x-edp
|
||||
- qcom,sc8280xp-edp
|
||||
then:
|
||||
properties:
|
||||
"#sound-dai-cells": false
|
||||
reg:
|
||||
maxItems: 4
|
||||
else:
|
||||
properties:
|
||||
aux-bus: false
|
||||
@ -193,6 +216,8 @@ examples:
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&typec>;
|
||||
data-lanes = <0 1>;
|
||||
link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -13,7 +13,15 @@ maintainers:
|
||||
description: |
|
||||
Common properties for QCom DPU display controller.
|
||||
|
||||
# Do not select this by default, otherwise it is also selected for all
|
||||
# display-controller@ nodes
|
||||
select:
|
||||
false
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: '^display-controller@[0-9a-f]+$'
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
@ -40,10 +48,6 @@ properties:
|
||||
- port@0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- interrupts
|
||||
- power-domains
|
||||
- operating-points-v2
|
||||
|
@ -9,14 +9,33 @@ title: Qualcomm Display DSI controller
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
allOf:
|
||||
- $ref: "../dsi-controller.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,mdss-dsi-ctrl
|
||||
- qcom,dsi-ctrl-6g-qcm2290
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,apq8064-dsi-ctrl
|
||||
- qcom,msm8916-dsi-ctrl
|
||||
- qcom,msm8953-dsi-ctrl
|
||||
- qcom,msm8974-dsi-ctrl
|
||||
- qcom,msm8996-dsi-ctrl
|
||||
- qcom,msm8998-dsi-ctrl
|
||||
- qcom,qcm2290-dsi-ctrl
|
||||
- qcom,sc7180-dsi-ctrl
|
||||
- qcom,sc7280-dsi-ctrl
|
||||
- qcom,sdm660-dsi-ctrl
|
||||
- qcom,sdm845-dsi-ctrl
|
||||
- qcom,sm8150-dsi-ctrl
|
||||
- qcom,sm8250-dsi-ctrl
|
||||
- qcom,sm8350-dsi-ctrl
|
||||
- qcom,sm8450-dsi-ctrl
|
||||
- qcom,sm8550-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
- items:
|
||||
- enum:
|
||||
- dsi-ctrl-6g-qcm2290
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
deprecated: true
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -28,22 +47,23 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display byte clock
|
||||
- description: Display byte interface clock
|
||||
- description: Display pixel clock
|
||||
- description: Display core clock
|
||||
- description: Display AHB clock
|
||||
- description: Display AXI clock
|
||||
description: |
|
||||
Several clocks are used, depending on the variant. Typical ones are::
|
||||
- bus:: Display AHB clock.
|
||||
- byte:: Display byte clock.
|
||||
- byte_intf:: Display byte interface clock.
|
||||
- core:: Display core clock.
|
||||
- core_mss:: Core MultiMedia SubSystem clock.
|
||||
- iface:: Display AXI clock.
|
||||
- mdp_core:: MDP Core clock.
|
||||
- mnoc:: MNOC clock
|
||||
- pixel:: Display pixel clock.
|
||||
minItems: 3
|
||||
maxItems: 9
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: byte
|
||||
- const: byte_intf
|
||||
- const: pixel
|
||||
- const: core
|
||||
- const: iface
|
||||
- const: bus
|
||||
minItems: 3
|
||||
maxItems: 9
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
@ -52,10 +72,6 @@ properties:
|
||||
deprecated: true
|
||||
const: dsi
|
||||
|
||||
"#address-cells": true
|
||||
|
||||
"#size-cells": true
|
||||
|
||||
syscon-sfpb:
|
||||
description: A phandle to mmss_sfpb syscon node (only for DSIv2).
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
@ -67,12 +83,16 @@ properties:
|
||||
2 DSI links.
|
||||
|
||||
assigned-clocks:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
description: |
|
||||
Parents of "byte" and "pixel" for the given platform.
|
||||
For DSIv2 platforms this should contain "byte", "esc", "src" and
|
||||
"pixel_src" clocks.
|
||||
|
||||
assigned-clock-parents:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
description: |
|
||||
The Byte clock and Pixel clock PLL outputs provided by a DSI PHY block.
|
||||
|
||||
@ -103,7 +123,7 @@ properties:
|
||||
properties:
|
||||
data-lanes:
|
||||
maxItems: 4
|
||||
minItems: 4
|
||||
minItems: 1
|
||||
items:
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
|
||||
@ -119,7 +139,7 @@ properties:
|
||||
properties:
|
||||
data-lanes:
|
||||
maxItems: 4
|
||||
minItems: 4
|
||||
minItems: 1
|
||||
items:
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
|
||||
@ -127,6 +147,26 @@ properties:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
avdd-supply:
|
||||
description:
|
||||
Phandle to vdd regulator device node
|
||||
|
||||
vcca-supply:
|
||||
description:
|
||||
Phandle to vdd regulator device node
|
||||
|
||||
vdd-supply:
|
||||
description:
|
||||
VDD regulator
|
||||
|
||||
vddio-supply:
|
||||
description:
|
||||
VDD-IO regulator
|
||||
|
||||
vdda-supply:
|
||||
description:
|
||||
VDDA regulator
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -139,7 +179,192 @@ required:
|
||||
- assigned-clock-parents
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: ../dsi-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,apq8064-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 7
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core_mmss
|
||||
- const: src
|
||||
- const: byte
|
||||
- const: pixel
|
||||
- const: core
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8916-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 6
|
||||
clock-names:
|
||||
items:
|
||||
- const: mdp_core
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: byte
|
||||
- const: pixel
|
||||
- const: core
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8953-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 6
|
||||
clock-names:
|
||||
items:
|
||||
- const: mdp_core
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: byte
|
||||
- const: pixel
|
||||
- const: core
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8974-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 7
|
||||
clock-names:
|
||||
items:
|
||||
- const: mdp_core
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: byte
|
||||
- const: pixel
|
||||
- const: core
|
||||
- const: core_mmss
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8996-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 7
|
||||
clock-names:
|
||||
items:
|
||||
- const: mdp_core
|
||||
- const: byte
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core_mmss
|
||||
- const: pixel
|
||||
- const: core
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8998-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 6
|
||||
clock-names:
|
||||
items:
|
||||
- const: byte
|
||||
- const: byte_intf
|
||||
- const: pixel
|
||||
- const: core
|
||||
- const: iface
|
||||
- const: bus
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sc7180-dsi-ctrl
|
||||
- qcom,sc7280-dsi-ctrl
|
||||
- qcom,sm8150-dsi-ctrl
|
||||
- qcom,sm8250-dsi-ctrl
|
||||
- qcom,sm8350-dsi-ctrl
|
||||
- qcom,sm8450-dsi-ctrl
|
||||
- qcom,sm8550-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 6
|
||||
clock-names:
|
||||
items:
|
||||
- const: byte
|
||||
- const: byte_intf
|
||||
- const: pixel
|
||||
- const: core
|
||||
- const: iface
|
||||
- const: bus
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sdm660-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 9
|
||||
clock-names:
|
||||
items:
|
||||
- const: mdp_core
|
||||
- const: byte
|
||||
- const: byte_intf
|
||||
- const: mnoc
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core_mmss
|
||||
- const: pixel
|
||||
- const: core
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sdm845-dsi-ctrl
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 6
|
||||
clock-names:
|
||||
items:
|
||||
- const: byte
|
||||
- const: byte_intf
|
||||
- const: pixel
|
||||
- const: core
|
||||
- const: iface
|
||||
- const: bus
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
@ -149,7 +374,7 @@ examples:
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,sc7180-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
|
@ -16,6 +16,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,dsi-phy-28nm-hpm
|
||||
- qcom,dsi-phy-28nm-hpm-fam-b
|
||||
- qcom,dsi-phy-28nm-lp
|
||||
- qcom,dsi-phy-28nm-8960
|
||||
|
||||
|
@ -18,6 +18,10 @@ properties:
|
||||
- qcom,dsi-phy-7nm
|
||||
- qcom,dsi-phy-7nm-8150
|
||||
- qcom,sc7280-dsi-phy-7nm
|
||||
- qcom,sm6375-dsi-phy-7nm
|
||||
- qcom,sm8350-dsi-phy-5nm
|
||||
- qcom,sm8450-dsi-phy-5nm
|
||||
- qcom,sm8550-dsi-phy-4nm
|
||||
|
||||
reg:
|
||||
items:
|
||||
@ -44,7 +48,6 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- vdds-supply
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
@ -4,14 +4,13 @@
|
||||
$id: http://devicetree.org/schemas/display/msm/dsi-phy-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Description of Qualcomm Display DSI PHY common dt properties
|
||||
title: Qualcomm Display DSI PHY Common Properties
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
|
||||
description: |
|
||||
This defines the DSI PHY dt properties which are common for all
|
||||
dsi phy versions.
|
||||
description:
|
||||
Common properties for Qualcomm Display DSI PHY.
|
||||
|
||||
properties:
|
||||
"#clock-cells":
|
||||
|
@ -149,6 +149,8 @@ allOf:
|
||||
description: GPU 3D engine clock
|
||||
- const: rbbmtimer
|
||||
description: GPU RBBM Timer for Adreno 5xx series
|
||||
- const: rbcpr
|
||||
description: GPU RB Core Power Reduction clock
|
||||
minItems: 2
|
||||
maxItems: 7
|
||||
|
||||
|
@ -1,132 +0,0 @@
|
||||
Qualcomm adreno/snapdragon MDP5 display controller
|
||||
|
||||
Description:
|
||||
|
||||
This is the bindings documentation for the MDP5 display
|
||||
controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and MSM8996.
|
||||
|
||||
MDP5:
|
||||
Required properties:
|
||||
- compatible:
|
||||
* "qcom,mdp5" - MDP5
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- reg-names: The names of register regions. The following regions are required:
|
||||
* "mdp_phys"
|
||||
- interrupts: Interrupt line from MDP5 to MDSS interrupt controller.
|
||||
- clocks: device clocks. See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: the following clocks are required.
|
||||
- * "bus"
|
||||
- * "iface"
|
||||
- * "core"
|
||||
- * "vsync"
|
||||
- ports: contains the list of output ports from MDP. These connect to interfaces
|
||||
that are external to the MDP hardware, such as HDMI, DSI, EDP etc (LVDS is a
|
||||
special case since it is a part of the MDP block itself).
|
||||
|
||||
Each output port contains an endpoint that describes how it is connected to an
|
||||
external interface. These are described by the standard properties documented
|
||||
here:
|
||||
Documentation/devicetree/bindings/graph.txt
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
|
||||
The availability of output ports can vary across SoC revisions:
|
||||
|
||||
For MSM8974 and APQ8084:
|
||||
Port 0 -> MDP_INTF0 (eDP)
|
||||
Port 1 -> MDP_INTF1 (DSI1)
|
||||
Port 2 -> MDP_INTF2 (DSI2)
|
||||
Port 3 -> MDP_INTF3 (HDMI)
|
||||
|
||||
For MSM8916:
|
||||
Port 0 -> MDP_INTF1 (DSI1)
|
||||
|
||||
For MSM8994 and MSM8996:
|
||||
Port 0 -> MDP_INTF1 (DSI1)
|
||||
Port 1 -> MDP_INTF2 (DSI2)
|
||||
Port 2 -> MDP_INTF3 (HDMI)
|
||||
|
||||
Optional properties:
|
||||
- clock-names: the following clocks are optional:
|
||||
* "lut"
|
||||
* "tbu"
|
||||
* "tbu_rt"
|
||||
|
||||
Example:
|
||||
|
||||
/ {
|
||||
...
|
||||
|
||||
mdss: mdss@1a00000 {
|
||||
compatible = "qcom,mdss";
|
||||
reg = <0x1a00000 0x1000>,
|
||||
<0x1ac8000 0x3000>;
|
||||
reg-names = "mdss_phys", "vbif_phys";
|
||||
|
||||
power-domains = <&gcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&gcc GCC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_MDSS_AXI_CLK>,
|
||||
<&gcc GCC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface",
|
||||
"bus",
|
||||
"vsync"
|
||||
|
||||
interrupts = <0 72 0>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
mdp: mdp@1a01000 {
|
||||
compatible = "qcom,mdp5";
|
||||
reg = <0x1a01000 0x90000>;
|
||||
reg-names = "mdp_phys";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0 0>;
|
||||
|
||||
clocks = <&gcc GCC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_MDSS_AXI_CLK>,
|
||||
<&gcc GCC_MDSS_MDP_CLK>,
|
||||
<&gcc GCC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface",
|
||||
"bus",
|
||||
"core",
|
||||
"vsync";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
mdp5_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0: dsi@1a98000 {
|
||||
...
|
||||
ports {
|
||||
...
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&mdp5_intf1_out>;
|
||||
};
|
||||
};
|
||||
...
|
||||
};
|
||||
...
|
||||
};
|
||||
|
||||
dsi_phy0: dsi-phy@1a98300 {
|
||||
...
|
||||
};
|
||||
};
|
||||
};
|
@ -15,7 +15,15 @@ description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc.
|
||||
|
||||
# Do not select this by default, otherwise it is also selected for qcom,mdss
|
||||
# devices.
|
||||
select:
|
||||
false
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^display-subsystem@[0-9a-f]+$"
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@ -70,7 +78,6 @@ properties:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
|
156
Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
Normal file
156
Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
Normal file
@ -0,0 +1,156 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,mdp5.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Adreno/Snapdragon Mobile Display controller (MDP5)
|
||||
|
||||
description:
|
||||
MDP5 display controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994
|
||||
and MSM8996.
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: qcom,mdp5
|
||||
deprecated: true
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,apq8084-mdp5
|
||||
- qcom,msm8916-mdp5
|
||||
- qcom,msm8917-mdp5
|
||||
- qcom,msm8953-mdp5
|
||||
- qcom,msm8974-mdp5
|
||||
- qcom,msm8976-mdp5
|
||||
- qcom,msm8994-mdp5
|
||||
- qcom,msm8996-mdp5
|
||||
- qcom,sdm630-mdp5
|
||||
- qcom,sdm660-mdp5
|
||||
- const: qcom,mdp5
|
||||
|
||||
$nodename:
|
||||
pattern: '^display-controller@[0-9a-f]+$'
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp_phys
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 4
|
||||
maxItems: 7
|
||||
|
||||
clock-names:
|
||||
oneOf:
|
||||
- minItems: 4
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
- const: vsync
|
||||
- const: lut
|
||||
- const: tbu
|
||||
- const: tbu_rt
|
||||
#MSM8996 has additional iommu clock
|
||||
- items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
- const: iommu
|
||||
- const: vsync
|
||||
|
||||
interconnects:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Interconnect path from mdp0 (or a single mdp) port to the data bus
|
||||
- description: Interconnect path from mdp1 port to the data bus
|
||||
- description: Interconnect path from rotator port to the data bus
|
||||
|
||||
interconnect-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: mdp0-mem
|
||||
- const: mdp1-mem
|
||||
- const: rotator-mem
|
||||
|
||||
iommus:
|
||||
items:
|
||||
- description: apps SMMU with the Stream-ID mask for Hard-Fail port0
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: >
|
||||
Contains the list of output ports from DPU device. These ports
|
||||
connect to interfaces that are external to the DPU hardware,
|
||||
such as DSI, DP etc. MDP5 devices support up to 4 ports:
|
||||
one or two DSI ports, HDMI and eDP.
|
||||
|
||||
patternProperties:
|
||||
"^port@[0-3]+$":
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
# at least one port is required
|
||||
required:
|
||||
- port@0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-msm8916.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
display-controller@1a01000 {
|
||||
compatible = "qcom,mdp5";
|
||||
reg = <0x1a01000 0x90000>;
|
||||
reg-names = "mdp_phys";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
clocks = <&gcc GCC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_MDSS_AXI_CLK>,
|
||||
<&gcc GCC_MDSS_MDP_CLK>,
|
||||
<&gcc GCC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface",
|
||||
"bus",
|
||||
"core",
|
||||
"vsync";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -15,6 +15,9 @@ description:
|
||||
encapsulates sub-blocks like MDP5, DSI, HDMI, eDP, etc.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^display-subsystem@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,mdss
|
||||
@ -44,18 +47,30 @@ properties:
|
||||
The MDSS power domain provided by GCC
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Display abh clock
|
||||
- description: Display axi clock
|
||||
- description: Display vsync clock
|
||||
oneOf:
|
||||
- minItems: 3
|
||||
items:
|
||||
- description: Display abh clock
|
||||
- description: Display axi clock
|
||||
- description: Display vsync clock
|
||||
- description: Display core clock
|
||||
- minItems: 1
|
||||
items:
|
||||
- description: Display abh clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: vsync
|
||||
oneOf:
|
||||
- minItems: 3
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: vsync
|
||||
- const: core
|
||||
- minItems: 1
|
||||
items:
|
||||
- const: iface
|
||||
- const: core
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
@ -84,17 +99,19 @@ required:
|
||||
- ranges
|
||||
|
||||
patternProperties:
|
||||
"^mdp@[1-9a-f][0-9a-f]*$":
|
||||
"^display-controller@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdp5
|
||||
contains:
|
||||
const: qcom,mdp5
|
||||
|
||||
"^dsi@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
contains:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
@ -107,12 +124,6 @@ patternProperties:
|
||||
- qcom,dsi-phy-20nm
|
||||
- qcom,dsi-phy-28nm-hpm
|
||||
- qcom,dsi-phy-28nm-lp
|
||||
|
||||
"^hdmi-phy@[1-9a-f][0-9a-f]*$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,hdmi-phy-8084
|
||||
- qcom,hdmi-phy-8660
|
||||
- qcom,hdmi-phy-8960
|
||||
@ -137,7 +148,7 @@ examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-msm8916.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
mdss@1a00000 {
|
||||
display-subsystem@1a00000 {
|
||||
compatible = "qcom,mdss";
|
||||
reg = <0x1a00000 0x1000>,
|
||||
<0x1ac8000 0x3000>;
|
||||
@ -161,8 +172,8 @@ examples:
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
mdp@1a01000 {
|
||||
compatible = "qcom,mdp5";
|
||||
display-controller@1a01000 {
|
||||
compatible = "qcom,msm8916-mdp5", "qcom,mdp5";
|
||||
reg = <0x01a01000 0x89000>;
|
||||
reg-names = "mdp_phys";
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,msm8998-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for MSM8998 target
|
||||
title: Qualcomm Display DPU on MSM8998
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,msm8998-dpu
|
||||
const: qcom,msm8998-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
@ -46,6 +45,13 @@ properties:
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,msm8998-mdss
|
||||
const: qcom,msm8998-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
@ -47,7 +46,9 @@ patternProperties:
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
items:
|
||||
- const: qcom,msm8998-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
@ -55,6 +56,9 @@ patternProperties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-10nm-8998
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
@ -126,7 +130,7 @@ examples:
|
||||
};
|
||||
|
||||
dsi@c994000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,msm8998-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0c994000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
@ -196,7 +200,7 @@ examples:
|
||||
};
|
||||
|
||||
dsi@c996000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,msm8998-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0c996000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,qcm2290-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for QCM2290 target
|
||||
title: Qualcomm Display DPU on QCM2290
|
||||
|
||||
maintainers:
|
||||
- Loic Poulain <loic.poulain@linaro.org>
|
||||
@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,qcm2290-dpu
|
||||
const: qcom,qcm2290-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
@ -42,6 +41,13 @@ properties:
|
||||
- const: lut
|
||||
- const: vsync
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,qcm2290-mdss
|
||||
const: qcom,qcm2290-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
@ -61,6 +60,9 @@ patternProperties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-14nm-2290
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sc7180-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SC7180 target
|
||||
title: Qualcomm Display DPU on SC7180
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sc7180-dpu
|
||||
const: qcom,sc7180-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
@ -44,6 +43,13 @@ properties:
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sc7180-mdss
|
||||
const: qcom,sc7180-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
@ -59,7 +58,9 @@ patternProperties:
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
items:
|
||||
- const: qcom,sc7180-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
@ -67,6 +68,9 @@ patternProperties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-10nm
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
@ -142,7 +146,7 @@ examples:
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,sc7180-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sc7280-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SC7280
|
||||
title: Qualcomm Display DPU on SC7280
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
@ -43,6 +43,13 @@ properties:
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -58,7 +58,9 @@ patternProperties:
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
items:
|
||||
- const: qcom,sc7280-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^edp@[0-9a-f]+$":
|
||||
type: object
|
||||
@ -74,6 +76,9 @@ patternProperties:
|
||||
- qcom,sc7280-dsi-phy-7nm
|
||||
- qcom,sc7280-edp-phy
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
@ -162,7 +167,7 @@ examples:
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,sc7280-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
|
@ -0,0 +1,122 @@
|
||||
# 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,151 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sc8280xp-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SC8280XP Mobile Display Subsystem
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <andersson@kernel.org>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem (MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc8280xp-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display AHB clock from dispcc
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: ahb
|
||||
- const: core
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc8280xp-dpu
|
||||
|
||||
"^displayport-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc8280xp-dp
|
||||
- qcom,sc8280xp-edp
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc8280xp.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sc8280xp.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
compatible = "qcom,sc8280xp-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
power-domains = <&dispcc0 MDSS_GDSC>;
|
||||
|
||||
clocks = <&gcc GCC_DISP_AHB_CLK>,
|
||||
<&dispcc0 DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc0 DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface",
|
||||
"ahb",
|
||||
"core";
|
||||
|
||||
resets = <&dispcc0 DISP_CC_MDSS_CORE_BCR>;
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>,
|
||||
<&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>;
|
||||
interconnect-names = "mdp0-mem", "mdp1-mem";
|
||||
|
||||
iommus = <&apps_smmu 0x1000 0x402>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sc8280xp-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&gcc GCC_DISP_SF_AXI_CLK>,
|
||||
<&dispcc0 DISP_CC_MDSS_AHB_CLK>,
|
||||
<&dispcc0 DISP_CC_MDSS_MDP_LUT_CLK>,
|
||||
<&dispcc0 DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc0 DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "bus",
|
||||
"nrt_bus",
|
||||
"iface",
|
||||
"lut",
|
||||
"core",
|
||||
"vsync";
|
||||
|
||||
assigned-clocks = <&dispcc0 DISP_CC_MDSS_VSYNC_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdss0_mdp_opp_table>;
|
||||
power-domains = <&rpmhpd SC8280XP_MMCX>;
|
||||
|
||||
interrupt-parent = <&mdss0>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&mdss0_dp0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
endpoint {
|
||||
remote-endpoint = <&mdss0_dp1_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@5 {
|
||||
reg = <5>;
|
||||
endpoint {
|
||||
remote-endpoint = <&mdss0_dp3_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@6 {
|
||||
reg = <6>;
|
||||
endpoint {
|
||||
remote-endpoint = <&mdss0_dp2_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sdm845-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SDM845 target
|
||||
title: Qualcomm Display DPU on SDM845
|
||||
|
||||
maintainers:
|
||||
- Krishna Manikandan <quic_mkrishn@quicinc.com>
|
||||
@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sdm845-dpu
|
||||
const: qcom,sdm845-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
@ -42,6 +41,13 @@ properties:
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sdm845-mdss
|
||||
const: qcom,sdm845-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
@ -47,11 +46,19 @@ patternProperties:
|
||||
compatible:
|
||||
const: qcom,sdm845-dpu
|
||||
|
||||
"^displayport-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sdm845-dp
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
items:
|
||||
- const: qcom,sdm845-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
@ -59,6 +66,9 @@ patternProperties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-10nm
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
@ -128,7 +138,7 @@ examples:
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,sdm845-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
@ -198,7 +208,7 @@ examples:
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,sdm845-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm6115-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display DPU dt properties for SM6115 target
|
||||
title: Qualcomm Display DPU on SM6115
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
@ -13,8 +13,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm6115-dpu
|
||||
const: qcom,sm6115-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm6115-mdss
|
||||
const: qcom,sm6115-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
@ -0,0 +1,92 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm8150-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM8150 Display DPU
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8150-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display ahb clock
|
||||
- description: Display hf axi clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sm8150.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm8150.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sm8150.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm8150-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface", "bus", "core", "vsync";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd SM8150_MMCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,332 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm8150-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM8150 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS are mentioned for SM8150 target.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm8150-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display hf axi clock
|
||||
- description: Display sf axi clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: nrt_bus
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8150-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm8150-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-7nm
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,dispcc-sm8150.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm8150.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sm8150.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
compatible = "qcom,sm8150-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP_PORT0 &mc_virt SLAVE_EBI_CH0>,
|
||||
<&mmss_noc MASTER_MDP_PORT1 &mc_virt SLAVE_EBI_CH0>;
|
||||
interconnect-names = "mdp0-mem", "mdp1-mem";
|
||||
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&gcc GCC_DISP_SF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "bus", "nrt_bus", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x800 0x420>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm8150-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
clock-names = "iface", "bus", "core", "vsync";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd SM8150_MMCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-171428571 {
|
||||
opp-hz = /bits/ 64 <171428571>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-345000000 {
|
||||
opp-hz = /bits/ 64 <345000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-460000000 {
|
||||
opp-hz = /bits/ 64 <460000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,sm8150-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SM8150_MMCX>;
|
||||
|
||||
phys = <&dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-187500000 {
|
||||
opp-hz = /bits/ 64 <187500000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,dsi-phy-7nm";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94900 0x260>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,sm8150-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <5>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SM8150_MMCX>;
|
||||
|
||||
phys = <&dsi1_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi1_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi1_phy: phy@ae96400 {
|
||||
compatible = "qcom,dsi-phy-7nm";
|
||||
reg = <0x0ae96400 0x200>,
|
||||
<0x0ae96600 0x280>,
|
||||
<0x0ae96900 0x260>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
};
|
||||
...
|
@ -39,6 +39,13 @@ properties:
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -18,8 +18,7 @@ $ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm8250-mdss
|
||||
const: qcom,sm8250-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
@ -55,7 +54,9 @@ patternProperties:
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,mdss-dsi-ctrl
|
||||
items:
|
||||
- const: qcom,sm8250-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
@ -63,6 +64,9 @@ patternProperties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-7nm
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
@ -167,7 +171,7 @@ examples:
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,sm8250-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
@ -257,7 +261,7 @@ examples:
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,mdss-dsi-ctrl";
|
||||
compatible = "qcom,sm8250-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
|
@ -0,0 +1,120 @@
|
||||
# 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,223 @@
|
||||
# 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:
|
||||
items:
|
||||
- const: qcom,sm8350-dsi-ctrl
|
||||
- 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,sm8350-dsi-ctrl", "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 {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,139 @@
|
||||
# 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,345 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm8450-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM8450 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
description:
|
||||
SM8450 MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like
|
||||
DPU display controller, DSI and DP interfaces etc.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8450-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB
|
||||
- description: Display hf AXI
|
||||
- description: Display sf AXI
|
||||
- description: Display core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8450-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm8450-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,dsi-phy-5nm-8450
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,sm8450-dispcc.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm8450.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,sm8450.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
compatible = "qcom,sm8450-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>,
|
||||
<&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>;
|
||||
interconnect-names = "mdp0-mem", "mdp1-mem";
|
||||
|
||||
resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
|
||||
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>,
|
||||
<&gcc GCC_DISP_SF_AXI_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_MDP_CLK>;
|
||||
clock-names = "iface", "bus", "nrt_bus", "core";
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x2800 0x402>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,sm8450-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SM8450_MMCX>;
|
||||
|
||||
phys = <&dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-160310000{
|
||||
opp-hz = /bits/ 64 <160310000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs_d1>;
|
||||
};
|
||||
|
||||
opp-187500000 {
|
||||
opp-hz = /bits/ 64 <187500000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,dsi-phy-5nm-8450";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94900 0x260>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,sm8450-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <5>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_ESC1_CLK>,
|
||||
<&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&gcc GCC_DISP_HF_AXI_CLK>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>,
|
||||
<&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>;
|
||||
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd SM8450_MMCX>;
|
||||
|
||||
phys = <&dsi1_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dsi1_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi1_phy: phy@ae96400 {
|
||||
compatible = "qcom,dsi-phy-5nm-8450";
|
||||
reg = <0x0ae96400 0x200>,
|
||||
<0x0ae96600 0x280>,
|
||||
<0x0ae96900 0x260>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
vdds-supply = <&vreg_dsi_phy>;
|
||||
};
|
||||
};
|
||||
...
|
@ -43,6 +43,9 @@ properties:
|
||||
vddio-supply:
|
||||
description: phandle to VDD I/O supply regulator
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
'#phy-cells':
|
||||
const: 0
|
||||
|
||||
@ -53,7 +56,6 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,hdmi-phy-8660
|
||||
- qcom,hdmi-phy-8960
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
@ -63,6 +65,24 @@ allOf:
|
||||
- const: slave_iface
|
||||
vddio-supply: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,hdmi-phy-8960
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: slave_iface
|
||||
- const: pxo
|
||||
vddio-supply: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@ -96,9 +116,10 @@ examples:
|
||||
"hdmi_pll";
|
||||
reg = <0x4a00400 0x60>,
|
||||
<0x4a00500 0x100>;
|
||||
#clock-cells = <0>;
|
||||
#phy-cells = <0>;
|
||||
power-domains = <&mmcc 1>;
|
||||
clock-names = "slave_iface";
|
||||
clocks = <&clk 21>;
|
||||
clock-names = "slave_iface", "pxo";
|
||||
clocks = <&clk 21>, <&pxo_board>;
|
||||
core-vdda-supply = <&pm8921_hdmi_mvs>;
|
||||
};
|
||||
|
@ -23,6 +23,7 @@ config DRM_MSM
|
||||
select SHMEM
|
||||
select TMPFS
|
||||
select QCOM_SCM
|
||||
select DEVFREQ_GOV_SIMPLE_ONDEMAND
|
||||
select WANT_DEV_COREDUMP
|
||||
select SND_SOC_HDMI_CODEC if SND_SOC
|
||||
select SYNC_FILE
|
||||
@ -140,12 +141,12 @@ config DRM_MSM_DSI_10NM_PHY
|
||||
Choose this option if DSI PHY on SDM845 is used on the platform.
|
||||
|
||||
config DRM_MSM_DSI_7NM_PHY
|
||||
bool "Enable DSI 7nm PHY driver in MSM DRM"
|
||||
bool "Enable DSI 7nm/5nm/4nm PHY driver in MSM DRM"
|
||||
depends on DRM_MSM_DSI
|
||||
default y
|
||||
help
|
||||
Choose this option if DSI PHY on SM8150/SM8250/SC7280 is used on
|
||||
the platform.
|
||||
Choose this option if DSI PHY on SM8150/SM8250/SM8350/SM8450/SM8550/SC7280
|
||||
is used on the platform.
|
||||
|
||||
config DRM_MSM_HDMI
|
||||
bool "Enable HDMI support in MSM DRM driver"
|
||||
|
@ -53,6 +53,8 @@ static void a2xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
|
||||
|
||||
static bool a2xx_me_init(struct msm_gpu *gpu)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
struct a2xx_gpu *a2xx_gpu = to_a2xx_gpu(adreno_gpu);
|
||||
struct msm_ringbuffer *ring = gpu->rb[0];
|
||||
|
||||
OUT_PKT3(ring, CP_ME_INIT, 18);
|
||||
@ -84,15 +86,20 @@ static bool a2xx_me_init(struct msm_gpu *gpu)
|
||||
/* NQ and External Memory Swap */
|
||||
OUT_RING(ring, 0x00000000);
|
||||
/* protected mode error checking (0x1f2 is REG_AXXX_CP_INT_CNTL) */
|
||||
OUT_RING(ring, 0x200001f2);
|
||||
if (a2xx_gpu->protection_disabled)
|
||||
OUT_RING(ring, 0x00000000);
|
||||
else
|
||||
OUT_RING(ring, 0x200001f2);
|
||||
/* Disable header dumping and Header dump address */
|
||||
OUT_RING(ring, 0x00000000);
|
||||
/* Header dump size */
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
||||
/* enable protected mode */
|
||||
OUT_PKT3(ring, CP_SET_PROTECTED_MODE, 1);
|
||||
OUT_RING(ring, 1);
|
||||
if (!a2xx_gpu->protection_disabled) {
|
||||
/* enable protected mode */
|
||||
OUT_PKT3(ring, CP_SET_PROTECTED_MODE, 1);
|
||||
OUT_RING(ring, 1);
|
||||
}
|
||||
|
||||
adreno_flush(gpu, ring, REG_AXXX_CP_RB_WPTR);
|
||||
return a2xx_idle(gpu);
|
||||
@ -101,6 +108,7 @@ static bool a2xx_me_init(struct msm_gpu *gpu)
|
||||
static int a2xx_hw_init(struct msm_gpu *gpu)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
struct a2xx_gpu *a2xx_gpu = to_a2xx_gpu(adreno_gpu);
|
||||
dma_addr_t pt_base, tran_error;
|
||||
uint32_t *ptr, len;
|
||||
int i, ret;
|
||||
@ -221,6 +229,17 @@ static int a2xx_hw_init(struct msm_gpu *gpu)
|
||||
len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
|
||||
DBG("loading PM4 ucode version: %x", ptr[1]);
|
||||
|
||||
/*
|
||||
* New firmware files seem to have GPU and firmware version in this
|
||||
* word (0x20xxxx for A200, 0x220xxx for A220, 0x225xxx for A225).
|
||||
* Older firmware files, which lack protection support, have 0 instead.
|
||||
*/
|
||||
if (ptr[1] == 0) {
|
||||
dev_warn(gpu->dev->dev,
|
||||
"Legacy firmware detected, disabling protection support\n");
|
||||
a2xx_gpu->protection_disabled = true;
|
||||
}
|
||||
|
||||
gpu_write(gpu, REG_AXXX_CP_DEBUG,
|
||||
AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE);
|
||||
gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0);
|
||||
|
@ -15,6 +15,7 @@
|
||||
struct a2xx_gpu {
|
||||
struct adreno_gpu base;
|
||||
bool pm_enabled;
|
||||
bool protection_disabled;
|
||||
};
|
||||
#define to_a2xx_gpu(x) container_of(x, struct a2xx_gpu, base)
|
||||
|
||||
|
@ -241,6 +241,9 @@ enum a6xx_shader_id {
|
||||
A6XX_HLSQ_FRONTEND_META = 97,
|
||||
A6XX_HLSQ_INDIRECT_META = 98,
|
||||
A6XX_HLSQ_BACKEND_META = 99,
|
||||
A6XX_SP_LB_6_DATA = 112,
|
||||
A6XX_SP_LB_7_DATA = 113,
|
||||
A6XX_HLSQ_INST_RAM_1 = 115,
|
||||
};
|
||||
|
||||
enum a6xx_debugbus_id {
|
||||
@ -274,19 +277,32 @@ enum a6xx_debugbus_id {
|
||||
A6XX_DBGBUS_HLSQ_SPTP = 31,
|
||||
A6XX_DBGBUS_RB_0 = 32,
|
||||
A6XX_DBGBUS_RB_1 = 33,
|
||||
A6XX_DBGBUS_RB_2 = 34,
|
||||
A6XX_DBGBUS_UCHE_WRAPPER = 36,
|
||||
A6XX_DBGBUS_CCU_0 = 40,
|
||||
A6XX_DBGBUS_CCU_1 = 41,
|
||||
A6XX_DBGBUS_CCU_2 = 42,
|
||||
A6XX_DBGBUS_VFD_0 = 56,
|
||||
A6XX_DBGBUS_VFD_1 = 57,
|
||||
A6XX_DBGBUS_VFD_2 = 58,
|
||||
A6XX_DBGBUS_VFD_3 = 59,
|
||||
A6XX_DBGBUS_VFD_4 = 60,
|
||||
A6XX_DBGBUS_VFD_5 = 61,
|
||||
A6XX_DBGBUS_SP_0 = 64,
|
||||
A6XX_DBGBUS_SP_1 = 65,
|
||||
A6XX_DBGBUS_SP_2 = 66,
|
||||
A6XX_DBGBUS_TPL1_0 = 72,
|
||||
A6XX_DBGBUS_TPL1_1 = 73,
|
||||
A6XX_DBGBUS_TPL1_2 = 74,
|
||||
A6XX_DBGBUS_TPL1_3 = 75,
|
||||
A6XX_DBGBUS_TPL1_4 = 76,
|
||||
A6XX_DBGBUS_TPL1_5 = 77,
|
||||
A6XX_DBGBUS_SPTP_0 = 88,
|
||||
A6XX_DBGBUS_SPTP_1 = 89,
|
||||
A6XX_DBGBUS_SPTP_2 = 90,
|
||||
A6XX_DBGBUS_SPTP_3 = 91,
|
||||
A6XX_DBGBUS_SPTP_4 = 92,
|
||||
A6XX_DBGBUS_SPTP_5 = 93,
|
||||
};
|
||||
|
||||
enum a6xx_cp_perfcounter_select {
|
||||
@ -1071,6 +1087,8 @@ enum a6xx_tex_type {
|
||||
|
||||
#define REG_A6XX_CP_MISC_CNTL 0x00000840
|
||||
|
||||
#define REG_A6XX_CP_CHICKEN_DBG 0x00000841
|
||||
|
||||
#define REG_A6XX_CP_APRIV_CNTL 0x00000844
|
||||
|
||||
#define REG_A6XX_CP_ROQ_THRESHOLDS_1 0x000008c1
|
||||
|
@ -2028,7 +2028,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
|
||||
* to cause power supply issues:
|
||||
*/
|
||||
if (adreno_is_a618(adreno_gpu) || adreno_is_7c3(adreno_gpu))
|
||||
gpu->clamp_to_idle = true;
|
||||
priv->gpu_clamp_to_idle = true;
|
||||
|
||||
/* Check if there is a GMU phandle and set it up */
|
||||
node = of_parse_phandle(pdev->dev.of_node, "qcom,gmu", 0);
|
||||
|
@ -385,6 +385,9 @@ static void a6xx_get_debugbus(struct msm_gpu *gpu,
|
||||
nr_debugbus_blocks = ARRAY_SIZE(a6xx_debugbus_blocks) +
|
||||
(a6xx_has_gbif(to_adreno_gpu(gpu)) ? 1 : 0);
|
||||
|
||||
if (adreno_is_a650_family(to_adreno_gpu(gpu)))
|
||||
nr_debugbus_blocks += ARRAY_SIZE(a650_debugbus_blocks);
|
||||
|
||||
a6xx_state->debugbus = state_kcalloc(a6xx_state, nr_debugbus_blocks,
|
||||
sizeof(*a6xx_state->debugbus));
|
||||
|
||||
@ -411,6 +414,15 @@ static void a6xx_get_debugbus(struct msm_gpu *gpu,
|
||||
|
||||
a6xx_state->nr_debugbus += 1;
|
||||
}
|
||||
|
||||
|
||||
if (adreno_is_a650_family(to_adreno_gpu(gpu))) {
|
||||
for (i = 0; i < ARRAY_SIZE(a650_debugbus_blocks); i++)
|
||||
a6xx_get_debugbus_block(gpu,
|
||||
a6xx_state,
|
||||
&a650_debugbus_blocks[i],
|
||||
&a6xx_state->debugbus[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the VBIF debugbus on applicable targets */
|
||||
@ -524,10 +536,21 @@ static void a6xx_get_cluster(struct msm_gpu *gpu,
|
||||
struct a6xx_gpu_state_obj *obj,
|
||||
struct a6xx_crashdumper *dumper)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
u64 *in = dumper->ptr;
|
||||
u64 out = dumper->iova + A6XX_CD_DATA_OFFSET;
|
||||
size_t datasize;
|
||||
int i, regcount = 0;
|
||||
u32 id = cluster->id;
|
||||
|
||||
/* Skip registers that are not present on older generation */
|
||||
if (!adreno_is_a660_family(adreno_gpu) &&
|
||||
cluster->registers == a660_fe_cluster)
|
||||
return;
|
||||
|
||||
if (adreno_is_a650_family(adreno_gpu) &&
|
||||
cluster->registers == a6xx_ps_cluster)
|
||||
id = CLUSTER_VPC_PS;
|
||||
|
||||
/* Some clusters need a selector register to be programmed too */
|
||||
if (cluster->sel_reg)
|
||||
@ -537,7 +560,7 @@ static void a6xx_get_cluster(struct msm_gpu *gpu,
|
||||
int j;
|
||||
|
||||
in += CRASHDUMP_WRITE(in, REG_A6XX_CP_APERTURE_CNTL_CD,
|
||||
(cluster->id << 8) | (i << 4) | i);
|
||||
(id << 8) | (i << 4) | i);
|
||||
|
||||
for (j = 0; j < cluster->count; j += 2) {
|
||||
int count = RANGE(cluster->registers, j);
|
||||
@ -687,6 +710,11 @@ static void a6xx_get_crashdumper_registers(struct msm_gpu *gpu,
|
||||
u64 out = dumper->iova + A6XX_CD_DATA_OFFSET;
|
||||
int i, regcount = 0;
|
||||
|
||||
/* Skip unsupported registers on older generations */
|
||||
if (!adreno_is_a660_family(to_adreno_gpu(gpu)) &&
|
||||
(regs->registers == a660_registers))
|
||||
return;
|
||||
|
||||
/* Some blocks might need to program a selector register first */
|
||||
if (regs->val0)
|
||||
in += CRASHDUMP_WRITE(in, regs->val0, regs->val1);
|
||||
@ -721,6 +749,11 @@ static void a6xx_get_ahb_gpu_registers(struct msm_gpu *gpu,
|
||||
{
|
||||
int i, regcount = 0, index = 0;
|
||||
|
||||
/* Skip unsupported registers on older generations */
|
||||
if (!adreno_is_a660_family(to_adreno_gpu(gpu)) &&
|
||||
(regs->registers == a660_registers))
|
||||
return;
|
||||
|
||||
for (i = 0; i < regs->count; i += 2)
|
||||
regcount += RANGE(regs->registers, i);
|
||||
|
||||
@ -909,15 +942,24 @@ static void a6xx_get_registers(struct msm_gpu *gpu,
|
||||
dumper);
|
||||
}
|
||||
|
||||
static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu)
|
||||
{
|
||||
/* The value at [16:31] is in 4dword units. Convert it to dwords */
|
||||
return gpu_read(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2) >> 14;
|
||||
}
|
||||
|
||||
/* Read a block of data from an indexed register pair */
|
||||
static void a6xx_get_indexed_regs(struct msm_gpu *gpu,
|
||||
struct a6xx_gpu_state *a6xx_state,
|
||||
const struct a6xx_indexed_registers *indexed,
|
||||
struct a6xx_indexed_registers *indexed,
|
||||
struct a6xx_gpu_state_obj *obj)
|
||||
{
|
||||
int i;
|
||||
|
||||
obj->handle = (const void *) indexed;
|
||||
if (indexed->count_fn)
|
||||
indexed->count = indexed->count_fn(gpu);
|
||||
|
||||
obj->data = state_kcalloc(a6xx_state, indexed->count, sizeof(u32));
|
||||
if (!obj->data)
|
||||
return;
|
||||
@ -946,6 +988,21 @@ static void a6xx_get_indexed_registers(struct msm_gpu *gpu,
|
||||
a6xx_get_indexed_regs(gpu, a6xx_state, &a6xx_indexed_reglist[i],
|
||||
&a6xx_state->indexed_regs[i]);
|
||||
|
||||
if (adreno_is_a650_family(to_adreno_gpu(gpu))) {
|
||||
u32 val;
|
||||
|
||||
val = gpu_read(gpu, REG_A6XX_CP_CHICKEN_DBG);
|
||||
gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, val | 4);
|
||||
|
||||
/* Get the contents of the CP mempool */
|
||||
a6xx_get_indexed_regs(gpu, a6xx_state, &a6xx_cp_mempool_indexed,
|
||||
&a6xx_state->indexed_regs[i]);
|
||||
|
||||
gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, val);
|
||||
a6xx_state->nr_indexed_regs = count;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the CP mempool size to 0 to stabilize it while dumping */
|
||||
mempool_size = gpu_read(gpu, REG_A6XX_CP_MEM_POOL_SIZE);
|
||||
gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 0);
|
||||
|
@ -36,16 +36,21 @@ static const u32 a6xx_fe_cluster[] = {
|
||||
0xa00e, 0xa0ef, 0xa0f8, 0xa0f8,
|
||||
};
|
||||
|
||||
static const u32 a660_fe_cluster[] = {
|
||||
0x9807, 0x9807,
|
||||
};
|
||||
|
||||
static const u32 a6xx_pc_vs_cluster[] = {
|
||||
0x9100, 0x9108, 0x9300, 0x9306, 0x9980, 0x9981, 0x9b00, 0x9b07,
|
||||
};
|
||||
|
||||
#define CLUSTER_FE 0
|
||||
#define CLUSTER_SP_VS 1
|
||||
#define CLUSTER_PC_VS 2
|
||||
#define CLUSTER_GRAS 3
|
||||
#define CLUSTER_SP_PS 4
|
||||
#define CLUSTER_PS 5
|
||||
#define CLUSTER_FE 0
|
||||
#define CLUSTER_SP_VS 1
|
||||
#define CLUSTER_PC_VS 2
|
||||
#define CLUSTER_GRAS 3
|
||||
#define CLUSTER_SP_PS 4
|
||||
#define CLUSTER_PS 5
|
||||
#define CLUSTER_VPC_PS 6
|
||||
|
||||
#define CLUSTER(_id, _reg, _sel_reg, _sel_val) \
|
||||
{ .id = _id, .name = #_id,\
|
||||
@ -67,6 +72,7 @@ static const struct a6xx_cluster {
|
||||
CLUSTER(CLUSTER_PS, a6xx_ps_cluster, 0, 0),
|
||||
CLUSTER(CLUSTER_FE, a6xx_fe_cluster, 0, 0),
|
||||
CLUSTER(CLUSTER_PC_VS, a6xx_pc_vs_cluster, 0, 0),
|
||||
CLUSTER(CLUSTER_FE, a660_fe_cluster, 0, 0),
|
||||
};
|
||||
|
||||
static const u32 a6xx_sp_vs_hlsq_cluster[] = {
|
||||
@ -105,7 +111,7 @@ static const u32 a6xx_sp_ps_hlsq_2d_cluster[] = {
|
||||
|
||||
static const u32 a6xx_sp_ps_sp_cluster[] = {
|
||||
0xa980, 0xa9a8, 0xa9b0, 0xa9bc, 0xa9d0, 0xa9d3, 0xa9e0, 0xa9f3,
|
||||
0xaa00, 0xaa00, 0xaa30, 0xaa31,
|
||||
0xaa00, 0xaa00, 0xaa30, 0xaa31, 0xaaf2, 0xaaf2,
|
||||
};
|
||||
|
||||
static const u32 a6xx_sp_ps_sp_2d_cluster[] = {
|
||||
@ -229,6 +235,9 @@ static const struct a6xx_shader_block {
|
||||
SHADER(A6XX_HLSQ_DATAPATH_META, 0x40),
|
||||
SHADER(A6XX_HLSQ_FRONTEND_META, 0x40),
|
||||
SHADER(A6XX_HLSQ_INDIRECT_META, 0x40),
|
||||
SHADER(A6XX_SP_LB_6_DATA, 0x200),
|
||||
SHADER(A6XX_SP_LB_7_DATA, 0x200),
|
||||
SHADER(A6XX_HLSQ_INST_RAM_1, 0x200),
|
||||
};
|
||||
|
||||
static const u32 a6xx_rb_rac_registers[] = {
|
||||
@ -251,7 +260,7 @@ static const u32 a6xx_registers[] = {
|
||||
0x0540, 0x0555,
|
||||
/* CP */
|
||||
0x0800, 0x0808, 0x0810, 0x0813, 0x0820, 0x0821, 0x0823, 0x0824,
|
||||
0x0826, 0x0827, 0x0830, 0x0833, 0x0840, 0x0843, 0x084f, 0x086f,
|
||||
0x0826, 0x0827, 0x0830, 0x0833, 0x0840, 0x0845, 0x084f, 0x086f,
|
||||
0x0880, 0x088a, 0x08a0, 0x08ab, 0x08c0, 0x08c4, 0x08d0, 0x08dd,
|
||||
0x08f0, 0x08f3, 0x0900, 0x0903, 0x0908, 0x0911, 0x0928, 0x093e,
|
||||
0x0942, 0x094d, 0x0980, 0x0984, 0x098d, 0x0996, 0x0998, 0x099e,
|
||||
@ -274,6 +283,13 @@ static const u32 a6xx_registers[] = {
|
||||
/* VFD */
|
||||
0xa600, 0xa601, 0xa603, 0xa603, 0xa60a, 0xa60a, 0xa610, 0xa617,
|
||||
0xa630, 0xa630,
|
||||
/* HLSQ */
|
||||
0xd002, 0xd003,
|
||||
};
|
||||
|
||||
static const u32 a660_registers[] = {
|
||||
/* UCHE */
|
||||
0x0e3c, 0x0e3c,
|
||||
};
|
||||
|
||||
#define REGS(_array, _sel_reg, _sel_val) \
|
||||
@ -282,6 +298,7 @@ static const u32 a6xx_registers[] = {
|
||||
|
||||
static const struct a6xx_registers a6xx_reglist[] = {
|
||||
REGS(a6xx_registers, 0, 0),
|
||||
REGS(a660_registers, 0, 0),
|
||||
REGS(a6xx_rb_rac_registers, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 0),
|
||||
REGS(a6xx_rb_rbp_registers, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 9),
|
||||
};
|
||||
@ -366,25 +383,28 @@ static const struct a6xx_registers a6xx_gmu_reglist[] = {
|
||||
REGS(a6xx_gmu_gx_registers, 0, 0),
|
||||
};
|
||||
|
||||
static const struct a6xx_indexed_registers {
|
||||
static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu);
|
||||
|
||||
static struct a6xx_indexed_registers {
|
||||
const char *name;
|
||||
u32 addr;
|
||||
u32 data;
|
||||
u32 count;
|
||||
u32 (*count_fn)(struct msm_gpu *gpu);
|
||||
} a6xx_indexed_reglist[] = {
|
||||
{ "CP_SQE_STAT", REG_A6XX_CP_SQE_STAT_ADDR,
|
||||
REG_A6XX_CP_SQE_STAT_DATA, 0x33 },
|
||||
REG_A6XX_CP_SQE_STAT_DATA, 0x33, NULL },
|
||||
{ "CP_DRAW_STATE", REG_A6XX_CP_DRAW_STATE_ADDR,
|
||||
REG_A6XX_CP_DRAW_STATE_DATA, 0x100 },
|
||||
REG_A6XX_CP_DRAW_STATE_DATA, 0x100, NULL },
|
||||
{ "CP_UCODE_DBG_DATA", REG_A6XX_CP_SQE_UCODE_DBG_ADDR,
|
||||
REG_A6XX_CP_SQE_UCODE_DBG_DATA, 0x6000 },
|
||||
REG_A6XX_CP_SQE_UCODE_DBG_DATA, 0x8000, NULL },
|
||||
{ "CP_ROQ", REG_A6XX_CP_ROQ_DBG_ADDR,
|
||||
REG_A6XX_CP_ROQ_DBG_DATA, 0x400 },
|
||||
REG_A6XX_CP_ROQ_DBG_DATA, 0, a6xx_get_cp_roq_size},
|
||||
};
|
||||
|
||||
static const struct a6xx_indexed_registers a6xx_cp_mempool_indexed = {
|
||||
static struct a6xx_indexed_registers a6xx_cp_mempool_indexed = {
|
||||
"CP_MEMPOOL", REG_A6XX_CP_MEM_POOL_DBG_ADDR,
|
||||
REG_A6XX_CP_MEM_POOL_DBG_DATA, 0x2060,
|
||||
REG_A6XX_CP_MEM_POOL_DBG_DATA, 0x2060, NULL,
|
||||
};
|
||||
|
||||
#define DEBUGBUS(_id, _count) { .id = _id, .name = #_id, .count = _count }
|
||||
@ -443,4 +463,20 @@ static const struct a6xx_debugbus_block a6xx_cx_debugbus_blocks[] = {
|
||||
DEBUGBUS(A6XX_DBGBUS_CX, 0x100),
|
||||
};
|
||||
|
||||
static const struct a6xx_debugbus_block a650_debugbus_blocks[] = {
|
||||
DEBUGBUS(A6XX_DBGBUS_RB_2, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_CCU_2, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_VFD_4, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_VFD_5, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_SP_2, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_TPL1_4, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_TPL1_5, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_SPTP_0, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_SPTP_1, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_SPTP_2, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_SPTP_3, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_SPTP_4, 0x100),
|
||||
DEBUGBUS(A6XX_DBGBUS_SPTP_5, 0x100),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1083,13 +1083,13 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
|
||||
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
|
||||
{
|
||||
struct msm_gpu *gpu = &adreno_gpu->base;
|
||||
struct msm_drm_private *priv = gpu->dev->dev_private;
|
||||
struct msm_drm_private *priv = gpu->dev ? gpu->dev->dev_private : NULL;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
|
||||
release_firmware(adreno_gpu->fw[i]);
|
||||
|
||||
if (pm_runtime_enabled(&priv->gpu_pdev->dev))
|
||||
if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev))
|
||||
pm_runtime_disable(&priv->gpu_pdev->dev);
|
||||
|
||||
msm_gpu_cleanup(&adreno_gpu->base);
|
||||
|
@ -748,7 +748,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
|
||||
int i;
|
||||
|
||||
|
||||
if (!state->color_mgmt_changed)
|
||||
if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
|
||||
return;
|
||||
|
||||
for (i = 0; i < cstate->num_mixers; i++) {
|
||||
@ -968,7 +968,10 @@ static void dpu_crtc_reset(struct drm_crtc *crtc)
|
||||
if (crtc->state)
|
||||
dpu_crtc_destroy_state(crtc, crtc->state);
|
||||
|
||||
__drm_atomic_helper_crtc_reset(crtc, &cstate->base);
|
||||
if (cstate)
|
||||
__drm_atomic_helper_crtc_reset(crtc, &cstate->base);
|
||||
else
|
||||
__drm_atomic_helper_crtc_reset(crtc, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1150,6 +1153,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
|
||||
|
||||
pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
|
||||
if (!pstates)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!crtc_state->enable || !crtc_state->active) {
|
||||
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
|
||||
@ -1517,16 +1522,12 @@ DEFINE_SHOW_ATTRIBUTE(dpu_crtc_debugfs_state);
|
||||
static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc)
|
||||
{
|
||||
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
|
||||
struct dentry *debugfs_root;
|
||||
|
||||
debugfs_root = debugfs_create_dir(dpu_crtc->name,
|
||||
crtc->dev->primary->debugfs_root);
|
||||
|
||||
debugfs_create_file("status", 0400,
|
||||
debugfs_root,
|
||||
crtc->debugfs_entry,
|
||||
dpu_crtc, &_dpu_debugfs_status_fops);
|
||||
debugfs_create_file("state", 0600,
|
||||
debugfs_root,
|
||||
crtc->debugfs_entry,
|
||||
&dpu_crtc->base,
|
||||
&dpu_crtc_debugfs_state_fops);
|
||||
|
||||
|
@ -162,6 +162,7 @@ enum dpu_enc_rc_states {
|
||||
* @vsync_event_work: worker to handle vsync event for autorefresh
|
||||
* @topology: topology of the display
|
||||
* @idle_timeout: idle timeout duration in milliseconds
|
||||
* @wide_bus_en: wide bus is enabled on this interface
|
||||
* @dsc: drm_dsc_config pointer, for DSC-enabled encoders
|
||||
*/
|
||||
struct dpu_encoder_virt {
|
||||
@ -340,9 +341,7 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
|
||||
phys_enc->intf_idx - INTF_0, phys_enc->wb_idx - WB_0,
|
||||
phys_enc->hw_pp->idx - PINGPONG_0, intr_idx);
|
||||
|
||||
if (phys_enc->parent_ops->handle_frame_done)
|
||||
phys_enc->parent_ops->handle_frame_done(
|
||||
phys_enc->parent, phys_enc,
|
||||
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
|
||||
DPU_ENCODER_FRAME_EVENT_ERROR);
|
||||
}
|
||||
|
||||
@ -579,19 +578,18 @@ static struct msm_display_topology dpu_encoder_get_topology(
|
||||
topology.num_dspp = topology.num_lm;
|
||||
}
|
||||
|
||||
topology.num_enc = 0;
|
||||
topology.num_intf = intf_count;
|
||||
|
||||
if (dpu_enc->dsc) {
|
||||
/* In case of Display Stream Compression (DSC), we would use
|
||||
* 2 encoders, 2 layer mixers and 1 interface
|
||||
/*
|
||||
* In case of Display Stream Compression (DSC), we would use
|
||||
* 2 DSC encoders, 2 layer mixers and 1 interface
|
||||
* this is power optimal and can drive up to (including) 4k
|
||||
* screens
|
||||
*/
|
||||
topology.num_enc = 2;
|
||||
topology.num_dsc = 2;
|
||||
topology.num_intf = 1;
|
||||
topology.num_lm = 2;
|
||||
topology.num_intf = 1;
|
||||
}
|
||||
|
||||
return topology;
|
||||
@ -1284,7 +1282,7 @@ static enum dpu_wb dpu_encoder_get_wb(const struct dpu_mdss_cfg *catalog,
|
||||
return WB_MAX;
|
||||
}
|
||||
|
||||
static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
|
||||
void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
|
||||
struct dpu_encoder_phys *phy_enc)
|
||||
{
|
||||
struct dpu_encoder_virt *dpu_enc = NULL;
|
||||
@ -1306,7 +1304,7 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
|
||||
DPU_ATRACE_END("encoder_vblank_callback");
|
||||
}
|
||||
|
||||
static void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
|
||||
void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
|
||||
struct dpu_encoder_phys *phy_enc)
|
||||
{
|
||||
if (!phy_enc)
|
||||
@ -1382,7 +1380,7 @@ void dpu_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
|
||||
spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
|
||||
}
|
||||
|
||||
static void dpu_encoder_frame_done_callback(
|
||||
void dpu_encoder_frame_done_callback(
|
||||
struct drm_encoder *drm_enc,
|
||||
struct dpu_encoder_phys *ready_phys, u32 event)
|
||||
{
|
||||
@ -1830,6 +1828,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
|
||||
if (hw_pp->ops.setup_dsc)
|
||||
hw_pp->ops.setup_dsc(hw_pp);
|
||||
|
||||
if (hw_dsc->ops.dsc_bind_pingpong_blk)
|
||||
hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, true, hw_pp->idx);
|
||||
|
||||
if (hw_pp->ops.enable_dsc)
|
||||
hw_pp->ops.enable_dsc(hw_pp);
|
||||
}
|
||||
@ -2233,12 +2234,6 @@ static int dpu_encoder_virt_add_phys_encs(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dpu_encoder_virt_ops dpu_encoder_parent_ops = {
|
||||
.handle_vblank_virt = dpu_encoder_vblank_callback,
|
||||
.handle_underrun_virt = dpu_encoder_underrun_callback,
|
||||
.handle_frame_done = dpu_encoder_frame_done_callback,
|
||||
};
|
||||
|
||||
static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
|
||||
struct dpu_kms *dpu_kms,
|
||||
struct msm_display_info *disp_info)
|
||||
@ -2258,7 +2253,6 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
|
||||
memset(&phys_params, 0, sizeof(phys_params));
|
||||
phys_params.dpu_kms = dpu_kms;
|
||||
phys_params.parent = &dpu_enc->base;
|
||||
phys_params.parent_ops = &dpu_encoder_parent_ops;
|
||||
phys_params.enc_spinlock = &dpu_enc->enc_spinlock;
|
||||
|
||||
switch (disp_info->intf_type) {
|
||||
|
@ -60,25 +60,6 @@ enum dpu_enc_enable_state {
|
||||
|
||||
struct dpu_encoder_phys;
|
||||
|
||||
/**
|
||||
* struct dpu_encoder_virt_ops - Interface the containing virtual encoder
|
||||
* provides for the physical encoders to use to callback.
|
||||
* @handle_vblank_virt: Notify virtual encoder of vblank IRQ reception
|
||||
* Note: This is called from IRQ handler context.
|
||||
* @handle_underrun_virt: Notify virtual encoder of underrun IRQ reception
|
||||
* Note: This is called from IRQ handler context.
|
||||
* @handle_frame_done: Notify virtual encoder that this phys encoder
|
||||
* completes last request frame.
|
||||
*/
|
||||
struct dpu_encoder_virt_ops {
|
||||
void (*handle_vblank_virt)(struct drm_encoder *,
|
||||
struct dpu_encoder_phys *phys);
|
||||
void (*handle_underrun_virt)(struct drm_encoder *,
|
||||
struct dpu_encoder_phys *phys);
|
||||
void (*handle_frame_done)(struct drm_encoder *,
|
||||
struct dpu_encoder_phys *phys, u32 event);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dpu_encoder_phys_ops - Interface the physical encoders provide to
|
||||
* the containing virtual encoder.
|
||||
@ -199,7 +180,6 @@ enum dpu_intr_idx {
|
||||
struct dpu_encoder_phys {
|
||||
struct drm_encoder *parent;
|
||||
struct dpu_encoder_phys_ops ops;
|
||||
const struct dpu_encoder_virt_ops *parent_ops;
|
||||
struct dpu_hw_mdp *hw_mdptop;
|
||||
struct dpu_hw_ctl *hw_ctl;
|
||||
struct dpu_hw_pingpong *hw_pp;
|
||||
@ -283,7 +263,6 @@ struct dpu_encoder_phys_cmd {
|
||||
struct dpu_enc_phys_init_params {
|
||||
struct dpu_kms *dpu_kms;
|
||||
struct drm_encoder *parent;
|
||||
const struct dpu_encoder_virt_ops *parent_ops;
|
||||
enum dpu_enc_split_role split_role;
|
||||
enum dpu_intf intf_idx;
|
||||
enum dpu_wb wb_idx;
|
||||
@ -400,4 +379,30 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
|
||||
*/
|
||||
void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
|
||||
|
||||
/**
|
||||
* dpu_encoder_vblank_callback - Notify virtual encoder of vblank IRQ reception
|
||||
* @drm_enc: Pointer to drm encoder structure
|
||||
* @phys_enc: Pointer to physical encoder
|
||||
* Note: This is called from IRQ handler context.
|
||||
*/
|
||||
void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
|
||||
struct dpu_encoder_phys *phy_enc);
|
||||
|
||||
/** dpu_encoder_underrun_callback - Notify virtual encoder of underrun IRQ reception
|
||||
* @drm_enc: Pointer to drm encoder structure
|
||||
* @phys_enc: Pointer to physical encoder
|
||||
* Note: This is called from IRQ handler context.
|
||||
*/
|
||||
void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
|
||||
struct dpu_encoder_phys *phy_enc);
|
||||
|
||||
/** dpu_encoder_frame_done_callback -- Notify virtual encoder that this phys encoder completes last request frame
|
||||
* @drm_enc: Pointer to drm encoder structure
|
||||
* @phys_enc: Pointer to physical encoder
|
||||
* @event: Event to process
|
||||
*/
|
||||
void dpu_encoder_frame_done_callback(
|
||||
struct drm_encoder *drm_enc,
|
||||
struct dpu_encoder_phys *ready_phys, u32 event);
|
||||
|
||||
#endif /* __dpu_encoder_phys_H__ */
|
||||
|
@ -61,6 +61,7 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg(
|
||||
intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD;
|
||||
intf_cfg.stream_sel = cmd_enc->stream_sel;
|
||||
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
|
||||
intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
|
||||
ctl->ops.setup_intf_cfg(ctl, &intf_cfg);
|
||||
|
||||
/* setup which pp blk will connect to this intf */
|
||||
@ -83,9 +84,7 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
|
||||
|
||||
DPU_ATRACE_BEGIN("pp_done_irq");
|
||||
/* notify all synchronous clients first, then asynchronous clients */
|
||||
if (phys_enc->parent_ops->handle_frame_done)
|
||||
phys_enc->parent_ops->handle_frame_done(phys_enc->parent,
|
||||
phys_enc, event);
|
||||
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
|
||||
|
||||
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
|
||||
new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
|
||||
@ -111,9 +110,7 @@ static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
|
||||
DPU_ATRACE_BEGIN("rd_ptr_irq");
|
||||
cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
|
||||
|
||||
if (phys_enc->parent_ops->handle_vblank_virt)
|
||||
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
|
||||
phys_enc);
|
||||
dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
|
||||
|
||||
atomic_add_unless(&cmd_enc->pending_vblank_cnt, -1, 0);
|
||||
wake_up_all(&cmd_enc->pending_vblank_wq);
|
||||
@ -137,9 +134,7 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg, int irq_idx)
|
||||
{
|
||||
struct dpu_encoder_phys *phys_enc = arg;
|
||||
|
||||
if (phys_enc->parent_ops->handle_underrun_virt)
|
||||
phys_enc->parent_ops->handle_underrun_virt(phys_enc->parent,
|
||||
phys_enc);
|
||||
dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
|
||||
}
|
||||
|
||||
static void dpu_encoder_phys_cmd_atomic_mode_set(
|
||||
@ -202,9 +197,7 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
|
||||
/* request a ctl reset before the next kickoff */
|
||||
phys_enc->enable_state = DPU_ENC_ERR_NEEDS_HW_RESET;
|
||||
|
||||
if (phys_enc->parent_ops->handle_frame_done)
|
||||
phys_enc->parent_ops->handle_frame_done(
|
||||
drm_enc, phys_enc, frame_event);
|
||||
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@ -780,7 +773,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
|
||||
|
||||
dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
|
||||
phys_enc->parent = p->parent;
|
||||
phys_enc->parent_ops = p->parent_ops;
|
||||
phys_enc->dpu_kms = p->dpu_kms;
|
||||
phys_enc->split_role = p->split_role;
|
||||
phys_enc->intf_mode = INTF_MODE_CMD;
|
||||
|
@ -274,6 +274,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
|
||||
intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID;
|
||||
intf_cfg.stream_sel = 0; /* Don't care value for video mode */
|
||||
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
|
||||
intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
|
||||
if (phys_enc->hw_pp->merge_3d)
|
||||
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
|
||||
|
||||
@ -308,9 +309,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
|
||||
|
||||
DPU_ATRACE_BEGIN("vblank_irq");
|
||||
|
||||
if (phys_enc->parent_ops->handle_vblank_virt)
|
||||
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
|
||||
phys_enc);
|
||||
dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
|
||||
|
||||
atomic_read(&phys_enc->pending_kickoff_cnt);
|
||||
|
||||
@ -330,7 +329,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
|
||||
/* Signal any waiting atomic commit thread */
|
||||
wake_up_all(&phys_enc->pending_kickoff_wq);
|
||||
|
||||
phys_enc->parent_ops->handle_frame_done(phys_enc->parent, phys_enc,
|
||||
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
|
||||
DPU_ENCODER_FRAME_EVENT_DONE);
|
||||
|
||||
DPU_ATRACE_END("vblank_irq");
|
||||
@ -340,9 +339,7 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
|
||||
{
|
||||
struct dpu_encoder_phys *phys_enc = arg;
|
||||
|
||||
if (phys_enc->parent_ops->handle_underrun_virt)
|
||||
phys_enc->parent_ops->handle_underrun_virt(phys_enc->parent,
|
||||
phys_enc);
|
||||
dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
|
||||
}
|
||||
|
||||
static bool dpu_encoder_phys_vid_needs_single_flush(
|
||||
@ -700,7 +697,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
|
||||
|
||||
dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
|
||||
phys_enc->parent = p->parent;
|
||||
phys_enc->parent_ops = p->parent_ops;
|
||||
phys_enc->dpu_kms = p->dpu_kms;
|
||||
phys_enc->split_role = p->split_role;
|
||||
phys_enc->intf_mode = INTF_MODE_VIDEO;
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
/**
|
||||
* dpu_encoder_phys_wb_is_master - report wb always as master encoder
|
||||
* @phys_enc: Pointer to physical encoder
|
||||
*/
|
||||
static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys *phys_enc)
|
||||
{
|
||||
@ -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);
|
||||
|
||||
if (phys_enc->parent_ops->handle_frame_done)
|
||||
phys_enc->parent_ops->handle_frame_done(phys_enc->parent,
|
||||
phys_enc, event);
|
||||
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
|
||||
|
||||
if (phys_enc->parent_ops->handle_vblank_virt)
|
||||
phys_enc->parent_ops->handle_vblank_virt(phys_enc->parent,
|
||||
phys_enc);
|
||||
dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
|
||||
|
||||
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
|
||||
atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
|
||||
@ -440,9 +437,7 @@ static void _dpu_encoder_phys_wb_handle_wbdone_timeout(
|
||||
if (wb_enc->wb_conn)
|
||||
drm_writeback_signal_completion(wb_enc->wb_conn, 0);
|
||||
|
||||
if (phys_enc->parent_ops->handle_frame_done)
|
||||
phys_enc->parent_ops->handle_frame_done(
|
||||
phys_enc->parent, phys_enc, frame_event);
|
||||
dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -722,7 +717,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
|
||||
|
||||
dpu_encoder_phys_wb_init_ops(&phys_enc->ops);
|
||||
phys_enc->parent = p->parent;
|
||||
phys_enc->parent_ops = p->parent_ops;
|
||||
phys_enc->dpu_kms = p->dpu_kms;
|
||||
phys_enc->split_role = p->split_role;
|
||||
phys_enc->intf_mode = INTF_MODE_WB_LINE;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -46,7 +46,11 @@
|
||||
#define DPU_HW_VER_620 DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */
|
||||
#define DPU_HW_VER_630 DPU_HW_VER(6, 3, 0) /* sm6115|sm4250 */
|
||||
#define DPU_HW_VER_650 DPU_HW_VER(6, 5, 0) /* qcm2290|sm4125 */
|
||||
#define DPU_HW_VER_700 DPU_HW_VER(7, 0, 0) /* sm8350 */
|
||||
#define DPU_HW_VER_720 DPU_HW_VER(7, 2, 0) /* sc7280 */
|
||||
#define DPU_HW_VER_800 DPU_HW_VER(8, 0, 0) /* sc8280xp */
|
||||
#define DPU_HW_VER_810 DPU_HW_VER(8, 1, 0) /* sm8450 */
|
||||
#define DPU_HW_VER_900 DPU_HW_VER(9, 0, 0) /* sm8550 */
|
||||
|
||||
#define IS_MSM8996_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_170)
|
||||
#define IS_MSM8998_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_300)
|
||||
@ -83,6 +87,8 @@ enum {
|
||||
* @DPU_MDP_UBWC_1_0, This chipsets supports Universal Bandwidth
|
||||
* compression initial revision
|
||||
* @DPU_MDP_UBWC_1_5, Universal Bandwidth compression version 1.5
|
||||
* @DPU_MDP_PERIPH_0_REMOVED Indicates that access to periph top0 block results
|
||||
* in a failure
|
||||
* @DPU_MDP_MAX Maximum value
|
||||
|
||||
*/
|
||||
@ -93,6 +99,7 @@ enum {
|
||||
DPU_MDP_UBWC_1_0,
|
||||
DPU_MDP_UBWC_1_5,
|
||||
DPU_MDP_AUDIO_SELECT,
|
||||
DPU_MDP_PERIPH_0_REMOVED,
|
||||
DPU_MDP_MAX
|
||||
};
|
||||
|
||||
@ -192,6 +199,7 @@ enum {
|
||||
* @DPU_CTL_SPLIT_DISPLAY: CTL supports video mode split display
|
||||
* @DPU_CTL_FETCH_ACTIVE: Active CTL for fetch HW (SSPPs)
|
||||
* @DPU_CTL_VM_CFG: CTL config to support multiple VMs
|
||||
* @DPU_CTL_HAS_LAYER_EXT4: CTL has the CTL_LAYER_EXT4 register
|
||||
* @DPU_CTL_MAX
|
||||
*/
|
||||
enum {
|
||||
@ -199,6 +207,7 @@ enum {
|
||||
DPU_CTL_ACTIVE_CFG,
|
||||
DPU_CTL_FETCH_ACTIVE,
|
||||
DPU_CTL_VM_CFG,
|
||||
DPU_CTL_HAS_LAYER_EXT4,
|
||||
DPU_CTL_MAX
|
||||
};
|
||||
|
||||
@ -266,6 +275,15 @@ enum {
|
||||
DPU_VBIF_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* DSC features
|
||||
* @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets
|
||||
* the pixel output from this DSC.
|
||||
*/
|
||||
enum {
|
||||
DPU_DSC_OUTPUT_CTRL = 0x1,
|
||||
};
|
||||
|
||||
/**
|
||||
* MACRO DPU_HW_BLK_INFO - information of HW blocks inside DPU
|
||||
* @name: string name for debug purposes
|
||||
@ -519,7 +537,6 @@ struct dpu_clk_ctrl_reg {
|
||||
* @base: register base offset to mdss
|
||||
* @features bit mask identifying sub-blocks/features
|
||||
* @highest_bank_bit: UBWC parameter
|
||||
* @ubwc_static: ubwc static configuration
|
||||
* @ubwc_swizzle: ubwc default swizzle setting
|
||||
* @clk_ctrls clock control register definition
|
||||
*/
|
||||
|
@ -17,6 +17,8 @@
|
||||
(0x70 + (((lm) - LM_0) * 0x004))
|
||||
#define CTL_LAYER_EXT3(lm) \
|
||||
(0xA0 + (((lm) - LM_0) * 0x004))
|
||||
#define CTL_LAYER_EXT4(lm) \
|
||||
(0xB8 + (((lm) - LM_0) * 0x004))
|
||||
#define CTL_TOP 0x014
|
||||
#define CTL_FLUSH 0x018
|
||||
#define CTL_START 0x01C
|
||||
@ -377,12 +379,37 @@ static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx)
|
||||
DPU_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0);
|
||||
}
|
||||
|
||||
struct ctl_blend_config {
|
||||
int idx, shift, ext_shift;
|
||||
};
|
||||
|
||||
static const struct ctl_blend_config ctl_blend_config[][2] = {
|
||||
[SSPP_NONE] = { { -1 }, { -1 } },
|
||||
[SSPP_MAX] = { { -1 }, { -1 } },
|
||||
[SSPP_VIG0] = { { 0, 0, 0 }, { 3, 0 } },
|
||||
[SSPP_VIG1] = { { 0, 3, 2 }, { 3, 4 } },
|
||||
[SSPP_VIG2] = { { 0, 6, 4 }, { 3, 8 } },
|
||||
[SSPP_VIG3] = { { 0, 26, 6 }, { 3, 12 } },
|
||||
[SSPP_RGB0] = { { 0, 9, 8 }, { -1 } },
|
||||
[SSPP_RGB1] = { { 0, 12, 10 }, { -1 } },
|
||||
[SSPP_RGB2] = { { 0, 15, 12 }, { -1 } },
|
||||
[SSPP_RGB3] = { { 0, 29, 14 }, { -1 } },
|
||||
[SSPP_DMA0] = { { 0, 18, 16 }, { 2, 8 } },
|
||||
[SSPP_DMA1] = { { 0, 21, 18 }, { 2, 12 } },
|
||||
[SSPP_DMA2] = { { 2, 0 }, { 2, 16 } },
|
||||
[SSPP_DMA3] = { { 2, 4 }, { 2, 20 } },
|
||||
[SSPP_DMA4] = { { 4, 0 }, { 4, 8 } },
|
||||
[SSPP_DMA5] = { { 4, 4 }, { 4, 12 } },
|
||||
[SSPP_CURSOR0] = { { 1, 20 }, { -1 } },
|
||||
[SSPP_CURSOR1] = { { 1, 26 }, { -1 } },
|
||||
};
|
||||
|
||||
static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
|
||||
enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
|
||||
{
|
||||
struct dpu_hw_blk_reg_map *c = &ctx->hw;
|
||||
u32 mixercfg = 0, mixercfg_ext = 0, mix, ext;
|
||||
u32 mixercfg_ext2 = 0, mixercfg_ext3 = 0;
|
||||
u32 mix, ext, mix_ext;
|
||||
u32 mixercfg[5] = { 0 };
|
||||
int i, j;
|
||||
int stages;
|
||||
int pipes_per_stage;
|
||||
@ -397,7 +424,7 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
|
||||
else
|
||||
pipes_per_stage = 1;
|
||||
|
||||
mixercfg = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */
|
||||
mixercfg[0] = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */
|
||||
|
||||
if (!stage_cfg)
|
||||
goto exit;
|
||||
@ -406,109 +433,35 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
|
||||
/* overflow to ext register if 'i + 1 > 7' */
|
||||
mix = (i + 1) & 0x7;
|
||||
ext = i >= 7;
|
||||
mix_ext = (i + 1) & 0xf;
|
||||
|
||||
for (j = 0 ; j < pipes_per_stage; j++) {
|
||||
enum dpu_sspp_multirect_index rect_index =
|
||||
stage_cfg->multirect_index[i][j];
|
||||
enum dpu_sspp pipe = stage_cfg->stage[i][j];
|
||||
const struct ctl_blend_config *cfg =
|
||||
&ctl_blend_config[pipe][rect_index == DPU_SSPP_RECT_1];
|
||||
|
||||
switch (stage_cfg->stage[i][j]) {
|
||||
case SSPP_VIG0:
|
||||
if (rect_index == DPU_SSPP_RECT_1) {
|
||||
mixercfg_ext3 |= ((i + 1) & 0xF) << 0;
|
||||
} else {
|
||||
mixercfg |= mix << 0;
|
||||
mixercfg_ext |= ext << 0;
|
||||
}
|
||||
break;
|
||||
case SSPP_VIG1:
|
||||
if (rect_index == DPU_SSPP_RECT_1) {
|
||||
mixercfg_ext3 |= ((i + 1) & 0xF) << 4;
|
||||
} else {
|
||||
mixercfg |= mix << 3;
|
||||
mixercfg_ext |= ext << 2;
|
||||
}
|
||||
break;
|
||||
case SSPP_VIG2:
|
||||
if (rect_index == DPU_SSPP_RECT_1) {
|
||||
mixercfg_ext3 |= ((i + 1) & 0xF) << 8;
|
||||
} else {
|
||||
mixercfg |= mix << 6;
|
||||
mixercfg_ext |= ext << 4;
|
||||
}
|
||||
break;
|
||||
case SSPP_VIG3:
|
||||
if (rect_index == DPU_SSPP_RECT_1) {
|
||||
mixercfg_ext3 |= ((i + 1) & 0xF) << 12;
|
||||
} else {
|
||||
mixercfg |= mix << 26;
|
||||
mixercfg_ext |= ext << 6;
|
||||
}
|
||||
break;
|
||||
case SSPP_RGB0:
|
||||
mixercfg |= mix << 9;
|
||||
mixercfg_ext |= ext << 8;
|
||||
break;
|
||||
case SSPP_RGB1:
|
||||
mixercfg |= mix << 12;
|
||||
mixercfg_ext |= ext << 10;
|
||||
break;
|
||||
case SSPP_RGB2:
|
||||
mixercfg |= mix << 15;
|
||||
mixercfg_ext |= ext << 12;
|
||||
break;
|
||||
case SSPP_RGB3:
|
||||
mixercfg |= mix << 29;
|
||||
mixercfg_ext |= ext << 14;
|
||||
break;
|
||||
case SSPP_DMA0:
|
||||
if (rect_index == DPU_SSPP_RECT_1) {
|
||||
mixercfg_ext2 |= ((i + 1) & 0xF) << 8;
|
||||
} else {
|
||||
mixercfg |= mix << 18;
|
||||
mixercfg_ext |= ext << 16;
|
||||
}
|
||||
break;
|
||||
case SSPP_DMA1:
|
||||
if (rect_index == DPU_SSPP_RECT_1) {
|
||||
mixercfg_ext2 |= ((i + 1) & 0xF) << 12;
|
||||
} else {
|
||||
mixercfg |= mix << 21;
|
||||
mixercfg_ext |= ext << 18;
|
||||
}
|
||||
break;
|
||||
case SSPP_DMA2:
|
||||
if (rect_index == DPU_SSPP_RECT_1) {
|
||||
mixercfg_ext2 |= ((i + 1) & 0xF) << 16;
|
||||
} else {
|
||||
mix |= (i + 1) & 0xF;
|
||||
mixercfg_ext2 |= mix << 0;
|
||||
}
|
||||
break;
|
||||
case SSPP_DMA3:
|
||||
if (rect_index == DPU_SSPP_RECT_1) {
|
||||
mixercfg_ext2 |= ((i + 1) & 0xF) << 20;
|
||||
} else {
|
||||
mix |= (i + 1) & 0xF;
|
||||
mixercfg_ext2 |= mix << 4;
|
||||
}
|
||||
break;
|
||||
case SSPP_CURSOR0:
|
||||
mixercfg_ext |= ((i + 1) & 0xF) << 20;
|
||||
break;
|
||||
case SSPP_CURSOR1:
|
||||
mixercfg_ext |= ((i + 1) & 0xF) << 26;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
/*
|
||||
* CTL_LAYER has 3-bit field (and extra bits in EXT register),
|
||||
* all EXT registers has 4-bit fields.
|
||||
*/
|
||||
if (cfg->idx == 0) {
|
||||
mixercfg[0] |= mix << cfg->shift;
|
||||
mixercfg[1] |= ext << cfg->ext_shift;
|
||||
} else {
|
||||
mixercfg[cfg->idx] |= mix_ext << cfg->shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg);
|
||||
DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg_ext);
|
||||
DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg_ext2);
|
||||
DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg_ext3);
|
||||
DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg[0]);
|
||||
DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg[1]);
|
||||
DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg[2]);
|
||||
DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg[3]);
|
||||
if ((test_bit(DPU_CTL_HAS_LAYER_EXT4, &ctx->caps->features)))
|
||||
DPU_REG_WRITE(c, CTL_LAYER_EXT4(lm), mixercfg[4]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#define DSC_RANGE_MAX_QP 0x0B0
|
||||
#define DSC_RANGE_BPG_OFFSET 0x0EC
|
||||
|
||||
#define DSC_CTL(m) (0x1800 - 0x3FC * (m - DSC_0))
|
||||
|
||||
static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc)
|
||||
{
|
||||
struct dpu_hw_blk_reg_map *c = &dsc->hw;
|
||||
@ -150,6 +152,29 @@ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc,
|
||||
}
|
||||
}
|
||||
|
||||
static void dpu_hw_dsc_bind_pingpong_blk(
|
||||
struct dpu_hw_dsc *hw_dsc,
|
||||
bool enable,
|
||||
const enum dpu_pingpong pp)
|
||||
{
|
||||
struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
|
||||
int mux_cfg = 0xF;
|
||||
u32 dsc_ctl_offset;
|
||||
|
||||
dsc_ctl_offset = DSC_CTL(hw_dsc->idx);
|
||||
|
||||
if (enable)
|
||||
mux_cfg = (pp - PINGPONG_0) & 0x7;
|
||||
|
||||
DRM_DEBUG_KMS("%s dsc:%d %s pp:%d\n",
|
||||
enable ? "Binding" : "Unbinding",
|
||||
hw_dsc->idx - DSC_0,
|
||||
enable ? "to" : "from",
|
||||
pp - PINGPONG_0);
|
||||
|
||||
DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg);
|
||||
}
|
||||
|
||||
static struct dpu_dsc_cfg *_dsc_offset(enum dpu_dsc dsc,
|
||||
const struct dpu_mdss_cfg *m,
|
||||
void __iomem *addr,
|
||||
@ -174,6 +199,8 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops,
|
||||
ops->dsc_disable = dpu_hw_dsc_disable;
|
||||
ops->dsc_config = dpu_hw_dsc_config;
|
||||
ops->dsc_config_thresh = dpu_hw_dsc_config_thresh;
|
||||
if (cap & BIT(DPU_DSC_OUTPUT_CTRL))
|
||||
ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk;
|
||||
};
|
||||
|
||||
struct dpu_hw_dsc *dpu_hw_dsc_init(enum dpu_dsc idx, void __iomem *addr,
|
||||
|
@ -42,6 +42,10 @@ struct dpu_hw_dsc_ops {
|
||||
*/
|
||||
void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc,
|
||||
struct drm_dsc_config *dsc);
|
||||
|
||||
void (*dsc_bind_pingpong_blk)(struct dpu_hw_dsc *hw_dsc,
|
||||
bool enable,
|
||||
enum dpu_pingpong pp);
|
||||
};
|
||||
|
||||
struct dpu_hw_dsc {
|
||||
|
@ -35,6 +35,9 @@
|
||||
#define MDP_INTF_3_OFF_REV_7xxx 0x37000
|
||||
#define MDP_INTF_4_OFF_REV_7xxx 0x38000
|
||||
#define MDP_INTF_5_OFF_REV_7xxx 0x39000
|
||||
#define MDP_INTF_6_OFF_REV_7xxx 0x3a000
|
||||
#define MDP_INTF_7_OFF_REV_7xxx 0x3b000
|
||||
#define MDP_INTF_8_OFF_REV_7xxx 0x3c000
|
||||
|
||||
/**
|
||||
* struct dpu_intr_reg - array of DPU register sets
|
||||
@ -139,6 +142,21 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
|
||||
MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_EN,
|
||||
MDP_INTF_5_OFF_REV_7xxx+INTF_INTR_STATUS
|
||||
},
|
||||
[MDP_INTF6_7xxx_INTR] = {
|
||||
MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_CLEAR,
|
||||
MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_EN,
|
||||
MDP_INTF_6_OFF_REV_7xxx+INTF_INTR_STATUS
|
||||
},
|
||||
[MDP_INTF7_7xxx_INTR] = {
|
||||
MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_CLEAR,
|
||||
MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_EN,
|
||||
MDP_INTF_7_OFF_REV_7xxx+INTF_INTR_STATUS
|
||||
},
|
||||
[MDP_INTF8_7xxx_INTR] = {
|
||||
MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_CLEAR,
|
||||
MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_EN,
|
||||
MDP_INTF_8_OFF_REV_7xxx+INTF_INTR_STATUS
|
||||
},
|
||||
};
|
||||
|
||||
#define DPU_IRQ_REG(irq_idx) (irq_idx / 32)
|
||||
@ -252,9 +270,9 @@ static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
|
||||
|
||||
cache_irq_mask = intr->cache_irq_mask[reg_idx];
|
||||
if (cache_irq_mask & DPU_IRQ_MASK(irq_idx)) {
|
||||
dbgstr = "DPU IRQ already set:";
|
||||
dbgstr = "already ";
|
||||
} else {
|
||||
dbgstr = "DPU IRQ enabled:";
|
||||
dbgstr = "";
|
||||
|
||||
cache_irq_mask |= DPU_IRQ_MASK(irq_idx);
|
||||
/* Cleaning any pending interrupt */
|
||||
@ -268,7 +286,7 @@ static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
|
||||
intr->cache_irq_mask[reg_idx] = cache_irq_mask;
|
||||
}
|
||||
|
||||
pr_debug("%s MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", dbgstr,
|
||||
pr_debug("DPU IRQ %d %senabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", irq_idx, dbgstr,
|
||||
DPU_IRQ_MASK(irq_idx), cache_irq_mask);
|
||||
|
||||
return 0;
|
||||
@ -301,9 +319,9 @@ static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
|
||||
|
||||
cache_irq_mask = intr->cache_irq_mask[reg_idx];
|
||||
if ((cache_irq_mask & DPU_IRQ_MASK(irq_idx)) == 0) {
|
||||
dbgstr = "DPU IRQ is already cleared:";
|
||||
dbgstr = "already ";
|
||||
} else {
|
||||
dbgstr = "DPU IRQ mask disable:";
|
||||
dbgstr = "";
|
||||
|
||||
cache_irq_mask &= ~DPU_IRQ_MASK(irq_idx);
|
||||
/* Disable interrupts based on the new mask */
|
||||
@ -317,7 +335,7 @@ static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
|
||||
intr->cache_irq_mask[reg_idx] = cache_irq_mask;
|
||||
}
|
||||
|
||||
pr_debug("%s MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", dbgstr,
|
||||
pr_debug("DPU IRQ %d %sdisabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n", irq_idx, dbgstr,
|
||||
DPU_IRQ_MASK(irq_idx), cache_irq_mask);
|
||||
|
||||
return 0;
|
||||
|
@ -31,6 +31,9 @@ enum dpu_hw_intr_reg {
|
||||
MDP_INTF3_7xxx_INTR,
|
||||
MDP_INTF4_7xxx_INTR,
|
||||
MDP_INTF5_7xxx_INTR,
|
||||
MDP_INTF6_7xxx_INTR,
|
||||
MDP_INTF7_7xxx_INTR,
|
||||
MDP_INTF8_7xxx_INTR,
|
||||
MDP_INTR_MAX,
|
||||
};
|
||||
|
||||
|
@ -120,6 +120,8 @@ enum dpu_sspp {
|
||||
SSPP_DMA1,
|
||||
SSPP_DMA2,
|
||||
SSPP_DMA3,
|
||||
SSPP_DMA4,
|
||||
SSPP_DMA5,
|
||||
SSPP_CURSOR0,
|
||||
SSPP_CURSOR1,
|
||||
SSPP_MAX
|
||||
@ -195,6 +197,8 @@ enum dpu_pingpong {
|
||||
PINGPONG_3,
|
||||
PINGPONG_4,
|
||||
PINGPONG_5,
|
||||
PINGPONG_6,
|
||||
PINGPONG_7,
|
||||
PINGPONG_S0,
|
||||
PINGPONG_MAX
|
||||
};
|
||||
@ -203,6 +207,7 @@ enum dpu_merge_3d {
|
||||
MERGE_3D_0 = 1,
|
||||
MERGE_3D_1,
|
||||
MERGE_3D_2,
|
||||
MERGE_3D_3,
|
||||
MERGE_3D_MAX
|
||||
};
|
||||
|
||||
@ -214,6 +219,8 @@ enum dpu_intf {
|
||||
INTF_4,
|
||||
INTF_5,
|
||||
INTF_6,
|
||||
INTF_7,
|
||||
INTF_8,
|
||||
INTF_MAX
|
||||
};
|
||||
|
||||
|
@ -310,7 +310,11 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
|
||||
ctx->mdp->highest_bank_bit << 18);
|
||||
switch (ctx->catalog->caps->ubwc_version) {
|
||||
case DPU_HW_UBWC_VER_10:
|
||||
/* TODO: UBWC v1 case */
|
||||
fast_clear = fmt->alpha_enable ? BIT(31) : 0;
|
||||
DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL,
|
||||
fast_clear | (ctx->mdp->ubwc_swizzle & 0x1) |
|
||||
BIT(8) |
|
||||
(ctx->mdp->highest_bank_bit << 4));
|
||||
break;
|
||||
case DPU_HW_UBWC_VER_20:
|
||||
fast_clear = fmt->alpha_enable ? BIT(31) : 0;
|
||||
|
@ -7,40 +7,17 @@
|
||||
#include "dpu_hw_top.h"
|
||||
#include "dpu_kms.h"
|
||||
|
||||
#define SSPP_SPARE 0x28
|
||||
|
||||
#define FLD_SPLIT_DISPLAY_CMD BIT(1)
|
||||
#define FLD_SMART_PANEL_FREE_RUN BIT(2)
|
||||
#define FLD_INTF_1_SW_TRG_MUX BIT(4)
|
||||
#define FLD_INTF_2_SW_TRG_MUX BIT(8)
|
||||
#define FLD_TE_LINE_INTER_WATERLEVEL_MASK 0xFFFF
|
||||
|
||||
#define DANGER_STATUS 0x360
|
||||
#define SAFE_STATUS 0x364
|
||||
|
||||
#define TE_LINE_INTERVAL 0x3F4
|
||||
|
||||
#define TRAFFIC_SHAPER_EN BIT(31)
|
||||
#define TRAFFIC_SHAPER_RD_CLIENT(num) (0x030 + (num * 4))
|
||||
#define TRAFFIC_SHAPER_WR_CLIENT(num) (0x060 + (num * 4))
|
||||
#define TRAFFIC_SHAPER_FIXPOINT_FACTOR 4
|
||||
|
||||
#define MDP_WD_TIMER_0_CTL 0x380
|
||||
#define MDP_WD_TIMER_0_CTL2 0x384
|
||||
#define MDP_WD_TIMER_0_LOAD_VALUE 0x388
|
||||
#define MDP_WD_TIMER_1_CTL 0x390
|
||||
#define MDP_WD_TIMER_1_CTL2 0x394
|
||||
#define MDP_WD_TIMER_1_LOAD_VALUE 0x398
|
||||
#define MDP_WD_TIMER_2_CTL 0x420
|
||||
#define MDP_WD_TIMER_2_CTL2 0x424
|
||||
#define MDP_WD_TIMER_2_LOAD_VALUE 0x428
|
||||
#define MDP_WD_TIMER_3_CTL 0x430
|
||||
#define MDP_WD_TIMER_3_CTL2 0x434
|
||||
#define MDP_WD_TIMER_3_LOAD_VALUE 0x438
|
||||
#define MDP_WD_TIMER_4_CTL 0x440
|
||||
#define MDP_WD_TIMER_4_CTL2 0x444
|
||||
#define MDP_WD_TIMER_4_LOAD_VALUE 0x448
|
||||
|
||||
#define MDP_TICK_COUNT 16
|
||||
#define XO_CLK_RATE 19200
|
||||
#define MS_TICKS_IN_SEC 1000
|
||||
@ -48,8 +25,6 @@
|
||||
#define CALCULATE_WD_LOAD_VALUE(fps) \
|
||||
((uint32_t)((MS_TICKS_IN_SEC * XO_CLK_RATE)/(MDP_TICK_COUNT * fps)))
|
||||
|
||||
#define DCE_SEL 0x450
|
||||
|
||||
static void dpu_hw_setup_split_pipe(struct dpu_hw_mdp *mdp,
|
||||
struct split_pipe_cfg *cfg)
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define INTR_CLEAR 0x018
|
||||
#define INTR2_EN 0x008
|
||||
#define INTR2_STATUS 0x00c
|
||||
#define SSPP_SPARE 0x028
|
||||
#define INTR2_CLEAR 0x02c
|
||||
#define HIST_INTR_EN 0x01c
|
||||
#define HIST_INTR_STATUS 0x020
|
||||
@ -28,7 +29,15 @@
|
||||
#define DSPP_IGC_COLOR0_RAM_LUTN 0x300
|
||||
#define DSPP_IGC_COLOR1_RAM_LUTN 0x304
|
||||
#define DSPP_IGC_COLOR2_RAM_LUTN 0x308
|
||||
#define DANGER_STATUS 0x360
|
||||
#define SAFE_STATUS 0x364
|
||||
#define HW_EVENTS_CTL 0x37C
|
||||
#define MDP_WD_TIMER_0_CTL 0x380
|
||||
#define MDP_WD_TIMER_0_CTL2 0x384
|
||||
#define MDP_WD_TIMER_0_LOAD_VALUE 0x388
|
||||
#define MDP_WD_TIMER_1_CTL 0x390
|
||||
#define MDP_WD_TIMER_1_CTL2 0x394
|
||||
#define MDP_WD_TIMER_1_LOAD_VALUE 0x398
|
||||
#define CLK_CTRL3 0x3A8
|
||||
#define CLK_STATUS3 0x3AC
|
||||
#define CLK_CTRL4 0x3B0
|
||||
@ -43,6 +52,18 @@
|
||||
#define HDMI_DP_CORE_SELECT 0x408
|
||||
#define MDP_OUT_CTL_0 0x410
|
||||
#define MDP_VSYNC_SEL 0x414
|
||||
#define MDP_WD_TIMER_2_CTL 0x420
|
||||
#define MDP_WD_TIMER_2_CTL2 0x424
|
||||
#define MDP_WD_TIMER_2_LOAD_VALUE 0x428
|
||||
#define MDP_WD_TIMER_3_CTL 0x430
|
||||
#define MDP_WD_TIMER_3_CTL2 0x434
|
||||
#define MDP_WD_TIMER_3_LOAD_VALUE 0x438
|
||||
#define MDP_WD_TIMER_4_CTL 0x440
|
||||
#define MDP_WD_TIMER_4_CTL2 0x444
|
||||
#define MDP_WD_TIMER_4_LOAD_VALUE 0x448
|
||||
#define DCE_SEL 0x450
|
||||
|
||||
#define MDP_PERIPH_TOP0 MDP_WD_TIMER_0_CTL
|
||||
#define MDP_PERIPH_TOP0_END CLK_CTRL3
|
||||
|
||||
#endif /*_DPU_HWIO_H */
|
||||
|
@ -927,8 +927,20 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k
|
||||
msm_disp_snapshot_add_block(disp_state, cat->wb[i].len,
|
||||
dpu_kms->mmio + cat->wb[i].base, "wb_%d", i);
|
||||
|
||||
msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len,
|
||||
dpu_kms->mmio + cat->mdp[0].base, "top");
|
||||
if (cat->mdp[0].features & BIT(DPU_MDP_PERIPH_0_REMOVED)) {
|
||||
msm_disp_snapshot_add_block(disp_state, MDP_PERIPH_TOP0,
|
||||
dpu_kms->mmio + cat->mdp[0].base, "top");
|
||||
msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len - MDP_PERIPH_TOP0_END,
|
||||
dpu_kms->mmio + cat->mdp[0].base + MDP_PERIPH_TOP0_END, "top_2");
|
||||
} else {
|
||||
msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len,
|
||||
dpu_kms->mmio + cat->mdp[0].base, "top");
|
||||
}
|
||||
|
||||
/* dump DSC sub-blocks HW regs info */
|
||||
for (i = 0; i < cat->dsc_count; i++)
|
||||
msm_disp_snapshot_add_block(disp_state, cat->dsc[i].len,
|
||||
dpu_kms->mmio + cat->dsc[i].base, "dsc_%d", i);
|
||||
|
||||
pm_runtime_put_sync(&dpu_kms->pdev->dev);
|
||||
}
|
||||
@ -1292,9 +1304,13 @@ static const struct of_device_id dpu_dt_match[] = {
|
||||
{ .compatible = "qcom,sc7180-dpu", },
|
||||
{ .compatible = "qcom,sc7280-dpu", },
|
||||
{ .compatible = "qcom,sc8180x-dpu", },
|
||||
{ .compatible = "qcom,sc8280xp-dpu", },
|
||||
{ .compatible = "qcom,sm6115-dpu", },
|
||||
{ .compatible = "qcom,sm8150-dpu", },
|
||||
{ .compatible = "qcom,sm8250-dpu", },
|
||||
{ .compatible = "qcom,sm8350-dpu", },
|
||||
{ .compatible = "qcom,sm8450-dpu", },
|
||||
{ .compatible = "qcom,sm8550-dpu", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dpu_dt_match);
|
||||
|
@ -1126,7 +1126,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
|
||||
struct dpu_plane_state *pstate = to_dpu_plane_state(state);
|
||||
struct drm_crtc *crtc = state->crtc;
|
||||
struct drm_framebuffer *fb = state->fb;
|
||||
bool is_rt_pipe, update_qos_remap;
|
||||
bool is_rt_pipe;
|
||||
const struct dpu_format *fmt =
|
||||
to_dpu_format(msm_framebuffer_format(fb));
|
||||
struct dpu_hw_pipe_cfg pipe_cfg;
|
||||
@ -1138,6 +1138,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
|
||||
pstate->pending = true;
|
||||
|
||||
is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
|
||||
pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
|
||||
pdpu->is_rt_pipe = is_rt_pipe;
|
||||
|
||||
_dpu_plane_set_qos_ctrl(plane, false, DPU_PLANE_QOS_PANIC_CTRL);
|
||||
|
||||
DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
|
||||
@ -1219,14 +1222,8 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
|
||||
_dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
|
||||
}
|
||||
|
||||
update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
|
||||
pstate->needs_qos_remap;
|
||||
|
||||
if (update_qos_remap) {
|
||||
if (is_rt_pipe != pdpu->is_rt_pipe)
|
||||
pdpu->is_rt_pipe = is_rt_pipe;
|
||||
else if (pstate->needs_qos_remap)
|
||||
pstate->needs_qos_remap = false;
|
||||
if (pstate->needs_qos_remap) {
|
||||
pstate->needs_qos_remap = false;
|
||||
_dpu_plane_set_qos_remap(plane);
|
||||
}
|
||||
|
||||
|
@ -496,6 +496,11 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
|
||||
|
||||
/* check if DSC required are allocated or not */
|
||||
for (i = 0; i < num_dsc; i++) {
|
||||
if (!rm->dsc_blks[i]) {
|
||||
DPU_ERROR("DSC %d does not exist\n", i);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (global_state->dsc_to_enc_id[i]) {
|
||||
DPU_ERROR("DSC %d is already allocated\n", i);
|
||||
return -EIO;
|
||||
@ -543,8 +548,8 @@ static int _dpu_rm_populate_requirements(
|
||||
{
|
||||
reqs->topology = req_topology;
|
||||
|
||||
DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n",
|
||||
reqs->topology.num_lm, reqs->topology.num_enc,
|
||||
DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
|
||||
reqs->topology.num_lm, reqs->topology.num_dsc,
|
||||
reqs->topology.num_intf);
|
||||
|
||||
return 0;
|
||||
@ -660,6 +665,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
|
||||
blks_size, enc_id);
|
||||
break;
|
||||
}
|
||||
if (!hw_blks[i]) {
|
||||
DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n",
|
||||
type, enc_id);
|
||||
break;
|
||||
}
|
||||
blks[num_blks++] = hw_blks[i];
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,8 @@ int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
|
||||
int rc = 0;
|
||||
|
||||
dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), GFP_KERNEL);
|
||||
if (!dpu_wb_conn)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_connector_helper_add(&dpu_wb_conn->base.base, &dpu_wb_conn_helper_funcs);
|
||||
|
||||
|
@ -69,8 +69,7 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
|
||||
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
|
||||
struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms);
|
||||
struct drm_device *dev = mdp4_kms->dev;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
unsigned int id;
|
||||
struct drm_crtc *crtc;
|
||||
uint32_t status, enable;
|
||||
|
||||
enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE);
|
||||
@ -81,9 +80,9 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
|
||||
|
||||
mdp_dispatch_irqs(mdp_kms, status);
|
||||
|
||||
for (id = 0; id < priv->num_crtcs; id++)
|
||||
if (status & mdp4_crtc_vblank(priv->crtcs[id]))
|
||||
drm_handle_vblank(dev, id);
|
||||
drm_for_each_crtc(crtc, dev)
|
||||
if (status & mdp4_crtc_vblank(crtc))
|
||||
drm_crtc_handle_vblank(crtc);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -1139,7 +1139,10 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc)
|
||||
if (crtc->state)
|
||||
mdp5_crtc_destroy_state(crtc, crtc->state);
|
||||
|
||||
__drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
|
||||
if (mdp5_cstate)
|
||||
__drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
|
||||
else
|
||||
__drm_atomic_helper_crtc_reset(crtc, NULL);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
|
||||
|
@ -82,8 +82,7 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
|
||||
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
|
||||
struct drm_device *dev = mdp5_kms->dev;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
unsigned int id;
|
||||
struct drm_crtc *crtc;
|
||||
uint32_t status, enable;
|
||||
|
||||
enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN);
|
||||
@ -94,9 +93,9 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
|
||||
|
||||
mdp_dispatch_irqs(mdp_kms, status);
|
||||
|
||||
for (id = 0; id < priv->num_crtcs; id++)
|
||||
if (status & mdp5_crtc_vblank(priv->crtcs[id]))
|
||||
drm_handle_vblank(dev, id);
|
||||
drm_for_each_crtc(crtc, dev)
|
||||
if (status & mdp5_crtc_vblank(crtc))
|
||||
drm_crtc_handle_vblank(crtc);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -129,6 +129,9 @@ void msm_disp_snapshot_destroy(struct drm_device *drm_dev)
|
||||
}
|
||||
|
||||
priv = drm_dev->dev_private;
|
||||
if (!priv->kms)
|
||||
return;
|
||||
|
||||
kms = priv->kms;
|
||||
|
||||
if (kms->dump_worker)
|
||||
|
@ -122,61 +122,64 @@ struct dp_display_private {
|
||||
|
||||
struct msm_dp_desc {
|
||||
phys_addr_t io_start;
|
||||
unsigned int id;
|
||||
unsigned int connector_type;
|
||||
bool wide_bus_en;
|
||||
};
|
||||
|
||||
struct msm_dp_config {
|
||||
const struct msm_dp_desc *descs;
|
||||
size_t num_descs;
|
||||
};
|
||||
|
||||
static const struct msm_dp_desc sc7180_dp_descs[] = {
|
||||
[MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
||||
};
|
||||
|
||||
static const struct msm_dp_config sc7180_dp_cfg = {
|
||||
.descs = sc7180_dp_descs,
|
||||
.num_descs = ARRAY_SIZE(sc7180_dp_descs),
|
||||
{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct msm_dp_desc sc7280_dp_descs[] = {
|
||||
[MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
[MSM_DP_CONTROLLER_1] = { .io_start = 0x0aea0000, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
|
||||
};
|
||||
|
||||
static const struct msm_dp_config sc7280_dp_cfg = {
|
||||
.descs = sc7280_dp_descs,
|
||||
.num_descs = ARRAY_SIZE(sc7280_dp_descs),
|
||||
{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct msm_dp_desc sc8180x_dp_descs[] = {
|
||||
[MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
||||
[MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
||||
[MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, .connector_type = DRM_MODE_CONNECTOR_eDP },
|
||||
{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
||||
{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
||||
{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct msm_dp_config sc8180x_dp_cfg = {
|
||||
.descs = sc8180x_dp_descs,
|
||||
.num_descs = ARRAY_SIZE(sc8180x_dp_descs),
|
||||
static const struct msm_dp_desc sc8280xp_dp_descs[] = {
|
||||
{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{ .io_start = 0x22090000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{ .io_start = 0x22098000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{ .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{ .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct msm_dp_desc sc8280xp_edp_descs[] = {
|
||||
{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
|
||||
{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
|
||||
{ .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
|
||||
{ .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct msm_dp_desc sm8350_dp_descs[] = {
|
||||
[MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
||||
};
|
||||
|
||||
static const struct msm_dp_config sm8350_dp_cfg = {
|
||||
.descs = sm8350_dp_descs,
|
||||
.num_descs = ARRAY_SIZE(sm8350_dp_descs),
|
||||
{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct of_device_id dp_dt_match[] = {
|
||||
{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_cfg },
|
||||
{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_cfg },
|
||||
{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_cfg },
|
||||
{ .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_cfg },
|
||||
{ .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_cfg },
|
||||
{ .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_cfg },
|
||||
{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
|
||||
{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
|
||||
{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
|
||||
{ .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_descs },
|
||||
{ .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_descs },
|
||||
{ .compatible = "qcom,sc8280xp-dp", .data = &sc8280xp_dp_descs },
|
||||
{ .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs },
|
||||
{ .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs },
|
||||
{ .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -390,6 +393,10 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
|
||||
struct edid *edid;
|
||||
|
||||
dp->panel->max_dp_lanes = dp->parser->max_dp_lanes;
|
||||
dp->panel->max_dp_link_rate = dp->parser->max_dp_link_rate;
|
||||
|
||||
drm_dbg_dp(dp->drm_dev, "max_lanes=%d max_link_rate=%d\n",
|
||||
dp->panel->max_dp_lanes, dp->panel->max_dp_link_rate);
|
||||
|
||||
rc = dp_panel_read_sink_caps(dp->panel, dp->dp_display.connector);
|
||||
if (rc)
|
||||
@ -607,8 +614,10 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
|
||||
}
|
||||
|
||||
/* enable HDP irq_hpd/replug interrupt */
|
||||
dp_catalog_hpd_config_intr(dp->catalog,
|
||||
DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, true);
|
||||
if (dp->dp_display.internal_hpd)
|
||||
dp_catalog_hpd_config_intr(dp->catalog,
|
||||
DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
|
||||
true);
|
||||
|
||||
drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
|
||||
dp->dp_display.connector_type, state);
|
||||
@ -648,8 +657,10 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
|
||||
dp->dp_display.connector_type, state);
|
||||
|
||||
/* disable irq_hpd/replug interrupts */
|
||||
dp_catalog_hpd_config_intr(dp->catalog,
|
||||
DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, false);
|
||||
if (dp->dp_display.internal_hpd)
|
||||
dp_catalog_hpd_config_intr(dp->catalog,
|
||||
DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
|
||||
false);
|
||||
|
||||
/* unplugged, no more irq_hpd handle */
|
||||
dp_del_event(dp, EV_IRQ_HPD_INT);
|
||||
@ -675,7 +686,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
|
||||
}
|
||||
|
||||
/* disable HPD plug interrupts */
|
||||
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false);
|
||||
if (dp->dp_display.internal_hpd)
|
||||
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false);
|
||||
|
||||
/*
|
||||
* We don't need separate work for disconnect as
|
||||
@ -693,7 +705,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
|
||||
dp_display_handle_plugged_change(&dp->dp_display, false);
|
||||
|
||||
/* enable HDP plug interrupt to prepare for next plugin */
|
||||
if (!dp->dp_display.is_edp)
|
||||
if (dp->dp_display.internal_hpd)
|
||||
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true);
|
||||
|
||||
drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
|
||||
@ -1078,8 +1090,8 @@ static void dp_display_config_hpd(struct dp_display_private *dp)
|
||||
dp_display_host_init(dp);
|
||||
dp_catalog_ctrl_hpd_config(dp->catalog);
|
||||
|
||||
/* Enable plug and unplug interrupts only for external DisplayPort */
|
||||
if (!dp->dp_display.is_edp)
|
||||
/* Enable plug and unplug interrupts only if requested */
|
||||
if (dp->dp_display.internal_hpd)
|
||||
dp_catalog_hpd_config_intr(dp->catalog,
|
||||
DP_DP_HPD_PLUG_INT_MASK |
|
||||
DP_DP_HPD_UNPLUG_INT_MASK,
|
||||
@ -1262,10 +1274,9 @@ int dp_display_request_irq(struct msm_dp *dp_display)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pdev,
|
||||
unsigned int *id)
|
||||
static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pdev)
|
||||
{
|
||||
const struct msm_dp_config *cfg = of_device_get_match_data(&pdev->dev);
|
||||
const struct msm_dp_desc *descs = of_device_get_match_data(&pdev->dev);
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
@ -1273,11 +1284,9 @@ static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pde
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < cfg->num_descs; i++) {
|
||||
if (cfg->descs[i].io_start == res->start) {
|
||||
*id = i;
|
||||
return &cfg->descs[i];
|
||||
}
|
||||
for (i = 0; i < descs[i].io_start; i++) {
|
||||
if (descs[i].io_start == res->start)
|
||||
return &descs[i];
|
||||
}
|
||||
|
||||
dev_err(&pdev->dev, "unknown displayport instance\n");
|
||||
@ -1299,12 +1308,13 @@ static int dp_display_probe(struct platform_device *pdev)
|
||||
if (!dp)
|
||||
return -ENOMEM;
|
||||
|
||||
desc = dp_display_get_desc(pdev, &dp->id);
|
||||
desc = dp_display_get_desc(pdev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
dp->pdev = pdev;
|
||||
dp->name = "drm_dp";
|
||||
dp->id = desc->id;
|
||||
dp->dp_display.connector_type = desc->connector_type;
|
||||
dp->wide_bus_en = desc->wide_bus_en;
|
||||
dp->dp_display.is_edp =
|
||||
@ -1373,8 +1383,7 @@ static int dp_pm_resume(struct device *dev)
|
||||
|
||||
dp_catalog_ctrl_hpd_config(dp->catalog);
|
||||
|
||||
|
||||
if (!dp->dp_display.is_edp)
|
||||
if (dp->dp_display.internal_hpd)
|
||||
dp_catalog_hpd_config_intr(dp->catalog,
|
||||
DP_DP_HPD_PLUG_INT_MASK |
|
||||
DP_DP_HPD_UNPLUG_INT_MASK,
|
||||
@ -1497,7 +1506,7 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
|
||||
dp = container_of(dp_display, struct dp_display_private, dp_display);
|
||||
|
||||
if (!dp_display->is_edp)
|
||||
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100);
|
||||
dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0);
|
||||
}
|
||||
|
||||
bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
|
||||
@ -1771,3 +1780,41 @@ void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
|
||||
dp_display->dp_mode.h_active_low =
|
||||
!!(dp_display->dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
|
||||
}
|
||||
|
||||
void dp_bridge_hpd_enable(struct drm_bridge *bridge)
|
||||
{
|
||||
struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
|
||||
struct msm_dp *dp_display = dp_bridge->dp_display;
|
||||
|
||||
dp_display->internal_hpd = true;
|
||||
}
|
||||
|
||||
void dp_bridge_hpd_disable(struct drm_bridge *bridge)
|
||||
{
|
||||
struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
|
||||
struct msm_dp *dp_display = dp_bridge->dp_display;
|
||||
|
||||
dp_display->internal_hpd = false;
|
||||
}
|
||||
|
||||
void dp_bridge_hpd_notify(struct drm_bridge *bridge,
|
||||
enum drm_connector_status status)
|
||||
{
|
||||
struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
|
||||
struct msm_dp *dp_display = dp_bridge->dp_display;
|
||||
struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
|
||||
|
||||
/* Without next_bridge interrupts are handled by the DP core directly */
|
||||
if (dp_display->internal_hpd)
|
||||
return;
|
||||
|
||||
if (!dp->core_initialized) {
|
||||
drm_dbg_dp(dp->drm_dev, "not initialized\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dp_display->is_connected && status == connector_status_connected)
|
||||
dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
|
||||
else if (dp_display->is_connected && status == connector_status_disconnected)
|
||||
dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ struct msm_dp {
|
||||
bool power_on;
|
||||
unsigned int connector_type;
|
||||
bool is_edp;
|
||||
bool internal_hpd;
|
||||
|
||||
hdmi_codec_plugged_cb plugged_cb;
|
||||
|
||||
|
@ -102,6 +102,9 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
|
||||
.get_modes = dp_bridge_get_modes,
|
||||
.detect = dp_bridge_detect,
|
||||
.atomic_check = dp_bridge_atomic_check,
|
||||
.hpd_enable = dp_bridge_hpd_enable,
|
||||
.hpd_disable = dp_bridge_hpd_disable,
|
||||
.hpd_notify = dp_bridge_hpd_notify,
|
||||
};
|
||||
|
||||
struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
|
||||
|
@ -32,5 +32,9 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
|
||||
const struct drm_display_mode *mode,
|
||||
const struct drm_display_mode *adjusted_mode);
|
||||
void dp_bridge_hpd_enable(struct drm_bridge *bridge);
|
||||
void dp_bridge_hpd_disable(struct drm_bridge *bridge);
|
||||
void dp_bridge_hpd_notify(struct drm_bridge *bridge,
|
||||
enum drm_connector_status status);
|
||||
|
||||
#endif /* _DP_DRM_H_ */
|
||||
|
@ -75,12 +75,13 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel)
|
||||
link_info->rate = drm_dp_bw_code_to_link_rate(dpcd[DP_MAX_LINK_RATE]);
|
||||
link_info->num_lanes = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
|
||||
|
||||
/* Limit data lanes from data-lanes of endpoint property of dtsi */
|
||||
if (link_info->num_lanes > dp_panel->max_dp_lanes)
|
||||
link_info->num_lanes = dp_panel->max_dp_lanes;
|
||||
|
||||
/* Limit support upto HBR2 until HBR3 support is added */
|
||||
if (link_info->rate >= (drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4)))
|
||||
link_info->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4);
|
||||
/* Limit link rate from link-frequencies of endpoint property of dtsi */
|
||||
if (link_info->rate > dp_panel->max_dp_link_rate)
|
||||
link_info->rate = dp_panel->max_dp_link_rate;
|
||||
|
||||
drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
|
||||
drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
|
||||
|
@ -50,6 +50,7 @@ struct dp_panel {
|
||||
|
||||
u32 vic;
|
||||
u32 max_dp_lanes;
|
||||
u32 max_dp_link_rate;
|
||||
|
||||
u32 max_bw_code;
|
||||
};
|
||||
|
@ -91,19 +91,53 @@ static int dp_parser_ctrl_res(struct dp_parser *parser)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 dp_parser_link_frequencies(struct device_node *of_node)
|
||||
{
|
||||
struct device_node *endpoint;
|
||||
u64 frequency = 0;
|
||||
int cnt;
|
||||
|
||||
endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */
|
||||
if (!endpoint)
|
||||
return 0;
|
||||
|
||||
cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
|
||||
|
||||
if (cnt > 0)
|
||||
of_property_read_u64_index(endpoint, "link-frequencies",
|
||||
cnt - 1, &frequency);
|
||||
of_node_put(endpoint);
|
||||
|
||||
do_div(frequency,
|
||||
10 * /* from symbol rate to link rate */
|
||||
1000); /* kbytes */
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
static int dp_parser_misc(struct dp_parser *parser)
|
||||
{
|
||||
struct device_node *of_node = parser->pdev->dev.of_node;
|
||||
int len;
|
||||
int cnt;
|
||||
|
||||
len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
|
||||
if (len < 0) {
|
||||
DRM_WARN("Invalid property \"data-lanes\", default max DP lanes = %d\n",
|
||||
DP_MAX_NUM_DP_LANES);
|
||||
len = DP_MAX_NUM_DP_LANES;
|
||||
/*
|
||||
* data-lanes is the property of dp_out endpoint
|
||||
*/
|
||||
cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
|
||||
if (cnt < 0) {
|
||||
/* legacy code, data-lanes is the property of mdss_dp node */
|
||||
cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
|
||||
}
|
||||
|
||||
parser->max_dp_lanes = len;
|
||||
if (cnt > 0)
|
||||
parser->max_dp_lanes = cnt;
|
||||
else
|
||||
parser->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
|
||||
|
||||
parser->max_dp_link_rate = dp_parser_link_frequencies(of_node);
|
||||
if (!parser->max_dp_link_rate)
|
||||
parser->max_dp_link_rate = DP_LINK_RATE_HBR2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define DP_LABEL "MDSS DP DISPLAY"
|
||||
#define DP_MAX_PIXEL_CLK_KHZ 675000
|
||||
#define DP_MAX_NUM_DP_LANES 4
|
||||
#define DP_LINK_RATE_HBR2 540000 /* kbytes */
|
||||
|
||||
enum dp_pm_type {
|
||||
DP_CORE_PM,
|
||||
@ -119,6 +120,7 @@ struct dp_parser {
|
||||
struct dp_io io;
|
||||
struct dp_display_data disp_data;
|
||||
u32 max_dp_lanes;
|
||||
u32 max_dp_link_rate;
|
||||
struct drm_bridge *next_bridge;
|
||||
|
||||
int (*parse)(struct dp_parser *parser);
|
||||
|
@ -118,6 +118,8 @@ int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
|
||||
int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
|
||||
void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
|
||||
void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
|
||||
unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_dsi,
|
||||
const struct drm_display_mode *mode);
|
||||
int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
|
||||
int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
|
||||
void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
|
||||
@ -139,6 +141,7 @@ struct msm_dsi_phy_shared_timings {
|
||||
u32 clk_post;
|
||||
u32 clk_pre;
|
||||
bool clk_pre_inc_by_2;
|
||||
bool byte_intf_clk_div_2;
|
||||
};
|
||||
|
||||
struct msm_dsi_phy_clk_request {
|
||||
|
@ -181,6 +181,20 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
|
||||
.num_dsi = 2,
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data sm8550_dsi_regulators[] = {
|
||||
{ .supply = "vdda", .init_load_uA = 16800 }, /* 1.2 V */
|
||||
};
|
||||
|
||||
static const struct msm_dsi_config sm8550_dsi_cfg = {
|
||||
.io_offset = DSI_6G_REG_SHIFT,
|
||||
.regulator_data = sm8550_dsi_regulators,
|
||||
.num_regulators = ARRAY_SIZE(sm8550_dsi_regulators),
|
||||
.bus_clk_names = dsi_sdm845_bus_clk_names,
|
||||
.num_bus_clks = ARRAY_SIZE(dsi_sdm845_bus_clk_names),
|
||||
.io_start = { 0xae94000, 0xae96000 },
|
||||
.num_dsi = 2,
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data sc7180_dsi_regulators[] = {
|
||||
{ .supply = "vdda", .init_load_uA = 21800 }, /* 1.2 V */
|
||||
};
|
||||
@ -209,8 +223,8 @@ static const struct msm_dsi_config sc7280_dsi_cfg = {
|
||||
.num_regulators = ARRAY_SIZE(sc7280_dsi_regulators),
|
||||
.bus_clk_names = dsi_sc7280_bus_clk_names,
|
||||
.num_bus_clks = ARRAY_SIZE(dsi_sc7280_bus_clk_names),
|
||||
.io_start = { 0xae94000 },
|
||||
.num_dsi = 1,
|
||||
.io_start = { 0xae94000, 0xae96000 },
|
||||
.num_dsi = 2,
|
||||
};
|
||||
|
||||
static const char * const dsi_qcm2290_bus_clk_names[] = {
|
||||
@ -300,6 +314,10 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
|
||||
&sc7180_dsi_cfg, &msm_dsi_6g_v2_host_ops},
|
||||
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_0,
|
||||
&sc7280_dsi_cfg, &msm_dsi_6g_v2_host_ops},
|
||||
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_6_0,
|
||||
&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
|
||||
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0,
|
||||
&sm8550_dsi_cfg, &msm_dsi_6g_v2_host_ops},
|
||||
};
|
||||
|
||||
const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
|
||||
|
@ -25,6 +25,8 @@
|
||||
#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_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
|
||||
|
||||
|
@ -122,6 +122,7 @@ struct msm_dsi_host {
|
||||
struct clk *byte_intf_clk;
|
||||
|
||||
unsigned long byte_clk_rate;
|
||||
unsigned long byte_intf_clk_rate;
|
||||
unsigned long pixel_clk_rate;
|
||||
unsigned long esc_clk_rate;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
unsigned long byte_intf_rate;
|
||||
int ret;
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
if (msm_host->byte_intf_clk) {
|
||||
/* For CPHY, byte_intf_clk is same as byte_clk */
|
||||
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);
|
||||
ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to set rate byte intf clk, %d\n",
|
||||
__func__, ret);
|
||||
@ -570,9 +564,8 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
|
||||
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;
|
||||
|
||||
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
|
||||
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;
|
||||
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;
|
||||
|
||||
if (lanes == 0) {
|
||||
@ -607,8 +602,14 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
|
||||
else
|
||||
do_div(pclk_bpp, (8 * lanes));
|
||||
|
||||
msm_host->pixel_clk_rate = pclk_rate;
|
||||
msm_host->byte_clk_rate = pclk_bpp;
|
||||
return 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,
|
||||
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)
|
||||
|
||||
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);
|
||||
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
|
||||
*/
|
||||
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
|
||||
* update.
|
||||
*/
|
||||
if (slice_per_intf > dsc->slice_count)
|
||||
if (dsc->slice_count > slice_per_intf)
|
||||
dsc->slice_count = 1;
|
||||
|
||||
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)
|
||||
if (!msm_host->dsc)
|
||||
wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
|
||||
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_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
|
||||
@ -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);
|
||||
if (!msm_host) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
msm_host->pdev = pdev;
|
||||
@ -1893,31 +1894,28 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
|
||||
ret = dsi_host_parse_dt(msm_host);
|
||||
if (ret) {
|
||||
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);
|
||||
if (IS_ERR(msm_host->ctrl_base)) {
|
||||
pr_err("%s: unable to map Dsi ctrl base\n", __func__);
|
||||
ret = PTR_ERR(msm_host->ctrl_base);
|
||||
goto fail;
|
||||
return PTR_ERR(msm_host->ctrl_base);
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
msm_host->cfg_hnd = dsi_get_config(msm_host);
|
||||
if (!msm_host->cfg_hnd) {
|
||||
ret = -EINVAL;
|
||||
pr_err("%s: get config failed\n", __func__);
|
||||
goto fail;
|
||||
return -EINVAL;
|
||||
}
|
||||
cfg = msm_host->cfg_hnd->cfg;
|
||||
|
||||
msm_host->id = dsi_host_get_id(msm_host);
|
||||
if (msm_host->id < 0) {
|
||||
ret = msm_host->id;
|
||||
pr_err("%s: unable to identify DSI host index\n", __func__);
|
||||
goto fail;
|
||||
return msm_host->id;
|
||||
}
|
||||
|
||||
/* fixup base address by io offset */
|
||||
@ -1927,19 +1925,18 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
|
||||
cfg->regulator_data,
|
||||
&msm_host->supplies);
|
||||
if (ret)
|
||||
goto fail;
|
||||
return ret;
|
||||
|
||||
ret = dsi_clk_init(msm_host);
|
||||
if (ret) {
|
||||
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);
|
||||
if (!msm_host->rx_buf) {
|
||||
ret = -ENOMEM;
|
||||
pr_err("%s: alloc rx temp buf failed\n", __func__);
|
||||
goto fail;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = devm_pm_opp_set_clkname(&pdev->dev, "byte");
|
||||
@ -1977,15 +1974,15 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
|
||||
|
||||
/* setup workqueue */
|
||||
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);
|
||||
|
||||
msm_dsi->id = msm_host->id;
|
||||
|
||||
DBG("Dsi Host %d initialized", msm_host->id);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
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,
|
||||
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);
|
||||
|
||||
ret = regulator_bulk_enable(msm_host->cfg_hnd->cfg->num_regulators,
|
||||
|
@ -450,6 +450,26 @@ static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
int id = dsi_mgr_bridge_get_id(bridge);
|
||||
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
|
||||
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);
|
||||
|
||||
opp = dev_pm_opp_find_freq_ceil(&pdev->dev, &byte_clk_rate);
|
||||
if (!IS_ERR(opp)) {
|
||||
dev_pm_opp_put(opp);
|
||||
} else if (PTR_ERR(opp) == -ERANGE) {
|
||||
/*
|
||||
* An empty table is created by devm_pm_opp_set_clkname() even
|
||||
* if there is none. Thus find_freq_ceil will still return
|
||||
* -ERANGE in such case.
|
||||
*/
|
||||
if (dev_pm_opp_get_opp_count(&pdev->dev) != 0)
|
||||
return MODE_CLOCK_RANGE;
|
||||
} else {
|
||||
return MODE_ERROR;
|
||||
}
|
||||
|
||||
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,
|
||||
timing->shared_timings.clk_pre_inc_by_2 = 0;
|
||||
}
|
||||
|
||||
timing->shared_timings.byte_intf_clk_div_2 = true;
|
||||
|
||||
timing->ta_go = 3;
|
||||
timing->ta_sure = 0;
|
||||
timing->ta_get = 4;
|
||||
@ -454,6 +456,8 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
|
||||
tmax = 255;
|
||||
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",
|
||||
timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
|
||||
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[] = {
|
||||
.data = &dsi_phy_7nm_8150_cfgs },
|
||||
{ .compatible = "qcom,sc7280-dsi-phy-7nm",
|
||||
.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
|
||||
{}
|
||||
};
|
||||
|
@ -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_8998_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_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 {
|
||||
u32 clk_zero;
|
||||
|
@ -39,8 +39,16 @@
|
||||
#define VCO_REF_CLK_RATE 19200000
|
||||
#define FRAC_BITS 18
|
||||
|
||||
/* Hardware is pre V4.1 */
|
||||
#define DSI_PHY_7NM_QUIRK_PRE_V4_1 BIT(0)
|
||||
/* Hardware is V4.1 */
|
||||
#define DSI_PHY_7NM_QUIRK_V4_1 BIT(0)
|
||||
#define DSI_PHY_7NM_QUIRK_V4_1 BIT(1)
|
||||
/* Hardware is V4.2 */
|
||||
#define DSI_PHY_7NM_QUIRK_V4_2 BIT(2)
|
||||
/* Hardware is V4.3 */
|
||||
#define DSI_PHY_7NM_QUIRK_V4_3 BIT(3)
|
||||
/* Hardware is V5.2 */
|
||||
#define DSI_PHY_7NM_QUIRK_V5_2 BIT(4)
|
||||
|
||||
struct dsi_pll_config {
|
||||
bool enable_ssc;
|
||||
@ -116,16 +124,27 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config
|
||||
dec_multiple = div_u64(pll_freq * multiplier, divider);
|
||||
dec = div_u64_rem(dec_multiple, multiplier, &frac);
|
||||
|
||||
if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1))
|
||||
if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)
|
||||
config->pll_clock_inverters = 0x28;
|
||||
else if (pll_freq <= 1000000000ULL)
|
||||
config->pll_clock_inverters = 0xa0;
|
||||
else if (pll_freq <= 2500000000ULL)
|
||||
config->pll_clock_inverters = 0x20;
|
||||
else if (pll_freq <= 3020000000ULL)
|
||||
config->pll_clock_inverters = 0x00;
|
||||
else
|
||||
config->pll_clock_inverters = 0x40;
|
||||
else if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
|
||||
if (pll_freq <= 1300000000ULL)
|
||||
config->pll_clock_inverters = 0xa0;
|
||||
else if (pll_freq <= 2500000000ULL)
|
||||
config->pll_clock_inverters = 0x20;
|
||||
else if (pll_freq <= 4000000000ULL)
|
||||
config->pll_clock_inverters = 0x00;
|
||||
else
|
||||
config->pll_clock_inverters = 0x40;
|
||||
} else {
|
||||
if (pll_freq <= 1000000000ULL)
|
||||
config->pll_clock_inverters = 0xa0;
|
||||
else if (pll_freq <= 2500000000ULL)
|
||||
config->pll_clock_inverters = 0x20;
|
||||
else if (pll_freq <= 3020000000ULL)
|
||||
config->pll_clock_inverters = 0x00;
|
||||
else
|
||||
config->pll_clock_inverters = 0x40;
|
||||
}
|
||||
|
||||
config->decimal_div_start = dec;
|
||||
config->frac_div_start = frac;
|
||||
@ -197,16 +216,32 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
|
||||
void __iomem *base = pll->phy->pll_base;
|
||||
u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;
|
||||
|
||||
if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
|
||||
if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1))
|
||||
if (pll->vco_current_rate >= 3100000000ULL)
|
||||
analog_controls_five_1 = 0x03;
|
||||
|
||||
if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
|
||||
if (pll->vco_current_rate < 1520000000ULL)
|
||||
vco_config_1 = 0x08;
|
||||
else if (pll->vco_current_rate < 2990000000ULL)
|
||||
vco_config_1 = 0x01;
|
||||
}
|
||||
|
||||
if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_2) ||
|
||||
(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3)) {
|
||||
if (pll->vco_current_rate < 1520000000ULL)
|
||||
vco_config_1 = 0x08;
|
||||
else if (pll->vco_current_rate >= 2990000000ULL)
|
||||
vco_config_1 = 0x01;
|
||||
}
|
||||
|
||||
if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
|
||||
if (pll->vco_current_rate < 1557000000ULL)
|
||||
vco_config_1 = 0x08;
|
||||
else
|
||||
vco_config_1 = 0x01;
|
||||
}
|
||||
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1,
|
||||
analog_controls_five_1);
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1);
|
||||
@ -231,9 +266,9 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f);
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a);
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT,
|
||||
pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1 ? 0x3f : 0x22);
|
||||
!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1) ? 0x3f : 0x22);
|
||||
|
||||
if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
|
||||
if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)) {
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
|
||||
if (pll->slave)
|
||||
dsi_phy_write(pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
|
||||
@ -788,7 +823,7 @@ static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy)
|
||||
const u8 *tx_dctrl = tx_dctrl_0;
|
||||
void __iomem *lane_base = phy->lane_base;
|
||||
|
||||
if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1)
|
||||
if (!(phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1))
|
||||
tx_dctrl = tx_dctrl_1;
|
||||
|
||||
/* Strength ctrl settings */
|
||||
@ -844,6 +879,13 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
|
||||
if (dsi_phy_hw_v4_0_is_pll_on(phy))
|
||||
pr_warn("PLL turned on before configuring PHY\n");
|
||||
|
||||
/* Request for REFGEN READY */
|
||||
if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) ||
|
||||
(phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
|
||||
dsi_phy_write(phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10, 0x1);
|
||||
udelay(500);
|
||||
}
|
||||
|
||||
/* wait for REFGEN READY */
|
||||
ret = readl_poll_timeout_atomic(base + REG_DSI_7nm_PHY_CMN_PHY_STATUS,
|
||||
status, (status & BIT(0)),
|
||||
@ -858,23 +900,64 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
|
||||
/* Alter PHY configurations if data rate less than 1.5GHZ*/
|
||||
less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000);
|
||||
|
||||
if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
|
||||
glbl_str_swi_cal_sel_ctrl = 0x00;
|
||||
if (phy->cphy_mode) {
|
||||
vreg_ctrl_0 = 0x51;
|
||||
vreg_ctrl_1 = 0x55;
|
||||
glbl_hstx_str_ctrl_0 = 0x00;
|
||||
glbl_pemph_ctrl_0 = 0x11;
|
||||
lane_ctrl0 = 0x17;
|
||||
} else {
|
||||
vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;
|
||||
vreg_ctrl_1 = 0x5c;
|
||||
glbl_hstx_str_ctrl_0 = 0x88;
|
||||
glbl_pemph_ctrl_0 = 0x00;
|
||||
lane_ctrl0 = 0x1f;
|
||||
}
|
||||
|
||||
if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
|
||||
if (phy->cphy_mode) {
|
||||
vreg_ctrl_0 = 0x45;
|
||||
vreg_ctrl_1 = 0x45;
|
||||
glbl_rescode_top_ctrl = 0x00;
|
||||
glbl_rescode_bot_ctrl = 0x00;
|
||||
} else {
|
||||
vreg_ctrl_0 = 0x44;
|
||||
vreg_ctrl_1 = 0x19;
|
||||
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3c : 0x03;
|
||||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x3c;
|
||||
}
|
||||
} else if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3)) {
|
||||
if (phy->cphy_mode) {
|
||||
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x01;
|
||||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x3b;
|
||||
} else {
|
||||
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x01;
|
||||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x39;
|
||||
}
|
||||
} else if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_2) {
|
||||
if (phy->cphy_mode) {
|
||||
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x01;
|
||||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x3b;
|
||||
} else {
|
||||
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3c : 0x00;
|
||||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 : 0x39;
|
||||
}
|
||||
} else if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
|
||||
if (phy->cphy_mode) {
|
||||
glbl_hstx_str_ctrl_0 = 0x88;
|
||||
glbl_rescode_top_ctrl = 0x00;
|
||||
glbl_rescode_bot_ctrl = 0x3c;
|
||||
} else {
|
||||
glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x00;
|
||||
glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c;
|
||||
}
|
||||
glbl_str_swi_cal_sel_ctrl = 0x00;
|
||||
glbl_hstx_str_ctrl_0 = 0x88;
|
||||
} else {
|
||||
vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
|
||||
if (phy->cphy_mode) {
|
||||
glbl_str_swi_cal_sel_ctrl = 0x03;
|
||||
glbl_hstx_str_ctrl_0 = 0x66;
|
||||
} else {
|
||||
vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
|
||||
glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
|
||||
glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88;
|
||||
}
|
||||
@ -882,17 +965,6 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
|
||||
glbl_rescode_bot_ctrl = 0x3c;
|
||||
}
|
||||
|
||||
if (phy->cphy_mode) {
|
||||
vreg_ctrl_0 = 0x51;
|
||||
vreg_ctrl_1 = 0x55;
|
||||
glbl_pemph_ctrl_0 = 0x11;
|
||||
lane_ctrl0 = 0x17;
|
||||
} else {
|
||||
vreg_ctrl_1 = 0x5c;
|
||||
glbl_pemph_ctrl_0 = 0x00;
|
||||
lane_ctrl0 = 0x1f;
|
||||
}
|
||||
|
||||
/* de-assert digital and pll power down */
|
||||
data = BIT(6) | BIT(5);
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
|
||||
@ -904,9 +976,8 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0x00);
|
||||
|
||||
/* program CMN_CTRL_4 for minor_ver 2 chipsets*/
|
||||
data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0);
|
||||
data = data & (0xf0);
|
||||
if (data == 0x20)
|
||||
if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) ||
|
||||
(dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0) & (0xf0)) == 0x20)
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_4, 0x04);
|
||||
|
||||
/* Configure PHY lane swap (TODO: we need to calculate this) */
|
||||
@ -1017,6 +1088,16 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
|
||||
pr_warn("Turning OFF PHY while PLL is on\n");
|
||||
|
||||
dsi_phy_hw_v4_0_config_lpcdrx(phy, false);
|
||||
|
||||
/* Turn off REFGEN Vote */
|
||||
if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) ||
|
||||
(phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
|
||||
dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10, 0x0);
|
||||
wmb();
|
||||
/* Delay to ensure HW removes vote before PHY shut down */
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_CTRL_0);
|
||||
|
||||
/* disable all lanes */
|
||||
@ -1040,6 +1121,14 @@ static const struct regulator_bulk_data dsi_phy_7nm_37750uA_regulators[] = {
|
||||
{ .supply = "vdds", .init_load_uA = 37550 },
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data dsi_phy_7nm_97800uA_regulators[] = {
|
||||
{ .supply = "vdds", .init_load_uA = 97800 },
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data dsi_phy_7nm_98400uA_regulators[] = {
|
||||
{ .supply = "vdds", .init_load_uA = 98400 },
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_7nm_36mA_regulators,
|
||||
@ -1063,6 +1152,26 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {
|
||||
.quirks = DSI_PHY_7NM_QUIRK_V4_1,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_7nm_6375_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.ops = {
|
||||
.enable = dsi_7nm_phy_enable,
|
||||
.disable = dsi_7nm_phy_disable,
|
||||
.pll_init = dsi_pll_7nm_init,
|
||||
.save_pll_state = dsi_7nm_pll_save_state,
|
||||
.restore_pll_state = dsi_7nm_pll_restore_state,
|
||||
},
|
||||
.min_pll_rate = 600000000UL,
|
||||
#ifdef CONFIG_64BIT
|
||||
.max_pll_rate = 5000000000ULL,
|
||||
#else
|
||||
.max_pll_rate = ULONG_MAX,
|
||||
#endif
|
||||
.io_start = { 0x5e94400 },
|
||||
.num_dsi_phy = 1,
|
||||
.quirks = DSI_PHY_7NM_QUIRK_V4_1,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_7nm_36mA_regulators,
|
||||
@ -1079,6 +1188,7 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {
|
||||
.max_pll_rate = 3500000000UL,
|
||||
.io_start = { 0xae94400, 0xae96400 },
|
||||
.num_dsi_phy = 2,
|
||||
.quirks = DSI_PHY_7NM_QUIRK_PRE_V4_1,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = {
|
||||
@ -1102,3 +1212,72 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = {
|
||||
.num_dsi_phy = 1,
|
||||
.quirks = DSI_PHY_7NM_QUIRK_V4_1,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_7nm_37750uA_regulators,
|
||||
.num_regulators = ARRAY_SIZE(dsi_phy_7nm_37750uA_regulators),
|
||||
.ops = {
|
||||
.enable = dsi_7nm_phy_enable,
|
||||
.disable = dsi_7nm_phy_disable,
|
||||
.pll_init = dsi_pll_7nm_init,
|
||||
.save_pll_state = dsi_7nm_pll_save_state,
|
||||
.restore_pll_state = dsi_7nm_pll_restore_state,
|
||||
.set_continuous_clock = dsi_7nm_set_continuous_clock,
|
||||
},
|
||||
.min_pll_rate = 600000000UL,
|
||||
#ifdef CONFIG_64BIT
|
||||
.max_pll_rate = 5000000000UL,
|
||||
#else
|
||||
.max_pll_rate = ULONG_MAX,
|
||||
#endif
|
||||
.io_start = { 0xae94400, 0xae96400 },
|
||||
.num_dsi_phy = 2,
|
||||
.quirks = DSI_PHY_7NM_QUIRK_V4_2,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_7nm_97800uA_regulators,
|
||||
.num_regulators = ARRAY_SIZE(dsi_phy_7nm_97800uA_regulators),
|
||||
.ops = {
|
||||
.enable = dsi_7nm_phy_enable,
|
||||
.disable = dsi_7nm_phy_disable,
|
||||
.pll_init = dsi_pll_7nm_init,
|
||||
.save_pll_state = dsi_7nm_pll_save_state,
|
||||
.restore_pll_state = dsi_7nm_pll_restore_state,
|
||||
.set_continuous_clock = dsi_7nm_set_continuous_clock,
|
||||
},
|
||||
.min_pll_rate = 600000000UL,
|
||||
#ifdef CONFIG_64BIT
|
||||
.max_pll_rate = 5000000000UL,
|
||||
#else
|
||||
.max_pll_rate = ULONG_MAX,
|
||||
#endif
|
||||
.io_start = { 0xae94400, 0xae96400 },
|
||||
.num_dsi_phy = 2,
|
||||
.quirks = DSI_PHY_7NM_QUIRK_V4_3,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_7nm_98400uA_regulators,
|
||||
.num_regulators = ARRAY_SIZE(dsi_phy_7nm_98400uA_regulators),
|
||||
.ops = {
|
||||
.enable = dsi_7nm_phy_enable,
|
||||
.disable = dsi_7nm_phy_disable,
|
||||
.pll_init = dsi_pll_7nm_init,
|
||||
.save_pll_state = dsi_7nm_pll_save_state,
|
||||
.restore_pll_state = dsi_7nm_pll_restore_state,
|
||||
.set_continuous_clock = dsi_7nm_set_continuous_clock,
|
||||
},
|
||||
.min_pll_rate = 600000000UL,
|
||||
#ifdef CONFIG_64BIT
|
||||
.max_pll_rate = 5000000000UL,
|
||||
#else
|
||||
.max_pll_rate = ULONG_MAX,
|
||||
#endif
|
||||
.io_start = { 0xae95000, 0xae97000 },
|
||||
.num_dsi_phy = 2,
|
||||
.quirks = DSI_PHY_7NM_QUIRK_V5_2,
|
||||
};
|
||||
|
@ -120,6 +120,10 @@ static int msm_hdmi_init(struct hdmi *hdmi)
|
||||
int ret;
|
||||
|
||||
hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
|
||||
if (!hdmi->workq) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdmi->i2c = msm_hdmi_i2c_init(hdmi);
|
||||
if (IS_ERR(hdmi->i2c)) {
|
||||
|
@ -406,14 +406,14 @@ static const struct clk_ops hdmi_pll_ops = {
|
||||
.set_rate = hdmi_pll_set_rate,
|
||||
};
|
||||
|
||||
static const char * const hdmi_pll_parents[] = {
|
||||
"pxo",
|
||||
static const struct clk_parent_data hdmi_pll_parents[] = {
|
||||
{ .fw_name = "pxo", .name = "pxo_board" },
|
||||
};
|
||||
|
||||
static struct clk_init_data pll_init = {
|
||||
.name = "hdmi_pll",
|
||||
.ops = &hdmi_pll_ops,
|
||||
.parent_names = hdmi_pll_parents,
|
||||
.parent_data = hdmi_pll_parents,
|
||||
.num_parents = ARRAY_SIZE(hdmi_pll_parents),
|
||||
.flags = CLK_IGNORE_UNUSED,
|
||||
};
|
||||
@ -422,8 +422,7 @@ int msm_hdmi_pll_8960_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct hdmi_pll_8960 *pll;
|
||||
struct clk *clk;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
/* sanity check: */
|
||||
for (i = 0; i < (ARRAY_SIZE(freqtbl) - 1); i++)
|
||||
@ -443,10 +442,16 @@ int msm_hdmi_pll_8960_init(struct platform_device *pdev)
|
||||
pll->pdev = pdev;
|
||||
pll->clk_hw.init = &pll_init;
|
||||
|
||||
clk = devm_clk_register(dev, &pll->clk_hw);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = devm_clk_hw_register(dev, &pll->clk_hw);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(dev, "failed to register pll clock\n");
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -305,6 +305,7 @@ void msm_debugfs_init(struct drm_minor *minor)
|
||||
{
|
||||
struct drm_device *dev = minor->dev;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct dentry *gpu_devfreq;
|
||||
|
||||
drm_debugfs_create_files(msm_debugfs_list,
|
||||
ARRAY_SIZE(msm_debugfs_list),
|
||||
@ -325,6 +326,17 @@ void msm_debugfs_init(struct drm_minor *minor)
|
||||
debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root,
|
||||
dev, &shrink_fops);
|
||||
|
||||
gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root);
|
||||
|
||||
debugfs_create_bool("idle_clamp",0600, gpu_devfreq,
|
||||
&priv->gpu_clamp_to_idle);
|
||||
|
||||
debugfs_create_u32("upthreshold",0600, gpu_devfreq,
|
||||
&priv->gpu_devfreq_config.upthreshold);
|
||||
|
||||
debugfs_create_u32("downdifferential",0600, gpu_devfreq,
|
||||
&priv->gpu_devfreq_config.downdifferential);
|
||||
|
||||
if (priv->kms && priv->kms->funcs->debugfs_init)
|
||||
priv->kms->funcs->debugfs_init(priv->kms, minor);
|
||||
|
||||
|
@ -45,9 +45,10 @@
|
||||
* - 1.7.0 - Add MSM_PARAM_SUSPENDS to access suspend count
|
||||
* - 1.8.0 - Add MSM_BO_CACHED_COHERENT for supported GPUs (a6xx)
|
||||
* - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN
|
||||
* - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT
|
||||
*/
|
||||
#define MSM_VERSION_MAJOR 1
|
||||
#define MSM_VERSION_MINOR 9
|
||||
#define MSM_VERSION_MINOR 10
|
||||
#define MSM_VERSION_PATCHLEVEL 0
|
||||
|
||||
static const struct drm_mode_config_funcs mode_config_funcs = {
|
||||
@ -149,6 +150,9 @@ static void msm_irq_uninstall(struct drm_device *dev)
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct msm_kms *kms = priv->kms;
|
||||
|
||||
if (!priv->kms)
|
||||
return;
|
||||
|
||||
kms->funcs->irq_uninstall(kms);
|
||||
if (kms->irq_requested)
|
||||
free_irq(kms->irq, dev);
|
||||
@ -266,8 +270,6 @@ static int msm_drm_uninit(struct device *dev)
|
||||
component_unbind_all(dev, ddev);
|
||||
|
||||
ddev->dev_private = NULL;
|
||||
drm_dev_put(ddev);
|
||||
|
||||
destroy_workqueue(priv->wq);
|
||||
|
||||
return 0;
|
||||
@ -418,6 +420,8 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
|
||||
priv->dev = ddev;
|
||||
|
||||
priv->wq = alloc_ordered_workqueue("msm", 0);
|
||||
if (!priv->wq)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&priv->objects);
|
||||
mutex_init(&priv->obj_lock);
|
||||
@ -440,12 +444,12 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
|
||||
|
||||
ret = msm_init_vram(ddev);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_drm_dev_put;
|
||||
|
||||
/* Bind all our sub-components: */
|
||||
ret = component_bind_all(dev, ddev);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_drm_dev_put;
|
||||
|
||||
dma_set_max_seg_size(dev, UINT_MAX);
|
||||
|
||||
@ -491,7 +495,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
|
||||
if (IS_ERR(priv->event_thread[i].worker)) {
|
||||
ret = PTR_ERR(priv->event_thread[i].worker);
|
||||
DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n");
|
||||
ret = PTR_ERR(priv->event_thread[i].worker);
|
||||
priv->event_thread[i].worker = NULL;
|
||||
goto err_msm_uninit;
|
||||
}
|
||||
|
||||
@ -540,6 +544,8 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
|
||||
|
||||
err_msm_uninit:
|
||||
msm_drm_uninit(dev);
|
||||
err_drm_dev_put:
|
||||
drm_dev_put(ddev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -61,6 +62,7 @@ enum msm_dp_controller {
|
||||
MSM_DP_CONTROLLER_0,
|
||||
MSM_DP_CONTROLLER_1,
|
||||
MSM_DP_CONTROLLER_2,
|
||||
MSM_DP_CONTROLLER_3,
|
||||
MSM_DP_CONTROLLER_COUNT,
|
||||
};
|
||||
|
||||
@ -82,14 +84,12 @@ enum msm_event_wait {
|
||||
/**
|
||||
* struct msm_display_topology - defines a display topology pipeline
|
||||
* @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_dspp: number of dspp blocks used
|
||||
* @num_dsc: number of Display Stream Compression (DSC) blocks used
|
||||
*/
|
||||
struct msm_display_topology {
|
||||
u32 num_lm;
|
||||
u32 num_enc;
|
||||
u32 num_intf;
|
||||
u32 num_dspp;
|
||||
u32 num_dsc;
|
||||
@ -233,6 +233,14 @@ struct msm_drm_private {
|
||||
*/
|
||||
unsigned int hangcheck_period;
|
||||
|
||||
/** gpu_devfreq_config: Devfreq tuning config for the GPU. */
|
||||
struct devfreq_simple_ondemand_data gpu_devfreq_config;
|
||||
|
||||
/**
|
||||
* gpu_clamp_to_idle: Enable clamping to idle freq when inactive
|
||||
*/
|
||||
bool gpu_clamp_to_idle;
|
||||
|
||||
/**
|
||||
* disable_err_irq:
|
||||
*
|
||||
|
@ -22,7 +22,7 @@ msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
fctx->dev = dev;
|
||||
strncpy(fctx->name, name, sizeof(fctx->name));
|
||||
strscpy(fctx->name, name, sizeof(fctx->name));
|
||||
fctx->context = dma_fence_context_alloc(1);
|
||||
fctx->index = index++;
|
||||
fctx->fenceptr = fenceptr;
|
||||
|
@ -209,6 +209,10 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit,
|
||||
goto out;
|
||||
}
|
||||
submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL);
|
||||
if (!submit->cmd[i].relocs) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
ret = copy_from_user(submit->cmd[i].relocs, userptr, sz);
|
||||
if (ret) {
|
||||
ret = -EFAULT;
|
||||
@ -334,9 +338,20 @@ static int submit_fence_sync(struct msm_gem_submit *submit, bool no_implicit)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* If userspace has determined that explicit fencing is
|
||||
* used, it can disable implicit sync on the entire
|
||||
* submit:
|
||||
*/
|
||||
if (no_implicit)
|
||||
continue;
|
||||
|
||||
/* Otherwise userspace can ask for implicit sync to be
|
||||
* disabled on specific buffers. This is useful for internal
|
||||
* usermode driver managed buffers, suballocation, etc.
|
||||
*/
|
||||
if (submit->bos[i].flags & MSM_SUBMIT_BO_NO_IMPLICIT)
|
||||
continue;
|
||||
|
||||
ret = drm_sched_job_add_implicit_dependencies(&submit->base,
|
||||
obj,
|
||||
write);
|
||||
|
@ -109,11 +109,15 @@ struct msm_gpu_devfreq {
|
||||
struct mutex lock;
|
||||
|
||||
/**
|
||||
* idle_constraint:
|
||||
* idle_freq:
|
||||
*
|
||||
* A PM QoS constraint to limit max freq while the GPU is idle.
|
||||
* Shadow frequency used while the GPU is idle. From the PoV of
|
||||
* the devfreq governor, we are continuing to sample busyness and
|
||||
* adjust frequency while the GPU is idle, but we use this shadow
|
||||
* value as the GPU is actually clamped to minimum frequency while
|
||||
* it is inactive.
|
||||
*/
|
||||
struct dev_pm_qos_request idle_freq;
|
||||
unsigned long idle_freq;
|
||||
|
||||
/**
|
||||
* boost_constraint:
|
||||
@ -135,8 +139,6 @@ struct msm_gpu_devfreq {
|
||||
/** idle_time: Time of last transition to idle: */
|
||||
ktime_t idle_time;
|
||||
|
||||
struct devfreq_dev_status average_status;
|
||||
|
||||
/**
|
||||
* idle_work:
|
||||
*
|
||||
@ -275,9 +277,6 @@ struct msm_gpu {
|
||||
|
||||
struct msm_gpu_state *crashstate;
|
||||
|
||||
/* Enable clamping to idle freq when inactive: */
|
||||
bool clamp_to_idle;
|
||||
|
||||
/* True if the hardware supports expanded apriv (a650 and newer) */
|
||||
bool hw_apriv;
|
||||
|
||||
|
@ -33,6 +33,16 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
|
||||
|
||||
trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp));
|
||||
|
||||
/*
|
||||
* If the GPU is idle, devfreq is not aware, so just stash
|
||||
* the new target freq (to use when we return to active)
|
||||
*/
|
||||
if (df->idle_freq) {
|
||||
df->idle_freq = *freq;
|
||||
dev_pm_opp_put(opp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gpu->funcs->gpu_set_freq) {
|
||||
mutex_lock(&df->lock);
|
||||
gpu->funcs->gpu_set_freq(gpu, opp, df->suspended);
|
||||
@ -48,15 +58,26 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
|
||||
|
||||
static unsigned long get_freq(struct msm_gpu *gpu)
|
||||
{
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
|
||||
/*
|
||||
* If the GPU is idle, use the shadow/saved freq to avoid
|
||||
* confusing devfreq (which is unaware that we are switching
|
||||
* to lowest freq until the device is active again)
|
||||
*/
|
||||
if (df->idle_freq)
|
||||
return df->idle_freq;
|
||||
|
||||
if (gpu->funcs->gpu_get_freq)
|
||||
return gpu->funcs->gpu_get_freq(gpu);
|
||||
|
||||
return clk_get_rate(gpu->core_clk);
|
||||
}
|
||||
|
||||
static void get_raw_dev_status(struct msm_gpu *gpu,
|
||||
static int msm_devfreq_get_dev_status(struct device *dev,
|
||||
struct devfreq_dev_status *status)
|
||||
{
|
||||
struct msm_gpu *gpu = dev_to_gpu(dev);
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
u64 busy_cycles, busy_time;
|
||||
unsigned long sample_rate;
|
||||
@ -72,7 +93,7 @@ static void get_raw_dev_status(struct msm_gpu *gpu,
|
||||
if (df->suspended) {
|
||||
mutex_unlock(&df->lock);
|
||||
status->busy_time = 0;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate);
|
||||
@ -87,71 +108,6 @@ static void get_raw_dev_status(struct msm_gpu *gpu,
|
||||
busy_time = ~0LU;
|
||||
|
||||
status->busy_time = busy_time;
|
||||
}
|
||||
|
||||
static void update_average_dev_status(struct msm_gpu *gpu,
|
||||
const struct devfreq_dev_status *raw)
|
||||
{
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
const u32 polling_ms = df->devfreq->profile->polling_ms;
|
||||
const u32 max_history_ms = polling_ms * 11 / 10;
|
||||
struct devfreq_dev_status *avg = &df->average_status;
|
||||
u64 avg_freq;
|
||||
|
||||
/* simple_ondemand governor interacts poorly with gpu->clamp_to_idle.
|
||||
* When we enforce the constraint on idle, it calls get_dev_status
|
||||
* which would normally reset the stats. When we remove the
|
||||
* constraint on active, it calls get_dev_status again where busy_time
|
||||
* would be 0.
|
||||
*
|
||||
* To remedy this, we always return the average load over the past
|
||||
* polling_ms.
|
||||
*/
|
||||
|
||||
/* raw is longer than polling_ms or avg has no history */
|
||||
if (div_u64(raw->total_time, USEC_PER_MSEC) >= polling_ms ||
|
||||
!avg->total_time) {
|
||||
*avg = *raw;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Truncate the oldest history first.
|
||||
*
|
||||
* Because we keep the history with a single devfreq_dev_status,
|
||||
* rather than a list of devfreq_dev_status, we have to assume freq
|
||||
* and load are the same over avg->total_time. We can scale down
|
||||
* avg->busy_time and avg->total_time by the same factor to drop
|
||||
* history.
|
||||
*/
|
||||
if (div_u64(avg->total_time + raw->total_time, USEC_PER_MSEC) >=
|
||||
max_history_ms) {
|
||||
const u32 new_total_time = polling_ms * USEC_PER_MSEC -
|
||||
raw->total_time;
|
||||
avg->busy_time = div_u64(
|
||||
mul_u32_u32(avg->busy_time, new_total_time),
|
||||
avg->total_time);
|
||||
avg->total_time = new_total_time;
|
||||
}
|
||||
|
||||
/* compute the average freq over avg->total_time + raw->total_time */
|
||||
avg_freq = mul_u32_u32(avg->current_frequency, avg->total_time);
|
||||
avg_freq += mul_u32_u32(raw->current_frequency, raw->total_time);
|
||||
do_div(avg_freq, avg->total_time + raw->total_time);
|
||||
|
||||
avg->current_frequency = avg_freq;
|
||||
avg->busy_time += raw->busy_time;
|
||||
avg->total_time += raw->total_time;
|
||||
}
|
||||
|
||||
static int msm_devfreq_get_dev_status(struct device *dev,
|
||||
struct devfreq_dev_status *status)
|
||||
{
|
||||
struct msm_gpu *gpu = dev_to_gpu(dev);
|
||||
struct devfreq_dev_status raw;
|
||||
|
||||
get_raw_dev_status(gpu, &raw);
|
||||
update_average_dev_status(gpu, &raw);
|
||||
*status = gpu->devfreq.average_status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -183,16 +139,23 @@ static bool has_devfreq(struct msm_gpu *gpu)
|
||||
void msm_devfreq_init(struct msm_gpu *gpu)
|
||||
{
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
struct msm_drm_private *priv = gpu->dev->dev_private;
|
||||
|
||||
/* We need target support to do devfreq */
|
||||
if (!gpu->funcs->gpu_busy)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Setup default values for simple_ondemand governor tuning. We
|
||||
* want to throttle up at 50% load for the double-buffer case,
|
||||
* where due to stalling waiting for vblank we could get stuck
|
||||
* at (for ex) 30fps at 50% utilization.
|
||||
*/
|
||||
priv->gpu_devfreq_config.upthreshold = 50;
|
||||
priv->gpu_devfreq_config.downdifferential = 10;
|
||||
|
||||
mutex_init(&df->lock);
|
||||
|
||||
dev_pm_qos_add_request(&gpu->pdev->dev, &df->idle_freq,
|
||||
DEV_PM_QOS_MAX_FREQUENCY,
|
||||
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
|
||||
dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
|
||||
DEV_PM_QOS_MIN_FREQUENCY, 0);
|
||||
|
||||
@ -209,11 +172,10 @@ void msm_devfreq_init(struct msm_gpu *gpu)
|
||||
|
||||
df->devfreq = devm_devfreq_add_device(&gpu->pdev->dev,
|
||||
&msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND,
|
||||
NULL);
|
||||
&priv->gpu_devfreq_config);
|
||||
|
||||
if (IS_ERR(df->devfreq)) {
|
||||
DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n");
|
||||
dev_pm_qos_remove_request(&df->idle_freq);
|
||||
dev_pm_qos_remove_request(&df->boost_freq);
|
||||
df->devfreq = NULL;
|
||||
return;
|
||||
@ -255,7 +217,6 @@ void msm_devfreq_cleanup(struct msm_gpu *gpu)
|
||||
|
||||
devfreq_cooling_unregister(gpu->cooling);
|
||||
dev_pm_qos_remove_request(&df->boost_freq);
|
||||
dev_pm_qos_remove_request(&df->idle_freq);
|
||||
}
|
||||
|
||||
void msm_devfreq_resume(struct msm_gpu *gpu)
|
||||
@ -328,6 +289,7 @@ void msm_devfreq_active(struct msm_gpu *gpu)
|
||||
{
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
unsigned int idle_time;
|
||||
unsigned long target_freq;
|
||||
|
||||
if (!has_devfreq(gpu))
|
||||
return;
|
||||
@ -337,8 +299,28 @@ void msm_devfreq_active(struct msm_gpu *gpu)
|
||||
*/
|
||||
cancel_idle_work(df);
|
||||
|
||||
/*
|
||||
* Hold devfreq lock to synchronize with get_dev_status()/
|
||||
* target() callbacks
|
||||
*/
|
||||
mutex_lock(&df->devfreq->lock);
|
||||
|
||||
target_freq = df->idle_freq;
|
||||
|
||||
idle_time = ktime_to_ms(ktime_sub(ktime_get(), df->idle_time));
|
||||
|
||||
df->idle_freq = 0;
|
||||
|
||||
/*
|
||||
* We could have become active again before the idle work had a
|
||||
* chance to run, in which case the df->idle_freq would have
|
||||
* still been zero. In this case, no need to change freq.
|
||||
*/
|
||||
if (target_freq)
|
||||
msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);
|
||||
|
||||
mutex_unlock(&df->devfreq->lock);
|
||||
|
||||
/*
|
||||
* If we've been idle for a significant fraction of a polling
|
||||
* interval, then we won't meet the threshold of busyness for
|
||||
@ -347,9 +329,6 @@ void msm_devfreq_active(struct msm_gpu *gpu)
|
||||
if (idle_time > msm_devfreq_profile.polling_ms) {
|
||||
msm_devfreq_boost(gpu, 2);
|
||||
}
|
||||
|
||||
dev_pm_qos_update_request(&df->idle_freq,
|
||||
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
|
||||
@ -358,11 +337,24 @@ static void msm_devfreq_idle_work(struct kthread_work *work)
|
||||
struct msm_gpu_devfreq *df = container_of(work,
|
||||
struct msm_gpu_devfreq, idle_work.work);
|
||||
struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq);
|
||||
struct msm_drm_private *priv = gpu->dev->dev_private;
|
||||
unsigned long idle_freq, target_freq = 0;
|
||||
|
||||
/*
|
||||
* Hold devfreq lock to synchronize with get_dev_status()/
|
||||
* target() callbacks
|
||||
*/
|
||||
mutex_lock(&df->devfreq->lock);
|
||||
|
||||
idle_freq = get_freq(gpu);
|
||||
|
||||
if (priv->gpu_clamp_to_idle)
|
||||
msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);
|
||||
|
||||
df->idle_time = ktime_get();
|
||||
df->idle_freq = idle_freq;
|
||||
|
||||
if (gpu->clamp_to_idle)
|
||||
dev_pm_qos_update_request(&df->idle_freq, 0);
|
||||
mutex_unlock(&df->devfreq->lock);
|
||||
}
|
||||
|
||||
void msm_devfreq_idle(struct msm_gpu *gpu)
|
||||
|
@ -286,9 +286,21 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss)
|
||||
/* UBWC_2_0 */
|
||||
msm_mdss_setup_ubwc_dec_20(msm_mdss, 0x11f);
|
||||
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:
|
||||
msm_mdss_setup_ubwc_dec_40(msm_mdss, UBWC_3_0, 6, 1, 1, 1);
|
||||
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;
|
||||
@ -515,9 +527,13 @@ static const struct of_device_id mdss_dt_match[] = {
|
||||
{ .compatible = "qcom,sc7180-mdss" },
|
||||
{ .compatible = "qcom,sc7280-mdss" },
|
||||
{ .compatible = "qcom,sc8180x-mdss" },
|
||||
{ .compatible = "qcom,sc8280xp-mdss" },
|
||||
{ .compatible = "qcom,sm6115-mdss" },
|
||||
{ .compatible = "qcom,sm8150-mdss" },
|
||||
{ .compatible = "qcom,sm8250-mdss" },
|
||||
{ .compatible = "qcom,sm8350-mdss" },
|
||||
{ .compatible = "qcom,sm8450-mdss" },
|
||||
{ .compatible = "qcom,sm8550-mdss" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mdss_dt_match);
|
||||
|
@ -273,8 +273,8 @@ void devm_devfreq_unregister_notifier(struct device *dev,
|
||||
struct devfreq *devfreq_get_devfreq_by_node(struct device_node *node);
|
||||
struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev,
|
||||
const char *phandle_name, int index);
|
||||
#endif /* CONFIG_PM_DEVFREQ */
|
||||
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
|
||||
/**
|
||||
* struct devfreq_simple_ondemand_data - ``void *data`` fed to struct devfreq
|
||||
* and devfreq_add_device
|
||||
@ -292,9 +292,7 @@ struct devfreq_simple_ondemand_data {
|
||||
unsigned int upthreshold;
|
||||
unsigned int downdifferential;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE)
|
||||
enum devfreq_parent_dev_type {
|
||||
DEVFREQ_PARENT_DEV,
|
||||
CPUFREQ_PARENT_DEV,
|
||||
@ -337,9 +335,8 @@ struct devfreq_passive_data {
|
||||
struct notifier_block nb;
|
||||
struct list_head cpu_data_list;
|
||||
};
|
||||
#endif
|
||||
|
||||
#else /* !CONFIG_PM_DEVFREQ */
|
||||
#if !defined(CONFIG_PM_DEVFREQ)
|
||||
static inline struct devfreq *devfreq_add_device(struct device *dev,
|
||||
struct devfreq_dev_profile *profile,
|
||||
const char *governor_name,
|
||||
|
@ -222,10 +222,12 @@ struct drm_msm_gem_submit_cmd {
|
||||
#define MSM_SUBMIT_BO_READ 0x0001
|
||||
#define MSM_SUBMIT_BO_WRITE 0x0002
|
||||
#define MSM_SUBMIT_BO_DUMP 0x0004
|
||||
#define MSM_SUBMIT_BO_NO_IMPLICIT 0x0008
|
||||
|
||||
#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | \
|
||||
MSM_SUBMIT_BO_WRITE | \
|
||||
MSM_SUBMIT_BO_DUMP)
|
||||
MSM_SUBMIT_BO_DUMP | \
|
||||
MSM_SUBMIT_BO_NO_IMPLICIT)
|
||||
|
||||
struct drm_msm_gem_submit_bo {
|
||||
__u32 flags; /* in, mask of MSM_SUBMIT_BO_x */
|
||||
|
Loading…
Reference in New Issue
Block a user