mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
Merge tag 'drm-msm-next-2025-05-16' of https://gitlab.freedesktop.org/drm/msm into drm-next
Updates for v6.16 CI: - uprev mesa GPU: - ACD (Adaptive Clock Distribution) support for X1-85. This is required enable the higher frequencies. - Drop fictional `address_space_size`. For some older devices, the address space size is limited to 4GB to avoid potential 64b rollover math problems in the fw. For these, an `ADRENO_QUIRK_4GB_VA` quirk is added. For everyone else we get the address space size from the SMMU `ias` (input address sizes), which is usually 48b. - Improve robustness when GMU HFI responses time out - Fix crash when throttling GPU immediately during boot - Fix for rgb565_predicator on Adreno 7c3 - Remove `MODULE_FIRMWARE()`s for GPU, the GPU can load the firmware after probe and having partial set of fw (ie. sqe+gmu but not zap) causes problems MDSS: - Added SAR2130P support to MDSS driver DPU: - Changed to use single CTL path for flushing on DPU 5.x+ - Improved SSPP allocation code to allow sharing of SSPP between planes - Enabled SmartDMA on SM8150, SC8180X, SC8280XP, SM8550 - Added SAR2130P support - Disabled DSC support on MSM8937, MSM8917, MSM8953, SDM660 - Misc fixes DP: - Switch to use new helpers for DP Audio / HDMI codec handling - Fixed LTTPR handling DSI: - Added support for SA8775P - Added SAR2130P support MDP4: - Fixed LCDC / LVDS controller on HDMI: - Switched to use new helpers for ACR data - Fixed old standing issue of HPD not working in some cases Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rob Clark <robdclark@gmail.com> Link: https://lore.kernel.org/r/CAF6AEGv2Go+nseaEwRgeZbecet-h+Pf2oBKw1CobCF01xu2XVg@mail.gmail.com
This commit is contained in:
commit
7c1a9408ce
|
@ -31,6 +31,7 @@ properties:
|
|||
- qcom,sm8650-dp
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sar2130p-dp
|
||||
- qcom,sm6350-dp
|
||||
- qcom,sm8150-dp
|
||||
- qcom,sm8250-dp
|
||||
|
|
|
@ -23,6 +23,8 @@ properties:
|
|||
- qcom,msm8996-dsi-ctrl
|
||||
- qcom,msm8998-dsi-ctrl
|
||||
- qcom,qcm2290-dsi-ctrl
|
||||
- qcom,sa8775p-dsi-ctrl
|
||||
- qcom,sar2130p-dsi-ctrl
|
||||
- qcom,sc7180-dsi-ctrl
|
||||
- qcom,sc7280-dsi-ctrl
|
||||
- qcom,sdm660-dsi-ctrl
|
||||
|
@ -314,6 +316,8 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- qcom,msm8998-dsi-ctrl
|
||||
- qcom,sa8775p-dsi-ctrl
|
||||
- qcom,sar2130p-dsi-ctrl
|
||||
- qcom,sc7180-dsi-ctrl
|
||||
- qcom,sc7280-dsi-ctrl
|
||||
- qcom,sdm845-dsi-ctrl
|
||||
|
|
|
@ -17,6 +17,8 @@ properties:
|
|||
enum:
|
||||
- qcom,dsi-phy-7nm
|
||||
- qcom,dsi-phy-7nm-8150
|
||||
- qcom,sa8775p-dsi-phy-5nm
|
||||
- qcom,sar2130p-dsi-phy-5nm
|
||||
- qcom,sc7280-dsi-phy-7nm
|
||||
- qcom,sm6375-dsi-phy-7nm
|
||||
- qcom,sm8350-dsi-phy-5nm
|
||||
|
|
|
@ -66,21 +66,6 @@ properties:
|
|||
maxItems: 1
|
||||
description: hpd pin
|
||||
|
||||
qcom,hdmi-tx-mux-en-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
description: HDMI mux enable pin
|
||||
|
||||
qcom,hdmi-tx-mux-sel-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
description: HDMI mux select pin
|
||||
|
||||
qcom,hdmi-tx-mux-lpm-gpios:
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
description: HDMI mux lpm pin
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
|
@ -89,12 +74,12 @@ properties:
|
|||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: |
|
||||
Input endpoints of the controller.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: |
|
||||
Output endpoints of the controller.
|
||||
|
||||
|
|
|
@ -18,9 +18,10 @@ properties:
|
|||
|
||||
clocks:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
maxItems: 8
|
||||
|
||||
clock-names:
|
||||
minItems: 6
|
||||
items:
|
||||
- const: core_clk
|
||||
- const: iface_clk
|
||||
|
@ -28,6 +29,12 @@ properties:
|
|||
- const: lut_clk
|
||||
- const: hdmi_clk
|
||||
- const: tv_clk
|
||||
- const: lcdc_clk
|
||||
- const: pxo
|
||||
description: XO used to drive the internal LVDS PLL
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
@ -84,6 +84,18 @@ properties:
|
|||
items:
|
||||
- description: MDSS_CORE reset
|
||||
|
||||
interconnects:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Interconnect path from mdp0 (or a single mdp) port to the data bus
|
||||
- description: Interconnect path from CPU to the reg bus
|
||||
|
||||
interconnect-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: mdp0-mem
|
||||
- const: cpu-cfg
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
@ -52,12 +52,23 @@ patternProperties:
|
|||
items:
|
||||
- const: qcom,sa8775p-dp
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,sa8775p-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sa8775p-edp-phy
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sa8775p-dsi-phy-5nm
|
||||
- qcom,sa8775p-edp-phy
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -139,6 +150,20 @@ examples:
|
|||
remote-endpoint = <&mdss0_dp0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&mdss0_dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&mdss0_dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss0_mdp_opp_table: opp-table {
|
||||
|
@ -186,6 +211,160 @@ examples:
|
|||
vdda-pll-supply = <&vreg_l4a>;
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,sa8775p-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispc_byte_clk>,
|
||||
<&dispcc_intf_clk>,
|
||||
<&dispcc_pclk>,
|
||||
<&dispcc_esc_clk>,
|
||||
<&dispcc_ahb_clk>,
|
||||
<&gcc_bus_clk>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&dispcc_byte_clk>,
|
||||
<&dispcc_pclk>;
|
||||
assigned-clock-parents = <&mdss0_dsi0_phy 0>, <&mdss0_dsi0_phy 1>;
|
||||
phys = <&mdss0_dsi0_phy>;
|
||||
|
||||
operating-points-v2 = <&dsi0_opp_table>;
|
||||
power-domains = <&rpmhpd SA8775P_MMCX>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
mdss0_dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
mdss0_dsi0_out: endpoint { };
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss0_dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,sa8775p-dsi-phy-5nm";
|
||||
reg = <0x0ae94400 0x200>,
|
||||
<0x0ae94600 0x280>,
|
||||
<0x0ae94900 0x27c>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc_iface_clk>,
|
||||
<&rpmhcc_ref_clk>;
|
||||
clock-names = "iface", "ref";
|
||||
|
||||
vdds-supply = <&vreg_dsi_supply>;
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,sa8775p-dsi-ctrl", "qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae96000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispc_byte_clk>,
|
||||
<&dispcc_intf_clk>,
|
||||
<&dispcc_pclk>,
|
||||
<&dispcc_esc_clk>,
|
||||
<&dispcc_ahb_clk>,
|
||||
<&gcc_bus_clk>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
assigned-clocks = <&dispcc_byte_clk>,
|
||||
<&dispcc_pclk>;
|
||||
assigned-clock-parents = <&mdss0_dsi1_phy 0>, <&mdss0_dsi1_phy 1>;
|
||||
phys = <&mdss0_dsi1_phy>;
|
||||
|
||||
operating-points-v2 = <&dsi1_opp_table>;
|
||||
power-domains = <&rpmhpd SA8775P_MMCX>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
mdss0_dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
mdss0_dsi1_out: endpoint { };
|
||||
};
|
||||
};
|
||||
|
||||
dsi1_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss0_dsi1_phy: phy@ae96400 {
|
||||
compatible = "qcom,sa8775p-dsi-phy-5nm";
|
||||
reg = <0x0ae96400 0x200>,
|
||||
<0x0ae96600 0x280>,
|
||||
<0x0ae96900 0x27c>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc_iface_clk>,
|
||||
<&rpmhcc_ref_clk>;
|
||||
clock-names = "iface", "ref";
|
||||
|
||||
vdds-supply = <&vreg_dsi_supply>;
|
||||
};
|
||||
|
||||
displayport-controller@af54000 {
|
||||
compatible = "qcom,sa8775p-dp";
|
||||
|
||||
|
|
|
@ -0,0 +1,439 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sar2130p-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SAR2130P Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Dmitry Baryshkov <lumag@kernel.org>
|
||||
|
||||
description:
|
||||
SAR2310P 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,sar2130p-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display MDSS AHB
|
||||
- description: Display AHB
|
||||
- description: Display hf AXI
|
||||
- description: Display core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
items:
|
||||
- description: Interconnect path from mdp0 port to the data bus
|
||||
- description: Interconnect path from CPU to the reg bus
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: mdp0-mem
|
||||
- const: cpu-cfg
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sar2130p-dpu
|
||||
|
||||
"^displayport-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,sar2130p-dp
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,sar2130p-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sar2130p-dsi-phy-5nm
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom,rpmhpd.h>
|
||||
#include <dt-bindings/phy/phy-qcom-qmp.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
compatible = "qcom,sar2130p-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
interconnects = <&mmss_noc_master_mdp &mc_virt_slave_ebi1>,
|
||||
<&gem_noc_master_appss_proc &config_noc_slave_display_cfg>;
|
||||
interconnect-names = "mdp0-mem", "cpu-cfg";
|
||||
|
||||
resets = <&dispcc_disp_cc_mdss_core_bcr>;
|
||||
|
||||
power-domains = <&dispcc_mdss_gdsc>;
|
||||
|
||||
clocks = <&dispcc_disp_cc_mdss_ahb_clk>,
|
||||
<&gcc_gcc_disp_ahb_clk>,
|
||||
<&gcc_gcc_disp_hf_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 0x1c00 0x2>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sar2130p-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&gcc_gcc_disp_ahb_clk>,
|
||||
<&gcc_gcc_disp_hf_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 RPMHPD_MMCX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
dpu_intf0_out: endpoint {
|
||||
remote-endpoint = <&mdss_dp0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&mdss_dsi0_in>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
|
||||
dpu_intf2_out: endpoint {
|
||||
remote-endpoint = <&mdss_dsi1_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-200000000 {
|
||||
opp-hz = /bits/ 64 <200000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-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-514000000 {
|
||||
opp-hz = /bits/ 64 <514000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
displayport-controller@ae90000 {
|
||||
compatible = "qcom,sar2130p-dp",
|
||||
"qcom,sm8350-dp";
|
||||
reg = <0xae90000 0x200>,
|
||||
<0xae90200 0x200>,
|
||||
<0xae90400 0xc00>,
|
||||
<0xae91000 0x400>,
|
||||
<0xae91400 0x400>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <12>;
|
||||
clocks = <&dispcc_disp_cc_mdss_ahb_clk>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_aux_clk>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_link_clk>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_link_intf_clk>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_pixel0_clk>;
|
||||
clock-names = "core_iface",
|
||||
"core_aux",
|
||||
"ctrl_link",
|
||||
"ctrl_link_iface",
|
||||
"stream_pixel";
|
||||
|
||||
assigned-clocks = <&dispcc_disp_cc_mdss_dptx0_link_clk_src>,
|
||||
<&dispcc_disp_cc_mdss_dptx0_pixel0_clk_src>;
|
||||
assigned-clock-parents = <&usb_dp_qmpphy_QMP_USB43DP_DP_LINK_CLK>,
|
||||
<&usb_dp_qmpphy_QMP_USB43DP_DP_VCO_DIV_CLK>;
|
||||
|
||||
phys = <&usb_dp_qmpphy QMP_USB43DP_DP_PHY>;
|
||||
phy-names = "dp";
|
||||
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
operating-points-v2 = <&dp_opp_table>;
|
||||
power-domains = <&rpmhpd RPMHPD_MMCX>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
mdss_dp0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
mdss_dp0_out: endpoint {
|
||||
remote-endpoint = <&usb_dp_qmpphy_dp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-162000000 {
|
||||
opp-hz = /bits/ 64 <162000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs_d1>;
|
||||
};
|
||||
|
||||
opp-270000000 {
|
||||
opp-hz = /bits/ 64 <270000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-540000000 {
|
||||
opp-hz = /bits/ 64 <540000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-810000000 {
|
||||
opp-hz = /bits/ 64 <810000000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,sar2130p-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 RPMHPD_MMCX>;
|
||||
|
||||
phys = <&mdss_dsi0_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mdss_dsi0_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
mdss_dsi0_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-187500000 {
|
||||
opp-hz = /bits/ 64 <187500000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-358000000 {
|
||||
opp-hz = /bits/ 64 <358000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss_dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,sar2130p-dsi-phy-5nm";
|
||||
reg = <0x0ae95000 0x200>,
|
||||
<0x0ae95200 0x280>,
|
||||
<0x0ae95500 0x400>;
|
||||
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";
|
||||
};
|
||||
|
||||
dsi@ae96000 {
|
||||
compatible = "qcom,sar2130p-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 = <&mdss_dsi1_phy 0>, <&mdss_dsi1_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi_opp_table>;
|
||||
power-domains = <&rpmhpd RPMHPD_MMCX>;
|
||||
|
||||
phys = <&mdss_dsi1_phy>;
|
||||
phy-names = "dsi";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mdss_dsi1_in: endpoint {
|
||||
remote-endpoint = <&dpu_intf2_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
mdss_dsi1_out: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss_dsi1_phy: phy@ae97000 {
|
||||
compatible = "qcom,sar2130p-dsi-phy-5nm";
|
||||
reg = <0x0ae97000 0x200>,
|
||||
<0x0ae97200 0x280>,
|
||||
<0x0ae97500 0x400>;
|
||||
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";
|
||||
};
|
||||
};
|
||||
...
|
|
@ -17,6 +17,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sar2130p-dpu
|
||||
- qcom,sc7280-dpu
|
||||
- qcom,sc8280xp-dpu
|
||||
- qcom,sm8350-dpu
|
||||
|
|
|
@ -38,12 +38,16 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: Interconnect path from the MDP0 port to the data bus
|
||||
- description: Interconnect path from the MDP1 port to the data bus
|
||||
- description: Interconnect path from the CPU to the reg bus
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: mdp0-mem
|
||||
- const: mdp1-mem
|
||||
- const: cpu-cfg
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
|
@ -88,6 +92,7 @@ examples:
|
|||
#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,icc.h>
|
||||
#include <dt-bindings/interconnect/qcom,sm8350.h>
|
||||
#include <dt-bindings/power/qcom,rpmhpd.h>
|
||||
|
||||
|
@ -97,8 +102,10 @@ examples:
|
|||
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";
|
||||
<&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>,
|
||||
<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
|
||||
&config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
|
||||
interconnect-names = "mdp0-mem", "mdp1-mem", "cpu-cfg";
|
||||
|
||||
power-domains = <&dispcc MDSS_GDSC>;
|
||||
resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/opp/opp-v2-qcom-adreno.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Adreno compatible OPP supply
|
||||
|
||||
description:
|
||||
Adreno GPUs present in Qualcomm's Snapdragon chipsets uses an OPP specific
|
||||
ACD related information tailored for the specific chipset. This binding
|
||||
provides the information needed to describe such a hardware value.
|
||||
|
||||
maintainers:
|
||||
- Rob Clark <robdclark@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: opp-v2-base.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: operating-points-v2-adreno
|
||||
|
||||
patternProperties:
|
||||
'^opp-[0-9]+$':
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
opp-hz: true
|
||||
|
||||
opp-level: true
|
||||
|
||||
opp-peak-kBps: true
|
||||
|
||||
opp-supported-hw: true
|
||||
|
||||
qcom,opp-acd-level:
|
||||
description: |
|
||||
A positive value representing the ACD (Adaptive Clock Distribution,
|
||||
a fancy name for clk throttling during voltage droop) level associated
|
||||
with this OPP node. This value is shared to a co-processor inside GPU
|
||||
(called Graphics Management Unit a.k.a GMU) during wake up. It may not
|
||||
be present for some OPPs and GMU will disable ACD while transitioning
|
||||
to that OPP. This value encodes a voltage threshold, delay cycles &
|
||||
calibration margins which are identified by characterization of the
|
||||
SoC. So, it doesn't have any unit. This data is passed to GMU firmware
|
||||
via 'HFI_H2F_MSG_ACD' packet.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
- opp-hz
|
||||
- opp-level
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
gpu_opp_table: opp-table {
|
||||
compatible = "operating-points-v2-adreno", "operating-points-v2";
|
||||
|
||||
opp-687000000 {
|
||||
opp-hz = /bits/ 64 <687000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
|
||||
opp-peak-kBps = <8171875>;
|
||||
qcom,opp-acd-level = <0x882e5ffd>;
|
||||
};
|
||||
|
||||
opp-550000000 {
|
||||
opp-hz = /bits/ 64 <550000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
|
||||
opp-peak-kBps = <6074219>;
|
||||
qcom,opp-acd-level = <0xc0285ffd>;
|
||||
};
|
||||
|
||||
opp-390000000 {
|
||||
opp-hz = /bits/ 64 <390000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
|
||||
opp-peak-kBps = <3000000>;
|
||||
qcom,opp-acd-level = <0xc0285ffd>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
|
||||
opp-peak-kBps = <2136719>;
|
||||
/* Intentionally left out qcom,opp-acd-level property here */
|
||||
};
|
||||
|
||||
};
|
|
@ -7521,6 +7521,7 @@ S: Maintained
|
|||
B: https://gitlab.freedesktop.org/drm/msm/-/issues
|
||||
T: git https://gitlab.freedesktop.org/drm/msm.git
|
||||
F: Documentation/devicetree/bindings/display/msm/gpu.yaml
|
||||
F: Documentation/devicetree/bindings/opp/opp-v2-qcom-adreno.yaml
|
||||
F: drivers/gpu/drm/msm/adreno/
|
||||
F: drivers/gpu/drm/msm/msm_gpu.*
|
||||
F: drivers/gpu/drm/msm/msm_gpu_devfreq.*
|
||||
|
|
|
@ -3752,60 +3752,83 @@
|
|||
};
|
||||
|
||||
gpu_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
compatible = "operating-points-v2-adreno", "operating-points-v2";
|
||||
|
||||
opp-1250000000 {
|
||||
opp-hz = /bits/ 64 <1250000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>;
|
||||
opp-peak-kBps = <16500000>;
|
||||
qcom,opp-acd-level = <0xa82a5ffd>;
|
||||
};
|
||||
|
||||
opp-1175000000 {
|
||||
opp-hz = /bits/ 64 <1175000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L2>;
|
||||
opp-peak-kBps = <14398438>;
|
||||
qcom,opp-acd-level = <0xa82a5ffd>;
|
||||
};
|
||||
|
||||
opp-1100000000 {
|
||||
opp-hz = /bits/ 64 <1100000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
|
||||
opp-peak-kBps = <16500000>;
|
||||
opp-peak-kBps = <14398438>;
|
||||
qcom,opp-acd-level = <0xa82a5ffd>;
|
||||
};
|
||||
|
||||
opp-1000000000 {
|
||||
opp-hz = /bits/ 64 <1000000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
|
||||
opp-peak-kBps = <14398438>;
|
||||
qcom,opp-acd-level = <0xa82b5ffd>;
|
||||
};
|
||||
|
||||
opp-925000000 {
|
||||
opp-hz = /bits/ 64 <925000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
|
||||
opp-peak-kBps = <14398438>;
|
||||
qcom,opp-acd-level = <0xa82b5ffd>;
|
||||
};
|
||||
|
||||
opp-800000000 {
|
||||
opp-hz = /bits/ 64 <800000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
|
||||
opp-peak-kBps = <12449219>;
|
||||
qcom,opp-acd-level = <0xa82c5ffd>;
|
||||
};
|
||||
|
||||
opp-744000000 {
|
||||
opp-hz = /bits/ 64 <744000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
|
||||
opp-peak-kBps = <10687500>;
|
||||
qcom,opp-acd-level = <0x882e5ffd>;
|
||||
};
|
||||
|
||||
opp-687000000 {
|
||||
opp-hz = /bits/ 64 <687000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
|
||||
opp-peak-kBps = <8171875>;
|
||||
qcom,opp-acd-level = <0x882e5ffd>;
|
||||
};
|
||||
|
||||
opp-550000000 {
|
||||
opp-hz = /bits/ 64 <550000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
|
||||
opp-peak-kBps = <6074219>;
|
||||
qcom,opp-acd-level = <0xc0285ffd>;
|
||||
};
|
||||
|
||||
opp-390000000 {
|
||||
opp-hz = /bits/ 64 <390000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
|
||||
opp-peak-kBps = <3000000>;
|
||||
qcom,opp-acd-level = <0xc0285ffd>;
|
||||
};
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
|
||||
opp-peak-kBps = <2136719>;
|
||||
qcom,opp-acd-level = <0xc02b5ffd>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -71,4 +71,4 @@ tar -cf artifacts/igt.tar /igt
|
|||
# Pass needed files to the test stage
|
||||
S3_ARTIFACT_NAME="igt.tar.gz"
|
||||
gzip -c artifacts/igt.tar > ${S3_ARTIFACT_NAME}
|
||||
ci-fairy s3cp --token-file "${S3_JWT_FILE}" ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${KERNEL_ARCH}/${S3_ARTIFACT_NAME}
|
||||
s3_upload ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${KERNEL_ARCH}/
|
||||
|
|
|
@ -148,13 +148,13 @@ if [[ "$UPLOAD_TO_MINIO" = "1" ]]; then
|
|||
|
||||
ls -l "${S3_JWT_FILE}"
|
||||
for f in $FILES_TO_UPLOAD; do
|
||||
ci-fairy s3cp --token-file "${S3_JWT_FILE}" /kernel/$f \
|
||||
https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/$f
|
||||
s3_upload /kernel/$f \
|
||||
https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/
|
||||
done
|
||||
|
||||
S3_ARTIFACT_NAME="kernel-files.tar.zst"
|
||||
tar --zstd -cf $S3_ARTIFACT_NAME install
|
||||
ci-fairy s3cp --token-file "${S3_JWT_FILE}" ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/${S3_ARTIFACT_NAME}
|
||||
s3_upload ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/
|
||||
|
||||
echo "Download vmlinux.xz from https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/vmlinux.xz"
|
||||
fi
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
variables:
|
||||
DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa
|
||||
DRM_CI_COMMIT_SHA: &drm-ci-commit-sha 82ab58f6c6f94fa80ca7e1615146f08356e3ba69
|
||||
DRM_CI_COMMIT_SHA: &drm-ci-commit-sha f73132f1215a37ce8ffc711a0136c90649aaf128
|
||||
|
||||
UPSTREAM_REPO: https://gitlab.freedesktop.org/drm/kernel.git
|
||||
TARGET_BRANCH: drm-next
|
||||
|
@ -20,8 +20,10 @@ variables:
|
|||
rm download-git-cache.sh
|
||||
set +o xtrace
|
||||
S3_JWT_FILE: /s3_jwt
|
||||
S3_JWT_HEADER_FILE: /s3_jwt_header
|
||||
S3_JWT_FILE_SCRIPT: |-
|
||||
echo -n '${S3_JWT}' > '${S3_JWT_FILE}' &&
|
||||
echo -n "Authorization: Bearer ${S3_JWT}" > '${S3_JWT_HEADER_FILE}' &&
|
||||
unset CI_JOB_JWT S3_JWT # Unsetting vulnerable env variables
|
||||
S3_HOST: s3.freedesktop.org
|
||||
# This bucket is used to fetch the kernel image
|
||||
|
@ -251,7 +253,7 @@ make git archive:
|
|||
- tar -cvzf ../$CI_PROJECT_NAME.tar.gz .
|
||||
|
||||
# Use id_tokens for JWT auth
|
||||
- ci-fairy s3cp --token-file "${S3_JWT_FILE}" ../$CI_PROJECT_NAME.tar.gz https://$S3_HOST/${S3_GITCACHE_BUCKET}/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/$CI_PROJECT_NAME.tar.gz
|
||||
- s3_upload ../$CI_PROJECT_NAME.tar.gz https://$S3_HOST/${S3_GITCACHE_BUCKET}/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/
|
||||
|
||||
|
||||
# Sanity checks of MR settings and commit logs
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
variables:
|
||||
CONTAINER_TAG: "20250307-mesa-uprev"
|
||||
CONTAINER_TAG: "20250328-mesa-uprev"
|
||||
DEBIAN_X86_64_BUILD_BASE_IMAGE: "debian/x86_64_build-base"
|
||||
DEBIAN_BASE_TAG: "${CONTAINER_TAG}"
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ cp artifacts/ci-common/init-*.sh results/job-rootfs-overlay/
|
|||
cp "$SCRIPTS_DIR"/setup-test-env.sh results/job-rootfs-overlay/
|
||||
|
||||
tar zcf job-rootfs-overlay.tar.gz -C results/job-rootfs-overlay/ .
|
||||
ci-fairy s3cp --token-file "${S3_JWT_FILE}" job-rootfs-overlay.tar.gz "https://${JOB_ROOTFS_OVERLAY_PATH}"
|
||||
s3_upload job-rootfs-overlay.tar.gz "https://${JOB_ARTIFACTS_BASE}"
|
||||
|
||||
# Prepare env vars for upload.
|
||||
section_switch variables "Environment variables passed through to device:"
|
||||
|
|
|
@ -104,6 +104,7 @@ config DRM_MSM_DPU
|
|||
config DRM_MSM_DP
|
||||
bool "Enable DisplayPort support in MSM DRM driver"
|
||||
depends on DRM_MSM
|
||||
select DRM_DISPLAY_HDMI_AUDIO_HELPER
|
||||
select RATIONAL
|
||||
default y
|
||||
help
|
||||
|
|
|
@ -48,7 +48,6 @@ msm-display-$(CONFIG_DRM_MSM_MDP4) += \
|
|||
disp/mdp4/mdp4_dsi_encoder.o \
|
||||
disp/mdp4/mdp4_dtv_encoder.o \
|
||||
disp/mdp4/mdp4_lcdc_encoder.o \
|
||||
disp/mdp4/mdp4_lvds_connector.o \
|
||||
disp/mdp4/mdp4_lvds_pll.o \
|
||||
disp/mdp4/mdp4_irq.o \
|
||||
disp/mdp4/mdp4_kms.o \
|
||||
|
|
|
@ -45,8 +45,3 @@ static const struct adreno_info a2xx_gpus[] = {
|
|||
}
|
||||
};
|
||||
DECLARE_ADRENO_GPULIST(a2xx);
|
||||
|
||||
MODULE_FIRMWARE("qcom/leia_pfp_470.fw");
|
||||
MODULE_FIRMWARE("qcom/leia_pm4_470.fw");
|
||||
MODULE_FIRMWARE("qcom/yamato_pfp.fw");
|
||||
MODULE_FIRMWARE("qcom/yamato_pm4.fw");
|
||||
|
|
|
@ -85,8 +85,3 @@ static const struct adreno_info a3xx_gpus[] = {
|
|||
}
|
||||
};
|
||||
DECLARE_ADRENO_GPULIST(a3xx);
|
||||
|
||||
MODULE_FIRMWARE("qcom/a300_pm4.fw");
|
||||
MODULE_FIRMWARE("qcom/a300_pfp.fw");
|
||||
MODULE_FIRMWARE("qcom/a330_pm4.fw");
|
||||
MODULE_FIRMWARE("qcom/a330_pfp.fw");
|
||||
|
|
|
@ -45,6 +45,3 @@ static const struct adreno_info a4xx_gpus[] = {
|
|||
}
|
||||
};
|
||||
DECLARE_ADRENO_GPULIST(a4xx);
|
||||
|
||||
MODULE_FIRMWARE("qcom/a420_pm4.fw");
|
||||
MODULE_FIRMWARE("qcom/a420_pfp.fw");
|
||||
|
|
|
@ -150,12 +150,3 @@ static const struct adreno_info a5xx_gpus[] = {
|
|||
}
|
||||
};
|
||||
DECLARE_ADRENO_GPULIST(a5xx);
|
||||
|
||||
MODULE_FIRMWARE("qcom/a530_pm4.fw");
|
||||
MODULE_FIRMWARE("qcom/a530_pfp.fw");
|
||||
MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2");
|
||||
MODULE_FIRMWARE("qcom/a530_zap.mdt");
|
||||
MODULE_FIRMWARE("qcom/a530_zap.b00");
|
||||
MODULE_FIRMWARE("qcom/a530_zap.b01");
|
||||
MODULE_FIRMWARE("qcom/a530_zap.b02");
|
||||
MODULE_FIRMWARE("qcom/a540_gpmu.fw2");
|
||||
|
|
|
@ -681,6 +681,7 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
[ADRENO_FW_SQE] = "a630_sqe.fw",
|
||||
},
|
||||
.gmem = (SZ_128K + SZ_4K),
|
||||
.quirks = ADRENO_QUIRK_4GB_VA,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a610_zap.mdt",
|
||||
|
@ -713,6 +714,7 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
[ADRENO_FW_GMU] = "a630_gmu.bin",
|
||||
},
|
||||
.gmem = SZ_512K,
|
||||
.quirks = ADRENO_QUIRK_4GB_VA,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a615_zap.mdt",
|
||||
|
@ -743,7 +745,8 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
},
|
||||
.gmem = SZ_512K,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
|
||||
ADRENO_QUIRK_4GB_VA,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a615_zap.mbn",
|
||||
.a6xx = &(const struct a6xx_info) {
|
||||
|
@ -769,7 +772,8 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
},
|
||||
.gmem = SZ_512K,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
|
||||
ADRENO_QUIRK_4GB_VA,
|
||||
.init = a6xx_gpu_init,
|
||||
.a6xx = &(const struct a6xx_info) {
|
||||
.protect = &a630_protect,
|
||||
|
@ -791,6 +795,7 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
[ADRENO_FW_GMU] = "a619_gmu.bin",
|
||||
},
|
||||
.gmem = SZ_512K,
|
||||
.quirks = ADRENO_QUIRK_4GB_VA,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a615_zap.mdt",
|
||||
|
@ -815,6 +820,7 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
[ADRENO_FW_GMU] = "a619_gmu.bin",
|
||||
},
|
||||
.gmem = SZ_512K,
|
||||
.quirks = ADRENO_QUIRK_4GB_VA,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a615_zap.mdt",
|
||||
|
@ -838,8 +844,9 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
[ADRENO_FW_GMU] = "a619_gmu.bin",
|
||||
},
|
||||
.gmem = SZ_512K,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
|
||||
ADRENO_QUIRK_4GB_VA,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a615_zap.mdt",
|
||||
.a6xx = &(const struct a6xx_info) {
|
||||
|
@ -874,7 +881,6 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
.gmu_cgc_mode = 0x00020200,
|
||||
.prim_fifo_threshold = 0x00010000,
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 137, 1 },
|
||||
|
@ -907,7 +913,6 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
{ /* sentinel */ },
|
||||
},
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
}, {
|
||||
.chip_ids = ADRENO_CHIP_IDS(
|
||||
0x06030001,
|
||||
|
@ -920,8 +925,9 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
[ADRENO_FW_GMU] = "a630_gmu.bin",
|
||||
},
|
||||
.gmem = SZ_1M,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
|
||||
ADRENO_QUIRK_4GB_VA,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a630_zap.mdt",
|
||||
.a6xx = &(const struct a6xx_info) {
|
||||
|
@ -939,8 +945,9 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
[ADRENO_FW_GMU] = "a640_gmu.bin",
|
||||
},
|
||||
.gmem = SZ_1M,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
|
||||
ADRENO_QUIRK_4GB_VA,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a640_zap.mdt",
|
||||
.a6xx = &(const struct a6xx_info) {
|
||||
|
@ -973,7 +980,6 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
.gmu_cgc_mode = 0x00020202,
|
||||
.prim_fifo_threshold = 0x00300200,
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 1, 1 },
|
||||
|
@ -1000,7 +1006,6 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
.gmu_cgc_mode = 0x00020000,
|
||||
.prim_fifo_threshold = 0x00300200,
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
}, {
|
||||
.chip_ids = ADRENO_CHIP_IDS(0x06060300),
|
||||
.family = ADRENO_6XX_GEN4,
|
||||
|
@ -1019,7 +1024,6 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
.gmu_cgc_mode = 0x00020200,
|
||||
.prim_fifo_threshold = 0x00300200,
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
}, {
|
||||
.chip_ids = ADRENO_CHIP_IDS(0x06030500),
|
||||
.family = ADRENO_6XX_GEN4,
|
||||
|
@ -1039,7 +1043,6 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
.gmu_cgc_mode = 0x00020202,
|
||||
.prim_fifo_threshold = 0x00200200,
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
.speedbins = ADRENO_SPEEDBINS(
|
||||
{ 0, 0 },
|
||||
{ 117, 0 },
|
||||
|
@ -1056,8 +1059,9 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
[ADRENO_FW_GMU] = "a640_gmu.bin",
|
||||
},
|
||||
.gmem = SZ_2M,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
|
||||
ADRENO_QUIRK_4GB_VA,
|
||||
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
|
||||
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
|
||||
.init = a6xx_gpu_init,
|
||||
.zapfw = "a640_zap.mdt",
|
||||
.a6xx = &(const struct a6xx_info) {
|
||||
|
@ -1085,22 +1089,10 @@ static const struct adreno_info a6xx_gpus[] = {
|
|||
.gmu_cgc_mode = 0x00020200,
|
||||
.prim_fifo_threshold = 0x00800200,
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
}
|
||||
};
|
||||
DECLARE_ADRENO_GPULIST(a6xx);
|
||||
|
||||
MODULE_FIRMWARE("qcom/a615_zap.mbn");
|
||||
MODULE_FIRMWARE("qcom/a619_gmu.bin");
|
||||
MODULE_FIRMWARE("qcom/a630_sqe.fw");
|
||||
MODULE_FIRMWARE("qcom/a630_gmu.bin");
|
||||
MODULE_FIRMWARE("qcom/a630_zap.mbn");
|
||||
MODULE_FIRMWARE("qcom/a640_gmu.bin");
|
||||
MODULE_FIRMWARE("qcom/a650_gmu.bin");
|
||||
MODULE_FIRMWARE("qcom/a650_sqe.fw");
|
||||
MODULE_FIRMWARE("qcom/a660_gmu.bin");
|
||||
MODULE_FIRMWARE("qcom/a660_sqe.fw");
|
||||
|
||||
static const struct adreno_reglist a702_hwcg[] = {
|
||||
{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222 },
|
||||
{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220 },
|
||||
|
@ -1395,7 +1387,6 @@ static const struct adreno_info a7xx_gpus[] = {
|
|||
.pwrup_reglist = &a7xx_pwrup_reglist,
|
||||
.gmu_cgc_mode = 0x00020000,
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
.preempt_record_size = 2860 * SZ_1K,
|
||||
}, {
|
||||
.chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
|
||||
|
@ -1429,7 +1420,6 @@ static const struct adreno_info a7xx_gpus[] = {
|
|||
{ /* sentinel */ },
|
||||
},
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
.preempt_record_size = 4192 * SZ_1K,
|
||||
}, {
|
||||
.chip_ids = ADRENO_CHIP_IDS(0x43050c01), /* "C512v2" */
|
||||
|
@ -1451,7 +1441,6 @@ static const struct adreno_info a7xx_gpus[] = {
|
|||
.gmu_chipid = 0x7050001,
|
||||
.gmu_cgc_mode = 0x00020202,
|
||||
},
|
||||
.address_space_size = SZ_256G,
|
||||
.preempt_record_size = 4192 * SZ_1K,
|
||||
}, {
|
||||
.chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
|
||||
|
@ -1484,7 +1473,6 @@ static const struct adreno_info a7xx_gpus[] = {
|
|||
{ /* sentinel */ },
|
||||
},
|
||||
},
|
||||
.address_space_size = SZ_16G,
|
||||
.preempt_record_size = 3572 * SZ_1K,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1064,14 +1064,6 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
|
|||
|
||||
gmu->hung = false;
|
||||
|
||||
/* Notify AOSS about the ACD state (unimplemented for now => disable it) */
|
||||
if (!IS_ERR(gmu->qmp)) {
|
||||
ret = qmp_send(gmu->qmp, "{class: gpu, res: acd, val: %d}",
|
||||
0 /* Hardcode ACD to be disabled for now */);
|
||||
if (ret)
|
||||
dev_err(gmu->dev, "failed to send GPU ACD state\n");
|
||||
}
|
||||
|
||||
/* Turn on the resources */
|
||||
pm_runtime_get_sync(gmu->dev);
|
||||
|
||||
|
@ -1671,6 +1663,75 @@ static int a6xx_gmu_pwrlevels_probe(struct a6xx_gmu *gmu)
|
|||
return a6xx_gmu_rpmh_votes_init(gmu);
|
||||
}
|
||||
|
||||
static int a6xx_gmu_acd_probe(struct a6xx_gmu *gmu)
|
||||
{
|
||||
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
|
||||
struct a6xx_hfi_acd_table *cmd = &gmu->acd_table;
|
||||
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
|
||||
struct msm_gpu *gpu = &adreno_gpu->base;
|
||||
int ret, i, cmd_idx = 0;
|
||||
extern bool disable_acd;
|
||||
|
||||
/* Skip ACD probe if requested via module param */
|
||||
if (disable_acd) {
|
||||
DRM_DEV_ERROR(gmu->dev, "Skipping GPU ACD probe\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd->version = 1;
|
||||
cmd->stride = 1;
|
||||
cmd->enable_by_level = 0;
|
||||
|
||||
/* Skip freq = 0 and parse acd-level for rest of the OPPs */
|
||||
for (i = 1; i < gmu->nr_gpu_freqs; i++) {
|
||||
struct dev_pm_opp *opp;
|
||||
struct device_node *np;
|
||||
unsigned long freq;
|
||||
u32 val;
|
||||
|
||||
freq = gmu->gpu_freqs[i];
|
||||
opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, freq, true);
|
||||
np = dev_pm_opp_get_of_node(opp);
|
||||
|
||||
ret = of_property_read_u32(np, "qcom,opp-acd-level", &val);
|
||||
of_node_put(np);
|
||||
dev_pm_opp_put(opp);
|
||||
if (ret == -EINVAL)
|
||||
continue;
|
||||
else if (ret) {
|
||||
DRM_DEV_ERROR(gmu->dev, "Unable to read acd level for freq %lu\n", freq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmd->enable_by_level |= BIT(i);
|
||||
cmd->data[cmd_idx++] = val;
|
||||
}
|
||||
|
||||
cmd->num_levels = cmd_idx;
|
||||
|
||||
/* It is a problem if qmp node is unavailable when ACD is required */
|
||||
if (cmd->enable_by_level && IS_ERR_OR_NULL(gmu->qmp)) {
|
||||
DRM_DEV_ERROR(gmu->dev, "Unable to send ACD state to AOSS\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Otherwise, nothing to do if qmp is unavailable */
|
||||
if (IS_ERR_OR_NULL(gmu->qmp))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Notify AOSS about the ACD state. AOSS is supposed to assume that ACD is disabled on
|
||||
* system reset. So it is harmless if we couldn't notify 'OFF' state
|
||||
*/
|
||||
ret = qmp_send(gmu->qmp, "{class: gpu, res: acd, val: %d}", !!cmd->enable_by_level);
|
||||
if (ret && cmd->enable_by_level) {
|
||||
DRM_DEV_ERROR(gmu->dev, "Failed to send ACD state to AOSS\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu)
|
||||
{
|
||||
int ret = devm_clk_bulk_get_all(gmu->dev, &gmu->clocks);
|
||||
|
@ -1989,10 +2050,11 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
|
|||
goto detach_cxpd;
|
||||
}
|
||||
|
||||
/* Other errors are handled during GPU ACD probe */
|
||||
gmu->qmp = qmp_get(gmu->dev);
|
||||
if (IS_ERR(gmu->qmp) && adreno_is_a7xx(adreno_gpu)) {
|
||||
ret = PTR_ERR(gmu->qmp);
|
||||
goto remove_device_link;
|
||||
if (PTR_ERR_OR_ZERO(gmu->qmp) == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto detach_gxpd;
|
||||
}
|
||||
|
||||
init_completion(&gmu->pd_gate);
|
||||
|
@ -2008,6 +2070,10 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
|
|||
/* Get the power levels for the GMU and GPU */
|
||||
a6xx_gmu_pwrlevels_probe(gmu);
|
||||
|
||||
ret = a6xx_gmu_acd_probe(gmu);
|
||||
if (ret)
|
||||
goto detach_gxpd;
|
||||
|
||||
/* Set up the HFI queues */
|
||||
a6xx_hfi_init(gmu);
|
||||
|
||||
|
@ -2018,7 +2084,13 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
|
|||
|
||||
return 0;
|
||||
|
||||
remove_device_link:
|
||||
detach_gxpd:
|
||||
if (!IS_ERR_OR_NULL(gmu->gxpd))
|
||||
dev_pm_domain_detach(gmu->gxpd, false);
|
||||
|
||||
if (!IS_ERR_OR_NULL(gmu->qmp))
|
||||
qmp_put(gmu->qmp);
|
||||
|
||||
device_link_del(link);
|
||||
|
||||
detach_cxpd:
|
||||
|
|
|
@ -93,6 +93,7 @@ struct a6xx_gmu {
|
|||
int nr_gpu_freqs;
|
||||
unsigned long gpu_freqs[GMU_MAX_GX_FREQS];
|
||||
u32 gx_arc_votes[GMU_MAX_GX_FREQS];
|
||||
struct a6xx_hfi_acd_table acd_table;
|
||||
|
||||
int nr_gpu_bws;
|
||||
unsigned long gpu_bw_table[GMU_MAX_GX_FREQS];
|
||||
|
|
|
@ -655,7 +655,6 @@ static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
|
|||
if (adreno_is_7c3(gpu)) {
|
||||
gpu->ubwc_config.highest_bank_bit = 14;
|
||||
gpu->ubwc_config.amsbc = 1;
|
||||
gpu->ubwc_config.rgb565_predicator = 1;
|
||||
gpu->ubwc_config.uavflagprd_inv = 2;
|
||||
gpu->ubwc_config.macrotile_mode = 1;
|
||||
}
|
||||
|
@ -2268,7 +2267,7 @@ a6xx_create_private_address_space(struct msm_gpu *gpu)
|
|||
return ERR_CAST(mmu);
|
||||
|
||||
return msm_gem_address_space_create(mmu,
|
||||
"gpu", 0x100000000ULL,
|
||||
"gpu", ADRENO_VM_START,
|
||||
adreno_private_address_space_size(gpu));
|
||||
}
|
||||
|
||||
|
|
|
@ -100,16 +100,14 @@ static int a6xx_hfi_queue_write(struct a6xx_gmu *gmu,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,
|
||||
u32 *payload, u32 payload_size)
|
||||
static int a6xx_hfi_wait_for_msg_interrupt(struct a6xx_gmu *gmu, u32 id, u32 seqnum)
|
||||
{
|
||||
struct a6xx_hfi_queue *queue = &gmu->queues[HFI_RESPONSE_QUEUE];
|
||||
u32 val;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
/* Wait for a response */
|
||||
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO, val,
|
||||
val & A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ, 100, 5000);
|
||||
val & A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ, 100, 1000000);
|
||||
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(gmu->dev,
|
||||
|
@ -122,6 +120,19 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,
|
|||
gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR,
|
||||
A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,
|
||||
u32 *payload, u32 payload_size)
|
||||
{
|
||||
struct a6xx_hfi_queue *queue = &gmu->queues[HFI_RESPONSE_QUEUE];
|
||||
int ret;
|
||||
|
||||
ret = a6xx_hfi_wait_for_msg_interrupt(gmu, id, seqnum);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (;;) {
|
||||
struct a6xx_hfi_msg_response resp;
|
||||
|
||||
|
@ -129,12 +140,18 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,
|
|||
ret = a6xx_hfi_queue_read(gmu, queue, (u32 *) &resp,
|
||||
sizeof(resp) >> 2);
|
||||
|
||||
/* If the queue is empty our response never made it */
|
||||
/* If the queue is empty, there may have been previous missed
|
||||
* responses that preceded the response to our packet. Wait
|
||||
* further before we give up.
|
||||
*/
|
||||
if (!ret) {
|
||||
DRM_DEV_ERROR(gmu->dev,
|
||||
"The HFI response queue is unexpectedly empty\n");
|
||||
|
||||
return -ENOENT;
|
||||
ret = a6xx_hfi_wait_for_msg_interrupt(gmu, id, seqnum);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(gmu->dev,
|
||||
"The HFI response queue is unexpectedly empty\n");
|
||||
return ret;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (HFI_HEADER_ID(resp.header) == HFI_F2H_MSG_ERROR) {
|
||||
|
@ -748,6 +765,38 @@ send:
|
|||
NULL, 0);
|
||||
}
|
||||
|
||||
#define HFI_FEATURE_ACD 12
|
||||
|
||||
static int a6xx_hfi_enable_acd(struct a6xx_gmu *gmu)
|
||||
{
|
||||
struct a6xx_hfi_acd_table *acd_table = &gmu->acd_table;
|
||||
struct a6xx_hfi_msg_feature_ctrl msg = {
|
||||
.feature = HFI_FEATURE_ACD,
|
||||
.enable = 1,
|
||||
.data = 0,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!acd_table->enable_by_level)
|
||||
return 0;
|
||||
|
||||
/* Enable ACD feature at GMU */
|
||||
ret = a6xx_hfi_send_msg(gmu, HFI_H2F_FEATURE_CTRL, &msg, sizeof(msg), NULL, 0);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(gmu->dev, "Unable to enable ACD (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Send ACD table to GMU */
|
||||
ret = a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_ACD, acd_table, sizeof(*acd_table), NULL, 0);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(gmu->dev, "Unable to ACD table (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a6xx_hfi_send_test(struct a6xx_gmu *gmu)
|
||||
{
|
||||
struct a6xx_hfi_msg_test msg = { 0 };
|
||||
|
@ -845,6 +894,10 @@ int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = a6xx_hfi_enable_acd(gmu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = a6xx_hfi_send_core_fw_start(gmu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -151,12 +151,33 @@ struct a6xx_hfi_msg_test {
|
|||
u32 header;
|
||||
};
|
||||
|
||||
#define HFI_H2F_MSG_ACD 7
|
||||
#define MAX_ACD_STRIDE 2
|
||||
|
||||
struct a6xx_hfi_acd_table {
|
||||
u32 header;
|
||||
u32 version;
|
||||
u32 enable_by_level;
|
||||
u32 stride;
|
||||
u32 num_levels;
|
||||
u32 data[16 * MAX_ACD_STRIDE];
|
||||
};
|
||||
|
||||
#define HFI_H2F_MSG_START 10
|
||||
|
||||
struct a6xx_hfi_msg_start {
|
||||
u32 header;
|
||||
};
|
||||
|
||||
#define HFI_H2F_FEATURE_CTRL 11
|
||||
|
||||
struct a6xx_hfi_msg_feature_ctrl {
|
||||
u32 header;
|
||||
u32 feature;
|
||||
u32 enable;
|
||||
u32 data;
|
||||
};
|
||||
|
||||
#define HFI_H2F_MSG_CORE_FW_START 14
|
||||
|
||||
struct a6xx_hfi_msg_core_fw_start {
|
||||
|
|
|
@ -24,6 +24,10 @@ int enable_preemption = -1;
|
|||
MODULE_PARM_DESC(enable_preemption, "Enable preemption (A7xx only) (1=on , 0=disable, -1=auto (default))");
|
||||
module_param(enable_preemption, int, 0600);
|
||||
|
||||
bool disable_acd;
|
||||
MODULE_PARM_DESC(disable_acd, "Forcefully disable GPU ACD");
|
||||
module_param_unsafe(disable_acd, bool, 0400);
|
||||
|
||||
extern const struct adreno_gpulist a2xx_gpulist;
|
||||
extern const struct adreno_gpulist a3xx_gpulist;
|
||||
extern const struct adreno_gpulist a4xx_gpulist;
|
||||
|
|
|
@ -236,14 +236,27 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu,
|
|||
u64 adreno_private_address_space_size(struct msm_gpu *gpu)
|
||||
{
|
||||
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
|
||||
struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(&gpu->pdev->dev);
|
||||
const struct io_pgtable_cfg *ttbr1_cfg;
|
||||
|
||||
if (address_space_size)
|
||||
return address_space_size;
|
||||
|
||||
if (adreno_gpu->info->address_space_size)
|
||||
return adreno_gpu->info->address_space_size;
|
||||
if (adreno_gpu->info->quirks & ADRENO_QUIRK_4GB_VA)
|
||||
return SZ_4G;
|
||||
|
||||
return SZ_4G;
|
||||
if (!adreno_smmu || !adreno_smmu->get_ttbr1_cfg)
|
||||
return SZ_4G;
|
||||
|
||||
ttbr1_cfg = adreno_smmu->get_ttbr1_cfg(adreno_smmu->cookie);
|
||||
|
||||
/*
|
||||
* Userspace VM is actually using TTBR0, but both are the same size,
|
||||
* with b48 (sign bit) selecting which TTBRn to use. So if IAS is
|
||||
* 48, the total (kernel+user) address space size is effectively
|
||||
* 49 bits. But what userspace is control of is the lower 48.
|
||||
*/
|
||||
return BIT(ttbr1_cfg->ias) - ADRENO_VM_START;
|
||||
}
|
||||
|
||||
#define ARM_SMMU_FSR_TF BIT(1)
|
||||
|
|
|
@ -57,6 +57,7 @@ enum adreno_family {
|
|||
#define ADRENO_QUIRK_HAS_HW_APRIV BIT(3)
|
||||
#define ADRENO_QUIRK_HAS_CACHED_COHERENT BIT(4)
|
||||
#define ADRENO_QUIRK_PREEMPTION BIT(5)
|
||||
#define ADRENO_QUIRK_4GB_VA BIT(6)
|
||||
|
||||
/* Helper for formating the chip_id in the way that userspace tools like
|
||||
* crashdec expect.
|
||||
|
@ -104,7 +105,6 @@ struct adreno_info {
|
|||
union {
|
||||
const struct a6xx_info *a6xx;
|
||||
};
|
||||
u64 address_space_size;
|
||||
/**
|
||||
* @speedbins: Optional table of fuse to speedbin mappings
|
||||
*
|
||||
|
@ -578,6 +578,8 @@ static inline int adreno_is_a7xx(struct adreno_gpu *gpu)
|
|||
adreno_is_a740_family(gpu);
|
||||
}
|
||||
|
||||
/* Put vm_start above 32b to catch issues with not setting xyz_BASE_HI */
|
||||
#define ADRENO_VM_START 0x100000000ULL
|
||||
u64 adreno_private_address_space_size(struct msm_gpu *gpu);
|
||||
int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
|
||||
uint32_t param, uint64_t *value, uint32_t *len);
|
||||
|
|
|
@ -27,17 +27,16 @@ static const struct dpu_mdp_cfg sm8650_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg sm8650_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x15000, .len = 0x1000,
|
||||
.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x16000, .len = 0x1000,
|
||||
.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
|
|
@ -100,14 +100,12 @@ static const struct dpu_pingpong_cfg msm8937_pp[] = {
|
|||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_MSM8996_MASK,
|
||||
.sblk = &msm8996_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x70800, .len = 0xd4,
|
||||
.features = PINGPONG_MSM8996_MASK,
|
||||
.sblk = &msm8996_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
|
||||
|
|
|
@ -93,7 +93,6 @@ static const struct dpu_pingpong_cfg msm8917_pp[] = {
|
|||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_MSM8996_MASK,
|
||||
.sblk = &msm8996_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
|
||||
|
|
|
@ -100,14 +100,12 @@ static const struct dpu_pingpong_cfg msm8953_pp[] = {
|
|||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_MSM8996_MASK,
|
||||
.sblk = &msm8996_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x70800, .len = 0xd4,
|
||||
.features = PINGPONG_MSM8996_MASK,
|
||||
.sblk = &msm8996_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
|
||||
|
|
|
@ -181,15 +181,15 @@ static const struct dpu_pingpong_cfg msm8996_pp[] = {
|
|||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_MSM8996_TE2_MASK,
|
||||
.sblk = &msm8996_pp_sblk_te,
|
||||
.features = PINGPONG_MSM8996_MASK,
|
||||
.sblk = &msm8996_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x70800, .len = 0xd4,
|
||||
.features = PINGPONG_MSM8996_TE2_MASK,
|
||||
.sblk = &msm8996_pp_sblk_te,
|
||||
.features = PINGPONG_MSM8996_MASK,
|
||||
.sblk = &msm8996_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
|
||||
}, {
|
||||
|
|
|
@ -170,15 +170,15 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = {
|
|||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_SDM845_TE2_MASK,
|
||||
.sblk = &sdm845_pp_sblk_te,
|
||||
.features = PINGPONG_SDM845_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x70800, .len = 0xd4,
|
||||
.features = PINGPONG_SDM845_TE2_MASK,
|
||||
.sblk = &sdm845_pp_sblk_te,
|
||||
.features = PINGPONG_SDM845_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
|
||||
}, {
|
||||
|
|
|
@ -141,15 +141,15 @@ static const struct dpu_pingpong_cfg sdm660_pp[] = {
|
|||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_SDM845_TE2_MASK,
|
||||
.sblk = &sdm845_pp_sblk_te,
|
||||
.features = PINGPONG_SDM845_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x70800, .len = 0xd4,
|
||||
.features = PINGPONG_SDM845_TE2_MASK,
|
||||
.sblk = &sdm845_pp_sblk_te,
|
||||
.features = PINGPONG_SDM845_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
|
||||
}, {
|
||||
|
|
|
@ -115,14 +115,14 @@ static const struct dpu_pingpong_cfg sdm630_pp[] = {
|
|||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_SDM845_TE2_MASK,
|
||||
.sblk = &sdm845_pp_sblk_te,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
|
||||
}, {
|
||||
.name = "pingpong_2", .id = PINGPONG_2,
|
||||
.base = 0x71000, .len = 0xd4,
|
||||
.features = PINGPONG_SDM845_MASK,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14),
|
||||
|
|
|
@ -194,15 +194,15 @@ static const struct dpu_pingpong_cfg sdm845_pp[] = {
|
|||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_SDM845_TE2_MASK,
|
||||
.sblk = &sdm845_pp_sblk_te,
|
||||
.features = PINGPONG_SDM845_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x70800, .len = 0xd4,
|
||||
.features = PINGPONG_SDM845_TE2_MASK,
|
||||
.sblk = &sdm845_pp_sblk_te,
|
||||
.features = PINGPONG_SDM845_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
|
||||
.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
|
||||
}, {
|
||||
|
|
|
@ -37,17 +37,16 @@ static const struct dpu_mdp_cfg sm8150_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg sm8150_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x1000, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x1200, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_1_4,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_1", .id = SSPP_VIG1,
|
||||
.base = 0x6000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_1_4,
|
||||
.xin_id = 4,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_2", .id = SSPP_VIG2,
|
||||
.base = 0x8000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_1_4,
|
||||
.xin_id = 8,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_3", .id = SSPP_VIG3,
|
||||
.base = 0xa000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_1_4,
|
||||
.xin_id = 12,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f0,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x1f0,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_10", .id = SSPP_DMA2,
|
||||
.base = 0x28000, .len = 0x1f0,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 9,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_11", .id = SSPP_DMA3,
|
||||
.base = 0x2a000, .len = 0x1f0,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 13,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -41,12 +41,12 @@ static const struct dpu_ctl_cfg sc8180x_ctl[] = {
|
|||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x1000, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x1200, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_1_4,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -83,7 +83,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_1", .id = SSPP_VIG1,
|
||||
.base = 0x6000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_1_4,
|
||||
.xin_id = 4,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -91,7 +91,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_2", .id = SSPP_VIG2,
|
||||
.base = 0x8000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_1_4,
|
||||
.xin_id = 8,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -99,7 +99,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_3", .id = SSPP_VIG3,
|
||||
.base = 0xa000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_1_4,
|
||||
.xin_id = 12,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -107,7 +107,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f0,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -115,7 +115,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x1f0,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -123,7 +123,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_10", .id = SSPP_DMA2,
|
||||
.base = 0x28000, .len = 0x1f0,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 9,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -131,7 +131,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_11", .id = SSPP_DMA3,
|
||||
.base = 0x2a000, .len = 0x1f0,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 13,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -38,12 +38,12 @@ static const struct dpu_ctl_cfg sm7150_ctl[] = {
|
|||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x1000, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x1200, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
@ -72,7 +72,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_2_4,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -80,7 +80,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_1", .id = SSPP_VIG1,
|
||||
.base = 0x6000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_2_4,
|
||||
.xin_id = 4,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -88,7 +88,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_2", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f0,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -96,7 +96,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x1f0,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -104,7 +104,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_10", .id = SSPP_DMA2,
|
||||
.base = 0x28000, .len = 0x1f0,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 9,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -69,7 +69,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_2_4,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f0,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x1f0,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sm8250_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg sm8250_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x1000, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x1200, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
|
|
@ -51,7 +51,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f8,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_0,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -59,7 +59,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f8,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -67,7 +67,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x1f8,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_10", .id = SSPP_DMA2,
|
||||
.base = 0x28000, .len = 0x1f8,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 9,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -38,7 +38,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f8,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_0,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -46,7 +46,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f8,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -59,7 +59,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f8,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_0,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -67,7 +67,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f8,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x1f8,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -83,7 +83,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_10", .id = SSPP_DMA2,
|
||||
.base = 0x28000, .len = 0x1f8,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 9,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -46,7 +46,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f8,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -39,7 +39,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f8,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_0,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -47,7 +47,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f8,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_NO_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sm8350_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg sm8350_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x15000, .len = 0x1e8,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
|
||||
.features = CTL_SC7280_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x16000, .len = 0x1e8,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
|
||||
.features = CTL_SC7280_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
|
|
@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sc8280xp_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg sc8280xp_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x15000, .len = 0x204,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
|
||||
.features = CTL_SC7280_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x16000, .len = 0x204,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
|
||||
.features = CTL_SC7280_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
@ -74,7 +73,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x2ac,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_0,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -82,7 +81,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_1", .id = SSPP_VIG1,
|
||||
.base = 0x6000, .len = 0x2ac,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_0,
|
||||
.xin_id = 4,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -90,7 +89,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_2", .id = SSPP_VIG2,
|
||||
.base = 0x8000, .len = 0x2ac,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_0,
|
||||
.xin_id = 8,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -98,7 +97,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_3", .id = SSPP_VIG3,
|
||||
.base = 0xa000, .len = 0x2ac,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_0,
|
||||
.xin_id = 12,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
|
@ -106,7 +105,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x2ac,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -114,7 +113,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x2ac,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -122,7 +121,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_10", .id = SSPP_DMA2,
|
||||
.base = 0x28000, .len = 0x2ac,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 9,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
@ -130,7 +129,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
|
|||
}, {
|
||||
.name = "sspp_11", .id = SSPP_DMA3,
|
||||
.base = 0x2a000, .len = 0x2ac,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 13,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
|
@ -36,17 +36,16 @@ static const struct dpu_mdp_cfg sm8450_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg sm8450_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x15000, .len = 0x204,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
|
||||
.features = CTL_SC7280_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x16000, .len = 0x204,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
|
||||
.features = CTL_SC7280_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
|
|
@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sa8775p_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg sa8775p_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x15000, .len = 0x204,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
|
||||
.features = CTL_SC7280_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x16000, .len = 0x204,
|
||||
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
|
||||
.features = CTL_SC7280_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
|
|
@ -27,17 +27,16 @@ static const struct dpu_mdp_cfg sm8550_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg sm8550_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x15000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x16000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
@ -66,70 +65,70 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
|
|||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x344,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_2,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
}, {
|
||||
.name = "sspp_1", .id = SSPP_VIG1,
|
||||
.base = 0x6000, .len = 0x344,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_2,
|
||||
.xin_id = 4,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
}, {
|
||||
.name = "sspp_2", .id = SSPP_VIG2,
|
||||
.base = 0x8000, .len = 0x344,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_2,
|
||||
.xin_id = 8,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
}, {
|
||||
.name = "sspp_3", .id = SSPP_VIG3,
|
||||
.base = 0xa000, .len = 0x344,
|
||||
.features = VIG_SDM845_MASK,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_2,
|
||||
.xin_id = 12,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x344,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x344,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_10", .id = SSPP_DMA2,
|
||||
.base = 0x28000, .len = 0x344,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 9,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_11", .id = SSPP_DMA3,
|
||||
.base = 0x2a000, .len = 0x344,
|
||||
.features = DMA_SDM845_MASK,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 13,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_12", .id = SSPP_DMA4,
|
||||
.base = 0x2c000, .len = 0x344,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 14,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_13", .id = SSPP_DMA5,
|
||||
.base = 0x2e000, .len = 0x344,
|
||||
.features = DMA_CURSOR_SDM845_MASK,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 15,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
|
|
433
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h
Normal file
433
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h
Normal file
|
@ -0,0 +1,433 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DPU_9_1_SAR2130P_H
|
||||
#define _DPU_9_1_SAR2130P_H
|
||||
|
||||
static const struct dpu_caps sar2130p_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0xb,
|
||||
.has_src_split = true,
|
||||
.has_dim_layer = true,
|
||||
.has_idle_pc = true,
|
||||
.has_3d_merge = true,
|
||||
.max_linewidth = 5120,
|
||||
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
|
||||
};
|
||||
|
||||
static const struct dpu_mdp_cfg sar2130p_mdp = {
|
||||
.name = "top_0",
|
||||
.base = 0, .len = 0x494,
|
||||
.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
|
||||
.clk_ctrls = {
|
||||
[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_ctl_cfg sar2130p_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x15000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x16000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
.base = 0x17000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
|
||||
}, {
|
||||
.name = "ctl_3", .id = CTL_3,
|
||||
.base = 0x18000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
|
||||
}, {
|
||||
.name = "ctl_4", .id = CTL_4,
|
||||
.base = 0x19000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
|
||||
}, {
|
||||
.name = "ctl_5", .id = CTL_5,
|
||||
.base = 0x1a000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_cfg sar2130p_sspp[] = {
|
||||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x344,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_2,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
}, {
|
||||
.name = "sspp_1", .id = SSPP_VIG1,
|
||||
.base = 0x6000, .len = 0x344,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_2,
|
||||
.xin_id = 4,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
}, {
|
||||
.name = "sspp_2", .id = SSPP_VIG2,
|
||||
.base = 0x8000, .len = 0x344,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_2,
|
||||
.xin_id = 8,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
}, {
|
||||
.name = "sspp_3", .id = SSPP_VIG3,
|
||||
.base = 0xa000, .len = 0x344,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_3_2,
|
||||
.xin_id = 12,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x344,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 1,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_9", .id = SSPP_DMA1,
|
||||
.base = 0x26000, .len = 0x344,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 5,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_10", .id = SSPP_DMA2,
|
||||
.base = 0x28000, .len = 0x344,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 9,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_11", .id = SSPP_DMA3,
|
||||
.base = 0x2a000, .len = 0x344,
|
||||
.features = DMA_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 13,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_12", .id = SSPP_DMA4,
|
||||
.base = 0x2c000, .len = 0x344,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 14,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
}, {
|
||||
.name = "sspp_13", .id = SSPP_DMA5,
|
||||
.base = 0x2e000, .len = 0x344,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 15,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_lm_cfg sar2130p_lm[] = {
|
||||
{
|
||||
.name = "lm_0", .id = LM_0,
|
||||
.base = 0x44000, .len = 0x320,
|
||||
.features = MIXER_SDM845_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.lm_pair = LM_1,
|
||||
.pingpong = PINGPONG_0,
|
||||
.dspp = DSPP_0,
|
||||
}, {
|
||||
.name = "lm_1", .id = LM_1,
|
||||
.base = 0x45000, .len = 0x320,
|
||||
.features = MIXER_SDM845_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.lm_pair = LM_0,
|
||||
.pingpong = PINGPONG_1,
|
||||
.dspp = DSPP_1,
|
||||
}, {
|
||||
.name = "lm_2", .id = LM_2,
|
||||
.base = 0x46000, .len = 0x320,
|
||||
.features = MIXER_SDM845_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.lm_pair = LM_3,
|
||||
.pingpong = PINGPONG_2,
|
||||
.dspp = DSPP_2,
|
||||
}, {
|
||||
.name = "lm_3", .id = LM_3,
|
||||
.base = 0x47000, .len = 0x320,
|
||||
.features = MIXER_SDM845_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.lm_pair = LM_2,
|
||||
.pingpong = PINGPONG_3,
|
||||
.dspp = DSPP_3,
|
||||
}, {
|
||||
.name = "lm_4", .id = LM_4,
|
||||
.base = 0x48000, .len = 0x320,
|
||||
.features = MIXER_SDM845_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.lm_pair = LM_5,
|
||||
.pingpong = PINGPONG_4,
|
||||
}, {
|
||||
.name = "lm_5", .id = LM_5,
|
||||
.base = 0x49000, .len = 0x320,
|
||||
.features = MIXER_SDM845_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.lm_pair = LM_4,
|
||||
.pingpong = PINGPONG_5,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_dspp_cfg sar2130p_dspp[] = {
|
||||
{
|
||||
.name = "dspp_0", .id = DSPP_0,
|
||||
.base = 0x54000, .len = 0x1800,
|
||||
.features = DSPP_SC7180_MASK,
|
||||
.sblk = &sdm845_dspp_sblk,
|
||||
}, {
|
||||
.name = "dspp_1", .id = DSPP_1,
|
||||
.base = 0x56000, .len = 0x1800,
|
||||
.features = DSPP_SC7180_MASK,
|
||||
.sblk = &sdm845_dspp_sblk,
|
||||
}, {
|
||||
.name = "dspp_2", .id = DSPP_2,
|
||||
.base = 0x58000, .len = 0x1800,
|
||||
.features = DSPP_SC7180_MASK,
|
||||
.sblk = &sdm845_dspp_sblk,
|
||||
}, {
|
||||
.name = "dspp_3", .id = DSPP_3,
|
||||
.base = 0x5a000, .len = 0x1800,
|
||||
.features = DSPP_SC7180_MASK,
|
||||
.sblk = &sdm845_dspp_sblk,
|
||||
},
|
||||
};
|
||||
static const struct dpu_pingpong_cfg sar2130p_pp[] = {
|
||||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x69000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
.merge_3d = MERGE_3D_0,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x6a000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
.merge_3d = MERGE_3D_0,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
|
||||
}, {
|
||||
.name = "pingpong_2", .id = PINGPONG_2,
|
||||
.base = 0x6b000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
.merge_3d = MERGE_3D_1,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
|
||||
}, {
|
||||
.name = "pingpong_3", .id = PINGPONG_3,
|
||||
.base = 0x6c000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
.merge_3d = MERGE_3D_1,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
|
||||
}, {
|
||||
.name = "pingpong_4", .id = PINGPONG_4,
|
||||
.base = 0x6d000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
.merge_3d = MERGE_3D_2,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
|
||||
}, {
|
||||
.name = "pingpong_5", .id = PINGPONG_5,
|
||||
.base = 0x6e000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
.merge_3d = MERGE_3D_2,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
|
||||
}, {
|
||||
.name = "pingpong_cwb_0", .id = PINGPONG_CWB_0,
|
||||
.base = 0x66000, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
.merge_3d = MERGE_3D_3,
|
||||
}, {
|
||||
.name = "pingpong_cwb_1", .id = PINGPONG_CWB_1,
|
||||
.base = 0x66400, .len = 0,
|
||||
.features = BIT(DPU_PINGPONG_DITHER),
|
||||
.sblk = &sc7280_pp_sblk,
|
||||
.merge_3d = MERGE_3D_3,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_merge_3d_cfg sar2130p_merge_3d[] = {
|
||||
{
|
||||
.name = "merge_3d_0", .id = MERGE_3D_0,
|
||||
.base = 0x4e000, .len = 0x8,
|
||||
}, {
|
||||
.name = "merge_3d_1", .id = MERGE_3D_1,
|
||||
.base = 0x4f000, .len = 0x8,
|
||||
}, {
|
||||
.name = "merge_3d_2", .id = MERGE_3D_2,
|
||||
.base = 0x50000, .len = 0x8,
|
||||
}, {
|
||||
.name = "merge_3d_3", .id = MERGE_3D_3,
|
||||
.base = 0x66700, .len = 0x8,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: Each display compression engine (DCE) contains dual hard
|
||||
* slice DSC encoders so both share same base address but with
|
||||
* its own different sub block address.
|
||||
*/
|
||||
static const struct dpu_dsc_cfg sar2130p_dsc[] = {
|
||||
{
|
||||
.name = "dce_0_0", .id = DSC_0,
|
||||
.base = 0x80000, .len = 0x4,
|
||||
.features = BIT(DPU_DSC_HW_REV_1_2),
|
||||
.sblk = &dsc_sblk_0,
|
||||
}, {
|
||||
.name = "dce_0_1", .id = DSC_1,
|
||||
.base = 0x80000, .len = 0x4,
|
||||
.features = BIT(DPU_DSC_HW_REV_1_2),
|
||||
.sblk = &dsc_sblk_1,
|
||||
}, {
|
||||
.name = "dce_1_0", .id = DSC_2,
|
||||
.base = 0x81000, .len = 0x4,
|
||||
.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
|
||||
.sblk = &dsc_sblk_0,
|
||||
}, {
|
||||
.name = "dce_1_1", .id = DSC_3,
|
||||
.base = 0x81000, .len = 0x4,
|
||||
.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
|
||||
.sblk = &dsc_sblk_1,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_wb_cfg sar2130p_wb[] = {
|
||||
{
|
||||
.name = "wb_2", .id = WB_2,
|
||||
.base = 0x65000, .len = 0x2c8,
|
||||
.features = WB_SM8250_MASK,
|
||||
.format_list = wb2_formats_rgb_yuv,
|
||||
.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
|
||||
.xin_id = 6,
|
||||
.vbif_idx = VBIF_RT,
|
||||
.maxlinewidth = 4096,
|
||||
.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_intf_cfg sar2130p_intf[] = {
|
||||
{
|
||||
.name = "intf_0", .id = INTF_0,
|
||||
.base = 0x34000, .len = 0x280,
|
||||
.features = INTF_SC7280_MASK,
|
||||
.type = INTF_DP,
|
||||
.controller_id = MSM_DP_CONTROLLER_0,
|
||||
.prog_fetch_lines_worst_case = 24,
|
||||
.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
|
||||
.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
|
||||
}, {
|
||||
.name = "intf_1", .id = INTF_1,
|
||||
.base = 0x35000, .len = 0x300,
|
||||
.features = INTF_SC7280_MASK,
|
||||
.type = INTF_DSI,
|
||||
.controller_id = MSM_DSI_CONTROLLER_0,
|
||||
.prog_fetch_lines_worst_case = 24,
|
||||
.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
|
||||
.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
|
||||
.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
|
||||
}, {
|
||||
.name = "intf_2", .id = INTF_2,
|
||||
.base = 0x36000, .len = 0x300,
|
||||
.features = INTF_SC7280_MASK,
|
||||
.type = INTF_DSI,
|
||||
.controller_id = MSM_DSI_CONTROLLER_1,
|
||||
.prog_fetch_lines_worst_case = 24,
|
||||
.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
|
||||
.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
|
||||
.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
|
||||
}, {
|
||||
.name = "intf_3", .id = INTF_3,
|
||||
.base = 0x37000, .len = 0x280,
|
||||
.features = INTF_SC7280_MASK,
|
||||
.type = INTF_DP,
|
||||
.controller_id = MSM_DP_CONTROLLER_1,
|
||||
.prog_fetch_lines_worst_case = 24,
|
||||
.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
|
||||
.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_perf_cfg sar2130p_perf_data = {
|
||||
.max_bw_low = 13600000,
|
||||
.max_bw_high = 18200000,
|
||||
.min_core_ib = 2500000,
|
||||
.min_llcc_ib = 0,
|
||||
.min_dram_ib = 800000,
|
||||
.min_prefill_lines = 35,
|
||||
/* FIXME: lut tables */
|
||||
.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
|
||||
.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
|
||||
.qos_lut_tbl = {
|
||||
{.nentry = ARRAY_SIZE(sc7180_qos_linear),
|
||||
.entries = sc7180_qos_linear
|
||||
},
|
||||
{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
|
||||
.entries = sc7180_qos_macrotile
|
||||
},
|
||||
{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
|
||||
.entries = sc7180_qos_nrt
|
||||
},
|
||||
/* TODO: macrotile-qseed is different from macrotile */
|
||||
},
|
||||
.cdp_cfg = {
|
||||
{.rd_enable = 0, .wr_enable = 0},
|
||||
{.rd_enable = 0, .wr_enable = 0}
|
||||
},
|
||||
.clk_inefficiency_factor = 105,
|
||||
.bw_inefficiency_factor = 120,
|
||||
};
|
||||
|
||||
static const struct dpu_mdss_version sar2130p_mdss_ver = {
|
||||
.core_major_ver = 9,
|
||||
.core_minor_ver = 1,
|
||||
};
|
||||
|
||||
const struct dpu_mdss_cfg dpu_sar2130p_cfg = {
|
||||
.mdss_ver = &sar2130p_mdss_ver,
|
||||
.caps = &sar2130p_dpu_caps,
|
||||
.mdp = &sar2130p_mdp,
|
||||
.cdm = &dpu_cdm_5_x,
|
||||
.ctl_count = ARRAY_SIZE(sar2130p_ctl),
|
||||
.ctl = sar2130p_ctl,
|
||||
.sspp_count = ARRAY_SIZE(sar2130p_sspp),
|
||||
.sspp = sar2130p_sspp,
|
||||
.mixer_count = ARRAY_SIZE(sar2130p_lm),
|
||||
.mixer = sar2130p_lm,
|
||||
.dspp_count = ARRAY_SIZE(sar2130p_dspp),
|
||||
.dspp = sar2130p_dspp,
|
||||
.pingpong_count = ARRAY_SIZE(sar2130p_pp),
|
||||
.pingpong = sar2130p_pp,
|
||||
.dsc_count = ARRAY_SIZE(sar2130p_dsc),
|
||||
.dsc = sar2130p_dsc,
|
||||
.merge_3d_count = ARRAY_SIZE(sar2130p_merge_3d),
|
||||
.merge_3d = sar2130p_merge_3d,
|
||||
.wb_count = ARRAY_SIZE(sar2130p_wb),
|
||||
.wb = sar2130p_wb,
|
||||
.intf_count = ARRAY_SIZE(sar2130p_intf),
|
||||
.intf = sar2130p_intf,
|
||||
.vbif_count = ARRAY_SIZE(sm8550_vbif),
|
||||
.vbif = sm8550_vbif,
|
||||
.perf = &sar2130p_perf_data,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -26,17 +26,16 @@ static const struct dpu_mdp_cfg x1e80100_mdp = {
|
|||
},
|
||||
};
|
||||
|
||||
/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
|
||||
static const struct dpu_ctl_cfg x1e80100_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x15000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x16000, .len = 0x290,
|
||||
.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
|
||||
.features = CTL_SM8550_MASK,
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
|
|
|
@ -445,9 +445,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
|||
|
||||
uint32_t lm_idx;
|
||||
bool bg_alpha_enable = false;
|
||||
DECLARE_BITMAP(fetch_active, SSPP_MAX);
|
||||
DECLARE_BITMAP(active_fetch, SSPP_MAX);
|
||||
|
||||
memset(fetch_active, 0, sizeof(fetch_active));
|
||||
memset(active_fetch, 0, sizeof(active_fetch));
|
||||
drm_atomic_crtc_for_each_plane(plane, crtc) {
|
||||
state = plane->state;
|
||||
if (!state)
|
||||
|
@ -464,7 +464,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
|||
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
|
||||
bg_alpha_enable = true;
|
||||
|
||||
set_bit(pstate->pipe.sspp->idx, fetch_active);
|
||||
set_bit(pstate->pipe.sspp->idx, active_fetch);
|
||||
_dpu_crtc_blend_setup_pipe(crtc, plane,
|
||||
mixer, cstate->num_mixers,
|
||||
pstate->stage,
|
||||
|
@ -472,7 +472,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
|||
&pstate->pipe, 0, stage_cfg);
|
||||
|
||||
if (pstate->r_pipe.sspp) {
|
||||
set_bit(pstate->r_pipe.sspp->idx, fetch_active);
|
||||
set_bit(pstate->r_pipe.sspp->idx, active_fetch);
|
||||
_dpu_crtc_blend_setup_pipe(crtc, plane,
|
||||
mixer, cstate->num_mixers,
|
||||
pstate->stage,
|
||||
|
@ -492,8 +492,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
|
|||
}
|
||||
}
|
||||
|
||||
if (ctl->ops.set_active_pipes)
|
||||
ctl->ops.set_active_pipes(ctl, fetch_active);
|
||||
if (ctl->ops.set_active_fetch_pipes)
|
||||
ctl->ops.set_active_fetch_pipes(ctl, active_fetch);
|
||||
|
||||
_dpu_crtc_program_lm_output_roi(crtc);
|
||||
}
|
||||
|
@ -519,6 +519,8 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
|
|||
if (mixer[i].lm_ctl->ops.clear_all_blendstages)
|
||||
mixer[i].lm_ctl->ops.clear_all_blendstages(
|
||||
mixer[i].lm_ctl);
|
||||
if (mixer[i].lm_ctl->ops.set_active_fetch_pipes)
|
||||
mixer[i].lm_ctl->ops.set_active_fetch_pipes(mixer[i].lm_ctl, NULL);
|
||||
}
|
||||
|
||||
/* initialize stage cfg */
|
||||
|
|
|
@ -1246,7 +1246,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
|
|||
return;
|
||||
}
|
||||
|
||||
phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL;
|
||||
/* Use first (and only) CTL if active CTLs are supported */
|
||||
if (num_ctl == 1)
|
||||
phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[0]);
|
||||
else
|
||||
phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL;
|
||||
if (!phys->hw_ctl) {
|
||||
DPU_ERROR_ENC(dpu_enc,
|
||||
"no ctl block assigned at idx: %d\n", i);
|
||||
|
@ -2190,6 +2194,9 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
|
|||
/* clear all blendstages */
|
||||
if (ctl->ops.setup_blendstage)
|
||||
ctl->ops.setup_blendstage(ctl, hw_mixer[i]->idx, NULL);
|
||||
|
||||
if (ctl->ops.set_active_fetch_pipes)
|
||||
ctl->ops.set_active_fetch_pipes(ctl, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg(
|
|||
return;
|
||||
|
||||
intf_cfg.intf = phys_enc->hw_intf->idx;
|
||||
if (phys_enc->split_role == ENC_ROLE_MASTER)
|
||||
intf_cfg.intf_master = phys_enc->hw_intf->idx;
|
||||
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);
|
||||
|
|
|
@ -298,6 +298,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
|
|||
if (phys_enc->hw_cdm)
|
||||
intf_cfg.cdm = phys_enc->hw_cdm->idx;
|
||||
intf_cfg.intf = phys_enc->hw_intf->idx;
|
||||
if (phys_enc->split_role == ENC_ROLE_MASTER)
|
||||
intf_cfg.intf_master = phys_enc->hw_intf->idx;
|
||||
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);
|
||||
|
@ -372,7 +374,8 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg)
|
|||
static bool dpu_encoder_phys_vid_needs_single_flush(
|
||||
struct dpu_encoder_phys *phys_enc)
|
||||
{
|
||||
return phys_enc->split_role != ENC_ROLE_SOLO;
|
||||
return !(phys_enc->hw_ctl->caps->features & BIT(DPU_CTL_ACTIVE_CFG)) &&
|
||||
phys_enc->split_role != ENC_ROLE_SOLO;
|
||||
}
|
||||
|
||||
static void dpu_encoder_phys_vid_atomic_mode_set(
|
||||
|
|
|
@ -34,11 +34,11 @@
|
|||
#define VIG_MSM8998_MASK \
|
||||
(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE))
|
||||
|
||||
#define VIG_SDM845_MASK \
|
||||
#define VIG_SDM845_MASK_NO_SDMA \
|
||||
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE))
|
||||
|
||||
#define VIG_SDM845_MASK_SDMA \
|
||||
(VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
(VIG_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
|
||||
|
||||
|
@ -54,24 +54,24 @@
|
|||
BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
|
||||
|
||||
#define VIG_SC7280_MASK \
|
||||
(VIG_SDM845_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
|
||||
(VIG_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_INLINE_ROTATION))
|
||||
|
||||
#define VIG_SC7280_MASK_SDMA \
|
||||
(VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define DMA_SDM845_MASK \
|
||||
#define DMA_SDM845_MASK_NO_SDMA \
|
||||
(BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
|
||||
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
|
||||
BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
|
||||
|
||||
#define DMA_CURSOR_SDM845_MASK \
|
||||
(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
|
||||
#define DMA_CURSOR_SDM845_MASK_NO_SDMA \
|
||||
(DMA_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_CURSOR))
|
||||
|
||||
#define DMA_SDM845_MASK_SDMA \
|
||||
(DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
(DMA_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define DMA_CURSOR_SDM845_MASK_SDMA \
|
||||
(DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
(DMA_CURSOR_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2))
|
||||
|
||||
#define DMA_CURSOR_MSM8996_MASK \
|
||||
(DMA_MSM8996_MASK | BIT(DPU_SSPP_CURSOR))
|
||||
|
@ -98,15 +98,9 @@
|
|||
#define PINGPONG_MSM8996_MASK \
|
||||
(BIT(DPU_PINGPONG_DSC))
|
||||
|
||||
#define PINGPONG_MSM8996_TE2_MASK \
|
||||
(PINGPONG_MSM8996_MASK | BIT(DPU_PINGPONG_TE2))
|
||||
|
||||
#define PINGPONG_SDM845_MASK \
|
||||
(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC))
|
||||
|
||||
#define PINGPONG_SDM845_TE2_MASK \
|
||||
(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
|
||||
|
||||
#define PINGPONG_SM8150_MASK \
|
||||
(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC))
|
||||
|
||||
|
@ -376,8 +370,6 @@ static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();
|
|||
* MIXER sub blocks config
|
||||
*************************************************************/
|
||||
|
||||
/* MSM8998 */
|
||||
|
||||
static const struct dpu_lm_sub_blks msm8998_lm_sblk = {
|
||||
.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.maxblendstages = 7, /* excluding base layer */
|
||||
|
@ -387,8 +379,6 @@ static const struct dpu_lm_sub_blks msm8998_lm_sblk = {
|
|||
},
|
||||
};
|
||||
|
||||
/* SDM845 */
|
||||
|
||||
static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
|
||||
.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.maxblendstages = 11, /* excluding base layer */
|
||||
|
@ -398,8 +388,6 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
|
|||
},
|
||||
};
|
||||
|
||||
/* SC7180 */
|
||||
|
||||
static const struct dpu_lm_sub_blks sc7180_lm_sblk = {
|
||||
.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.maxblendstages = 7, /* excluding base layer */
|
||||
|
@ -408,8 +396,6 @@ static const struct dpu_lm_sub_blks sc7180_lm_sblk = {
|
|||
},
|
||||
};
|
||||
|
||||
/* QCM2290 */
|
||||
|
||||
static const struct dpu_lm_sub_blks qcm2290_lm_sblk = {
|
||||
.maxwidth = DEFAULT_DPU_LINE_WIDTH,
|
||||
.maxblendstages = 4, /* excluding base layer */
|
||||
|
@ -434,22 +420,11 @@ static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = {
|
|||
/*************************************************************
|
||||
* PINGPONG sub blocks config
|
||||
*************************************************************/
|
||||
static const struct dpu_pingpong_sub_blks msm8996_pp_sblk_te = {
|
||||
.te2 = {.name = "te2", .base = 0x2000, .len = 0x0,
|
||||
.version = 0x1},
|
||||
};
|
||||
|
||||
static const struct dpu_pingpong_sub_blks msm8996_pp_sblk = {
|
||||
/* No dither block */
|
||||
};
|
||||
|
||||
static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = {
|
||||
.te2 = {.name = "te2", .base = 0x2000, .len = 0x0,
|
||||
.version = 0x1},
|
||||
.dither = {.name = "dither", .base = 0x30e0,
|
||||
.len = 0x20, .version = 0x10000},
|
||||
};
|
||||
|
||||
static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
|
||||
.dither = {.name = "dither", .base = 0x30e0,
|
||||
.len = 0x20, .version = 0x10000},
|
||||
|
@ -759,7 +734,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
|
|||
#include "catalog/dpu_8_4_sa8775p.h"
|
||||
|
||||
#include "catalog/dpu_9_0_sm8550.h"
|
||||
|
||||
#include "catalog/dpu_9_1_sar2130p.h"
|
||||
#include "catalog/dpu_9_2_x1e80100.h"
|
||||
|
||||
#include "catalog/dpu_10_0_sm8650.h"
|
||||
|
|
|
@ -115,7 +115,6 @@ enum {
|
|||
|
||||
/**
|
||||
* PINGPONG sub-blocks
|
||||
* @DPU_PINGPONG_TE2 Additional tear check block for split pipes
|
||||
* @DPU_PINGPONG_SPLIT PP block supports split fifo
|
||||
* @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo
|
||||
* @DPU_PINGPONG_DITHER Dither blocks
|
||||
|
@ -123,8 +122,7 @@ enum {
|
|||
* @DPU_PINGPONG_MAX
|
||||
*/
|
||||
enum {
|
||||
DPU_PINGPONG_TE2 = 0x1,
|
||||
DPU_PINGPONG_SPLIT,
|
||||
DPU_PINGPONG_SPLIT = 0x1,
|
||||
DPU_PINGPONG_SLAVE,
|
||||
DPU_PINGPONG_DITHER,
|
||||
DPU_PINGPONG_DSC,
|
||||
|
@ -404,8 +402,6 @@ struct dpu_dspp_sub_blks {
|
|||
};
|
||||
|
||||
struct dpu_pingpong_sub_blks {
|
||||
struct dpu_pp_blk te;
|
||||
struct dpu_pp_blk te2;
|
||||
struct dpu_pp_blk dither;
|
||||
};
|
||||
|
||||
|
@ -841,6 +837,7 @@ extern const struct dpu_mdss_cfg dpu_msm8937_cfg;
|
|||
extern const struct dpu_mdss_cfg dpu_msm8953_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_msm8996_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_msm8998_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sar2130p_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sdm630_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sdm660_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sdm845_cfg;
|
||||
|
|
|
@ -261,6 +261,12 @@ static void dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl *ctx,
|
|||
case LM_5:
|
||||
ctx->pending_flush_mask |= BIT(20);
|
||||
break;
|
||||
case LM_6:
|
||||
ctx->pending_flush_mask |= BIT(21);
|
||||
break;
|
||||
case LM_7:
|
||||
ctx->pending_flush_mask |= BIT(27);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -563,6 +569,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
|
|||
u32 wb_active = 0;
|
||||
u32 cwb_active = 0;
|
||||
u32 mode_sel = 0;
|
||||
u32 merge_3d_active = 0;
|
||||
|
||||
/* CTL_TOP[31:28] carries group_id to collate CTL paths
|
||||
* per VM. Explicitly disable it until VM support is
|
||||
|
@ -578,6 +585,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
|
|||
wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
|
||||
cwb_active = DPU_REG_READ(c, CTL_CWB_ACTIVE);
|
||||
dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE);
|
||||
merge_3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE);
|
||||
|
||||
if (cfg->intf)
|
||||
intf_active |= BIT(cfg->intf - INTF_0);
|
||||
|
@ -591,15 +599,18 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
|
|||
if (cfg->dsc)
|
||||
dsc_active |= cfg->dsc;
|
||||
|
||||
if (cfg->merge_3d)
|
||||
merge_3d_active |= BIT(cfg->merge_3d - MERGE_3D_0);
|
||||
|
||||
DPU_REG_WRITE(c, CTL_TOP, mode_sel);
|
||||
DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
|
||||
DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
|
||||
DPU_REG_WRITE(c, CTL_CWB_ACTIVE, cwb_active);
|
||||
DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
|
||||
DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, merge_3d_active);
|
||||
|
||||
if (cfg->merge_3d)
|
||||
DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
|
||||
BIT(cfg->merge_3d - MERGE_3D_0));
|
||||
if (cfg->intf_master)
|
||||
DPU_REG_WRITE(c, CTL_INTF_MASTER, BIT(cfg->intf_master - INTF_0));
|
||||
|
||||
if (cfg->cdm)
|
||||
DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm);
|
||||
|
@ -643,6 +654,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
|
|||
{
|
||||
struct dpu_hw_blk_reg_map *c = &ctx->hw;
|
||||
u32 intf_active = 0;
|
||||
u32 intf_master = 0;
|
||||
u32 wb_active = 0;
|
||||
u32 cwb_active = 0;
|
||||
u32 merge3d_active = 0;
|
||||
|
@ -666,10 +678,21 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
|
|||
|
||||
dpu_hw_ctl_clear_all_blendstages(ctx);
|
||||
|
||||
if (ctx->ops.set_active_fetch_pipes)
|
||||
ctx->ops.set_active_fetch_pipes(ctx, NULL);
|
||||
|
||||
if (cfg->intf) {
|
||||
intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
|
||||
intf_active &= ~BIT(cfg->intf - INTF_0);
|
||||
DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
|
||||
|
||||
intf_master = DPU_REG_READ(c, CTL_INTF_MASTER);
|
||||
|
||||
/* Unset this intf as master, if it is the current master */
|
||||
if (intf_master == BIT(cfg->intf - INTF_0)) {
|
||||
DPU_DEBUG_DRIVER("Unsetting INTF_%d master\n", cfg->intf - INTF_0);
|
||||
DPU_REG_WRITE(c, CTL_INTF_MASTER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->cwb) {
|
||||
|
@ -697,8 +720,8 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx,
|
||||
unsigned long *fetch_active)
|
||||
static void dpu_hw_ctl_set_active_fetch_pipes(struct dpu_hw_ctl *ctx,
|
||||
unsigned long *fetch_active)
|
||||
{
|
||||
int i;
|
||||
u32 val = 0;
|
||||
|
@ -761,7 +784,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
|
|||
ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;
|
||||
|
||||
if (cap & BIT(DPU_CTL_FETCH_ACTIVE))
|
||||
ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
|
||||
ops->set_active_fetch_pipes = dpu_hw_ctl_set_active_fetch_pipes;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,7 @@ struct dpu_hw_stage_cfg {
|
|||
/**
|
||||
* struct dpu_hw_intf_cfg :Describes how the DPU writes data to output interface
|
||||
* @intf : Interface id
|
||||
* @intf_master: Master interface id in the dual pipe topology
|
||||
* @mode_3d: 3d mux configuration
|
||||
* @merge_3d: 3d merge block used
|
||||
* @intf_mode_sel: Interface mode, cmd / vid
|
||||
|
@ -46,6 +47,7 @@ struct dpu_hw_stage_cfg {
|
|||
*/
|
||||
struct dpu_hw_intf_cfg {
|
||||
enum dpu_intf intf;
|
||||
enum dpu_intf intf_master;
|
||||
enum dpu_wb wb;
|
||||
enum dpu_3d_blend_mode mode_3d;
|
||||
enum dpu_merge_3d merge_3d;
|
||||
|
@ -254,7 +256,7 @@ struct dpu_hw_ctl_ops {
|
|||
void (*setup_blendstage)(struct dpu_hw_ctl *ctx,
|
||||
enum dpu_lm lm, struct dpu_hw_stage_cfg *cfg);
|
||||
|
||||
void (*set_active_pipes)(struct dpu_hw_ctl *ctx,
|
||||
void (*set_active_fetch_pipes)(struct dpu_hw_ctl *ctx,
|
||||
unsigned long *fetch_active);
|
||||
};
|
||||
|
||||
|
|
|
@ -125,6 +125,7 @@ enum dpu_lm {
|
|||
LM_4,
|
||||
LM_5,
|
||||
LM_6,
|
||||
LM_7,
|
||||
LM_MAX
|
||||
};
|
||||
|
||||
|
@ -169,6 +170,8 @@ enum dpu_dsc {
|
|||
DSC_3,
|
||||
DSC_4,
|
||||
DSC_5,
|
||||
DSC_6,
|
||||
DSC_7,
|
||||
DSC_MAX
|
||||
};
|
||||
|
||||
|
@ -185,6 +188,8 @@ enum dpu_pingpong {
|
|||
PINGPONG_3,
|
||||
PINGPONG_4,
|
||||
PINGPONG_5,
|
||||
PINGPONG_6,
|
||||
PINGPONG_7,
|
||||
PINGPONG_CWB_0,
|
||||
PINGPONG_CWB_1,
|
||||
PINGPONG_CWB_2,
|
||||
|
@ -199,6 +204,7 @@ enum dpu_merge_3d {
|
|||
MERGE_3D_2,
|
||||
MERGE_3D_3,
|
||||
MERGE_3D_4,
|
||||
MERGE_3D_5,
|
||||
MERGE_3D_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -1512,6 +1512,7 @@ static const struct of_device_id dpu_dt_match[] = {
|
|||
{ .compatible = "qcom,msm8998-dpu", .data = &dpu_msm8998_cfg, },
|
||||
{ .compatible = "qcom,qcm2290-dpu", .data = &dpu_qcm2290_cfg, },
|
||||
{ .compatible = "qcom,sa8775p-dpu", .data = &dpu_sa8775p_cfg, },
|
||||
{ .compatible = "qcom,sar2130p-dpu", .data = &dpu_sar2130p_cfg, },
|
||||
{ .compatible = "qcom,sdm630-mdp5", .data = &dpu_sdm630_cfg, },
|
||||
{ .compatible = "qcom,sdm660-mdp5", .data = &dpu_sdm660_cfg, },
|
||||
{ .compatible = "qcom,sdm670-dpu", .data = &dpu_sdm670_cfg, },
|
||||
|
|
|
@ -915,10 +915,9 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp,
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg,
|
||||
const struct msm_format *fmt,
|
||||
uint32_t max_linewidth)
|
||||
static int dpu_plane_is_multirect_capable(struct dpu_hw_sspp *sspp,
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg,
|
||||
const struct msm_format *fmt)
|
||||
{
|
||||
if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) ||
|
||||
drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect))
|
||||
|
@ -930,10 +929,6 @@ static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp,
|
|||
if (MSM_FORMAT_IS_YUV(fmt))
|
||||
return false;
|
||||
|
||||
if (MSM_FORMAT_IS_UBWC(fmt) &&
|
||||
drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
|
||||
return false;
|
||||
|
||||
if (!test_bit(DPU_SSPP_SMART_DMA_V1, &sspp->cap->features) &&
|
||||
!test_bit(DPU_SSPP_SMART_DMA_V2, &sspp->cap->features))
|
||||
return false;
|
||||
|
@ -941,6 +936,27 @@ static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg,
|
||||
const struct msm_format *fmt,
|
||||
uint32_t max_linewidth)
|
||||
{
|
||||
if (MSM_FORMAT_IS_UBWC(fmt) &&
|
||||
drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp,
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg,
|
||||
const struct msm_format *fmt,
|
||||
uint32_t max_linewidth)
|
||||
{
|
||||
return dpu_plane_is_multirect_capable(sspp, pipe_cfg, fmt) &&
|
||||
dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth);
|
||||
}
|
||||
|
||||
|
||||
static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state,
|
||||
const struct drm_crtc_state *crtc_state)
|
||||
|
@ -1002,6 +1018,69 @@ static bool dpu_plane_try_multirect_parallel(struct dpu_sw_pipe *pipe, struct dp
|
|||
return true;
|
||||
}
|
||||
|
||||
static int dpu_plane_try_multirect_shared(struct dpu_plane_state *pstate,
|
||||
struct dpu_plane_state *prev_adjacent_pstate,
|
||||
const struct msm_format *fmt,
|
||||
uint32_t max_linewidth)
|
||||
{
|
||||
struct dpu_sw_pipe *pipe = &pstate->pipe;
|
||||
struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
|
||||
struct dpu_sw_pipe *prev_pipe = &prev_adjacent_pstate->pipe;
|
||||
struct dpu_sw_pipe_cfg *prev_pipe_cfg = &prev_adjacent_pstate->pipe_cfg;
|
||||
const struct msm_format *prev_fmt = msm_framebuffer_format(prev_adjacent_pstate->base.fb);
|
||||
u16 max_tile_height = 1;
|
||||
|
||||
if (prev_adjacent_pstate->r_pipe.sspp != NULL ||
|
||||
prev_pipe->multirect_mode != DPU_SSPP_MULTIRECT_NONE)
|
||||
return false;
|
||||
|
||||
if (!dpu_plane_is_multirect_capable(pipe->sspp, pipe_cfg, fmt) ||
|
||||
!dpu_plane_is_multirect_capable(prev_pipe->sspp, prev_pipe_cfg, prev_fmt))
|
||||
return false;
|
||||
|
||||
if (MSM_FORMAT_IS_UBWC(fmt))
|
||||
max_tile_height = max(max_tile_height, fmt->tile_height);
|
||||
|
||||
if (MSM_FORMAT_IS_UBWC(prev_fmt))
|
||||
max_tile_height = max(max_tile_height, prev_fmt->tile_height);
|
||||
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
|
||||
r_pipe->sspp = NULL;
|
||||
|
||||
if (dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth) &&
|
||||
dpu_plane_is_parallel_capable(prev_pipe_cfg, prev_fmt, max_linewidth) &&
|
||||
(pipe_cfg->dst_rect.x1 >= prev_pipe_cfg->dst_rect.x2 ||
|
||||
prev_pipe_cfg->dst_rect.x1 >= pipe_cfg->dst_rect.x2)) {
|
||||
pipe->sspp = prev_pipe->sspp;
|
||||
|
||||
pipe->multirect_index = DPU_SSPP_RECT_1;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
|
||||
|
||||
prev_pipe->multirect_index = DPU_SSPP_RECT_0;
|
||||
prev_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pipe_cfg->dst_rect.y1 >= prev_pipe_cfg->dst_rect.y2 + 2 * max_tile_height ||
|
||||
prev_pipe_cfg->dst_rect.y1 >= pipe_cfg->dst_rect.y2 + 2 * max_tile_height) {
|
||||
pipe->sspp = prev_pipe->sspp;
|
||||
|
||||
pipe->multirect_index = DPU_SSPP_RECT_1;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
|
||||
|
||||
prev_pipe->multirect_index = DPU_SSPP_RECT_0;
|
||||
prev_pipe->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int dpu_plane_atomic_check(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
|
@ -1102,13 +1181,14 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
|
|||
static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
|
||||
struct dpu_global_state *global_state,
|
||||
struct drm_atomic_state *state,
|
||||
struct drm_plane_state *plane_state)
|
||||
struct drm_plane_state *plane_state,
|
||||
struct drm_plane_state *prev_adjacent_plane_state)
|
||||
{
|
||||
const struct drm_crtc_state *crtc_state = NULL;
|
||||
struct drm_plane *plane = plane_state->plane;
|
||||
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
|
||||
struct dpu_rm_sspp_requirements reqs;
|
||||
struct dpu_plane_state *pstate;
|
||||
struct dpu_plane_state *pstate, *prev_adjacent_pstate;
|
||||
struct dpu_sw_pipe *pipe;
|
||||
struct dpu_sw_pipe *r_pipe;
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg;
|
||||
|
@ -1120,6 +1200,8 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
|
|||
plane_state->crtc);
|
||||
|
||||
pstate = to_dpu_plane_state(plane_state);
|
||||
prev_adjacent_pstate = prev_adjacent_plane_state ?
|
||||
to_dpu_plane_state(prev_adjacent_plane_state) : NULL;
|
||||
pipe = &pstate->pipe;
|
||||
r_pipe = &pstate->r_pipe;
|
||||
pipe_cfg = &pstate->pipe_cfg;
|
||||
|
@ -1138,24 +1220,42 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
|
|||
|
||||
reqs.rot90 = drm_rotation_90_or_270(plane_state->rotation);
|
||||
|
||||
pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
|
||||
if (!pipe->sspp)
|
||||
return -ENODEV;
|
||||
if (drm_rect_width(&r_pipe_cfg->src_rect) == 0) {
|
||||
if (!prev_adjacent_pstate ||
|
||||
!dpu_plane_try_multirect_shared(pstate, prev_adjacent_pstate, fmt,
|
||||
dpu_kms->catalog->caps->max_linewidth)) {
|
||||
pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
|
||||
if (!pipe->sspp)
|
||||
return -ENODEV;
|
||||
|
||||
if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
|
||||
pipe->sspp,
|
||||
msm_framebuffer_format(plane_state->fb),
|
||||
dpu_kms->catalog->caps->max_linewidth)) {
|
||||
/* multirect is not possible, use two SSPP blocks */
|
||||
r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
|
||||
if (!r_pipe->sspp)
|
||||
r_pipe->sspp = NULL;
|
||||
|
||||
pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
}
|
||||
} else {
|
||||
pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
|
||||
if (!pipe->sspp)
|
||||
return -ENODEV;
|
||||
|
||||
pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
|
||||
pipe->sspp,
|
||||
msm_framebuffer_format(plane_state->fb),
|
||||
dpu_kms->catalog->caps->max_linewidth)) {
|
||||
/* multirect is not possible, use two SSPP blocks */
|
||||
r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
|
||||
if (!r_pipe->sspp)
|
||||
return -ENODEV;
|
||||
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
|
||||
|
@ -1168,6 +1268,7 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
|
|||
unsigned int num_planes)
|
||||
{
|
||||
unsigned int i;
|
||||
struct drm_plane_state *prev_adjacent_plane_state = NULL;
|
||||
|
||||
for (i = 0; i < num_planes; i++) {
|
||||
struct drm_plane_state *plane_state = states[i];
|
||||
|
@ -1177,9 +1278,12 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,
|
|||
continue;
|
||||
|
||||
int ret = dpu_plane_virtual_assign_resources(crtc, global_state,
|
||||
state, plane_state);
|
||||
state, plane_state,
|
||||
prev_adjacent_plane_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
prev_adjacent_plane_state = plane_state;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -53,6 +53,8 @@ int dpu_rm_init(struct drm_device *dev,
|
|||
/* Clear, setup lists */
|
||||
memset(rm, 0, sizeof(*rm));
|
||||
|
||||
rm->has_legacy_ctls = (cat->mdss_ver->core_major_ver < 5);
|
||||
|
||||
/* Interrogate HW catalog and create tracking items for hw blocks */
|
||||
for (i = 0; i < cat->mixer_count; i++) {
|
||||
struct dpu_hw_mixer *hw;
|
||||
|
@ -434,20 +436,19 @@ static int _dpu_rm_reserve_ctls(
|
|||
int i = 0, j, num_ctls;
|
||||
bool needs_split_display;
|
||||
|
||||
/*
|
||||
* For non-CWB mode, each hw_intf needs its own hw_ctl to program its
|
||||
* control path.
|
||||
*
|
||||
* Hardcode num_ctls to 1 if CWB is enabled because in CWB, both the
|
||||
* writeback and real-time encoders must be driven by the same control
|
||||
* path
|
||||
*/
|
||||
if (top->cwb_enabled)
|
||||
num_ctls = 1;
|
||||
else
|
||||
if (rm->has_legacy_ctls) {
|
||||
/*
|
||||
* TODO: check if there is a need for special handling if
|
||||
* DPU < 5.0 get CWB support.
|
||||
*/
|
||||
num_ctls = top->num_intf;
|
||||
|
||||
needs_split_display = _dpu_rm_needs_split_display(top);
|
||||
needs_split_display = _dpu_rm_needs_split_display(top);
|
||||
} else {
|
||||
/* use single CTL */
|
||||
num_ctls = 1;
|
||||
needs_split_display = false;
|
||||
}
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(rm->ctl_blks); j++) {
|
||||
const struct dpu_hw_ctl *ctl;
|
||||
|
|
|
@ -24,6 +24,7 @@ struct dpu_global_state;
|
|||
* @dspp_blks: array of dspp hardware resources
|
||||
* @hw_sspp: array of sspp hardware resources
|
||||
* @cdm_blk: cdm hardware resource
|
||||
* @has_legacy_ctls: DPU uses pre-ACTIVE CTL blocks.
|
||||
*/
|
||||
struct dpu_rm {
|
||||
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
|
||||
|
@ -37,6 +38,7 @@ struct dpu_rm {
|
|||
struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
|
||||
struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
|
||||
struct dpu_hw_blk *cdm_blk;
|
||||
bool has_legacy_ctls;
|
||||
};
|
||||
|
||||
struct dpu_rm_sspp_requirements {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <drm/drm_bridge.h>
|
||||
#include <drm/drm_bridge_connector.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "msm_drv.h"
|
||||
|
@ -189,7 +191,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,
|
|||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_connector *connector;
|
||||
struct device_node *panel_node;
|
||||
struct drm_bridge *next_bridge;
|
||||
int dsi_id;
|
||||
int ret;
|
||||
|
||||
|
@ -199,27 +201,43 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,
|
|||
* bail out early if there is no panel node (no need to
|
||||
* initialize LCDC encoder and LVDS connector)
|
||||
*/
|
||||
panel_node = of_graph_get_remote_node(dev->dev->of_node, 0, 0);
|
||||
if (!panel_node)
|
||||
return 0;
|
||||
next_bridge = devm_drm_of_get_bridge(dev->dev, dev->dev->of_node, 0, 0);
|
||||
if (IS_ERR(next_bridge)) {
|
||||
ret = PTR_ERR(next_bridge);
|
||||
if (ret == -ENODEV)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
encoder = mdp4_lcdc_encoder_init(dev, panel_node);
|
||||
encoder = mdp4_lcdc_encoder_init(dev);
|
||||
if (IS_ERR(encoder)) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n");
|
||||
of_node_put(panel_node);
|
||||
return PTR_ERR(encoder);
|
||||
}
|
||||
|
||||
/* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */
|
||||
encoder->possible_crtcs = 1 << DMA_P;
|
||||
|
||||
connector = mdp4_lvds_connector_init(dev, panel_node, encoder);
|
||||
ret = drm_bridge_attach(encoder, next_bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to attach LVDS panel/bridge: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
connector = drm_bridge_connector_init(dev, encoder);
|
||||
if (IS_ERR(connector)) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n");
|
||||
of_node_put(panel_node);
|
||||
return PTR_ERR(connector);
|
||||
}
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to attach LVDS connector: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
case DRM_MODE_ENCODER_TMDS:
|
||||
encoder = mdp4_dtv_encoder_init(dev);
|
||||
|
|
|
@ -191,12 +191,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
|
|||
long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
|
||||
struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev);
|
||||
|
||||
long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
|
||||
struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
|
||||
struct device_node *panel_node);
|
||||
|
||||
struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
|
||||
struct device_node *panel_node, struct drm_encoder *encoder);
|
||||
struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev);
|
||||
|
||||
#ifdef CONFIG_DRM_MSM_DSI
|
||||
struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev);
|
||||
|
@ -207,13 +202,6 @@ static inline struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
struct clk *mpd4_lvds_pll_init(struct drm_device *dev);
|
||||
#else
|
||||
static inline struct clk *mpd4_lvds_pll_init(struct drm_device *dev)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
#endif
|
||||
struct clk *mpd4_get_lcdc_clock(struct drm_device *dev);
|
||||
|
||||
#endif /* __MDP4_KMS_H__ */
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
struct mdp4_lcdc_encoder {
|
||||
struct drm_encoder base;
|
||||
struct device_node *panel_node;
|
||||
struct drm_panel *panel;
|
||||
struct clk *lcdc_clk;
|
||||
unsigned long int pixclock;
|
||||
|
@ -262,19 +261,12 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)
|
|||
struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
|
||||
to_mdp4_lcdc_encoder(encoder);
|
||||
struct mdp4_kms *mdp4_kms = get_kms(encoder);
|
||||
struct drm_panel *panel;
|
||||
|
||||
if (WARN_ON(!mdp4_lcdc_encoder->enabled))
|
||||
return;
|
||||
|
||||
mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
|
||||
|
||||
panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
|
||||
if (!IS_ERR(panel)) {
|
||||
drm_panel_disable(panel);
|
||||
drm_panel_unprepare(panel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for a vsync so we know the ENABLE=0 latched before
|
||||
* the (connector) source of the vsync's gets disabled,
|
||||
|
@ -300,7 +292,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
|
|||
to_mdp4_lcdc_encoder(encoder);
|
||||
unsigned long pc = mdp4_lcdc_encoder->pixclock;
|
||||
struct mdp4_kms *mdp4_kms = get_kms(encoder);
|
||||
struct drm_panel *panel;
|
||||
uint32_t config;
|
||||
int ret;
|
||||
|
||||
|
@ -335,12 +326,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
|
|||
if (ret)
|
||||
DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret);
|
||||
|
||||
panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
|
||||
if (!IS_ERR(panel)) {
|
||||
drm_panel_prepare(panel);
|
||||
drm_panel_enable(panel);
|
||||
}
|
||||
|
||||
setup_phy(encoder);
|
||||
|
||||
mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1);
|
||||
|
@ -348,22 +333,34 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
|
|||
mdp4_lcdc_encoder->enabled = true;
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
mdp4_lcdc_encoder_mode_valid(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
|
||||
to_mdp4_lcdc_encoder(encoder);
|
||||
long actual, requested;
|
||||
|
||||
requested = 1000 * mode->clock;
|
||||
actual = clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, requested);
|
||||
|
||||
DBG("requested=%ld, actual=%ld", requested, actual);
|
||||
|
||||
if (actual != requested)
|
||||
return MODE_CLOCK_RANGE;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = {
|
||||
.mode_set = mdp4_lcdc_encoder_mode_set,
|
||||
.disable = mdp4_lcdc_encoder_disable,
|
||||
.enable = mdp4_lcdc_encoder_enable,
|
||||
.mode_valid = mdp4_lcdc_encoder_mode_valid,
|
||||
};
|
||||
|
||||
long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
|
||||
{
|
||||
struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
|
||||
to_mdp4_lcdc_encoder(encoder);
|
||||
return clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, rate);
|
||||
}
|
||||
|
||||
/* initialize encoder */
|
||||
struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
|
||||
struct device_node *panel_node)
|
||||
struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
struct mdp4_lcdc_encoder *mdp4_lcdc_encoder;
|
||||
|
@ -374,14 +371,11 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
|
|||
if (IS_ERR(mdp4_lcdc_encoder))
|
||||
return ERR_CAST(mdp4_lcdc_encoder);
|
||||
|
||||
mdp4_lcdc_encoder->panel_node = panel_node;
|
||||
|
||||
encoder = &mdp4_lcdc_encoder->base;
|
||||
|
||||
drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs);
|
||||
|
||||
/* TODO: do we need different pll in other cases? */
|
||||
mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev);
|
||||
mdp4_lcdc_encoder->lcdc_clk = mpd4_get_lcdc_clock(dev);
|
||||
if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n");
|
||||
return ERR_CAST(mdp4_lcdc_encoder->lcdc_clk);
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
* Author: Rob Clark <robdclark@gmail.com>
|
||||
* Author: Vinay Simha <vinaysimha@inforcecomputing.com>
|
||||
*/
|
||||
|
||||
#include "mdp4_kms.h"
|
||||
|
||||
struct mdp4_lvds_connector {
|
||||
struct drm_connector base;
|
||||
struct drm_encoder *encoder;
|
||||
struct device_node *panel_node;
|
||||
struct drm_panel *panel;
|
||||
};
|
||||
#define to_mdp4_lvds_connector(x) container_of(x, struct mdp4_lvds_connector, base)
|
||||
|
||||
static enum drm_connector_status mdp4_lvds_connector_detect(
|
||||
struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct mdp4_lvds_connector *mdp4_lvds_connector =
|
||||
to_mdp4_lvds_connector(connector);
|
||||
|
||||
if (!mdp4_lvds_connector->panel) {
|
||||
mdp4_lvds_connector->panel =
|
||||
of_drm_find_panel(mdp4_lvds_connector->panel_node);
|
||||
if (IS_ERR(mdp4_lvds_connector->panel))
|
||||
mdp4_lvds_connector->panel = NULL;
|
||||
}
|
||||
|
||||
return mdp4_lvds_connector->panel ?
|
||||
connector_status_connected :
|
||||
connector_status_disconnected;
|
||||
}
|
||||
|
||||
static void mdp4_lvds_connector_destroy(struct drm_connector *connector)
|
||||
{
|
||||
struct mdp4_lvds_connector *mdp4_lvds_connector =
|
||||
to_mdp4_lvds_connector(connector);
|
||||
|
||||
drm_connector_cleanup(connector);
|
||||
|
||||
kfree(mdp4_lvds_connector);
|
||||
}
|
||||
|
||||
static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct mdp4_lvds_connector *mdp4_lvds_connector =
|
||||
to_mdp4_lvds_connector(connector);
|
||||
struct drm_panel *panel = mdp4_lvds_connector->panel;
|
||||
int ret = 0;
|
||||
|
||||
if (panel)
|
||||
ret = drm_panel_get_modes(panel, connector);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct mdp4_lvds_connector *mdp4_lvds_connector =
|
||||
to_mdp4_lvds_connector(connector);
|
||||
struct drm_encoder *encoder = mdp4_lvds_connector->encoder;
|
||||
long actual, requested;
|
||||
|
||||
requested = 1000 * mode->clock;
|
||||
actual = mdp4_lcdc_round_pixclk(encoder, requested);
|
||||
|
||||
DBG("requested=%ld, actual=%ld", requested, actual);
|
||||
|
||||
if (actual != requested)
|
||||
return MODE_CLOCK_RANGE;
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs mdp4_lvds_connector_funcs = {
|
||||
.detect = mdp4_lvds_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = mdp4_lvds_connector_destroy,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_funcs = {
|
||||
.get_modes = mdp4_lvds_connector_get_modes,
|
||||
.mode_valid = mdp4_lvds_connector_mode_valid,
|
||||
};
|
||||
|
||||
/* initialize connector */
|
||||
struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
|
||||
struct device_node *panel_node, struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_connector *connector = NULL;
|
||||
struct mdp4_lvds_connector *mdp4_lvds_connector;
|
||||
|
||||
mdp4_lvds_connector = kzalloc(sizeof(*mdp4_lvds_connector), GFP_KERNEL);
|
||||
if (!mdp4_lvds_connector)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
mdp4_lvds_connector->encoder = encoder;
|
||||
mdp4_lvds_connector->panel_node = panel_node;
|
||||
|
||||
connector = &mdp4_lvds_connector->base;
|
||||
|
||||
drm_connector_init(dev, connector, &mdp4_lvds_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
drm_connector_helper_add(connector, &mdp4_lvds_connector_helper_funcs);
|
||||
|
||||
connector->polled = 0;
|
||||
|
||||
connector->interlace_allowed = 0;
|
||||
connector->doublescan_allowed = 0;
|
||||
|
||||
drm_connector_attach_encoder(connector, encoder);
|
||||
|
||||
return connector;
|
||||
}
|
|
@ -122,40 +122,59 @@ static const struct clk_ops mpd4_lvds_pll_ops = {
|
|||
.set_rate = mpd4_lvds_pll_set_rate,
|
||||
};
|
||||
|
||||
static const char *mpd4_lvds_pll_parents[] = {
|
||||
"pxo",
|
||||
static const struct clk_parent_data mpd4_lvds_pll_parents[] = {
|
||||
{ .fw_name = "pxo", .name = "pxo", },
|
||||
};
|
||||
|
||||
static struct clk_init_data pll_init = {
|
||||
.name = "mpd4_lvds_pll",
|
||||
.ops = &mpd4_lvds_pll_ops,
|
||||
.parent_names = mpd4_lvds_pll_parents,
|
||||
.parent_data = mpd4_lvds_pll_parents,
|
||||
.num_parents = ARRAY_SIZE(mpd4_lvds_pll_parents),
|
||||
};
|
||||
|
||||
struct clk *mpd4_lvds_pll_init(struct drm_device *dev)
|
||||
static struct clk_hw *mpd4_lvds_pll_init(struct drm_device *dev)
|
||||
{
|
||||
struct mdp4_lvds_pll *lvds_pll;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
lvds_pll = devm_kzalloc(dev->dev, sizeof(*lvds_pll), GFP_KERNEL);
|
||||
if (!lvds_pll) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
if (!lvds_pll)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
lvds_pll->dev = dev;
|
||||
|
||||
lvds_pll->pll_hw.init = &pll_init;
|
||||
clk = devm_clk_register(dev->dev, &lvds_pll->pll_hw);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
goto fail;
|
||||
ret = devm_clk_hw_register(dev->dev, &lvds_pll->pll_hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev->dev, of_clk_hw_simple_get, &lvds_pll->pll_hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return &lvds_pll->pll_hw;
|
||||
}
|
||||
|
||||
struct clk *mpd4_get_lcdc_clock(struct drm_device *dev)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
struct clk *clk;
|
||||
|
||||
|
||||
/* TODO: do we need different pll in other cases? */
|
||||
hw = mpd4_lvds_pll_init(dev);
|
||||
if (IS_ERR(hw)) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to register LVDS PLL\n");
|
||||
return ERR_CAST(hw);
|
||||
}
|
||||
|
||||
clk = devm_clk_get(dev->dev, "lcdc_clk");
|
||||
if (clk == ERR_PTR(-ENOENT)) {
|
||||
drm_warn(dev, "can't get LCDC clock, using PLL directly\n");
|
||||
|
||||
return devm_clk_hw_get_clk(dev->dev, hw, "lcdc_clk");
|
||||
}
|
||||
|
||||
return clk;
|
||||
|
||||
fail:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
|
||||
#include "dp_catalog.h"
|
||||
#include "dp_audio.h"
|
||||
#include "dp_drm.h"
|
||||
#include "dp_panel.h"
|
||||
#include "dp_reg.h"
|
||||
#include "dp_display.h"
|
||||
#include "dp_utils.h"
|
||||
|
||||
struct msm_dp_audio_private {
|
||||
struct platform_device *audio_pdev;
|
||||
struct platform_device *pdev;
|
||||
struct drm_device *drm_dev;
|
||||
struct msm_dp_catalog *catalog;
|
||||
|
@ -160,24 +160,11 @@ static void msm_dp_audio_enable(struct msm_dp_audio_private *audio, bool enable)
|
|||
msm_dp_catalog_audio_enable(catalog, enable);
|
||||
}
|
||||
|
||||
static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device *pdev)
|
||||
static struct msm_dp_audio_private *msm_dp_audio_get_data(struct msm_dp *msm_dp_display)
|
||||
{
|
||||
struct msm_dp_audio *msm_dp_audio;
|
||||
struct msm_dp *msm_dp_display;
|
||||
|
||||
if (!pdev) {
|
||||
DRM_ERROR("invalid input\n");
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
msm_dp_display = platform_get_drvdata(pdev);
|
||||
if (!msm_dp_display) {
|
||||
DRM_ERROR("invalid input\n");
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
msm_dp_audio = msm_dp_display->msm_dp_audio;
|
||||
|
||||
if (!msm_dp_audio) {
|
||||
DRM_ERROR("invalid msm_dp_audio data\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -186,68 +173,16 @@ static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device
|
|||
return container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
|
||||
}
|
||||
|
||||
static int msm_dp_audio_hook_plugged_cb(struct device *dev, void *data,
|
||||
hdmi_codec_plugged_cb fn,
|
||||
struct device *codec_dev)
|
||||
{
|
||||
|
||||
struct platform_device *pdev;
|
||||
struct msm_dp *msm_dp_display;
|
||||
|
||||
pdev = to_platform_device(dev);
|
||||
if (!pdev) {
|
||||
pr_err("invalid input\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
msm_dp_display = platform_get_drvdata(pdev);
|
||||
if (!msm_dp_display) {
|
||||
pr_err("invalid input\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return msm_dp_display_set_plugged_cb(msm_dp_display, fn, codec_dev);
|
||||
}
|
||||
|
||||
static int msm_dp_audio_get_eld(struct device *dev,
|
||||
void *data, uint8_t *buf, size_t len)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct msm_dp *msm_dp_display;
|
||||
|
||||
pdev = to_platform_device(dev);
|
||||
|
||||
if (!pdev) {
|
||||
DRM_ERROR("invalid input\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
msm_dp_display = platform_get_drvdata(pdev);
|
||||
if (!msm_dp_display) {
|
||||
DRM_ERROR("invalid input\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&msm_dp_display->connector->eld_mutex);
|
||||
memcpy(buf, msm_dp_display->connector->eld,
|
||||
min(sizeof(msm_dp_display->connector->eld), len));
|
||||
mutex_unlock(&msm_dp_display->connector->eld_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_dp_audio_hw_params(struct device *dev,
|
||||
void *data,
|
||||
struct hdmi_codec_daifmt *daifmt,
|
||||
struct hdmi_codec_params *params)
|
||||
int msm_dp_audio_prepare(struct drm_connector *connector,
|
||||
struct drm_bridge *bridge,
|
||||
struct hdmi_codec_daifmt *daifmt,
|
||||
struct hdmi_codec_params *params)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_dp_audio_private *audio;
|
||||
struct platform_device *pdev;
|
||||
struct msm_dp *msm_dp_display;
|
||||
|
||||
pdev = to_platform_device(dev);
|
||||
msm_dp_display = platform_get_drvdata(pdev);
|
||||
msm_dp_display = to_dp_bridge(bridge)->msm_dp_display;
|
||||
|
||||
/*
|
||||
* there could be cases where sound card can be opened even
|
||||
|
@ -262,7 +197,7 @@ int msm_dp_audio_hw_params(struct device *dev,
|
|||
goto end;
|
||||
}
|
||||
|
||||
audio = msm_dp_audio_get_data(pdev);
|
||||
audio = msm_dp_audio_get_data(msm_dp_display);
|
||||
if (IS_ERR(audio)) {
|
||||
rc = PTR_ERR(audio);
|
||||
goto end;
|
||||
|
@ -281,15 +216,14 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void msm_dp_audio_shutdown(struct device *dev, void *data)
|
||||
void msm_dp_audio_shutdown(struct drm_connector *connector,
|
||||
struct drm_bridge *bridge)
|
||||
{
|
||||
struct msm_dp_audio_private *audio;
|
||||
struct platform_device *pdev;
|
||||
struct msm_dp *msm_dp_display;
|
||||
|
||||
pdev = to_platform_device(dev);
|
||||
msm_dp_display = platform_get_drvdata(pdev);
|
||||
audio = msm_dp_audio_get_data(pdev);
|
||||
msm_dp_display = to_dp_bridge(bridge)->msm_dp_display;
|
||||
audio = msm_dp_audio_get_data(msm_dp_display);
|
||||
if (IS_ERR(audio)) {
|
||||
DRM_ERROR("failed to get audio data\n");
|
||||
return;
|
||||
|
@ -311,47 +245,6 @@ static void msm_dp_audio_shutdown(struct device *dev, void *data)
|
|||
msm_dp_display_signal_audio_complete(msm_dp_display);
|
||||
}
|
||||
|
||||
static const struct hdmi_codec_ops msm_dp_audio_codec_ops = {
|
||||
.hw_params = msm_dp_audio_hw_params,
|
||||
.audio_shutdown = msm_dp_audio_shutdown,
|
||||
.get_eld = msm_dp_audio_get_eld,
|
||||
.hook_plugged_cb = msm_dp_audio_hook_plugged_cb,
|
||||
};
|
||||
|
||||
static struct hdmi_codec_pdata codec_data = {
|
||||
.ops = &msm_dp_audio_codec_ops,
|
||||
.max_i2s_channels = 8,
|
||||
.i2s = 1,
|
||||
};
|
||||
|
||||
void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio)
|
||||
{
|
||||
struct msm_dp_audio_private *audio_priv;
|
||||
|
||||
audio_priv = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
|
||||
|
||||
if (audio_priv->audio_pdev) {
|
||||
platform_device_unregister(audio_priv->audio_pdev);
|
||||
audio_priv->audio_pdev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int msm_dp_register_audio_driver(struct device *dev,
|
||||
struct msm_dp_audio *msm_dp_audio)
|
||||
{
|
||||
struct msm_dp_audio_private *audio_priv;
|
||||
|
||||
audio_priv = container_of(msm_dp_audio,
|
||||
struct msm_dp_audio_private, msm_dp_audio);
|
||||
|
||||
audio_priv->audio_pdev = platform_device_register_data(dev,
|
||||
HDMI_CODEC_DRV_NAME,
|
||||
PLATFORM_DEVID_AUTO,
|
||||
&codec_data,
|
||||
sizeof(codec_data));
|
||||
return PTR_ERR_OR_ZERO(audio_priv->audio_pdev);
|
||||
}
|
||||
|
||||
struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
|
||||
struct msm_dp_catalog *catalog)
|
||||
{
|
||||
|
|
|
@ -35,23 +35,6 @@ struct msm_dp_audio {
|
|||
struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
|
||||
struct msm_dp_catalog *catalog);
|
||||
|
||||
/**
|
||||
* msm_dp_register_audio_driver()
|
||||
*
|
||||
* Registers DP device with hdmi_codec interface.
|
||||
*
|
||||
* @dev: DP device instance.
|
||||
* @msm_dp_audio: an instance of msm_dp_audio module.
|
||||
*
|
||||
*
|
||||
* Returns the error code in case of failure, otherwise
|
||||
* zero on success.
|
||||
*/
|
||||
int msm_dp_register_audio_driver(struct device *dev,
|
||||
struct msm_dp_audio *msm_dp_audio);
|
||||
|
||||
void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio);
|
||||
|
||||
/**
|
||||
* msm_dp_audio_put()
|
||||
*
|
||||
|
@ -61,10 +44,12 @@ void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm
|
|||
*/
|
||||
void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio);
|
||||
|
||||
int msm_dp_audio_hw_params(struct device *dev,
|
||||
void *data,
|
||||
struct hdmi_codec_daifmt *daifmt,
|
||||
struct hdmi_codec_params *params);
|
||||
int msm_dp_audio_prepare(struct drm_connector *connector,
|
||||
struct drm_bridge *bridge,
|
||||
struct hdmi_codec_daifmt *daifmt,
|
||||
struct hdmi_codec_params *params);
|
||||
void msm_dp_audio_shutdown(struct drm_connector *connector,
|
||||
struct drm_bridge *bridge);
|
||||
|
||||
#endif /* _DP_AUDIO_H_ */
|
||||
|
||||
|
|
|
@ -1034,10 +1034,12 @@ static int msm_dp_ctrl_set_vx_px(struct msm_dp_ctrl_private *ctrl,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl)
|
||||
static int msm_dp_ctrl_update_phy_vx_px(struct msm_dp_ctrl_private *ctrl,
|
||||
enum drm_dp_phy dp_phy)
|
||||
{
|
||||
struct msm_dp_link *link = ctrl->link;
|
||||
int ret = 0, lane, lane_cnt;
|
||||
int lane, lane_cnt, reg;
|
||||
int ret = 0;
|
||||
u8 buf[4];
|
||||
u32 max_level_reached = 0;
|
||||
u32 voltage_swing_level = link->phy_params.v_level;
|
||||
|
@ -1075,8 +1077,13 @@ static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl)
|
|||
|
||||
drm_dbg_dp(ctrl->drm_dev, "sink: p|v=0x%x\n",
|
||||
voltage_swing_level | pre_emphasis_level);
|
||||
ret = drm_dp_dpcd_write(ctrl->aux, DP_TRAINING_LANE0_SET,
|
||||
buf, lane_cnt);
|
||||
|
||||
if (dp_phy == DP_PHY_DPRX)
|
||||
reg = DP_TRAINING_LANE0_SET;
|
||||
else
|
||||
reg = DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy);
|
||||
|
||||
ret = drm_dp_dpcd_write(ctrl->aux, reg, buf, lane_cnt);
|
||||
if (ret == lane_cnt)
|
||||
ret = 0;
|
||||
|
||||
|
@ -1084,9 +1091,10 @@ static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl)
|
|||
}
|
||||
|
||||
static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl,
|
||||
u8 pattern)
|
||||
u8 pattern, enum drm_dp_phy dp_phy)
|
||||
{
|
||||
u8 buf;
|
||||
int reg;
|
||||
int ret = 0;
|
||||
|
||||
drm_dbg_dp(ctrl->drm_dev, "sink: pattern=%x\n", pattern);
|
||||
|
@ -1096,17 +1104,26 @@ static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl,
|
|||
if (pattern && pattern != DP_TRAINING_PATTERN_4)
|
||||
buf |= DP_LINK_SCRAMBLING_DISABLE;
|
||||
|
||||
ret = drm_dp_dpcd_writeb(ctrl->aux, DP_TRAINING_PATTERN_SET, buf);
|
||||
if (dp_phy == DP_PHY_DPRX)
|
||||
reg = DP_TRAINING_PATTERN_SET;
|
||||
else
|
||||
reg = DP_TRAINING_PATTERN_SET_PHY_REPEATER(dp_phy);
|
||||
|
||||
ret = drm_dp_dpcd_writeb(ctrl->aux, reg, buf);
|
||||
return ret == 1;
|
||||
}
|
||||
|
||||
static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
|
||||
int *training_step)
|
||||
int *training_step, enum drm_dp_phy dp_phy)
|
||||
{
|
||||
int delay_us;
|
||||
int tries, old_v_level, ret = 0;
|
||||
u8 link_status[DP_LINK_STATUS_SIZE];
|
||||
int const maximum_retries = 4;
|
||||
|
||||
delay_us = drm_dp_read_clock_recovery_delay(ctrl->aux,
|
||||
ctrl->panel->dpcd, dp_phy, false);
|
||||
|
||||
msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
|
||||
|
||||
*training_step = DP_TRAINING_1;
|
||||
|
@ -1115,18 +1132,19 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
|
|||
if (ret)
|
||||
return ret;
|
||||
msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 |
|
||||
DP_LINK_SCRAMBLING_DISABLE);
|
||||
DP_LINK_SCRAMBLING_DISABLE, dp_phy);
|
||||
|
||||
ret = msm_dp_ctrl_update_vx_px(ctrl);
|
||||
msm_dp_link_reset_phy_params_vx_px(ctrl->link);
|
||||
ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tries = 0;
|
||||
old_v_level = ctrl->link->phy_params.v_level;
|
||||
for (tries = 0; tries < maximum_retries; tries++) {
|
||||
drm_dp_link_train_clock_recovery_delay(ctrl->aux, ctrl->panel->dpcd);
|
||||
fsleep(delay_us);
|
||||
|
||||
ret = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
|
||||
ret = drm_dp_dpcd_read_phy_link_status(ctrl->aux, dp_phy, link_status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1147,7 +1165,7 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
|
|||
}
|
||||
|
||||
msm_dp_link_adjust_levels(ctrl->link, link_status);
|
||||
ret = msm_dp_ctrl_update_vx_px(ctrl);
|
||||
ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -1199,21 +1217,31 @@ static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl)
|
||||
static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl,
|
||||
enum drm_dp_phy dp_phy)
|
||||
{
|
||||
msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE);
|
||||
drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
|
||||
int delay_us;
|
||||
|
||||
msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE, dp_phy);
|
||||
|
||||
delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
|
||||
ctrl->panel->dpcd, dp_phy, false);
|
||||
fsleep(delay_us);
|
||||
}
|
||||
|
||||
static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
|
||||
int *training_step)
|
||||
int *training_step, enum drm_dp_phy dp_phy)
|
||||
{
|
||||
int delay_us;
|
||||
int tries = 0, ret = 0;
|
||||
u8 pattern;
|
||||
u32 state_ctrl_bit;
|
||||
int const maximum_retries = 5;
|
||||
u8 link_status[DP_LINK_STATUS_SIZE];
|
||||
|
||||
delay_us = drm_dp_read_channel_eq_delay(ctrl->aux,
|
||||
ctrl->panel->dpcd, dp_phy, false);
|
||||
|
||||
msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
|
||||
|
||||
*training_step = DP_TRAINING_2;
|
||||
|
@ -1233,12 +1261,12 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
msm_dp_ctrl_train_pattern_set(ctrl, pattern);
|
||||
msm_dp_ctrl_train_pattern_set(ctrl, pattern, dp_phy);
|
||||
|
||||
for (tries = 0; tries <= maximum_retries; tries++) {
|
||||
drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
|
||||
fsleep(delay_us);
|
||||
|
||||
ret = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
|
||||
ret = drm_dp_dpcd_read_phy_link_status(ctrl->aux, dp_phy, link_status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1248,7 +1276,7 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
|
|||
}
|
||||
|
||||
msm_dp_link_adjust_levels(ctrl->link, link_status);
|
||||
ret = msm_dp_ctrl_update_vx_px(ctrl);
|
||||
ret = msm_dp_ctrl_update_phy_vx_px(ctrl, dp_phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1257,9 +1285,32 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int msm_dp_ctrl_link_train_1_2(struct msm_dp_ctrl_private *ctrl,
|
||||
int *training_step, enum drm_dp_phy dp_phy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = msm_dp_ctrl_link_train_1(ctrl, training_step, dp_phy);
|
||||
if (ret) {
|
||||
DRM_ERROR("link training #1 on phy %d failed. ret=%d\n", dp_phy, ret);
|
||||
return ret;
|
||||
}
|
||||
drm_dbg_dp(ctrl->drm_dev, "link training #1 on phy %d successful\n", dp_phy);
|
||||
|
||||
ret = msm_dp_ctrl_link_train_2(ctrl, training_step, dp_phy);
|
||||
if (ret) {
|
||||
DRM_ERROR("link training #2 on phy %d failed. ret=%d\n", dp_phy, ret);
|
||||
return ret;
|
||||
}
|
||||
drm_dbg_dp(ctrl->drm_dev, "link training #2 on phy %d successful\n", dp_phy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
|
||||
int *training_step)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
const u8 *dpcd = ctrl->panel->dpcd;
|
||||
u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
|
||||
|
@ -1272,8 +1323,6 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
|
|||
link_info.rate = ctrl->link->link_params.rate;
|
||||
link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING;
|
||||
|
||||
msm_dp_link_reset_phy_params_vx_px(ctrl->link);
|
||||
|
||||
msm_dp_aux_link_configure(ctrl->aux, &link_info);
|
||||
|
||||
if (drm_dp_max_downspread(dpcd))
|
||||
|
@ -1288,24 +1337,27 @@ static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
|
|||
&assr, 1);
|
||||
}
|
||||
|
||||
ret = msm_dp_ctrl_link_train_1(ctrl, training_step);
|
||||
for (i = ctrl->link->lttpr_count - 1; i >= 0; i--) {
|
||||
enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i);
|
||||
|
||||
ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, dp_phy);
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl, dp_phy);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
DRM_ERROR("link training #1 failed. ret=%d\n", ret);
|
||||
DRM_ERROR("link training of LTTPR(s) failed. ret=%d\n", ret);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* print success info as this is a result of user initiated action */
|
||||
drm_dbg_dp(ctrl->drm_dev, "link training #1 successful\n");
|
||||
|
||||
ret = msm_dp_ctrl_link_train_2(ctrl, training_step);
|
||||
ret = msm_dp_ctrl_link_train_1_2(ctrl, training_step, DP_PHY_DPRX);
|
||||
if (ret) {
|
||||
DRM_ERROR("link training #2 failed. ret=%d\n", ret);
|
||||
DRM_ERROR("link training on sink failed. ret=%d\n", ret);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* print success info as this is a result of user initiated action */
|
||||
drm_dbg_dp(ctrl->drm_dev, "link training #2 successful\n");
|
||||
|
||||
end:
|
||||
msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
|
||||
|
||||
|
@ -1622,7 +1674,7 @@ static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)
|
|||
if (ret)
|
||||
goto end;
|
||||
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl);
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
|
||||
|
||||
msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
|
||||
|
||||
|
@ -1646,7 +1698,7 @@ static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)
|
|||
return false;
|
||||
}
|
||||
msm_dp_catalog_ctrl_send_phy_pattern(ctrl->catalog, pattern_requested);
|
||||
msm_dp_ctrl_update_vx_px(ctrl);
|
||||
msm_dp_ctrl_update_phy_vx_px(ctrl, DP_PHY_DPRX);
|
||||
msm_dp_link_send_test_response(ctrl->link);
|
||||
|
||||
pattern_sent = msm_dp_catalog_ctrl_read_phy_pattern(ctrl->catalog);
|
||||
|
@ -1888,7 +1940,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
|
|||
}
|
||||
|
||||
/* stop link training before start re training */
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl);
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
|
||||
}
|
||||
|
||||
rc = msm_dp_ctrl_reinitialize_mainlink(ctrl);
|
||||
|
@ -1912,7 +1964,7 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
|
|||
* link training failed
|
||||
* end txing train pattern here
|
||||
*/
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl);
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
|
||||
|
||||
msm_dp_ctrl_deinitialize_mainlink(ctrl);
|
||||
rc = -ECONNRESET;
|
||||
|
@ -1983,7 +2035,7 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train
|
|||
msm_dp_ctrl_link_retrain(ctrl);
|
||||
|
||||
/* stop txing train pattern to end link training */
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl);
|
||||
msm_dp_ctrl_clear_training_pattern(ctrl, DP_PHY_DPRX);
|
||||
|
||||
/*
|
||||
* Set up transfer unit values and set controller state to send
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <drm/display/drm_dp_aux_bus.h>
|
||||
#include <drm/display/drm_hdmi_audio_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
#include "msm_drv.h"
|
||||
|
@ -288,13 +289,6 @@ static int msm_dp_display_bind(struct device *dev, struct device *master,
|
|||
goto end;
|
||||
}
|
||||
|
||||
|
||||
rc = msm_dp_register_audio_driver(dev, dp->audio);
|
||||
if (rc) {
|
||||
DRM_ERROR("Audio registration Dp failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = msm_dp_hpd_event_thread_start(dp);
|
||||
if (rc) {
|
||||
DRM_ERROR("Event thread create failed\n");
|
||||
|
@ -316,7 +310,6 @@ static void msm_dp_display_unbind(struct device *dev, struct device *master,
|
|||
|
||||
of_dp_aux_depopulate_bus(dp->aux);
|
||||
|
||||
msm_dp_unregister_audio_driver(dev, dp->audio);
|
||||
msm_dp_aux_unregister(dp->aux);
|
||||
dp->drm_dev = NULL;
|
||||
dp->aux->drm_dev = NULL;
|
||||
|
@ -367,17 +360,21 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void msm_dp_display_lttpr_init(struct msm_dp_display_private *dp)
|
||||
static int msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd)
|
||||
{
|
||||
u8 lttpr_caps[DP_LTTPR_COMMON_CAP_SIZE];
|
||||
int rc;
|
||||
int rc, lttpr_count;
|
||||
|
||||
if (drm_dp_read_lttpr_common_caps(dp->aux, dp->panel->dpcd, lttpr_caps))
|
||||
return;
|
||||
if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, dp->link->lttpr_common_caps))
|
||||
return 0;
|
||||
|
||||
rc = drm_dp_lttpr_init(dp->aux, drm_dp_lttpr_count(lttpr_caps));
|
||||
if (rc)
|
||||
lttpr_count = drm_dp_lttpr_count(dp->link->lttpr_common_caps);
|
||||
rc = drm_dp_lttpr_init(dp->aux, lttpr_count);
|
||||
if (rc) {
|
||||
DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return lttpr_count;
|
||||
}
|
||||
|
||||
static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
|
||||
|
@ -385,13 +382,18 @@ static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
|
|||
struct drm_connector *connector = dp->msm_dp_display.connector;
|
||||
const struct drm_display_info *info = &connector->display_info;
|
||||
int rc = 0;
|
||||
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
||||
|
||||
rc = drm_dp_read_dpcd_caps(dp->aux, dpcd);
|
||||
if (rc)
|
||||
goto end;
|
||||
|
||||
dp->link->lttpr_count = msm_dp_display_lttpr_init(dp, dpcd);
|
||||
|
||||
rc = msm_dp_panel_read_sink_caps(dp->panel, connector);
|
||||
if (rc)
|
||||
goto end;
|
||||
|
||||
msm_dp_display_lttpr_init(dp);
|
||||
|
||||
msm_dp_link_process_request(dp->link);
|
||||
|
||||
if (!dp->msm_dp_display.is_edp)
|
||||
|
@ -626,9 +628,9 @@ static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,
|
|||
struct msm_dp_display_private, msm_dp_display);
|
||||
|
||||
/* notify audio subsystem only if sink supports audio */
|
||||
if (msm_dp_display->plugged_cb && msm_dp_display->codec_dev &&
|
||||
dp->audio_supported)
|
||||
msm_dp_display->plugged_cb(msm_dp_display->codec_dev, plugged);
|
||||
if (dp->audio_supported)
|
||||
drm_connector_hdmi_audio_plugged_notify(msm_dp_display->connector,
|
||||
plugged);
|
||||
}
|
||||
|
||||
static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data)
|
||||
|
@ -907,19 +909,6 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display,
|
||||
hdmi_codec_plugged_cb fn, struct device *codec_dev)
|
||||
{
|
||||
bool plugged;
|
||||
|
||||
msm_dp_display->plugged_cb = fn;
|
||||
msm_dp_display->codec_dev = codec_dev;
|
||||
plugged = msm_dp_display->link_ready;
|
||||
msm_dp_display_handle_plugged_change(msm_dp_display, plugged);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* msm_dp_bridge_mode_valid - callback to determine if specified mode is valid
|
||||
* @bridge: Pointer to drm bridge structure
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#define _DP_DISPLAY_H_
|
||||
|
||||
#include "dp_panel.h"
|
||||
#include <sound/hdmi-codec.h>
|
||||
#include "disp/msm_disp_snapshot.h"
|
||||
|
||||
#define DP_MAX_PIXEL_CLK_KHZ 675000
|
||||
|
@ -15,7 +14,6 @@
|
|||
struct msm_dp {
|
||||
struct drm_device *drm_dev;
|
||||
struct platform_device *pdev;
|
||||
struct device *codec_dev;
|
||||
struct drm_connector *connector;
|
||||
struct drm_bridge *next_bridge;
|
||||
bool link_ready;
|
||||
|
@ -25,14 +23,10 @@ struct msm_dp {
|
|||
bool is_edp;
|
||||
bool internal_hpd;
|
||||
|
||||
hdmi_codec_plugged_cb plugged_cb;
|
||||
|
||||
struct msm_dp_audio *msm_dp_audio;
|
||||
bool psr_supported;
|
||||
};
|
||||
|
||||
int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display,
|
||||
hdmi_codec_plugged_cb fn, struct device *codec_dev);
|
||||
int msm_dp_display_get_modes(struct msm_dp *msm_dp_display);
|
||||
bool msm_dp_display_check_video_test(struct msm_dp *msm_dp_display);
|
||||
int msm_dp_display_get_test_bpp(struct msm_dp *msm_dp_display);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "msm_drv.h"
|
||||
#include "msm_kms.h"
|
||||
#include "dp_audio.h"
|
||||
#include "dp_drm.h"
|
||||
|
||||
/**
|
||||
|
@ -114,6 +115,9 @@ static const struct drm_bridge_funcs msm_dp_bridge_ops = {
|
|||
.hpd_disable = msm_dp_bridge_hpd_disable,
|
||||
.hpd_notify = msm_dp_bridge_hpd_notify,
|
||||
.debugfs_init = msm_dp_bridge_debugfs_init,
|
||||
|
||||
.dp_audio_prepare = msm_dp_audio_prepare,
|
||||
.dp_audio_shutdown = msm_dp_audio_shutdown,
|
||||
};
|
||||
|
||||
static int msm_edp_bridge_atomic_check(struct drm_bridge *drm_bridge,
|
||||
|
@ -321,9 +325,13 @@ int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
|
|||
*/
|
||||
if (!msm_dp_display->is_edp) {
|
||||
bridge->ops =
|
||||
DRM_BRIDGE_OP_DP_AUDIO |
|
||||
DRM_BRIDGE_OP_DETECT |
|
||||
DRM_BRIDGE_OP_HPD |
|
||||
DRM_BRIDGE_OP_MODES;
|
||||
bridge->hdmi_audio_dev = &msm_dp_display->pdev->dev;
|
||||
bridge->hdmi_audio_max_i2s_playback_channels = 8;
|
||||
bridge->hdmi_audio_dai_port = -1;
|
||||
}
|
||||
|
||||
rc = devm_drm_bridge_add(dev->dev, bridge);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define _DP_LINK_H_
|
||||
|
||||
#include "dp_aux.h"
|
||||
#include <drm/display/drm_dp_helper.h>
|
||||
|
||||
#define DS_PORT_STATUS_CHANGED 0x200
|
||||
#define DP_TEST_BIT_DEPTH_UNKNOWN 0xFFFFFFFF
|
||||
|
@ -60,6 +61,9 @@ struct msm_dp_link_phy_params {
|
|||
};
|
||||
|
||||
struct msm_dp_link {
|
||||
u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
|
||||
int lttpr_count;
|
||||
|
||||
u32 sink_request;
|
||||
u32 test_response;
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel)
|
|||
|
||||
static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
|
||||
{
|
||||
int rc;
|
||||
int rc, max_lttpr_lanes, max_lttpr_rate;
|
||||
struct msm_dp_panel_private *panel;
|
||||
struct msm_dp_link_info *link_info;
|
||||
u8 *dpcd, major, minor;
|
||||
|
@ -75,6 +75,16 @@ static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
|
|||
if (link_info->rate > msm_dp_panel->max_dp_link_rate)
|
||||
link_info->rate = msm_dp_panel->max_dp_link_rate;
|
||||
|
||||
/* Limit data lanes from LTTPR capabilities, if any */
|
||||
max_lttpr_lanes = drm_dp_lttpr_max_lane_count(panel->link->lttpr_common_caps);
|
||||
if (max_lttpr_lanes && max_lttpr_lanes < link_info->num_lanes)
|
||||
link_info->num_lanes = max_lttpr_lanes;
|
||||
|
||||
/* Limit link rate from LTTPR capabilities, if any */
|
||||
max_lttpr_rate = drm_dp_lttpr_max_link_rate(panel->link->lttpr_common_caps);
|
||||
if (max_lttpr_rate && max_lttpr_rate < link_info->rate)
|
||||
link_info->rate = max_lttpr_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);
|
||||
drm_dbg_dp(panel->drm_dev, "lane_count=%d\n", link_info->num_lanes);
|
||||
|
|
|
@ -221,6 +221,22 @@ static const struct msm_dsi_config sc7280_dsi_cfg = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data sa8775p_dsi_regulators[] = {
|
||||
{ .supply = "vdda", .init_load_uA = 8300 }, /* 1.2 V */
|
||||
{ .supply = "refgen" },
|
||||
};
|
||||
|
||||
static const struct msm_dsi_config sa8775p_dsi_cfg = {
|
||||
.io_offset = DSI_6G_REG_SHIFT,
|
||||
.regulator_data = sa8775p_dsi_regulators,
|
||||
.num_regulators = ARRAY_SIZE(sa8775p_dsi_regulators),
|
||||
.bus_clk_names = dsi_v2_4_clk_names,
|
||||
.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
|
||||
.io_start = {
|
||||
{ 0xae94000, 0xae96000 },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
|
||||
.link_clk_set_rate = dsi_link_clk_set_rate_v2,
|
||||
.link_clk_enable = dsi_link_clk_enable_v2,
|
||||
|
@ -294,6 +310,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
|
|||
&sdm845_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_5_1,
|
||||
&sa8775p_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,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#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_5_1 0x20050001
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_6_0 0x20060000
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_7_0 0x20070000
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_8_0 0x20080000
|
||||
|
|
|
@ -581,6 +581,10 @@ static const struct of_device_id dsi_phy_dt_match[] = {
|
|||
.data = &dsi_phy_7nm_cfgs },
|
||||
{ .compatible = "qcom,dsi-phy-7nm-8150",
|
||||
.data = &dsi_phy_7nm_8150_cfgs },
|
||||
{ .compatible = "qcom,sa8775p-dsi-phy-5nm",
|
||||
.data = &dsi_phy_5nm_8775p_cfgs },
|
||||
{ .compatible = "qcom,sar2130p-dsi-phy-5nm",
|
||||
.data = &dsi_phy_5nm_sar2130p_cfgs },
|
||||
{ .compatible = "qcom,sc7280-dsi-phy-7nm",
|
||||
.data = &dsi_phy_7nm_7280_cfgs },
|
||||
{ .compatible = "qcom,sm6375-dsi-phy-7nm",
|
||||
|
|
|
@ -59,6 +59,8 @@ 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_5nm_8775p_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_5nm_sar2130p_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs;
|
||||
|
||||
|
|
|
@ -1147,6 +1147,10 @@ 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_48000uA_regulators[] = {
|
||||
{ .supply = "vdds", .init_load_uA = 48000 },
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data dsi_phy_7nm_98000uA_regulators[] = {
|
||||
{ .supply = "vdds", .init_load_uA = 98000 },
|
||||
};
|
||||
|
@ -1289,6 +1293,52 @@ const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs = {
|
|||
.quirks = DSI_PHY_7NM_QUIRK_V4_3,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_5nm_8775p_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_7nm_48000uA_regulators,
|
||||
.num_regulators = ARRAY_SIZE(dsi_phy_7nm_48000uA_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_sar2130p_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 = { 0xae95000, 0xae97000 },
|
||||
.num_dsi_phy = 2,
|
||||
.quirks = DSI_PHY_7NM_QUIRK_V5_2,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_7nm_98400uA_regulators,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <drm/drm_bridge_connector.h>
|
||||
|
@ -199,12 +200,6 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
ret = msm_hdmi_hpd_enable(hdmi->bridge);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
@ -220,28 +215,24 @@ fail:
|
|||
* The hdmi device:
|
||||
*/
|
||||
|
||||
#define HDMI_CFG(item, entry) \
|
||||
.item ## _names = item ##_names_ ## entry, \
|
||||
.item ## _cnt = ARRAY_SIZE(item ## _names_ ## entry)
|
||||
|
||||
static const char *hpd_reg_names_8960[] = {"core-vdda"};
|
||||
static const char *hpd_clk_names_8960[] = {"core", "master_iface", "slave_iface"};
|
||||
static const char * const pwr_reg_names_8960[] = {"core-vdda"};
|
||||
static const char * const pwr_clk_names_8960[] = {"core", "master_iface", "slave_iface"};
|
||||
|
||||
static const struct hdmi_platform_config hdmi_tx_8960_config = {
|
||||
HDMI_CFG(hpd_reg, 8960),
|
||||
HDMI_CFG(hpd_clk, 8960),
|
||||
.pwr_reg_names = pwr_reg_names_8960,
|
||||
.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names_8960),
|
||||
.pwr_clk_names = pwr_clk_names_8960,
|
||||
.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names_8960),
|
||||
};
|
||||
|
||||
static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
|
||||
static const char *pwr_clk_names_8x74[] = {"extp", "alt_iface"};
|
||||
static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core"};
|
||||
static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0};
|
||||
static const char * const pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
|
||||
static const char * const pwr_clk_names_8x74[] = {"iface", "core", "mdp_core", "alt_iface"};
|
||||
|
||||
static const struct hdmi_platform_config hdmi_tx_8974_config = {
|
||||
HDMI_CFG(pwr_reg, 8x74),
|
||||
HDMI_CFG(pwr_clk, 8x74),
|
||||
HDMI_CFG(hpd_clk, 8x74),
|
||||
.hpd_freq = hpd_clk_freq_8x74,
|
||||
.pwr_reg_names = pwr_reg_names_8x74,
|
||||
.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names_8x74),
|
||||
.pwr_clk_names = pwr_clk_names_8x74,
|
||||
.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names_8x74),
|
||||
};
|
||||
|
||||
static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
|
||||
|
@ -264,9 +255,6 @@ static void msm_hdmi_unbind(struct device *dev, struct device *master,
|
|||
struct msm_drm_private *priv = dev_get_drvdata(master);
|
||||
|
||||
if (priv->hdmi) {
|
||||
if (priv->hdmi->bridge)
|
||||
msm_hdmi_hpd_disable(priv->hdmi);
|
||||
|
||||
msm_hdmi_destroy(priv->hdmi);
|
||||
priv->hdmi = NULL;
|
||||
}
|
||||
|
@ -296,6 +284,7 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
|
|||
hdmi->pdev = pdev;
|
||||
hdmi->config = config;
|
||||
spin_lock_init(&hdmi->reg_lock);
|
||||
mutex_init(&hdmi->state_mutex);
|
||||
|
||||
ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, 1, 0, NULL, &hdmi->next_bridge);
|
||||
if (ret && ret != -ENODEV)
|
||||
|
@ -322,20 +311,6 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
|
|||
if (hdmi->irq < 0)
|
||||
return hdmi->irq;
|
||||
|
||||
hdmi->hpd_regs = devm_kcalloc(&pdev->dev,
|
||||
config->hpd_reg_cnt,
|
||||
sizeof(hdmi->hpd_regs[0]),
|
||||
GFP_KERNEL);
|
||||
if (!hdmi->hpd_regs)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < config->hpd_reg_cnt; i++)
|
||||
hdmi->hpd_regs[i].supply = config->hpd_reg_names[i];
|
||||
|
||||
ret = devm_regulator_bulk_get(&pdev->dev, config->hpd_reg_cnt, hdmi->hpd_regs);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to get hpd regulators\n");
|
||||
|
||||
hdmi->pwr_regs = devm_kcalloc(&pdev->dev,
|
||||
config->pwr_reg_cnt,
|
||||
sizeof(hdmi->pwr_regs[0]),
|
||||
|
@ -350,25 +325,6 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to get pwr regulators\n");
|
||||
|
||||
hdmi->hpd_clks = devm_kcalloc(&pdev->dev,
|
||||
config->hpd_clk_cnt,
|
||||
sizeof(hdmi->hpd_clks[0]),
|
||||
GFP_KERNEL);
|
||||
if (!hdmi->hpd_clks)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < config->hpd_clk_cnt; i++) {
|
||||
struct clk *clk;
|
||||
|
||||
clk = msm_clk_get(pdev, config->hpd_clk_names[i]);
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(dev, PTR_ERR(clk),
|
||||
"failed to get hpd clk: %s\n",
|
||||
config->hpd_clk_names[i]);
|
||||
|
||||
hdmi->hpd_clks[i] = clk;
|
||||
}
|
||||
|
||||
hdmi->pwr_clks = devm_kcalloc(&pdev->dev,
|
||||
config->pwr_clk_cnt,
|
||||
sizeof(hdmi->pwr_clks[0]),
|
||||
|
@ -376,17 +332,17 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
|
|||
if (!hdmi->pwr_clks)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < config->pwr_clk_cnt; i++) {
|
||||
struct clk *clk;
|
||||
for (i = 0; i < config->pwr_clk_cnt; i++)
|
||||
hdmi->pwr_clks[i].id = config->pwr_clk_names[i];
|
||||
|
||||
clk = msm_clk_get(pdev, config->pwr_clk_names[i]);
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(dev, PTR_ERR(clk),
|
||||
"failed to get pwr clk: %s\n",
|
||||
config->pwr_clk_names[i]);
|
||||
ret = devm_clk_bulk_get(&pdev->dev, config->pwr_clk_cnt, hdmi->pwr_clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hdmi->pwr_clks[i] = clk;
|
||||
}
|
||||
hdmi->extp_clk = devm_clk_get_optional(&pdev->dev, "extp");
|
||||
if (IS_ERR(hdmi->extp_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(hdmi->extp_clk),
|
||||
"failed to get extp clock\n");
|
||||
|
||||
hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
|
||||
/* This will catch e.g. -EPROBE_DEFER */
|
||||
|
@ -432,6 +388,48 @@ static void msm_hdmi_dev_remove(struct platform_device *pdev)
|
|||
msm_hdmi_put_phy(hdmi);
|
||||
}
|
||||
|
||||
static int msm_hdmi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct hdmi *hdmi = dev_get_drvdata(dev);
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
|
||||
clk_bulk_disable_unprepare(config->pwr_clk_cnt, hdmi->pwr_clks);
|
||||
|
||||
pinctrl_pm_select_sleep_state(dev);
|
||||
|
||||
regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_hdmi_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct hdmi *hdmi = dev_get_drvdata(dev);
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
int ret;
|
||||
|
||||
ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pinctrl_pm_select_default_state(dev);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = clk_bulk_prepare_enable(config->pwr_clk_cnt, hdmi->pwr_clks);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
pinctrl_pm_select_sleep_state(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_RUNTIME_DEV_PM_OPS(msm_hdmi_pm_ops, msm_hdmi_runtime_suspend, msm_hdmi_runtime_resume, NULL);
|
||||
|
||||
static const struct of_device_id msm_hdmi_dt_match[] = {
|
||||
{ .compatible = "qcom,hdmi-tx-8998", .data = &hdmi_tx_8974_config },
|
||||
{ .compatible = "qcom,hdmi-tx-8996", .data = &hdmi_tx_8974_config },
|
||||
|
@ -449,6 +447,7 @@ static struct platform_driver msm_hdmi_driver = {
|
|||
.driver = {
|
||||
.name = "hdmi_msm",
|
||||
.of_match_table = msm_hdmi_dt_match,
|
||||
.pm = &msm_hdmi_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -41,16 +41,17 @@ struct hdmi {
|
|||
|
||||
/* video state: */
|
||||
bool power_on;
|
||||
bool hpd_enabled;
|
||||
struct mutex state_mutex; /* protects two booleans */
|
||||
unsigned long int pixclock;
|
||||
|
||||
void __iomem *mmio;
|
||||
void __iomem *qfprom_mmio;
|
||||
phys_addr_t mmio_phy_addr;
|
||||
|
||||
struct regulator_bulk_data *hpd_regs;
|
||||
struct regulator_bulk_data *pwr_regs;
|
||||
struct clk **hpd_clks;
|
||||
struct clk **pwr_clks;
|
||||
struct clk_bulk_data *pwr_clks;
|
||||
struct clk *extp_clk;
|
||||
|
||||
struct gpio_desc *hpd_gpiod;
|
||||
|
||||
|
@ -83,21 +84,12 @@ struct hdmi {
|
|||
|
||||
/* platform config data (ie. from DT, or pdata) */
|
||||
struct hdmi_platform_config {
|
||||
/* regulators that need to be on for hpd: */
|
||||
const char **hpd_reg_names;
|
||||
int hpd_reg_cnt;
|
||||
|
||||
/* regulators that need to be on for screen pwr: */
|
||||
const char **pwr_reg_names;
|
||||
const char * const *pwr_reg_names;
|
||||
int pwr_reg_cnt;
|
||||
|
||||
/* clks that need to be on for hpd: */
|
||||
const char **hpd_clk_names;
|
||||
const long unsigned *hpd_freq;
|
||||
int hpd_clk_cnt;
|
||||
|
||||
/* clks that need to be on for screen pwr (ie pixel clk): */
|
||||
const char **pwr_clk_names;
|
||||
/* clks that need to be on: */
|
||||
const char * const *pwr_clk_names;
|
||||
int pwr_clk_cnt;
|
||||
};
|
||||
|
||||
|
@ -224,8 +216,8 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi);
|
|||
void msm_hdmi_hpd_irq(struct drm_bridge *bridge);
|
||||
enum drm_connector_status msm_hdmi_bridge_detect(
|
||||
struct drm_bridge *bridge);
|
||||
int msm_hdmi_hpd_enable(struct drm_bridge *bridge);
|
||||
void msm_hdmi_hpd_disable(struct hdmi *hdmi);
|
||||
void msm_hdmi_hpd_enable(struct drm_bridge *bridge);
|
||||
void msm_hdmi_hpd_disable(struct drm_bridge *bridge);
|
||||
|
||||
/*
|
||||
* i2c adapter for ddc:
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Author: Rob Clark <robdclark@gmail.com>
|
||||
*/
|
||||
|
||||
#include <drm/display/drm_hdmi_helper.h>
|
||||
#include <drm/display/drm_hdmi_state_helper.h>
|
||||
|
||||
#include <linux/hdmi.h>
|
||||
|
@ -12,71 +13,9 @@
|
|||
|
||||
#include "hdmi.h"
|
||||
|
||||
/* Supported HDMI Audio sample rates */
|
||||
#define MSM_HDMI_SAMPLE_RATE_32KHZ 0
|
||||
#define MSM_HDMI_SAMPLE_RATE_44_1KHZ 1
|
||||
#define MSM_HDMI_SAMPLE_RATE_48KHZ 2
|
||||
#define MSM_HDMI_SAMPLE_RATE_88_2KHZ 3
|
||||
#define MSM_HDMI_SAMPLE_RATE_96KHZ 4
|
||||
#define MSM_HDMI_SAMPLE_RATE_176_4KHZ 5
|
||||
#define MSM_HDMI_SAMPLE_RATE_192KHZ 6
|
||||
#define MSM_HDMI_SAMPLE_RATE_MAX 7
|
||||
|
||||
|
||||
struct hdmi_msm_audio_acr {
|
||||
uint32_t n; /* N parameter for clock regeneration */
|
||||
uint32_t cts; /* CTS parameter for clock regeneration */
|
||||
};
|
||||
|
||||
struct hdmi_msm_audio_arcs {
|
||||
unsigned long int pixclock;
|
||||
struct hdmi_msm_audio_acr lut[MSM_HDMI_SAMPLE_RATE_MAX];
|
||||
};
|
||||
|
||||
#define HDMI_MSM_AUDIO_ARCS(pclk, ...) { (1000 * (pclk)), __VA_ARGS__ }
|
||||
|
||||
/* Audio constants lookup table for hdmi_msm_audio_acr_setup */
|
||||
/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
|
||||
static const struct hdmi_msm_audio_arcs acr_lut[] = {
|
||||
/* 25.200MHz */
|
||||
HDMI_MSM_AUDIO_ARCS(25200, {
|
||||
{4096, 25200}, {6272, 28000}, {6144, 25200}, {12544, 28000},
|
||||
{12288, 25200}, {25088, 28000}, {24576, 25200} }),
|
||||
/* 27.000MHz */
|
||||
HDMI_MSM_AUDIO_ARCS(27000, {
|
||||
{4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
|
||||
{12288, 27000}, {25088, 30000}, {24576, 27000} }),
|
||||
/* 27.027MHz */
|
||||
HDMI_MSM_AUDIO_ARCS(27030, {
|
||||
{4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030},
|
||||
{12288, 27027}, {25088, 30030}, {24576, 27027} }),
|
||||
/* 74.250MHz */
|
||||
HDMI_MSM_AUDIO_ARCS(74250, {
|
||||
{4096, 74250}, {6272, 82500}, {6144, 74250}, {12544, 82500},
|
||||
{12288, 74250}, {25088, 82500}, {24576, 74250} }),
|
||||
/* 148.500MHz */
|
||||
HDMI_MSM_AUDIO_ARCS(148500, {
|
||||
{4096, 148500}, {6272, 165000}, {6144, 148500}, {12544, 165000},
|
||||
{12288, 148500}, {25088, 165000}, {24576, 148500} }),
|
||||
};
|
||||
|
||||
static const struct hdmi_msm_audio_arcs *get_arcs(unsigned long int pixclock)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(acr_lut); i++) {
|
||||
const struct hdmi_msm_audio_arcs *arcs = &acr_lut[i];
|
||||
if (arcs->pixclock == pixclock)
|
||||
return arcs;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int msm_hdmi_audio_update(struct hdmi *hdmi)
|
||||
{
|
||||
struct hdmi_audio *audio = &hdmi->audio;
|
||||
const struct hdmi_msm_audio_arcs *arcs = NULL;
|
||||
bool enabled = audio->enabled;
|
||||
uint32_t acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl;
|
||||
uint32_t audio_config;
|
||||
|
@ -94,15 +33,6 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
|
|||
enabled = false;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
arcs = get_arcs(hdmi->pixclock);
|
||||
if (!arcs) {
|
||||
DBG("disabling audio: unsupported pixclock: %lu",
|
||||
hdmi->pixclock);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read first before writing */
|
||||
acr_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_ACR_PKT_CTRL);
|
||||
vbi_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_VBI_PKT_CTRL);
|
||||
|
@ -116,15 +46,12 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
|
|||
uint32_t n, cts, multiplier;
|
||||
enum hdmi_acr_cts select;
|
||||
|
||||
n = arcs->lut[audio->rate].n;
|
||||
cts = arcs->lut[audio->rate].cts;
|
||||
drm_hdmi_acr_get_n_cts(hdmi->pixclock, audio->rate, &n, &cts);
|
||||
|
||||
if ((MSM_HDMI_SAMPLE_RATE_192KHZ == audio->rate) ||
|
||||
(MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio->rate)) {
|
||||
if (audio->rate == 192000 || audio->rate == 176400) {
|
||||
multiplier = 4;
|
||||
n >>= 2; /* divide N by 4 and use multiplier */
|
||||
} else if ((MSM_HDMI_SAMPLE_RATE_96KHZ == audio->rate) ||
|
||||
(MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio->rate)) {
|
||||
} else if (audio->rate == 96000 || audio->rate == 88200) {
|
||||
multiplier = 2;
|
||||
n >>= 1; /* divide N by 2 and use multiplier */
|
||||
} else {
|
||||
|
@ -137,13 +64,11 @@ int msm_hdmi_audio_update(struct hdmi *hdmi)
|
|||
acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_AUDIO_PRIORITY;
|
||||
acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_N_MULTIPLIER(multiplier);
|
||||
|
||||
if ((MSM_HDMI_SAMPLE_RATE_48KHZ == audio->rate) ||
|
||||
(MSM_HDMI_SAMPLE_RATE_96KHZ == audio->rate) ||
|
||||
(MSM_HDMI_SAMPLE_RATE_192KHZ == audio->rate))
|
||||
if (audio->rate == 48000 || audio->rate == 96000 ||
|
||||
audio->rate == 192000)
|
||||
select = ACR_48;
|
||||
else if ((MSM_HDMI_SAMPLE_RATE_44_1KHZ == audio->rate) ||
|
||||
(MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio->rate) ||
|
||||
(MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio->rate))
|
||||
else if (audio->rate == 44100 || audio->rate == 88200 ||
|
||||
audio->rate == 176400)
|
||||
select = ACR_44;
|
||||
else /* default to 32k */
|
||||
select = ACR_32;
|
||||
|
@ -204,7 +129,6 @@ int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,
|
|||
{
|
||||
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
|
||||
struct hdmi *hdmi = hdmi_bridge->hdmi;
|
||||
unsigned int rate;
|
||||
int ret;
|
||||
|
||||
drm_dbg_driver(bridge->dev, "%u Hz, %d bit, %d channels\n",
|
||||
|
@ -214,25 +138,12 @@ int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,
|
|||
|
||||
switch (params->sample_rate) {
|
||||
case 32000:
|
||||
rate = MSM_HDMI_SAMPLE_RATE_32KHZ;
|
||||
break;
|
||||
case 44100:
|
||||
rate = MSM_HDMI_SAMPLE_RATE_44_1KHZ;
|
||||
break;
|
||||
case 48000:
|
||||
rate = MSM_HDMI_SAMPLE_RATE_48KHZ;
|
||||
break;
|
||||
case 88200:
|
||||
rate = MSM_HDMI_SAMPLE_RATE_88_2KHZ;
|
||||
break;
|
||||
case 96000:
|
||||
rate = MSM_HDMI_SAMPLE_RATE_96KHZ;
|
||||
break;
|
||||
case 176400:
|
||||
rate = MSM_HDMI_SAMPLE_RATE_176_4KHZ;
|
||||
break;
|
||||
case 192000:
|
||||
rate = MSM_HDMI_SAMPLE_RATE_192KHZ;
|
||||
break;
|
||||
default:
|
||||
drm_err(bridge->dev, "rate[%d] not supported!\n",
|
||||
|
@ -245,7 +156,7 @@ int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
hdmi->audio.rate = rate;
|
||||
hdmi->audio.rate = params->sample_rate;
|
||||
hdmi->audio.channels = params->cea.channels;
|
||||
hdmi->audio.enabled = true;
|
||||
|
||||
|
|
|
@ -18,52 +18,34 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge)
|
|||
struct drm_device *dev = bridge->dev;
|
||||
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
|
||||
struct hdmi *hdmi = hdmi_bridge->hdmi;
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
int i, ret;
|
||||
int ret;
|
||||
|
||||
pm_runtime_get_sync(&hdmi->pdev->dev);
|
||||
pm_runtime_resume_and_get(&hdmi->pdev->dev);
|
||||
|
||||
ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs);
|
||||
if (ret)
|
||||
DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %d\n", ret);
|
||||
|
||||
if (config->pwr_clk_cnt > 0) {
|
||||
if (hdmi->extp_clk) {
|
||||
DBG("pixclock: %lu", hdmi->pixclock);
|
||||
ret = clk_set_rate(hdmi->pwr_clks[0], hdmi->pixclock);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to set pixel clk: %s (%d)\n",
|
||||
config->pwr_clk_names[0], ret);
|
||||
}
|
||||
}
|
||||
ret = clk_set_rate(hdmi->extp_clk, hdmi->pixclock);
|
||||
if (ret)
|
||||
DRM_DEV_ERROR(dev->dev, "failed to set extp clk rate: %d\n", ret);
|
||||
|
||||
for (i = 0; i < config->pwr_clk_cnt; i++) {
|
||||
ret = clk_prepare_enable(hdmi->pwr_clks[i]);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev->dev, "failed to enable pwr clk: %s (%d)\n",
|
||||
config->pwr_clk_names[i], ret);
|
||||
}
|
||||
ret = clk_prepare_enable(hdmi->extp_clk);
|
||||
if (ret)
|
||||
DRM_DEV_ERROR(dev->dev, "failed to enable extp clk: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void power_off(struct drm_bridge *bridge)
|
||||
{
|
||||
struct drm_device *dev = bridge->dev;
|
||||
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
|
||||
struct hdmi *hdmi = hdmi_bridge->hdmi;
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
int i, ret;
|
||||
|
||||
/* TODO do we need to wait for final vblank somewhere before
|
||||
* cutting the clocks?
|
||||
*/
|
||||
mdelay(16 + 4);
|
||||
|
||||
for (i = 0; i < config->pwr_clk_cnt; i++)
|
||||
clk_disable_unprepare(hdmi->pwr_clks[i]);
|
||||
|
||||
ret = regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs);
|
||||
if (ret)
|
||||
DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %d\n", ret);
|
||||
if (hdmi->extp_clk)
|
||||
clk_disable_unprepare(hdmi->extp_clk);
|
||||
|
||||
pm_runtime_put(&hdmi->pdev->dev);
|
||||
}
|
||||
|
@ -320,13 +302,16 @@ static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
|
|||
|
||||
msm_hdmi_set_timings(hdmi, &crtc_state->adjusted_mode);
|
||||
|
||||
mutex_lock(&hdmi->state_mutex);
|
||||
if (!hdmi->power_on) {
|
||||
msm_hdmi_phy_resource_enable(phy);
|
||||
msm_hdmi_power_on(bridge);
|
||||
hdmi->power_on = true;
|
||||
if (connector->display_info.is_hdmi)
|
||||
msm_hdmi_audio_update(hdmi);
|
||||
}
|
||||
mutex_unlock(&hdmi->state_mutex);
|
||||
|
||||
if (connector->display_info.is_hdmi)
|
||||
msm_hdmi_audio_update(hdmi);
|
||||
|
||||
drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
|
||||
|
||||
|
@ -349,7 +334,10 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
|
|||
msm_hdmi_hdcp_off(hdmi->hdcp_ctrl);
|
||||
|
||||
DBG("power down");
|
||||
msm_hdmi_set_mode(hdmi, false);
|
||||
|
||||
/* Keep the HDMI enabled if the HPD is enabled */
|
||||
mutex_lock(&hdmi->state_mutex);
|
||||
msm_hdmi_set_mode(hdmi, hdmi->hpd_enabled);
|
||||
|
||||
msm_hdmi_phy_powerdown(phy);
|
||||
|
||||
|
@ -360,6 +348,7 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
|
|||
msm_hdmi_audio_update(hdmi);
|
||||
msm_hdmi_phy_resource_disable(phy);
|
||||
}
|
||||
mutex_unlock(&hdmi->state_mutex);
|
||||
}
|
||||
|
||||
static void msm_hdmi_set_timings(struct hdmi *hdmi,
|
||||
|
@ -411,9 +400,6 @@ static void msm_hdmi_set_timings(struct hdmi *hdmi,
|
|||
frame_ctrl |= HDMI_FRAME_CTRL_INTERLACED_EN;
|
||||
DBG("frame_ctrl=%08x", frame_ctrl);
|
||||
hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl);
|
||||
|
||||
if (hdmi->connector->display_info.is_hdmi)
|
||||
msm_hdmi_audio_update(hdmi);
|
||||
}
|
||||
|
||||
static const struct drm_edid *msm_hdmi_bridge_edid_read(struct drm_bridge *bridge,
|
||||
|
@ -440,7 +426,6 @@ static enum drm_mode_status msm_hdmi_bridge_tmds_char_rate_valid(const struct dr
|
|||
{
|
||||
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
|
||||
struct hdmi *hdmi = hdmi_bridge->hdmi;
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
struct msm_drm_private *priv = bridge->dev->dev_private;
|
||||
struct msm_kms *kms = priv->kms;
|
||||
long actual;
|
||||
|
@ -453,8 +438,8 @@ static enum drm_mode_status msm_hdmi_bridge_tmds_char_rate_valid(const struct dr
|
|||
actual = kms->funcs->round_pixclk(kms,
|
||||
tmds_rate,
|
||||
hdmi_bridge->hdmi->encoder);
|
||||
else if (config->pwr_clk_cnt > 0)
|
||||
actual = clk_round_rate(hdmi->pwr_clks[0], tmds_rate);
|
||||
else if (hdmi->extp_clk)
|
||||
actual = clk_round_rate(hdmi->extp_clk, tmds_rate);
|
||||
else
|
||||
actual = tmds_rate;
|
||||
|
||||
|
@ -474,6 +459,8 @@ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
|
|||
.atomic_post_disable = msm_hdmi_bridge_atomic_post_disable,
|
||||
.edid_read = msm_hdmi_bridge_edid_read,
|
||||
.detect = msm_hdmi_bridge_detect,
|
||||
.hpd_enable = msm_hdmi_hpd_enable,
|
||||
.hpd_disable = msm_hdmi_hpd_disable,
|
||||
.hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid,
|
||||
.hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe,
|
||||
.hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe,
|
||||
|
|
|
@ -60,68 +60,30 @@ static void msm_hdmi_phy_reset(struct hdmi *hdmi)
|
|||
}
|
||||
}
|
||||
|
||||
static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
|
||||
{
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
struct device *dev = &hdmi->pdev->dev;
|
||||
int i, ret;
|
||||
|
||||
if (enable) {
|
||||
for (i = 0; i < config->hpd_clk_cnt; i++) {
|
||||
if (config->hpd_freq && config->hpd_freq[i]) {
|
||||
ret = clk_set_rate(hdmi->hpd_clks[i],
|
||||
config->hpd_freq[i]);
|
||||
if (ret)
|
||||
dev_warn(dev,
|
||||
"failed to set clk %s (%d)\n",
|
||||
config->hpd_clk_names[i], ret);
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(hdmi->hpd_clks[i]);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev,
|
||||
"failed to enable hpd clk: %s (%d)\n",
|
||||
config->hpd_clk_names[i], ret);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
|
||||
clk_disable_unprepare(hdmi->hpd_clks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
|
||||
void msm_hdmi_hpd_enable(struct drm_bridge *bridge)
|
||||
{
|
||||
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
|
||||
struct hdmi *hdmi = hdmi_bridge->hdmi;
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
struct device *dev = &hdmi->pdev->dev;
|
||||
uint32_t hpd_ctrl;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
ret = regulator_bulk_enable(config->hpd_reg_cnt, hdmi->hpd_regs);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev, "failed to enable hpd regulators: %d\n", ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = pinctrl_pm_select_default_state(dev);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev, "pinctrl state chg failed: %d\n", ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hdmi->hpd_gpiod)
|
||||
gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1);
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
enable_hpd_clocks(hdmi, true);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (WARN_ON(ret))
|
||||
return;
|
||||
|
||||
mutex_lock(&hdmi->state_mutex);
|
||||
msm_hdmi_set_mode(hdmi, false);
|
||||
msm_hdmi_phy_reset(hdmi);
|
||||
msm_hdmi_set_mode(hdmi, true);
|
||||
|
||||
hdmi->hpd_enabled = true;
|
||||
mutex_unlock(&hdmi->state_mutex);
|
||||
|
||||
hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);
|
||||
|
||||
/* enable HPD events: */
|
||||
|
@ -140,34 +102,23 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
|
|||
hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
|
||||
HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
|
||||
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void msm_hdmi_hpd_disable(struct hdmi *hdmi)
|
||||
void msm_hdmi_hpd_disable(struct drm_bridge *bridge)
|
||||
{
|
||||
const struct hdmi_platform_config *config = hdmi->config;
|
||||
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
|
||||
struct hdmi *hdmi = hdmi_bridge->hdmi;
|
||||
struct device *dev = &hdmi->pdev->dev;
|
||||
int ret;
|
||||
|
||||
/* Disable HPD interrupt */
|
||||
hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);
|
||||
|
||||
msm_hdmi_set_mode(hdmi, false);
|
||||
mutex_lock(&hdmi->state_mutex);
|
||||
hdmi->hpd_enabled = false;
|
||||
msm_hdmi_set_mode(hdmi, hdmi->power_on);
|
||||
mutex_unlock(&hdmi->state_mutex);
|
||||
|
||||
enable_hpd_clocks(hdmi, false);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
ret = pinctrl_pm_select_sleep_state(dev);
|
||||
if (ret)
|
||||
dev_warn(dev, "pinctrl state chg failed: %d\n", ret);
|
||||
|
||||
ret = regulator_bulk_disable(config->hpd_reg_cnt, hdmi->hpd_regs);
|
||||
if (ret)
|
||||
dev_warn(dev, "failed to disable hpd regulator: %d\n", ret);
|
||||
}
|
||||
|
||||
void msm_hdmi_hpd_irq(struct drm_bridge *bridge)
|
||||
|
@ -202,14 +153,16 @@ void msm_hdmi_hpd_irq(struct drm_bridge *bridge)
|
|||
|
||||
static enum drm_connector_status detect_reg(struct hdmi *hdmi)
|
||||
{
|
||||
uint32_t hpd_int_status;
|
||||
u32 hpd_int_status = 0;
|
||||
int ret;
|
||||
|
||||
pm_runtime_get_sync(&hdmi->pdev->dev);
|
||||
enable_hpd_clocks(hdmi, true);
|
||||
ret = pm_runtime_resume_and_get(&hdmi->pdev->dev);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
|
||||
|
||||
enable_hpd_clocks(hdmi, false);
|
||||
out:
|
||||
pm_runtime_put(&hdmi->pdev->dev);
|
||||
|
||||
return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
|
||||
|
|
|
@ -107,11 +107,15 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,
|
|||
if (num == 0)
|
||||
return num;
|
||||
|
||||
ret = pm_runtime_resume_and_get(&hdmi->pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
init_ddc(hdmi_i2c);
|
||||
|
||||
ret = ddc_clear_irq(hdmi_i2c);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
struct i2c_msg *p = &msgs[i];
|
||||
|
@ -169,7 +173,7 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,
|
|||
hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS),
|
||||
hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS),
|
||||
hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL));
|
||||
return ret;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ddc_status = hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS);
|
||||
|
@ -202,7 +206,13 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,
|
|||
}
|
||||
}
|
||||
|
||||
pm_runtime_put(&hdmi->pdev->dev);
|
||||
|
||||
return i;
|
||||
|
||||
fail:
|
||||
pm_runtime_put(&hdmi->pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 msm_hdmi_i2c_func(struct i2c_adapter *adapter)
|
||||
|
|
|
@ -58,7 +58,11 @@ int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy)
|
|||
struct device *dev = &phy->pdev->dev;
|
||||
int i, ret = 0;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dev, "runtime resume failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regulator_bulk_enable(cfg->num_regs, phy->regs);
|
||||
if (ret) {
|
||||
|
|
|
@ -156,6 +156,7 @@ void msm_devfreq_init(struct msm_gpu *gpu)
|
|||
priv->gpu_devfreq_config.downdifferential = 10;
|
||||
|
||||
mutex_init(&df->lock);
|
||||
df->suspended = true;
|
||||
|
||||
ret = dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
|
||||
DEV_PM_QOS_MIN_FREQUENCY, 0);
|
||||
|
|
|
@ -592,6 +592,16 @@ static const struct msm_mdss_data sa8775p_data = {
|
|||
.reg_bus_bw = 74000,
|
||||
};
|
||||
|
||||
static const struct msm_mdss_data sar2130p_data = {
|
||||
.ubwc_enc_version = UBWC_3_0, /* 4.0.2 in hw */
|
||||
.ubwc_dec_version = UBWC_4_3,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_bank_spread = true,
|
||||
.highest_bank_bit = 0,
|
||||
.macrotile_mode = 1,
|
||||
.reg_bus_bw = 74000,
|
||||
};
|
||||
|
||||
static const struct msm_mdss_data sc7180_data = {
|
||||
.ubwc_enc_version = UBWC_2_0,
|
||||
.ubwc_dec_version = UBWC_2_0,
|
||||
|
@ -738,6 +748,7 @@ static const struct of_device_id mdss_dt_match[] = {
|
|||
{ .compatible = "qcom,msm8998-mdss", .data = &msm8998_data },
|
||||
{ .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data },
|
||||
{ .compatible = "qcom,sa8775p-mdss", .data = &sa8775p_data },
|
||||
{ .compatible = "qcom,sar2130p-mdss", .data = &sar2130p_data },
|
||||
{ .compatible = "qcom,sdm670-mdss", .data = &sdm670_data },
|
||||
{ .compatible = "qcom,sdm845-mdss", .data = &sdm845_data },
|
||||
{ .compatible = "qcom,sc7180-mdss", .data = &sc7180_data },
|
||||
|
|
|
@ -93,7 +93,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
|
|||
}
|
||||
|
||||
msm_gem_object_set_name(ring->bo, "ring%d", id);
|
||||
args.name = to_msm_bo(ring->bo)->name,
|
||||
args.name = to_msm_bo(ring->bo)->name;
|
||||
|
||||
ring->end = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2);
|
||||
ring->next = ring->start;
|
||||
|
|
Loading…
Reference in New Issue
Block a user