Merge tag 'drm-msm-next-2023-12-15' of https://gitlab.freedesktop.org/drm/msm into drm-next

Updates for v6.8:

Core:
- Add support for SDM670, SM8650
- Handle the CFG interconnect to fix the obscure hangs / timeouts
  on register write
- Kconfig fix for QMP dependency
- DT schema fixes

DPU:
- Add support for SDM670, SM8650
- Enable SmartDMA on SM8350 and SM8450
- Correct UBWC settings for SC8280XP
- Fix catalog settings for SC8180X
- Actually make use of the version to switch between QSEED3/3LITE/4
  scalers
- Use devres-managed and drm-managed allocations where appropriate
- misc other fixes
- Enabled YUV writeback on SC7280, SM8250
- Enabled writeback on SM8350, SM8450
- CRC fix when encoder is selected as the input source
- other misc fixes

MDP4:
- Use devres-managed and drm-managed allocations where appropriate
- flush vblank event on CRTC disable

MDP5:
- Use devres-managed and drm-managed allocations where appropriate

DP:
- Add support for SM8650
- Enable PM runtime support
- Merge msm-specific debugfs dir with the generic one
- Described DisplayPort on SM8150 in DeviceTree bindings
- Moved dp_display_get_next_bridge() to probe()

DSI:
- Add support for SM8650
- Enable PM runtime support

GPU/GEM:
- demote userspace triggerable warnings to debug
- add GEM object metadata UAPI
- move GPU devcoredumps to GPU device
- fix hangcheck to skip retired submits
- expose UBWC config to userspace
- fix a680 chip-id
- drm_exec conversion
- drm/ci: remove rebase-merge directory (to unblock CI)

[airlied: fix drm_exec/amd interaction]
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGs9auYqmo-7NSd9FsbNBCDf7aBevd=4xkcF3A5G_OGvMQ@mail.gmail.com
This commit is contained in:
Dave Airlie 2023-12-20 07:43:25 +10:00
commit 22a2decedf
144 changed files with 3623 additions and 2015 deletions

View file

@ -26,8 +26,10 @@ properties:
- qcom,sc8280xp-edp
- qcom,sdm845-dp
- qcom,sm8350-dp
- qcom,sm8650-dp
- items:
- enum:
- qcom,sm8150-dp
- qcom,sm8250-dp
- qcom,sm8450-dp
- qcom,sm8550-dp

View file

@ -25,6 +25,7 @@ properties:
- qcom,sc7180-dsi-ctrl
- qcom,sc7280-dsi-ctrl
- qcom,sdm660-dsi-ctrl
- qcom,sdm670-dsi-ctrl
- qcom,sdm845-dsi-ctrl
- qcom,sm6115-dsi-ctrl
- qcom,sm6125-dsi-ctrl
@ -35,6 +36,7 @@ properties:
- qcom,sm8350-dsi-ctrl
- qcom,sm8450-dsi-ctrl
- qcom,sm8550-dsi-ctrl
- qcom,sm8650-dsi-ctrl
- const: qcom,mdss-dsi-ctrl
- enum:
- qcom,dsi-ctrl-6g-qcm2290
@ -333,6 +335,7 @@ allOf:
- qcom,sm8350-dsi-ctrl
- qcom,sm8450-dsi-ctrl
- qcom,sm8550-dsi-ctrl
- qcom,sm8650-dsi-ctrl
then:
properties:
clocks:

View file

@ -22,6 +22,7 @@ properties:
- qcom,sm8350-dsi-phy-5nm
- qcom,sm8450-dsi-phy-5nm
- qcom,sm8550-dsi-phy-4nm
- qcom,sm8650-dsi-phy-4nm
reg:
items:

View file

@ -61,17 +61,27 @@ properties:
ranges: true
# This is not a perfect description, but it's impossible to discern and match
# the entries like we do with interconnect-names
interconnects:
minItems: 1
items:
- description: Interconnect path from mdp0 (or a single mdp) port to the data bus
- description: Interconnect path from mdp1 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
minItems: 1
items:
- const: mdp0-mem
- const: mdp1-mem
oneOf:
- minItems: 1
items:
- const: mdp0-mem
- const: cpu-cfg
- minItems: 2
items:
- const: mdp0-mem
- const: mdp1-mem
- const: cpu-cfg
resets:
items:

View file

@ -36,10 +36,14 @@ properties:
maxItems: 2
interconnects:
maxItems: 1
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
maxItems: 1
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":
@ -56,7 +60,9 @@ patternProperties:
properties:
compatible:
const: qcom,dsi-ctrl-6g-qcm2290
items:
- const: qcom,qcm2290-dsi-ctrl
- const: qcom,mdss-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
@ -96,8 +102,10 @@ examples:
interrupt-controller;
#interrupt-cells = <1>;
interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>;
interconnect-names = "mdp0-mem";
interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>,
<&bimc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>;
interconnect-names = "mdp0-mem",
"cpu-cfg";
iommus = <&apps_smmu 0x420 0x2>,
<&apps_smmu 0x421 0x0>;
@ -136,7 +144,8 @@ examples:
};
dsi@5e94000 {
compatible = "qcom,dsi-ctrl-6g-qcm2290";
compatible = "qcom,qcm2290-dsi-ctrl",
"qcom,mdss-dsi-ctrl";
reg = <0x05e94000 0x400>;
reg-names = "dsi_ctrl";

View file

@ -36,10 +36,14 @@ properties:
maxItems: 1
interconnects:
maxItems: 1
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
maxItems: 1
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":
@ -106,8 +110,10 @@ examples:
interrupt-controller;
#interrupt-cells = <1>;
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
interconnect-names = "mdp0-mem";
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>,
<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>;
interconnect-names = "mdp0-mem",
"cpu-cfg";
iommus = <&apps_smmu 0x800 0x2>;
ranges;

View file

@ -36,10 +36,14 @@ properties:
maxItems: 1
interconnects:
maxItems: 1
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
maxItems: 1
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":
@ -118,8 +122,10 @@ examples:
interrupt-controller;
#interrupt-cells = <1>;
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
interconnect-names = "mdp0-mem";
interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>,
<&gem_noc MASTER_APPSS_PROC &cnoc2 SLAVE_DISPLAY_CFG>;
interconnect-names = "mdp0-mem",
"cpu-cfg";
iommus = <&apps_smmu 0x900 0x402>;
ranges;

View file

@ -0,0 +1,292 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sdm670-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SDM670 Display MDSS
maintainers:
- Richard Acayan <mailingradian@gmail.com>
description:
SDM670 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,sdm670-mdss
clocks:
items:
- description: Display AHB clock from gcc
- description: Display core clock
clock-names:
items:
- const: iface
- const: core
iommus:
maxItems: 2
interconnects:
maxItems: 2
interconnect-names:
maxItems: 2
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,sdm670-dpu
"^displayport-controller@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,sdm670-dp
"^dsi@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
contains:
const: qcom,sdm670-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,dsi-phy-10nm
required:
- compatible
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interconnect/qcom,sdm670-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom-rpmpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sdm670-mdss";
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
power-domains = <&dispcc MDSS_GDSC>;
clocks = <&gcc GCC_DISP_AHB_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>;
clock-names = "iface", "core";
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;
interconnects = <&mmss_noc MASTER_MDP_PORT0 0 &mem_noc SLAVE_EBI_CH0 0>,
<&mmss_noc MASTER_MDP_PORT1 0 &mem_noc SLAVE_EBI_CH0 0>;
interconnect-names = "mdp0-mem", "mdp1-mem";
iommus = <&apps_smmu 0x880 0x8>,
<&apps_smmu 0xc80 0x8>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
display-controller@ae01000 {
compatible = "qcom,sdm670-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc GCC_DISP_AXI_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&dispcc DISP_CC_MDSS_AXI_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>,
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "gcc-bus", "iface", "bus", "core", "vsync";
interrupt-parent = <&mdss>;
interrupts = <0>;
power-domains = <&rpmhpd SDM670_CX>;
operating-points-v2 = <&mdp_opp_table>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpu_intf1_out: endpoint {
remote-endpoint = <&mdss_dsi0_in>;
};
};
port@1 {
reg = <1>;
dpu_intf2_out: endpoint {
remote-endpoint = <&mdss_dsi1_in>;
};
};
};
};
dsi@ae94000 {
compatible = "qcom,sdm670-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>,
<&dispcc DISP_CC_MDSS_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 SDM670_CX>;
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 {
};
};
};
};
mdss_dsi0_phy: phy@ae94400 {
compatible = "qcom,dsi-phy-10nm";
reg = <0x0ae94400 0x200>,
<0x0ae94600 0x280>,
<0x0ae94a00 0x1e0>;
reg-names = "dsi_phy",
"dsi_phy_lane",
"dsi_pll";
#clock-cells = <1>;
#phy-cells = <0>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
vdds-supply = <&vreg_dsi_phy>;
};
dsi@ae96000 {
compatible = "qcom,sdm670-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>,
<&dispcc DISP_CC_MDSS_AXI_CLK>;
clock-names = "byte",
"byte_intf",
"pixel",
"core",
"iface",
"bus";
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>,
<&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>;
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SDM670_CX>;
phys = <&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@ae96400 {
compatible = "qcom,dsi-phy-10nm";
reg = <0x0ae96400 0x200>,
<0x0ae96600 0x280>,
<0x0ae96a00 0x10e>;
reg-names = "dsi_phy",
"dsi_phy_lane",
"dsi_pll";
#clock-cells = <1>;
#phy-cells = <0>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface", "ref";
vdds-supply = <&vreg_dsi_phy>;
};
};
...

View file

@ -13,7 +13,9 @@ $ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
const: qcom,sdm845-dpu
enum:
- qcom,sdm670-dpu
- qcom,sdm845-dpu
reg:
items:

View file

@ -29,6 +29,16 @@ properties:
iommus:
maxItems: 2
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

View file

@ -35,10 +35,14 @@ properties:
maxItems: 1
interconnects:
maxItems: 2
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
maxItems: 2
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":

View file

@ -35,10 +35,14 @@ properties:
maxItems: 1
interconnects:
maxItems: 2
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
maxItems: 2
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":

View file

@ -35,10 +35,14 @@ properties:
maxItems: 1
interconnects:
maxItems: 2
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
maxItems: 2
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":

View file

@ -69,7 +69,7 @@ patternProperties:
properties:
compatible:
const: qcom,dsi-phy-7nm
const: qcom,dsi-phy-7nm-8150
unevaluatedProperties: false
@ -247,7 +247,7 @@ examples:
};
dsi0_phy: phy@ae94400 {
compatible = "qcom,dsi-phy-7nm";
compatible = "qcom,dsi-phy-7nm-8150";
reg = <0x0ae94400 0x200>,
<0x0ae94600 0x280>,
<0x0ae94900 0x260>;
@ -318,7 +318,7 @@ examples:
};
dsi1_phy: phy@ae96400 {
compatible = "qcom,dsi-phy-7nm";
compatible = "qcom,dsi-phy-7nm-8150";
reg = <0x0ae96400 0x200>,
<0x0ae96600 0x280>,
<0x0ae96900 0x260>;

View file

@ -52,6 +52,16 @@ patternProperties:
compatible:
const: qcom,sm8250-dpu
"^displayport-controller@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
items:
- const: qcom,sm8250-dp
- const: qcom,sm8350-dp
"^dsi@[0-9a-f]+$":
type: object
additionalProperties: true

View file

@ -30,10 +30,10 @@ properties:
maxItems: 1
interconnects:
maxItems: 2
maxItems: 3
interconnect-names:
maxItems: 2
maxItems: 3
patternProperties:
"^display-controller@[0-9a-f]+$":
@ -91,9 +91,12 @@ examples:
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
interconnects = <&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>,
<&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>;
interconnect-names = "mdp0-mem", "mdp1-mem";
interconnects = <&mmss_noc MASTER_MDP_DISP &mc_virt SLAVE_EBI1_DISP>,
<&mmss_noc MASTER_MDP_DISP &mc_virt SLAVE_EBI1_DISP>,
<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>;
interconnect-names = "mdp0-mem",
"mdp1-mem",
"cpu-cfg";
resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;

View file

@ -0,0 +1,127 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8650-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8650 Display DPU
maintainers:
- Neil Armstrong <neil.armstrong@linaro.org>
$ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
const: qcom,sm8650-dpu
reg:
items:
- description: Address offset and size for mdp register set
- description: Address offset and size for vbif register set
reg-names:
items:
- const: mdp
- const: vbif
clocks:
items:
- description: Display hf axi
- description: Display MDSS ahb
- description: Display lut
- description: Display core
- description: Display vsync
clock-names:
items:
- const: nrt_bus
- const: iface
- const: lut
- const: core
- const: vsync
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8650-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc_axi_clk>,
<&dispcc_ahb_clk>,
<&dispcc_mdp_lut_clk>,
<&dispcc_mdp_clk>,
<&dispcc_vsync_clk>;
clock-names = "nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc_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_intf1_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
port@1 {
reg = <1>;
dpu_intf2_out: endpoint {
remote-endpoint = <&dsi1_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-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>;
};
};
};
...

View file

@ -0,0 +1,328 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm8650-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM8650 Display MDSS
maintainers:
- Neil Armstrong <neil.armstrong@linaro.org>
description:
SM8650 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,sm8650-mdss
clocks:
items:
- description: Display AHB
- description: Display hf AXI
- description: Display core
iommus:
maxItems: 1
interconnects:
maxItems: 2
interconnect-names:
maxItems: 2
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,sm8650-dpu
"^displayport-controller@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,sm8650-dp
"^dsi@[0-9a-f]+$":
type: object
properties:
compatible:
items:
- const: qcom,sm8650-dsi-ctrl
- const: qcom,mdss-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
properties:
compatible:
const: qcom,sm8650-dsi-phy-4nm
required:
- compatible
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8650-mdss";
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
resets = <&dispcc_core_bcr>;
power-domains = <&dispcc_gdsc>;
clocks = <&gcc_ahb_clk>,
<&gcc_axi_clk>,
<&dispcc_mdp_clk>;
clock-names = "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,sm8650-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc_axi_clk>,
<&dispcc_ahb_clk>,
<&dispcc_mdp_lut_clk>,
<&dispcc_mdp_clk>,
<&dispcc_mdp_vsync_clk>;
clock-names = "nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc_mdp_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_intf1_out: endpoint {
remote-endpoint = <&dsi0_in>;
};
};
port@1 {
reg = <1>;
dpu_intf2_out: endpoint {
remote-endpoint = <&dsi1_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-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>;
};
};
};
dsi@ae94000 {
compatible = "qcom,sm8650-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 = <&dsi0_phy 0>, <&dsi0_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&dsi0_phy>;
phy-names = "dsi";
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi0_in: endpoint {
remote-endpoint = <&dpu_intf1_out>;
};
};
port@1 {
reg = <1>;
dsi0_out: endpoint {
};
};
};
dsi_opp_table: opp-table {
compatible = "operating-points-v2";
opp-187500000 {
opp-hz = /bits/ 64 <187500000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-358000000 {
opp-hz = /bits/ 64 <358000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
};
};
dsi0_phy: phy@ae94400 {
compatible = "qcom,sm8650-dsi-phy-4nm";
reg = <0x0ae95000 0x200>,
<0x0ae95200 0x280>,
<0x0ae95500 0x400>;
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";
};
dsi@ae96000 {
compatible = "qcom,sm8650-dsi-ctrl", "qcom,mdss-dsi-ctrl";
reg = <0x0ae96000 0x400>;
reg-names = "dsi_ctrl";
interrupt-parent = <&mdss>;
interrupts = <5>;
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 = <&dsi1_phy 0>, <&dsi1_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&dsi1_phy>;
phy-names = "dsi";
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dsi1_in: endpoint {
remote-endpoint = <&dpu_intf2_out>;
};
};
port@1 {
reg = <1>;
dsi1_out: endpoint {
};
};
};
};
dsi1_phy: phy@ae96400 {
compatible = "qcom,sm8650-dsi-phy-4nm";
reg = <0x0ae97000 0x200>,
<0x0ae97200 0x280>,
<0x0ae97500 0x400>;
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";
};
};
...

View file

@ -1147,7 +1147,7 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
ctx->n_vms = 1;
ctx->sync = &mem->sync;
drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&ctx->exec) {
ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
drm_exec_retry_on_contention(&ctx->exec);
@ -1186,7 +1186,7 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
int ret;
ctx->sync = &mem->sync;
drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&ctx->exec) {
ctx->n_vms = 0;
list_for_each_entry(entry, &mem->attachments, list) {
@ -2595,7 +2595,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
amdgpu_sync_create(&sync);
drm_exec_init(&exec, 0);
drm_exec_init(&exec, 0, 0);
/* Reserve all BOs and page tables for validation */
drm_exec_until_all_locked(&exec) {
/* Reserve all the page directories */
@ -2853,7 +2853,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
mutex_lock(&process_info->lock);
drm_exec_init(&exec, 0);
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
list_for_each_entry(peer_vm, &process_info->vm_list_head,
vm_list_node) {

View file

@ -66,7 +66,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,
amdgpu_sync_create(&p->sync);
drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
DRM_EXEC_IGNORE_DUPLICATES);
DRM_EXEC_IGNORE_DUPLICATES, 0);
return 0;
}

View file

@ -70,7 +70,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct drm_exec exec;
int r;
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&exec) {
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))
@ -110,7 +110,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct drm_exec exec;
int r;
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&exec) {
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))

View file

@ -203,7 +203,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
struct drm_exec exec;
long r;
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES);
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
drm_exec_until_all_locked(&exec) {
r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1);
drm_exec_retry_on_contention(&exec);
@ -739,7 +739,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
}
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
DRM_EXEC_IGNORE_DUPLICATES);
DRM_EXEC_IGNORE_DUPLICATES, 0);
drm_exec_until_all_locked(&exec) {
if (gobj) {
r = drm_exec_lock_obj(&exec, gobj);

View file

@ -1183,7 +1183,7 @@ int amdgpu_mes_ctx_map_meta_data(struct amdgpu_device *adev,
amdgpu_sync_create(&sync);
drm_exec_init(&exec, 0);
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
r = drm_exec_lock_obj(&exec,
&ctx_data->meta_data_obj->tbo.base);
@ -1254,7 +1254,7 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev,
struct drm_exec exec;
long r;
drm_exec_init(&exec, 0);
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
r = drm_exec_lock_obj(&exec,
&ctx_data->meta_data_obj->tbo.base);

View file

@ -61,7 +61,7 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (!bo)
return -EINVAL;
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&exec) {
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))
@ -122,7 +122,7 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv)
vm = &fpriv->vm;
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
drm_exec_until_all_locked(&exec) {
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))

View file

@ -86,7 +86,7 @@ static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
amdgpu_sync_create(&sync);
drm_exec_init(&exec, 0);
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
drm_exec_retry_on_contention(&exec);
@ -149,7 +149,7 @@ static int unmap_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct drm_exec exec;
long r;
drm_exec_init(&exec, 0);
drm_exec_init(&exec, 0, 0);
drm_exec_until_all_locked(&exec) {
r = drm_exec_lock_obj(&exec, &bo->tbo.base);
drm_exec_retry_on_contention(&exec);

View file

@ -1481,7 +1481,7 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx, bool intr)
uint32_t gpuidx;
int r;
drm_exec_init(&ctx->exec, intr ? DRM_EXEC_INTERRUPTIBLE_WAIT: 0);
drm_exec_init(&ctx->exec, intr ? DRM_EXEC_INTERRUPTIBLE_WAIT: 0, 0);
drm_exec_until_all_locked(&ctx->exec) {
for_each_set_bit(gpuidx, ctx->bitmap, MAX_GPU_INSTANCE) {
pdd = kfd_process_device_from_gpuidx(ctx->process, gpuidx);

View file

@ -58,6 +58,9 @@ git config --global user.email "fdo@example.com"
git config --global user.name "freedesktop.org CI"
git config --global pull.rebase true
# cleanup git state on the worker
rm -rf .git/rebase-merge
# Try to merge fixes from target repo
if [ "$(git ls-remote --exit-code --heads ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes)" ]; then
git pull ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes

View file

@ -69,16 +69,23 @@ static void drm_exec_unlock_all(struct drm_exec *exec)
* drm_exec_init - initialize a drm_exec object
* @exec: the drm_exec object to initialize
* @flags: controls locking behavior, see DRM_EXEC_* defines
* @nr: the initial # of objects
*
* Initialize the object and make sure that we can track locked objects.
*
* If nr is non-zero then it is used as the initial objects table size.
* In either case, the table will grow (be re-allocated) on demand.
*/
void drm_exec_init(struct drm_exec *exec, uint32_t flags)
void drm_exec_init(struct drm_exec *exec, uint32_t flags, unsigned nr)
{
if (!nr)
nr = PAGE_SIZE / sizeof(void *);
exec->flags = flags;
exec->objects = kmalloc(PAGE_SIZE, GFP_KERNEL);
exec->objects = kvmalloc_array(nr, sizeof(void *), GFP_KERNEL);
/* If allocation here fails, just delay that till the first use */
exec->max_objects = exec->objects ? PAGE_SIZE / sizeof(void *) : 0;
exec->max_objects = exec->objects ? nr : 0;
exec->num_objects = 0;
exec->contended = DRM_EXEC_DUMMY;
exec->prelocked = NULL;

View file

@ -1250,7 +1250,7 @@ drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec)
unsigned int num_fences = vm_exec->num_fences;
int ret;
drm_exec_init(exec, vm_exec->flags);
drm_exec_init(exec, vm_exec->flags, 0);
drm_exec_until_all_locked(exec) {
ret = drm_gpuvm_prepare_vm(gpuvm, exec, num_fences);
@ -1341,7 +1341,7 @@ drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec,
struct drm_exec *exec = &vm_exec->exec;
int ret;
drm_exec_init(exec, vm_exec->flags);
drm_exec_init(exec, vm_exec->flags, 0);
drm_exec_until_all_locked(exec) {
ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range,

View file

@ -746,7 +746,7 @@ pvr_submit_jobs(struct pvr_device *pvr_dev, struct pvr_file *pvr_file,
if (err)
goto out_job_data_cleanup;
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | DRM_EXEC_IGNORE_DUPLICATES);
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | DRM_EXEC_IGNORE_DUPLICATES, 0);
xa_init_flags(&signal_array, XA_FLAGS_ALLOC);

View file

@ -6,6 +6,7 @@ config DRM_MSM
depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST
depends on COMMON_CLK
depends on IOMMU_SUPPORT
depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
depends on QCOM_OCMEM || QCOM_OCMEM=n
depends on QCOM_LLCC || QCOM_LLCC=n
depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n
@ -16,6 +17,7 @@ config DRM_MSM
select DRM_DP_AUX_BUS
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HELPER
select DRM_EXEC
select DRM_KMS_HELPER
select DRM_PANEL
select DRM_BRIDGE

View file

@ -63,6 +63,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_encoder_phys_wb.o \
disp/dpu1/dpu_formats.o \
disp/dpu1/dpu_hw_catalog.o \
disp/dpu1/dpu_hw_cdm.o \
disp/dpu1/dpu_hw_ctl.o \
disp/dpu1/dpu_hw_dsc.o \
disp/dpu1/dpu_hw_dsc_1_2.o \

View file

@ -684,7 +684,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
u32 regbit;
u32 hbb;
int ret;
gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
@ -820,18 +820,15 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
/* Set the highest bank bit */
if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
regbit = 2;
else
regbit = 1;
BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, regbit << 7);
gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, regbit << 1);
gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, hbb << 7);
gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, hbb << 1);
if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) ||
adreno_is_a540(adreno_gpu))
gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, regbit);
gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, hbb);
/* Disable All flat shading optimization (ALLFLATOPTDIS) */
gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10));
@ -1785,5 +1782,11 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
/* Set up the preemption specific bits and pieces for each ringbuffer */
a5xx_preempt_init(gpu);
/* Set the highest bank bit */
if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
adreno_gpu->ubwc_config.highest_bank_bit = 15;
else
adreno_gpu->ubwc_config.highest_bank_bit = 14;
return gpu;
}

View file

@ -1270,87 +1270,92 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu)
gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]);
}
static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
/* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */
u32 rgb565_predicator = 0;
gpu->ubwc_config.rgb565_predicator = 0;
/* Unknown, introduced with A650 family */
u32 uavflagprd_inv = 0;
gpu->ubwc_config.uavflagprd_inv = 0;
/* Whether the minimum access length is 64 bits */
u32 min_acc_len = 0;
gpu->ubwc_config.min_acc_len = 0;
/* Entirely magic, per-GPU-gen value */
u32 ubwc_mode = 0;
gpu->ubwc_config.ubwc_mode = 0;
/*
* The Highest Bank Bit value represents the bit of the highest DDR bank.
* We then subtract 13 from it (13 is the minimum value allowed by hw) and
* write the lowest two bits of the remaining value as hbb_lo and the
* one above it as hbb_hi to the hardware. This should ideally use DRAM
* type detection.
* This should ideally use DRAM type detection.
*/
u32 hbb_hi = 0;
u32 hbb_lo = 2;
/* Unknown, introduced with A640/680 */
u32 amsbc = 0;
gpu->ubwc_config.highest_bank_bit = 15;
if (adreno_is_a610(adreno_gpu)) {
/* HBB = 14 */
hbb_lo = 1;
min_acc_len = 1;
ubwc_mode = 1;
if (adreno_is_a610(gpu)) {
gpu->ubwc_config.highest_bank_bit = 14;
gpu->ubwc_config.min_acc_len = 1;
gpu->ubwc_config.ubwc_mode = 1;
}
/* a618 is using the hw default values */
if (adreno_is_a618(adreno_gpu))
if (adreno_is_a618(gpu))
return;
if (adreno_is_a619_holi(adreno_gpu))
hbb_lo = 0;
if (adreno_is_a619_holi(gpu))
gpu->ubwc_config.highest_bank_bit = 13;
if (adreno_is_a640_family(adreno_gpu))
amsbc = 1;
if (adreno_is_a640_family(gpu))
gpu->ubwc_config.amsbc = 1;
if (adreno_is_a650(adreno_gpu) ||
adreno_is_a660(adreno_gpu) ||
adreno_is_a730(adreno_gpu) ||
adreno_is_a740_family(adreno_gpu)) {
if (adreno_is_a650(gpu) ||
adreno_is_a660(gpu) ||
adreno_is_a690(gpu) ||
adreno_is_a730(gpu) ||
adreno_is_a740_family(gpu)) {
/* TODO: get ddr type from bootloader and use 2 for LPDDR4 */
hbb_lo = 3;
amsbc = 1;
rgb565_predicator = 1;
uavflagprd_inv = 2;
gpu->ubwc_config.highest_bank_bit = 16;
gpu->ubwc_config.amsbc = 1;
gpu->ubwc_config.rgb565_predicator = 1;
gpu->ubwc_config.uavflagprd_inv = 2;
}
if (adreno_is_a690(adreno_gpu)) {
hbb_lo = 2;
amsbc = 1;
rgb565_predicator = 1;
uavflagprd_inv = 2;
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;
}
}
if (adreno_is_7c3(adreno_gpu)) {
hbb_lo = 1;
amsbc = 1;
rgb565_predicator = 1;
uavflagprd_inv = 2;
}
static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
/*
* We subtract 13 from the highest bank bit (13 is the minimum value
* allowed by hw) and write the lowest two bits of the remaining value
* as hbb_lo and the one above it as hbb_hi to the hardware.
*/
BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
u32 hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
u32 hbb_hi = hbb >> 2;
u32 hbb_lo = hbb & 3;
gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL,
rgb565_predicator << 11 | hbb_hi << 10 | amsbc << 4 |
min_acc_len << 3 | hbb_lo << 1 | ubwc_mode);
adreno_gpu->ubwc_config.rgb565_predicator << 11 |
hbb_hi << 10 | adreno_gpu->ubwc_config.amsbc << 4 |
adreno_gpu->ubwc_config.min_acc_len << 3 |
hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, hbb_hi << 4 |
min_acc_len << 3 | hbb_lo << 1 | ubwc_mode);
adreno_gpu->ubwc_config.min_acc_len << 3 |
hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 |
uavflagprd_inv << 4 | min_acc_len << 3 |
hbb_lo << 1 | ubwc_mode);
adreno_gpu->ubwc_config.uavflagprd_inv << 4 |
adreno_gpu->ubwc_config.min_acc_len << 3 |
hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
if (adreno_is_a7xx(adreno_gpu))
gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
FIELD_PREP(GENMASK(8, 5), hbb_lo));
gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, min_acc_len << 23 | hbb_lo << 21);
gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL,
adreno_gpu->ubwc_config.min_acc_len << 23 | hbb_lo << 21);
}
static int a6xx_cp_init(struct msm_gpu *gpu)
@ -1741,7 +1746,9 @@ static int hw_init(struct msm_gpu *gpu)
/* Setting the primFifo thresholds default values,
* and vccCacheSkipDis=1 bit (0x200) for A640 and newer
*/
if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu) || adreno_is_a690(adreno_gpu))
if (adreno_is_a690(adreno_gpu))
gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200);
else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu))
gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200);
@ -1775,6 +1782,8 @@ static int hw_init(struct msm_gpu *gpu)
if (adreno_is_a730(adreno_gpu) ||
adreno_is_a740_family(adreno_gpu))
gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcfffff);
else if (adreno_is_a690(adreno_gpu))
gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff);
else if (adreno_is_a619(adreno_gpu))
gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff);
else if (adreno_is_a610(adreno_gpu))
@ -1782,7 +1791,7 @@ static int hw_init(struct msm_gpu *gpu)
else
gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, 1);
gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, BIT(7) | 0x1);
/* Set weights for bicubic filtering */
if (adreno_is_a650_family(adreno_gpu)) {
@ -1808,12 +1817,17 @@ static int hw_init(struct msm_gpu *gpu)
a6xx_set_cp_protect(gpu);
if (adreno_is_a660_family(adreno_gpu)) {
gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
if (adreno_is_a690(adreno_gpu))
gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x00028801);
else
gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
}
if (adreno_is_a690(adreno_gpu))
gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x90);
/* Set dualQ + disable afull for A660 GPU */
if (adreno_is_a660(adreno_gpu))
else if (adreno_is_a660(adreno_gpu))
gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906);
else if (adreno_is_a7xx(adreno_gpu))
gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG,
@ -2908,5 +2922,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
a6xx_fault_handler);
a6xx_calc_ubwc_config(adreno_gpu);
return gpu;
}

View file

@ -464,7 +464,7 @@ static const struct adreno_info gpulist[] = {
{ 190, 1 },
),
}, {
.chip_ids = ADRENO_CHIP_IDS(0x06080000),
.chip_ids = ADRENO_CHIP_IDS(0x06080001),
.family = ADRENO_6XX_GEN2,
.revn = 680,
.fw = {

View file

@ -373,6 +373,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
return -EINVAL;
*value = ctx->aspace->va_size;
return 0;
case MSM_PARAM_HIGHEST_BANK_BIT:
*value = adreno_gpu->ubwc_config.highest_bank_bit;
return 0;
default:
DBG("%s: invalid param: %u", gpu->name, param);
return -EINVAL;

View file

@ -165,6 +165,15 @@ struct adreno_gpu {
/* firmware: */
const struct firmware *fw[ADRENO_FW_MAX];
struct {
u32 rgb565_predicator;
u32 uavflagprd_inv;
u32 min_acc_len;
u32 ubwc_mode;
u32 highest_bank_bit;
u32 amsbc;
} ubwc_config;
/*
* Register offsets are different between some GPUs.
* GPU specific offsets will be exported by GPU specific

View file

@ -0,0 +1,457 @@
/* 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_10_0_SM8650_H
#define _DPU_10_0_SM8650_H
static const struct dpu_caps sm8650_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 = 8192,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
};
static const struct dpu_mdp_cfg sm8650_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 },
},
};
/* 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),
.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),
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
}, {
.name = "ctl_2", .id = CTL_2,
.base = 0x17000, .len = 0x1000,
.features = CTL_SM8550_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
}, {
.name = "ctl_3", .id = CTL_3,
.base = 0x18000, .len = 0x1000,
.features = CTL_SM8550_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
}, {
.name = "ctl_4", .id = CTL_4,
.base = 0x19000, .len = 0x1000,
.features = CTL_SM8550_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
}, {
.name = "ctl_5", .id = CTL_5,
.base = 0x1a000, .len = 0x1000,
.features = CTL_SM8550_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
},
};
static const struct dpu_sspp_cfg sm8650_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x344,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_3,
.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_3,
.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_3,
.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_3,
.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 sm8650_lm[] = {
{
.name = "lm_0", .id = LM_0,
.base = 0x44000, .len = 0x400,
.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 = 0x400,
.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 = 0x400,
.features = MIXER_SDM845_MASK,
.sblk = &sdm845_lm_sblk,
.lm_pair = LM_3,
.pingpong = PINGPONG_2,
}, {
.name = "lm_3", .id = LM_3,
.base = 0x47000, .len = 0x400,
.features = MIXER_SDM845_MASK,
.sblk = &sdm845_lm_sblk,
.lm_pair = LM_2,
.pingpong = PINGPONG_3,
}, {
.name = "lm_4", .id = LM_4,
.base = 0x48000, .len = 0x400,
.features = MIXER_SDM845_MASK,
.sblk = &sdm845_lm_sblk,
.lm_pair = LM_5,
.pingpong = PINGPONG_4,
}, {
.name = "lm_5", .id = LM_5,
.base = 0x49000, .len = 0x400,
.features = MIXER_SDM845_MASK,
.sblk = &sdm845_lm_sblk,
.lm_pair = LM_4,
.pingpong = PINGPONG_5,
},
};
static const struct dpu_dspp_cfg sm8650_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 sm8650_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_6", .id = PINGPONG_6,
.base = 0x66000, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
}, {
.name = "pingpong_7", .id = PINGPONG_7,
.base = 0x66400, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_3,
}, {
.name = "pingpong_8", .id = PINGPONG_8,
.base = 0x7e000, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_4,
}, {
.name = "pingpong_9", .id = PINGPONG_9,
.base = 0x7e400, .len = 0,
.features = BIT(DPU_PINGPONG_DITHER),
.sblk = &sc7280_pp_sblk,
.merge_3d = MERGE_3D_4,
},
};
static const struct dpu_merge_3d_cfg sm8650_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,
}, {
.name = "merge_3d_4", .id = MERGE_3D_4,
.base = 0x7e700, .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 sm8650_dsc[] = {
{
.name = "dce_0_0", .id = DSC_0,
.base = 0x80000, .len = 0x6,
.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
.sblk = &dsc_sblk_0,
}, {
.name = "dce_0_1", .id = DSC_1,
.base = 0x80000, .len = 0x6,
.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
.sblk = &dsc_sblk_1,
}, {
.name = "dce_1_0", .id = DSC_2,
.base = 0x81000, .len = 0x6,
.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 = 0x6,
.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
.sblk = &dsc_sblk_1,
}, {
.name = "dce_2_0", .id = DSC_4,
.base = 0x82000, .len = 0x6,
.features = BIT(DPU_DSC_HW_REV_1_2),
.sblk = &dsc_sblk_0,
}, {
.name = "dce_2_1", .id = DSC_5,
.base = 0x82000, .len = 0x6,
.features = BIT(DPU_DSC_HW_REV_1_2),
.sblk = &dsc_sblk_1,
},
};
static const struct dpu_wb_cfg sm8650_wb[] = {
{
.name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8,
.features = WB_SM8250_MASK,
.format_list = wb2_formats_rgb,
.num_formats = ARRAY_SIZE(wb2_formats_rgb),
.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 sm8650_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 sm8650_perf_data = {
.max_bw_low = 17000000,
.max_bw_high = 27000000,
.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 = 1, .wr_enable = 1},
{.rd_enable = 1, .wr_enable = 0}
},
.clk_inefficiency_factor = 105,
.bw_inefficiency_factor = 120,
};
static const struct dpu_mdss_version sm8650_mdss_ver = {
.core_major_ver = 10,
.core_minor_ver = 0,
};
const struct dpu_mdss_cfg dpu_sm8650_cfg = {
.mdss_ver = &sm8650_mdss_ver,
.caps = &sm8650_dpu_caps,
.mdp = &sm8650_mdp,
.ctl_count = ARRAY_SIZE(sm8650_ctl),
.ctl = sm8650_ctl,
.sspp_count = ARRAY_SIZE(sm8650_sspp),
.sspp = sm8650_sspp,
.mixer_count = ARRAY_SIZE(sm8650_lm),
.mixer = sm8650_lm,
.dspp_count = ARRAY_SIZE(sm8650_dspp),
.dspp = sm8650_dspp,
.pingpong_count = ARRAY_SIZE(sm8650_pp),
.pingpong = sm8650_pp,
.dsc_count = ARRAY_SIZE(sm8650_dsc),
.dsc = sm8650_dsc,
.merge_3d_count = ARRAY_SIZE(sm8650_merge_3d),
.merge_3d = sm8650_merge_3d,
.wb_count = ARRAY_SIZE(sm8650_wb),
.wb = sm8650_wb,
.intf_count = ARRAY_SIZE(sm8650_intf),
.intf = sm8650_intf,
.vbif_count = ARRAY_SIZE(sm8650_vbif),
.vbif = sm8650_vbif,
.perf = &sm8650_perf_data,
};
#endif

View file

@ -10,7 +10,6 @@
static const struct dpu_caps msm8998_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x7,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -70,7 +69,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1ac,
.features = VIG_MSM8998_MASK,
.sblk = &msm8998_vig_sblk_0,
.sblk = &dpu_vig_sblk_qseed3_1_2,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -78,7 +77,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x1ac,
.features = VIG_MSM8998_MASK,
.sblk = &msm8998_vig_sblk_1,
.sblk = &dpu_vig_sblk_qseed3_1_2,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
@ -86,7 +85,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
.name = "sspp_2", .id = SSPP_VIG2,
.base = 0x8000, .len = 0x1ac,
.features = VIG_MSM8998_MASK,
.sblk = &msm8998_vig_sblk_2,
.sblk = &dpu_vig_sblk_qseed3_1_2,
.xin_id = 8,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG2,
@ -94,7 +93,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
.name = "sspp_3", .id = SSPP_VIG3,
.base = 0xa000, .len = 0x1ac,
.features = VIG_MSM8998_MASK,
.sblk = &msm8998_vig_sblk_3,
.sblk = &dpu_vig_sblk_qseed3_1_2,
.xin_id = 12,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG3,
@ -102,7 +101,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1ac,
.features = DMA_MSM8998_MASK,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -110,7 +109,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x1ac,
.features = DMA_MSM8998_MASK,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -118,7 +117,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x1ac,
.features = DMA_CURSOR_MSM8998_MASK,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
@ -126,7 +125,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
.name = "sspp_11", .id = SSPP_DMA3,
.base = 0x2a000, .len = 0x1ac,
.features = DMA_CURSOR_MSM8998_MASK,
.sblk = &sdm845_dma_sblk_3,
.sblk = &dpu_dma_sblk,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA3,

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sdm845_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -68,7 +67,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1c8,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &sdm845_vig_sblk_0,
.sblk = &dpu_vig_sblk_qseed3_1_3,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x1c8,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &sdm845_vig_sblk_1,
.sblk = &dpu_vig_sblk_qseed3_1_3,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
.name = "sspp_2", .id = SSPP_VIG2,
.base = 0x8000, .len = 0x1c8,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &sdm845_vig_sblk_2,
.sblk = &dpu_vig_sblk_qseed3_1_3,
.xin_id = 8,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG2,
@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
.name = "sspp_3", .id = SSPP_VIG3,
.base = 0xa000, .len = 0x1c8,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &sdm845_vig_sblk_3,
.sblk = &dpu_vig_sblk_qseed3_1_3,
.xin_id = 12,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG3,
@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1c8,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x1c8,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x1c8,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = {
.name = "sspp_11", .id = SSPP_DMA3,
.base = 0x2a000, .len = 0x1c8,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_3,
.sblk = &dpu_dma_sblk,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA3,

View file

@ -0,0 +1,104 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2023, Richard Acayan. All rights reserved.
*/
#ifndef _DPU_4_1_SDM670_H
#define _DPU_4_1_SDM670_H
static const struct dpu_mdp_cfg sdm670_mdp = {
.name = "top_0",
.base = 0x0, .len = 0x45c,
.features = BIT(DPU_MDP_AUDIO_SELECT),
.clk_ctrls = {
[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
},
};
static const struct dpu_sspp_cfg sdm670_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1c8,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_1_3,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
}, {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x1c8,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_1_3,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
}, {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1c8,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
}, {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x1c8,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
}, {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x1c8,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
},
};
static const struct dpu_dsc_cfg sdm670_dsc[] = {
{
.name = "dsc_0", .id = DSC_0,
.base = 0x80000, .len = 0x140,
}, {
.name = "dsc_1", .id = DSC_1,
.base = 0x80400, .len = 0x140,
},
};
static const struct dpu_mdss_version sdm670_mdss_ver = {
.core_major_ver = 4,
.core_minor_ver = 1,
};
const struct dpu_mdss_cfg dpu_sdm670_cfg = {
.mdss_ver = &sdm670_mdss_ver,
.caps = &sdm845_dpu_caps,
.mdp = &sdm670_mdp,
.ctl_count = ARRAY_SIZE(sdm845_ctl),
.ctl = sdm845_ctl,
.sspp_count = ARRAY_SIZE(sdm670_sspp),
.sspp = sdm670_sspp,
.mixer_count = ARRAY_SIZE(sdm845_lm),
.mixer = sdm845_lm,
.pingpong_count = ARRAY_SIZE(sdm845_pp),
.pingpong = sdm845_pp,
.dsc_count = ARRAY_SIZE(sdm670_dsc),
.dsc = sdm670_dsc,
.intf_count = ARRAY_SIZE(sdm845_intf),
.intf = sdm845_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
.vbif = sdm845_vbif,
.perf = &sdm845_perf_data,
};
#endif

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sm8150_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -77,7 +76,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f0,
.features = VIG_SDM845_MASK,
.sblk = &sdm845_vig_sblk_0,
.sblk = &dpu_vig_sblk_qseed3_1_4,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -85,7 +84,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x1f0,
.features = VIG_SDM845_MASK,
.sblk = &sdm845_vig_sblk_1,
.sblk = &dpu_vig_sblk_qseed3_1_4,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
@ -93,7 +92,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
.name = "sspp_2", .id = SSPP_VIG2,
.base = 0x8000, .len = 0x1f0,
.features = VIG_SDM845_MASK,
.sblk = &sdm845_vig_sblk_2,
.sblk = &dpu_vig_sblk_qseed3_1_4,
.xin_id = 8,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG2,
@ -101,7 +100,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
.name = "sspp_3", .id = SSPP_VIG3,
.base = 0xa000, .len = 0x1f0,
.features = VIG_SDM845_MASK,
.sblk = &sdm845_vig_sblk_3,
.sblk = &dpu_vig_sblk_qseed3_1_4,
.xin_id = 12,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG3,
@ -109,7 +108,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f0,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -117,7 +116,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x1f0,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -125,7 +124,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x1f0,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
@ -133,7 +132,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
.name = "sspp_11", .id = SSPP_DMA3,
.base = 0x2a000, .len = 0x1f0,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_3,
.sblk = &dpu_dma_sblk,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA3,

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sc8180x_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -76,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,
.sblk = &sdm845_vig_sblk_0,
.sblk = &dpu_vig_sblk_qseed3_1_4,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -84,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,
.sblk = &sdm845_vig_sblk_1,
.sblk = &dpu_vig_sblk_qseed3_1_4,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
@ -92,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,
.sblk = &sdm845_vig_sblk_2,
.sblk = &dpu_vig_sblk_qseed3_1_4,
.xin_id = 8,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG2,
@ -100,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,
.sblk = &sdm845_vig_sblk_3,
.sblk = &dpu_vig_sblk_qseed3_1_4,
.xin_id = 12,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG3,
@ -108,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,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -116,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,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -124,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,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
@ -132,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,
.sblk = &sdm845_dma_sblk_3,
.sblk = &dpu_dma_sblk,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA3,
@ -367,6 +366,7 @@ static const struct dpu_perf_cfg sc8180x_perf_data = {
.min_llcc_ib = 800000,
.min_dram_ib = 800000,
.danger_lut_tbl = {0xf, 0xffff, 0x0},
.safe_lut_tbl = {0xfff0, 0xf000, 0xffff},
.qos_lut_tbl = {
{.nentry = ARRAY_SIZE(sc7180_qos_linear),
.entries = sc7180_qos_linear

View file

@ -68,8 +68,8 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f0,
.features = VIG_SM6125_MASK,
.sblk = &sm6125_vig_sblk_0,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_2_4,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -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,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -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,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sm8250_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -32,7 +31,7 @@ static const struct dpu_mdp_cfg sm8250_mdp = {
[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
},
};
@ -75,32 +74,32 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f8,
.features = VIG_SC7180_MASK_SDMA,
.sblk = &sm8250_vig_sblk_0,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
}, {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x1f8,
.features = VIG_SC7180_MASK_SDMA,
.sblk = &sm8250_vig_sblk_1,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
}, {
.name = "sspp_2", .id = SSPP_VIG2,
.base = 0x8000, .len = 0x1f8,
.features = VIG_SC7180_MASK_SDMA,
.sblk = &sm8250_vig_sblk_2,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 8,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG2,
}, {
.name = "sspp_3", .id = SSPP_VIG3,
.base = 0xa000, .len = 0x1f8,
.features = VIG_SC7180_MASK_SDMA,
.sblk = &sm8250_vig_sblk_3,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 12,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG3,
@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f8,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x1f8,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x1f8,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = {
.name = "sspp_11", .id = SSPP_DMA3,
.base = 0x2a000, .len = 0x1f8,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_3,
.sblk = &dpu_dma_sblk,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA3,
@ -337,8 +336,8 @@ static const struct dpu_wb_cfg sm8250_wb[] = {
.name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8,
.features = WB_SM8250_MASK,
.format_list = wb2_formats,
.num_formats = ARRAY_SIZE(wb2_formats),
.format_list = wb2_formats_rgb_yuv,
.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
.clk_ctrl = DPU_CLK_CTRL_WB2,
.xin_id = 6,
.vbif_idx = VBIF_RT,
@ -385,6 +384,7 @@ const struct dpu_mdss_cfg dpu_sm8250_cfg = {
.mdss_ver = &sm8250_mdss_ver,
.caps = &sm8250_dpu_caps,
.mdp = &sm8250_mdp,
.cdm = &sc7280_cdm,
.ctl_count = ARRAY_SIZE(sm8250_ctl),
.ctl = sm8250_ctl,
.sspp_count = ARRAY_SIZE(sm8250_sspp),

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sc7180_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x9,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_dim_layer = true,
.has_idle_pc = true,
.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
@ -25,7 +24,7 @@ static const struct dpu_mdp_cfg sc7180_mdp = {
[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
},
};
@ -52,8 +51,8 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f8,
.features = VIG_SC7180_MASK,
.sblk = &sc7180_vig_sblk_0,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -61,7 +60,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f8,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -69,7 +68,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x1f8,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -77,7 +76,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x1f8,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
@ -158,8 +157,8 @@ static const struct dpu_wb_cfg sc7180_wb[] = {
.name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8,
.features = WB_SM8250_MASK,
.format_list = wb2_formats,
.num_formats = ARRAY_SIZE(wb2_formats),
.format_list = wb2_formats_rgb,
.num_formats = ARRAY_SIZE(wb2_formats_rgb),
.clk_ctrl = DPU_CLK_CTRL_WB2,
.xin_id = 6,
.vbif_idx = VBIF_RT,

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sm6115_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
.max_mixer_blendstages = 0x4,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_dim_layer = true,
.has_idle_pc = true,
.max_linewidth = 2160,
@ -39,8 +38,8 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f8,
.features = VIG_SC7180_MASK,
.sblk = &sm6115_vig_sblk_0,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -48,7 +47,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f8,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,

View file

@ -11,7 +11,6 @@
static const struct dpu_caps sm6350_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x7,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -59,8 +58,8 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f8,
.features = VIG_SC7180_MASK,
.sblk = &sc7180_vig_sblk_0,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -68,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,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -76,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,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -84,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,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,

View file

@ -39,7 +39,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = {
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f8,
.features = VIG_QCM2290_MASK,
.sblk = &qcm2290_vig_sblk_0,
.sblk = &dpu_vig_sblk_noscale,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -47,7 +47,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f8,
.features = DMA_SDM845_MASK,
.sblk = &qcm2290_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,

View file

@ -11,7 +11,6 @@
static const struct dpu_caps sm6375_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
.max_mixer_blendstages = 0x4,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_dim_layer = true,
.has_idle_pc = true,
.max_linewidth = 2160,
@ -40,8 +39,8 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f8,
.features = VIG_SC7180_MASK,
.sblk = &sm6115_vig_sblk_0,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -49,7 +48,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f8,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sm8350_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -31,6 +30,7 @@ static const struct dpu_mdp_cfg sm8350_mdp = {
[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
},
};
@ -74,64 +74,64 @@ static const struct dpu_sspp_cfg sm8350_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f8,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_0,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
}, {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x1f8,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_1,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
}, {
.name = "sspp_2", .id = SSPP_VIG2,
.base = 0x8000, .len = 0x1f8,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_2,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 8,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG2,
}, {
.name = "sspp_3", .id = SSPP_VIG3,
.base = 0xa000, .len = 0x1f8,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_3,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 12,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG3,
}, {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f8,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_0,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
}, {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x1f8,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_1,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
}, {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x1f8,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_2,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
}, {
.name = "sspp_11", .id = SSPP_DMA3,
.base = 0x2a000, .len = 0x1f8,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_3,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA3,
@ -298,6 +298,21 @@ static const struct dpu_dsc_cfg sm8350_dsc[] = {
},
};
static const struct dpu_wb_cfg sm8350_wb[] = {
{
.name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8,
.features = WB_SM8250_MASK,
.format_list = wb2_formats_rgb,
.num_formats = ARRAY_SIZE(wb2_formats_rgb),
.clk_ctrl = DPU_CLK_CTRL_WB2,
.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 sm8350_intf[] = {
{
.name = "intf_0", .id = INTF_0,
@ -393,6 +408,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = {
.dsc = sm8350_dsc,
.merge_3d_count = ARRAY_SIZE(sm8350_merge_3d),
.merge_3d = sm8350_merge_3d,
.wb_count = ARRAY_SIZE(sm8350_wb),
.wb = sm8350_wb,
.intf_count = ARRAY_SIZE(sm8350_intf),
.intf = sm8350_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sc7280_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x7,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_dim_layer = true,
.has_idle_pc = true,
.max_linewidth = 2400,
@ -25,7 +24,7 @@ static const struct dpu_mdp_cfg sc7280_mdp = {
[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
},
};
@ -58,7 +57,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = {
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f8,
.features = VIG_SC7280_MASK_SDMA,
.sblk = &sc7280_vig_sblk_0,
.sblk = &dpu_vig_sblk_qseed3_3_0_rot_v2,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
@ -66,7 +65,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f8,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -74,7 +73,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x1f8,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -82,7 +81,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x1f8,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
@ -170,8 +169,8 @@ static const struct dpu_wb_cfg sc7280_wb[] = {
.name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8,
.features = WB_SM8250_MASK,
.format_list = wb2_formats,
.num_formats = ARRAY_SIZE(wb2_formats),
.format_list = wb2_formats_rgb_yuv,
.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
.clk_ctrl = DPU_CLK_CTRL_WB2,
.xin_id = 6,
.vbif_idx = VBIF_RT,
@ -249,6 +248,7 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = {
.mdss_ver = &sc7280_mdss_ver,
.caps = &sc7280_dpu_caps,
.mdp = &sc7280_mdp,
.cdm = &sc7280_cdm,
.ctl_count = ARRAY_SIZE(sc7280_ctl),
.ctl = sc7280_ctl,
.sspp_count = ARRAY_SIZE(sc7280_sspp),

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sc8280xp_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 11,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -75,32 +74,32 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x2ac,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_0,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
}, {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x2ac,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_1,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
}, {
.name = "sspp_2", .id = SSPP_VIG2,
.base = 0x8000, .len = 0x2ac,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_2,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 8,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG2,
}, {
.name = "sspp_3", .id = SSPP_VIG3,
.base = 0xa000, .len = 0x2ac,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_3,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_3_0,
.xin_id = 12,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG3,
@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x2ac,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_0,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x2ac,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_1,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x2ac,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_2,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
.name = "sspp_11", .id = SSPP_DMA3,
.base = 0x2a000, .len = 0x2ac,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_3,
.sblk = &dpu_dma_sblk,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA3,

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sm8450_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -32,6 +31,7 @@ static const struct dpu_mdp_cfg sm8450_mdp = {
[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
},
};
@ -75,64 +75,64 @@ static const struct dpu_sspp_cfg sm8450_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x32c,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_0,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_1,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
}, {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x32c,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_1,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_1,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
}, {
.name = "sspp_2", .id = SSPP_VIG2,
.base = 0x8000, .len = 0x32c,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_2,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_1,
.xin_id = 8,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG2,
}, {
.name = "sspp_3", .id = SSPP_VIG3,
.base = 0xa000, .len = 0x32c,
.features = VIG_SC7180_MASK,
.sblk = &sm8250_vig_sblk_3,
.features = VIG_SDM845_MASK_SDMA,
.sblk = &dpu_vig_sblk_qseed3_3_1,
.xin_id = 12,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG3,
}, {
.name = "sspp_8", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x32c,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_0,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 1,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA0,
}, {
.name = "sspp_9", .id = SSPP_DMA1,
.base = 0x26000, .len = 0x32c,
.features = DMA_SDM845_MASK,
.sblk = &sdm845_dma_sblk_1,
.features = DMA_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 5,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA1,
}, {
.name = "sspp_10", .id = SSPP_DMA2,
.base = 0x28000, .len = 0x32c,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_2,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
}, {
.name = "sspp_11", .id = SSPP_DMA3,
.base = 0x2a000, .len = 0x32c,
.features = DMA_CURSOR_SDM845_MASK,
.sblk = &sdm845_dma_sblk_3,
.features = DMA_CURSOR_SDM845_MASK_SDMA,
.sblk = &dpu_dma_sblk,
.xin_id = 13,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA3,
@ -316,6 +316,21 @@ static const struct dpu_dsc_cfg sm8450_dsc[] = {
},
};
static const struct dpu_wb_cfg sm8450_wb[] = {
{
.name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8,
.features = WB_SM8250_MASK,
.format_list = wb2_formats_rgb,
.num_formats = ARRAY_SIZE(wb2_formats_rgb),
.clk_ctrl = DPU_CLK_CTRL_WB2,
.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 sm8450_intf[] = {
{
.name = "intf_0", .id = INTF_0,
@ -411,6 +426,8 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = {
.dsc = sm8450_dsc,
.merge_3d_count = ARRAY_SIZE(sm8450_merge_3d),
.merge_3d = sm8450_merge_3d,
.wb_count = ARRAY_SIZE(sm8450_wb),
.wb = sm8450_wb,
.intf_count = ARRAY_SIZE(sm8450_intf),
.intf = sm8450_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),

View file

@ -10,7 +10,6 @@
static const struct dpu_caps sm8550_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
.has_src_split = true,
.has_dim_layer = true,
.has_idle_pc = true,
@ -67,71 +66,71 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x344,
.features = VIG_SC7180_MASK,
.sblk = &sm8550_vig_sblk_0,
.features = VIG_SDM845_MASK,
.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_SC7180_MASK,
.sblk = &sm8550_vig_sblk_1,
.features = VIG_SDM845_MASK,
.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_SC7180_MASK,
.sblk = &sm8550_vig_sblk_2,
.features = VIG_SDM845_MASK,
.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_SC7180_MASK,
.sblk = &sm8550_vig_sblk_3,
.features = VIG_SDM845_MASK,
.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,
.sblk = &sdm845_dma_sblk_0,
.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,
.sblk = &sdm845_dma_sblk_1,
.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,
.sblk = &sdm845_dma_sblk_2,
.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,
.sblk = &sdm845_dma_sblk_3,
.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,
.sblk = &sm8550_dma_sblk_4,
.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,
.sblk = &sm8550_dma_sblk_5,
.sblk = &dpu_dma_sblk,
.xin_id = 15,
.type = SSPP_TYPE_DMA,
},
@ -316,8 +315,8 @@ static const struct dpu_wb_cfg sm8550_wb[] = {
.name = "wb_2", .id = WB_2,
.base = 0x65000, .len = 0x2c8,
.features = WB_SM8250_MASK,
.format_list = wb2_formats,
.num_formats = ARRAY_SIZE(wb2_formats),
.format_list = wb2_formats_rgb,
.num_formats = ARRAY_SIZE(wb2_formats_rgb),
.xin_id = 6,
.vbif_idx = VBIF_RT,
.maxlinewidth = 4096,

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
@ -51,17 +51,6 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
return to_dpu_kms(priv->kms);
}
static void dpu_crtc_destroy(struct drm_crtc *crtc)
{
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
if (!crtc)
return;
drm_crtc_cleanup(crtc);
kfree(dpu_crtc);
}
static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@ -125,7 +114,7 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state)
continue;
/* Calculate MISR over 1 frame */
m->hw_lm->ops.setup_misr(m->hw_lm, true, 1);
m->hw_lm->ops.setup_misr(m->hw_lm);
}
}
@ -1435,7 +1424,6 @@ static int dpu_crtc_late_register(struct drm_crtc *crtc)
static const struct drm_crtc_funcs dpu_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = dpu_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
.reset = dpu_crtc_reset,
.atomic_duplicate_state = dpu_crtc_duplicate_state,
@ -1469,9 +1457,13 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
struct dpu_crtc *dpu_crtc;
int i, ret;
dpu_crtc = kzalloc(sizeof(*dpu_crtc), GFP_KERNEL);
if (!dpu_crtc)
return ERR_PTR(-ENOMEM);
dpu_crtc = drmm_crtc_alloc_with_planes(dev, struct dpu_crtc, base,
plane, cursor,
&dpu_crtc_funcs,
NULL);
if (IS_ERR(dpu_crtc))
return ERR_CAST(dpu_crtc);
crtc = &dpu_crtc->base;
crtc->dev = dev;
@ -1491,9 +1483,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
dpu_crtc_frame_event_work);
}
drm_crtc_init_with_planes(dev, crtc, plane, cursor, &dpu_crtc_funcs,
NULL);
drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
if (dpu_kms->catalog->dspp_count)

View file

@ -2,7 +2,7 @@
/*
* Copyright (C) 2013 Red Hat
* Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Author: Rob Clark <robdclark@gmail.com>
*/
@ -16,6 +16,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_file.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_framebuffer.h>
#include "msm_drv.h"
#include "dpu_kms.h"
@ -26,6 +27,7 @@
#include "dpu_hw_dspp.h"
#include "dpu_hw_dsc.h"
#include "dpu_hw_merge3d.h"
#include "dpu_hw_cdm.h"
#include "dpu_formats.h"
#include "dpu_encoder_phys.h"
#include "dpu_crtc.h"
@ -39,6 +41,9 @@
#define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\
(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\
(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
/*
* Two to anticipate panels that can do cmd/vid dynamic switching
* plan is to create all possible physical encoder types, and switch between
@ -151,6 +156,8 @@ enum dpu_enc_rc_states {
* @crtc_frame_event_cb: callback handler for frame event
* @crtc_frame_event_cb_data: callback handler private data
* @frame_done_timeout_ms: frame done timeout in ms
* @frame_done_timeout_cnt: atomic counter tracking the number of frame
* done timeouts
* @frame_done_timer: watchdog timer for frame done event
* @disp_info: local copy of msm_display_info struct
* @idle_pc_supported: indicate if idle power collaps is supported
@ -184,13 +191,13 @@ struct dpu_encoder_virt {
struct drm_crtc *crtc;
struct drm_connector *connector;
struct dentry *debugfs_root;
struct mutex enc_lock;
DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL);
void (*crtc_frame_event_cb)(void *, u32 event);
void *crtc_frame_event_cb_data;
atomic_t frame_done_timeout_ms;
atomic_t frame_done_timeout_cnt;
struct timer_list frame_done_timer;
struct msm_display_info disp_info;
@ -255,7 +262,7 @@ void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc)
if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr)
continue;
phys->hw_intf->ops.setup_misr(phys->hw_intf, true, 1);
phys->hw_intf->ops.setup_misr(phys->hw_intf);
}
}
@ -439,41 +446,6 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc)
return linecount;
}
static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
{
struct dpu_encoder_virt *dpu_enc = NULL;
int i = 0;
if (!drm_enc) {
DPU_ERROR("invalid encoder\n");
return;
}
dpu_enc = to_dpu_encoder_virt(drm_enc);
DPU_DEBUG_ENC(dpu_enc, "\n");
mutex_lock(&dpu_enc->enc_lock);
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
if (phys->ops.destroy) {
phys->ops.destroy(phys);
--dpu_enc->num_phys_encs;
dpu_enc->phys_encs[i] = NULL;
}
}
if (dpu_enc->num_phys_encs)
DPU_ERROR_ENC(dpu_enc, "expected 0 num_phys_encs not %d\n",
dpu_enc->num_phys_encs);
dpu_enc->num_phys_encs = 0;
mutex_unlock(&dpu_enc->enc_lock);
drm_encoder_cleanup(drm_enc);
mutex_destroy(&dpu_enc->enc_lock);
}
void dpu_encoder_helper_split_config(
struct dpu_encoder_phys *phys_enc,
enum dpu_intf interface)
@ -614,6 +586,7 @@ static int dpu_encoder_virt_atomic_check(
struct drm_display_mode *adj_mode;
struct msm_display_topology topology;
struct dpu_global_state *global_state;
struct drm_framebuffer *fb;
struct drm_dsc_config *dsc;
int i = 0;
int ret = 0;
@ -654,6 +627,22 @@ static int dpu_encoder_virt_atomic_check(
topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc);
/*
* Use CDM only for writeback at the moment as other interfaces cannot handle it.
* if writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
* earlier.
*/
if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) {
fb = conn_state->writeback_job->fb;
if (fb && DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb))))
topology.needs_cdm = true;
if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
crtc_state->mode_changed = true;
else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm)
crtc_state->mode_changed = true;
}
/*
* Release and Allocate resources on every modeset
* Dont allocate when active is false.
@ -1094,6 +1083,15 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
dpu_enc->dsc_mask = dsc_mask;
if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) {
struct dpu_hw_blk *hw_cdm = NULL;
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_CDM,
&hw_cdm, 1);
dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
}
cstate = to_dpu_crtc_state(crtc_state);
for (i = 0; i < num_lm; i++) {
@ -1204,6 +1202,8 @@ static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc,
dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc);
atomic_set(&dpu_enc->frame_done_timeout_cnt, 0);
if (disp_info->intf_type == INTF_DP)
dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]);
else if (disp_info->intf_type == INTF_DSI)
@ -2080,6 +2080,15 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
phys_enc->hw_pp->merge_3d->idx);
}
if (phys_enc->hw_cdm) {
if (phys_enc->hw_cdm->ops.bind_pingpong_blk && phys_enc->hw_pp)
phys_enc->hw_cdm->ops.bind_pingpong_blk(phys_enc->hw_cdm,
PINGPONG_NONE);
if (phys_enc->hw_ctl->ops.update_pending_flush_cdm)
phys_enc->hw_ctl->ops.update_pending_flush_cdm(phys_enc->hw_ctl,
phys_enc->hw_cdm->idx);
}
if (dpu_enc->dsc) {
dpu_encoder_unprep_dsc(dpu_enc);
dpu_enc->dsc = NULL;
@ -2108,18 +2117,20 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
#ifdef CONFIG_DEBUG_FS
static int _dpu_encoder_status_show(struct seq_file *s, void *data)
{
struct dpu_encoder_virt *dpu_enc = s->private;
struct drm_encoder *drm_enc = s->private;
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
int i;
mutex_lock(&dpu_enc->enc_lock);
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
seq_printf(s, "intf:%d wb:%d vsync:%8d underrun:%8d ",
seq_printf(s, "intf:%d wb:%d vsync:%8d underrun:%8d frame_done_cnt:%d",
phys->hw_intf ? phys->hw_intf->idx - INTF_0 : -1,
phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1,
atomic_read(&phys->vsync_cnt),
atomic_read(&phys->underrun_cnt));
atomic_read(&phys->underrun_cnt),
atomic_read(&dpu_enc->frame_done_timeout_cnt));
seq_printf(s, "mode: %s\n", dpu_encoder_helper_get_intf_type(phys->intf_mode));
}
@ -2130,49 +2141,18 @@ static int _dpu_encoder_status_show(struct seq_file *s, void *data)
DEFINE_SHOW_ATTRIBUTE(_dpu_encoder_status);
static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
static void dpu_encoder_debugfs_init(struct drm_encoder *drm_enc, struct dentry *root)
{
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
char name[12];
if (!drm_enc->dev) {
DPU_ERROR("invalid encoder or kms\n");
return -EINVAL;
}
snprintf(name, sizeof(name), "encoder%u", drm_enc->base.id);
/* create overall sub-directory for the encoder */
dpu_enc->debugfs_root = debugfs_create_dir(name,
drm_enc->dev->primary->debugfs_root);
/* don't error check these */
debugfs_create_file("status", 0600,
dpu_enc->debugfs_root, dpu_enc, &_dpu_encoder_status_fops);
return 0;
root, drm_enc, &_dpu_encoder_status_fops);
}
#else
static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
{
return 0;
}
#define dpu_encoder_debugfs_init NULL
#endif
static int dpu_encoder_late_register(struct drm_encoder *encoder)
{
return _dpu_encoder_init_debugfs(encoder);
}
static void dpu_encoder_early_unregister(struct drm_encoder *encoder)
{
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
debugfs_remove_recursive(dpu_enc->debugfs_root);
}
static int dpu_encoder_virt_add_phys_encs(
struct drm_device *dev,
struct msm_display_info *disp_info,
struct dpu_encoder_virt *dpu_enc,
struct dpu_enc_phys_init_params *params)
@ -2194,7 +2174,7 @@ static int dpu_encoder_virt_add_phys_encs(
if (disp_info->intf_type == INTF_WB) {
enc = dpu_encoder_phys_wb_init(params);
enc = dpu_encoder_phys_wb_init(dev, params);
if (IS_ERR(enc)) {
DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n",
@ -2205,7 +2185,7 @@ static int dpu_encoder_virt_add_phys_encs(
dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc;
++dpu_enc->num_phys_encs;
} else if (disp_info->is_cmd_mode) {
enc = dpu_encoder_phys_cmd_init(params);
enc = dpu_encoder_phys_cmd_init(dev, params);
if (IS_ERR(enc)) {
DPU_ERROR_ENC(dpu_enc, "failed to init cmd enc: %ld\n",
@ -2216,7 +2196,7 @@ static int dpu_encoder_virt_add_phys_encs(
dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc;
++dpu_enc->num_phys_encs;
} else {
enc = dpu_encoder_phys_vid_init(params);
enc = dpu_encoder_phys_vid_init(dev, params);
if (IS_ERR(enc)) {
DPU_ERROR_ENC(dpu_enc, "failed to init vid enc: %ld\n",
@ -2305,7 +2285,7 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
break;
}
ret = dpu_encoder_virt_add_phys_encs(disp_info,
ret = dpu_encoder_virt_add_phys_encs(dpu_kms->dev, disp_info,
dpu_enc, &phys_params);
if (ret) {
DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n");
@ -2339,7 +2319,10 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)
return;
}
DPU_ERROR_ENC(dpu_enc, "frame done timeout\n");
DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n");
if (atomic_inc_return(&dpu_enc->frame_done_timeout_cnt) == 1)
msm_disp_snapshot_state(drm_enc->dev);
event = DPU_ENCODER_FRAME_EVENT_ERROR;
trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event);
@ -2354,9 +2337,7 @@ static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = {
};
static const struct drm_encoder_funcs dpu_encoder_funcs = {
.destroy = dpu_encoder_destroy,
.late_register = dpu_encoder_late_register,
.early_unregister = dpu_encoder_early_unregister,
.debugfs_init = dpu_encoder_debugfs_init,
};
struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
@ -2365,20 +2346,13 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
{
struct msm_drm_private *priv = dev->dev_private;
struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
struct drm_encoder *drm_enc = NULL;
struct dpu_encoder_virt *dpu_enc = NULL;
int ret = 0;
struct dpu_encoder_virt *dpu_enc;
int ret;
dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL);
if (!dpu_enc)
return ERR_PTR(-ENOMEM);
ret = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs,
drm_enc_mode, NULL);
if (ret) {
devm_kfree(dev->dev, dpu_enc);
return ERR_PTR(ret);
}
dpu_enc = drmm_encoder_alloc(dev, struct dpu_encoder_virt, base,
&dpu_encoder_funcs, drm_enc_mode, NULL);
if (IS_ERR(dpu_enc))
return ERR_CAST(dpu_enc);
drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs);
@ -2388,10 +2362,13 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
mutex_init(&dpu_enc->rc_lock);
ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info);
if (ret)
goto fail;
if (ret) {
DPU_ERROR("failed to setup encoder\n");
return ERR_PTR(-ENOMEM);
}
atomic_set(&dpu_enc->frame_done_timeout_ms, 0);
atomic_set(&dpu_enc->frame_done_timeout_cnt, 0);
timer_setup(&dpu_enc->frame_done_timer,
dpu_encoder_frame_done_timeout, 0);
@ -2404,13 +2381,6 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
DPU_DEBUG_ENC(dpu_enc, "created\n");
return &dpu_enc->base;
fail:
DPU_ERROR("failed to create encoder\n");
if (drm_enc)
dpu_encoder_destroy(drm_enc);
return ERR_PTR(ret);
}
int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
@ -2437,9 +2407,6 @@ int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
case MSM_ENC_TX_COMPLETE:
fn_wait = phys->ops.wait_for_tx_complete;
break;
case MSM_ENC_VBLANK:
fn_wait = phys->ops.wait_for_vblank;
break;
default:
DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n",
event);
@ -2497,7 +2464,6 @@ void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc,
phys_enc->enc_spinlock = p->enc_spinlock;
phys_enc->enable_state = DPU_ENC_DISABLED;
atomic_set(&phys_enc->vblank_refcount, 0);
atomic_set(&phys_enc->pending_kickoff_cnt, 0);
atomic_set(&phys_enc->pending_ctlstart_cnt, 0);

View file

@ -14,8 +14,10 @@
#include "dpu_hw_intf.h"
#include "dpu_hw_wb.h"
#include "dpu_hw_pingpong.h"
#include "dpu_hw_cdm.h"
#include "dpu_hw_ctl.h"
#include "dpu_hw_top.h"
#include "dpu_hw_util.h"
#include "dpu_encoder.h"
#include "dpu_crtc.h"
@ -72,7 +74,6 @@ struct dpu_encoder_phys;
* @enable: DRM Call. Enable a DRM mode.
* @disable: DRM Call. Disable mode.
* @atomic_check: DRM Call. Atomic check new DRM state.
* @destroy: DRM Call. Destroy and release resources.
* @control_vblank_irq Register/Deregister for VBLANK IRQ
* @wait_for_commit_done: Wait for hardware to have flushed the
* current pending frames to hardware
@ -102,11 +103,9 @@ struct dpu_encoder_phys_ops {
int (*atomic_check)(struct dpu_encoder_phys *encoder,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state);
void (*destroy)(struct dpu_encoder_phys *encoder);
int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable);
int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc);
void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc);
void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc);
void (*trigger_start)(struct dpu_encoder_phys *phys_enc);
@ -153,8 +152,10 @@ enum dpu_intr_idx {
* @hw_pp: Hardware interface to the ping pong registers
* @hw_intf: Hardware interface to the intf registers
* @hw_wb: Hardware interface to the wb registers
* @hw_cdm: Hardware interface to the CDM registers
* @dpu_kms: Pointer to the dpu_kms top level
* @cached_mode: DRM mode cached at mode_set time, acted on in enable
* @vblank_ctl_lock: Vblank ctl mutex lock to protect vblank_refcount
* @enabled: Whether the encoder has enabled and running a mode
* @split_role: Role to play in a split-panel configuration
* @intf_mode: Interface mode
@ -181,13 +182,15 @@ struct dpu_encoder_phys {
struct dpu_hw_pingpong *hw_pp;
struct dpu_hw_intf *hw_intf;
struct dpu_hw_wb *hw_wb;
struct dpu_hw_cdm *hw_cdm;
struct dpu_kms *dpu_kms;
struct drm_display_mode cached_mode;
struct mutex vblank_ctl_lock;
enum dpu_enc_split_role split_role;
enum dpu_intf_mode intf_mode;
spinlock_t *enc_spinlock;
enum dpu_enc_enable_state enable_state;
atomic_t vblank_refcount;
int vblank_refcount;
atomic_t vsync_cnt;
atomic_t underrun_cnt;
atomic_t pending_ctlstart_cnt;
@ -210,6 +213,7 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
* @wbirq_refcount: Reference count of writeback interrupt
* @wb_done_timeout_cnt: number of wb done irq timeout errors
* @wb_cfg: writeback block config to store fb related details
* @cdm_cfg: cdm block config needed to store writeback block's CDM configuration
* @wb_conn: backpointer to writeback connector
* @wb_job: backpointer to current writeback job
* @dest: dpu buffer layout for current writeback output buffer
@ -219,6 +223,7 @@ struct dpu_encoder_phys_wb {
atomic_t wbirq_refcount;
int wb_done_timeout_cnt;
struct dpu_hw_wb_cfg wb_cfg;
struct dpu_hw_cdm_cfg cdm_cfg;
struct drm_writeback_connector *wb_conn;
struct drm_writeback_job *wb_job;
struct dpu_hw_fmt_layout dest;
@ -281,22 +286,24 @@ struct dpu_encoder_wait_info {
* @p: Pointer to init params structure
* Return: Error code or newly allocated encoder
*/
struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev,
struct dpu_enc_phys_init_params *p);
/**
* dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder
* @dev: Corresponding device for devres management
* @p: Pointer to init params structure
* Return: Error code or newly allocated encoder
*/
struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev,
struct dpu_enc_phys_init_params *p);
/**
* dpu_encoder_phys_wb_init - initialize writeback encoder
* @dev: Corresponding device for devres management
* @init: Pointer to init info structure with initialization params
*/
struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev,
struct dpu_enc_phys_init_params *p);
/**

View file

@ -13,6 +13,8 @@
#include "dpu_trace.h"
#include "disp/msm_disp_snapshot.h"
#include <drm/drm_managed.h>
#define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
(e) && (e)->base.parent ? \
(e)->base.parent->base.id : -1, \
@ -244,7 +246,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
return -EINVAL;
}
refcount = atomic_read(&phys_enc->vblank_refcount);
mutex_lock(&phys_enc->vblank_ctl_lock);
refcount = phys_enc->vblank_refcount;
/* Slave encoders don't report vblank */
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
@ -260,16 +263,24 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
phys_enc->hw_pp->idx - PINGPONG_0,
enable ? "true" : "false", refcount);
if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
phys_enc->irq[INTR_IDX_RDPTR],
dpu_encoder_phys_cmd_te_rd_ptr_irq,
phys_enc);
else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
phys_enc->irq[INTR_IDX_RDPTR]);
if (enable) {
if (phys_enc->vblank_refcount == 0)
ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
phys_enc->irq[INTR_IDX_RDPTR],
dpu_encoder_phys_cmd_te_rd_ptr_irq,
phys_enc);
if (!ret)
phys_enc->vblank_refcount++;
} else if (!enable) {
if (phys_enc->vblank_refcount == 1)
ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
phys_enc->irq[INTR_IDX_RDPTR]);
if (!ret)
phys_enc->vblank_refcount--;
}
end:
mutex_unlock(&phys_enc->vblank_ctl_lock);
if (ret) {
DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n",
DRMID(phys_enc->parent),
@ -285,7 +296,7 @@ static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
{
trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
phys_enc->hw_pp->idx - PINGPONG_0,
enable, atomic_read(&phys_enc->vblank_refcount));
enable, phys_enc->vblank_refcount);
if (enable) {
dpu_core_irq_register_callback(phys_enc->dpu_kms,
@ -558,14 +569,6 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc)
phys_enc->enable_state = DPU_ENC_DISABLED;
}
static void dpu_encoder_phys_cmd_destroy(struct dpu_encoder_phys *phys_enc)
{
struct dpu_encoder_phys_cmd *cmd_enc =
to_dpu_encoder_phys_cmd(phys_enc);
kfree(cmd_enc);
}
static void dpu_encoder_phys_cmd_prepare_for_kickoff(
struct dpu_encoder_phys *phys_enc)
{
@ -681,33 +684,6 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done(
return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc);
}
static int dpu_encoder_phys_cmd_wait_for_vblank(
struct dpu_encoder_phys *phys_enc)
{
int rc = 0;
struct dpu_encoder_phys_cmd *cmd_enc;
struct dpu_encoder_wait_info wait_info;
cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
/* only required for master controller */
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
return rc;
wait_info.wq = &cmd_enc->pending_vblank_wq;
wait_info.atomic_cnt = &cmd_enc->pending_vblank_cnt;
wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
atomic_inc(&cmd_enc->pending_vblank_cnt);
rc = dpu_encoder_helper_wait_for_irq(phys_enc,
phys_enc->irq[INTR_IDX_RDPTR],
dpu_encoder_phys_cmd_te_rd_ptr_irq,
&wait_info);
return rc;
}
static void dpu_encoder_phys_cmd_handle_post_kickoff(
struct dpu_encoder_phys *phys_enc)
{
@ -731,12 +707,10 @@ static void dpu_encoder_phys_cmd_init_ops(
ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set;
ops->enable = dpu_encoder_phys_cmd_enable;
ops->disable = dpu_encoder_phys_cmd_disable;
ops->destroy = dpu_encoder_phys_cmd_destroy;
ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq;
ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done;
ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff;
ops->wait_for_tx_complete = dpu_encoder_phys_cmd_wait_for_tx_complete;
ops->wait_for_vblank = dpu_encoder_phys_cmd_wait_for_vblank;
ops->trigger_start = dpu_encoder_phys_cmd_trigger_start;
ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush;
ops->irq_control = dpu_encoder_phys_cmd_irq_control;
@ -746,7 +720,7 @@ static void dpu_encoder_phys_cmd_init_ops(
ops->get_line_count = dpu_encoder_phys_cmd_get_line_count;
}
struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev,
struct dpu_enc_phys_init_params *p)
{
struct dpu_encoder_phys *phys_enc = NULL;
@ -754,7 +728,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
DPU_DEBUG("intf\n");
cmd_enc = kzalloc(sizeof(*cmd_enc), GFP_KERNEL);
cmd_enc = drmm_kzalloc(dev, sizeof(*cmd_enc), GFP_KERNEL);
if (!cmd_enc) {
DPU_ERROR("failed to allocate\n");
return ERR_PTR(-ENOMEM);
@ -763,6 +737,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
dpu_encoder_phys_init(phys_enc, p);
mutex_init(&phys_enc->vblank_ctl_lock);
phys_enc->vblank_refcount = 0;
dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
phys_enc->intf_mode = INTF_MODE_CMD;
cmd_enc->stream_sel = 0;

View file

@ -11,6 +11,8 @@
#include "dpu_trace.h"
#include "disp/msm_disp_snapshot.h"
#include <drm/drm_managed.h>
#define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
(e) && (e)->parent ? \
(e)->parent->base.id : -1, \
@ -364,7 +366,8 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
int ret = 0;
int refcount;
refcount = atomic_read(&phys_enc->vblank_refcount);
mutex_lock(&phys_enc->vblank_ctl_lock);
refcount = phys_enc->vblank_refcount;
/* Slave encoders don't report vblank */
if (!dpu_encoder_phys_vid_is_master(phys_enc))
@ -377,18 +380,26 @@ static int dpu_encoder_phys_vid_control_vblank_irq(
}
DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
atomic_read(&phys_enc->vblank_refcount));
refcount);
if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
phys_enc->irq[INTR_IDX_VSYNC],
dpu_encoder_phys_vid_vblank_irq,
phys_enc);
else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
phys_enc->irq[INTR_IDX_VSYNC]);
if (enable) {
if (phys_enc->vblank_refcount == 0)
ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
phys_enc->irq[INTR_IDX_VSYNC],
dpu_encoder_phys_vid_vblank_irq,
phys_enc);
if (!ret)
phys_enc->vblank_refcount++;
} else if (!enable) {
if (phys_enc->vblank_refcount == 1)
ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
phys_enc->irq[INTR_IDX_VSYNC]);
if (!ret)
phys_enc->vblank_refcount--;
}
end:
mutex_unlock(&phys_enc->vblank_ctl_lock);
if (ret) {
DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n",
DRMID(phys_enc->parent),
@ -438,13 +449,7 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
phys_enc->enable_state = DPU_ENC_ENABLING;
}
static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc)
{
DPU_DEBUG_VIDENC(phys_enc, "\n");
kfree(phys_enc);
}
static int dpu_encoder_phys_vid_wait_for_vblank(
static int dpu_encoder_phys_vid_wait_for_tx_complete(
struct dpu_encoder_phys *phys_enc)
{
struct dpu_encoder_wait_info wait_info;
@ -558,7 +563,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
* scanout buffer) don't latch properly..
*/
if (dpu_encoder_phys_vid_is_master(phys_enc)) {
ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc);
ret = dpu_encoder_phys_vid_wait_for_tx_complete(phys_enc);
if (ret) {
atomic_set(&phys_enc->pending_kickoff_cnt, 0);
DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n",
@ -578,7 +583,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
dpu_encoder_phys_inc_pending(phys_enc);
spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc);
ret = dpu_encoder_phys_vid_wait_for_tx_complete(phys_enc);
if (ret) {
atomic_set(&phys_enc->pending_kickoff_cnt, 0);
DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n",
@ -618,7 +623,7 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent),
phys_enc->hw_intf->idx - INTF_0,
enable,
atomic_read(&phys_enc->vblank_refcount));
phys_enc->vblank_refcount);
if (enable) {
ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true);
@ -681,11 +686,9 @@ static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops)
ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set;
ops->enable = dpu_encoder_phys_vid_enable;
ops->disable = dpu_encoder_phys_vid_disable;
ops->destroy = dpu_encoder_phys_vid_destroy;
ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq;
ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done;
ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank;
ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_vblank;
ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_tx_complete;
ops->irq_control = dpu_encoder_phys_vid_irq_control;
ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff;
ops->handle_post_kickoff = dpu_encoder_phys_vid_handle_post_kickoff;
@ -694,7 +697,7 @@ static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops)
ops->get_frame_count = dpu_encoder_phys_vid_get_frame_count;
}
struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev,
struct dpu_enc_phys_init_params *p)
{
struct dpu_encoder_phys *phys_enc = NULL;
@ -704,7 +707,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
return ERR_PTR(-EINVAL);
}
phys_enc = kzalloc(sizeof(*phys_enc), GFP_KERNEL);
phys_enc = drmm_kzalloc(dev, sizeof(*phys_enc), GFP_KERNEL);
if (!phys_enc) {
DPU_ERROR("failed to create encoder due to memory allocation error\n");
return ERR_PTR(-ENOMEM);
@ -713,6 +716,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
DPU_DEBUG_VIDENC(phys_enc, "\n");
dpu_encoder_phys_init(phys_enc, p);
mutex_init(&phys_enc->vblank_ctl_lock);
phys_enc->vblank_refcount = 0;
dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
phys_enc->intf_mode = INTF_MODE_VIDEO;

View file

@ -8,6 +8,7 @@
#include <linux/debugfs.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_managed.h>
#include "dpu_encoder_phys.h"
#include "dpu_formats.h"
@ -206,13 +207,14 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc,
}
/**
* dpu_encoder_phys_wb_setup_cdp - setup chroma down prefetch block
* dpu_encoder_phys_wb_setup_ctl - setup wb pipeline for ctl path
* @phys_enc:Pointer to physical encoder
*/
static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc)
static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc)
{
struct dpu_hw_wb *hw_wb;
struct dpu_hw_ctl *ctl;
struct dpu_hw_cdm *hw_cdm;
if (!phys_enc) {
DPU_ERROR("invalid encoder\n");
@ -221,6 +223,7 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc)
hw_wb = phys_enc->hw_wb;
ctl = phys_enc->hw_ctl;
hw_cdm = phys_enc->hw_cdm;
if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) &&
(phys_enc->hw_ctl &&
@ -237,6 +240,9 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc)
if (mode_3d && hw_pp && hw_pp->merge_3d)
intf_cfg.merge_3d = hw_pp->merge_3d->idx;
if (hw_cdm)
intf_cfg.cdm = hw_cdm->idx;
if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode)
phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
mode_3d);
@ -258,6 +264,96 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc)
}
}
/**
* dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
* This API does not handle DPU_CHROMA_H1V2.
* @phys_enc:Pointer to physical encoder
*/
static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc)
{
struct dpu_hw_cdm *hw_cdm;
struct dpu_hw_cdm_cfg *cdm_cfg;
struct dpu_hw_pingpong *hw_pp;
struct dpu_encoder_phys_wb *wb_enc;
const struct msm_format *format;
const struct dpu_format *dpu_fmt;
struct drm_writeback_job *wb_job;
int ret;
if (!phys_enc)
return;
wb_enc = to_dpu_encoder_phys_wb(phys_enc);
cdm_cfg = &wb_enc->cdm_cfg;
hw_pp = phys_enc->hw_pp;
hw_cdm = phys_enc->hw_cdm;
wb_job = wb_enc->wb_job;
format = msm_framebuffer_format(wb_enc->wb_job->fb);
dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier);
if (!hw_cdm)
return;
if (!DPU_FORMAT_IS_YUV(dpu_fmt)) {
DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", DRMID(phys_enc->parent),
dpu_fmt->base.pixel_format);
if (hw_cdm->ops.bind_pingpong_blk)
hw_cdm->ops.bind_pingpong_blk(hw_cdm, PINGPONG_NONE);
return;
}
memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg));
cdm_cfg->output_width = wb_job->fb->width;
cdm_cfg->output_height = wb_job->fb->height;
cdm_cfg->output_fmt = dpu_fmt;
cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB;
cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ?
CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT;
cdm_cfg->csc_cfg = &dpu_csc10_rgb2yuv_601l;
/* enable 10 bit logic */
switch (cdm_cfg->output_fmt->chroma_sample) {
case DPU_CHROMA_RGB:
cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
break;
case DPU_CHROMA_H2V1:
cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
break;
case DPU_CHROMA_420:
cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE;
break;
case DPU_CHROMA_H1V2:
default:
DPU_ERROR("[enc:%d] unsupported chroma sampling type\n",
DRMID(phys_enc->parent));
cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
break;
}
DPU_DEBUG("[enc:%d] cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n",
DRMID(phys_enc->parent), cdm_cfg->output_width,
cdm_cfg->output_height, cdm_cfg->output_fmt->base.pixel_format,
cdm_cfg->output_type, cdm_cfg->output_bit_depth,
cdm_cfg->h_cdwn_type, cdm_cfg->v_cdwn_type);
if (hw_cdm->ops.enable) {
cdm_cfg->pp_id = hw_pp->idx;
ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg);
if (ret < 0) {
DPU_ERROR("[enc:%d] failed to enable CDM; ret:%d\n",
DRMID(phys_enc->parent), ret);
return;
}
}
}
/**
* dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states
* @phys_enc: Pointer to physical encoder
@ -307,7 +403,7 @@ static int dpu_encoder_phys_wb_atomic_check(
return -EINVAL;
}
return 0;
return drm_atomic_helper_check_wb_connector_state(conn_state->connector, conn_state->state);
}
@ -320,6 +416,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
struct dpu_hw_wb *hw_wb;
struct dpu_hw_ctl *hw_ctl;
struct dpu_hw_pingpong *hw_pp;
struct dpu_hw_cdm *hw_cdm;
u32 pending_flush = 0;
if (!phys_enc)
@ -328,6 +425,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
hw_wb = phys_enc->hw_wb;
hw_pp = phys_enc->hw_pp;
hw_ctl = phys_enc->hw_ctl;
hw_cdm = phys_enc->hw_cdm;
DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
@ -343,6 +441,9 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl,
hw_pp->merge_3d->idx);
if (hw_cdm && hw_ctl->ops.update_pending_flush_cdm)
hw_ctl->ops.update_pending_flush_cdm(hw_ctl, hw_cdm->idx);
if (hw_ctl->ops.get_pending_flush)
pending_flush = hw_ctl->ops.get_pending_flush(hw_ctl);
@ -374,8 +475,9 @@ static void dpu_encoder_phys_wb_setup(
dpu_encoder_phys_wb_setup_fb(phys_enc, fb);
dpu_encoder_phys_wb_setup_cdp(phys_enc);
dpu_encoder_helper_phys_setup_cdm(phys_enc);
dpu_encoder_phys_wb_setup_ctl(phys_enc);
}
/**
@ -580,20 +682,6 @@ static void dpu_encoder_phys_wb_disable(struct dpu_encoder_phys *phys_enc)
phys_enc->enable_state = DPU_ENC_DISABLED;
}
/**
* dpu_encoder_phys_wb_destroy - destroy writeback encoder
* @phys_enc: Pointer to physical encoder
*/
static void dpu_encoder_phys_wb_destroy(struct dpu_encoder_phys *phys_enc)
{
if (!phys_enc)
return;
DPU_DEBUG("[wb:%d]\n", phys_enc->hw_wb->idx - WB_0);
kfree(phys_enc);
}
static void dpu_encoder_phys_wb_prepare_wb_job(struct dpu_encoder_phys *phys_enc,
struct drm_writeback_job *job)
{
@ -689,7 +777,6 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops)
ops->atomic_mode_set = dpu_encoder_phys_wb_atomic_mode_set;
ops->enable = dpu_encoder_phys_wb_enable;
ops->disable = dpu_encoder_phys_wb_disable;
ops->destroy = dpu_encoder_phys_wb_destroy;
ops->atomic_check = dpu_encoder_phys_wb_atomic_check;
ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done;
ops->prepare_for_kickoff = dpu_encoder_phys_wb_prepare_for_kickoff;
@ -705,9 +792,10 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops)
/**
* dpu_encoder_phys_wb_init - initialize writeback encoder
* @dev: Corresponding device for devres management
* @p: Pointer to init info structure with initialization params
*/
struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev,
struct dpu_enc_phys_init_params *p)
{
struct dpu_encoder_phys *phys_enc = NULL;
@ -720,7 +808,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
return ERR_PTR(-EINVAL);
}
wb_enc = kzalloc(sizeof(*wb_enc), GFP_KERNEL);
wb_enc = drmm_kzalloc(dev, sizeof(*wb_enc), GFP_KERNEL);
if (!wb_enc) {
DPU_ERROR("failed to allocate wb phys_enc enc\n");
return ERR_PTR(-ENOMEM);

View file

@ -22,23 +22,14 @@
BIT(DPU_SSPP_CSC_10BIT))
#define VIG_MSM8998_MASK \
(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE))
#define VIG_SDM845_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
(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))
#define VIG_SC7180_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
#define VIG_SM6125_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
#define VIG_SC7180_MASK_SDMA \
(VIG_SC7180_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
#define DMA_MSM8998_MASK \
@ -47,7 +38,7 @@
BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
#define VIG_SC7280_MASK \
(VIG_SC7180_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
(VIG_SDM845_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
#define VIG_SC7280_MASK_SDMA \
(VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
@ -211,7 +202,7 @@ static const u32 rotation_v2_formats[] = {
/* TODO add formats after validation */
};
static const uint32_t wb2_formats[] = {
static const u32 wb2_formats_rgb[] = {
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
DRM_FORMAT_RGB888,
@ -245,21 +236,56 @@ static const uint32_t wb2_formats[] = {
DRM_FORMAT_XBGR4444,
};
static const u32 wb2_formats_rgb_yuv[] = {
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
DRM_FORMAT_RGB888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_RGBA8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_RGBX8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ARGB1555,
DRM_FORMAT_RGBA5551,
DRM_FORMAT_XRGB1555,
DRM_FORMAT_RGBX5551,
DRM_FORMAT_ARGB4444,
DRM_FORMAT_RGBA4444,
DRM_FORMAT_RGBX4444,
DRM_FORMAT_XRGB4444,
DRM_FORMAT_BGR565,
DRM_FORMAT_BGR888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_BGRA8888,
DRM_FORMAT_BGRX8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ABGR1555,
DRM_FORMAT_BGRA5551,
DRM_FORMAT_XBGR1555,
DRM_FORMAT_BGRX5551,
DRM_FORMAT_ABGR4444,
DRM_FORMAT_BGRA4444,
DRM_FORMAT_BGRX4444,
DRM_FORMAT_XBGR4444,
DRM_FORMAT_NV12,
};
/*************************************************************
* SSPP sub blocks config
*************************************************************/
#define SSPP_SCALER_VER(maj, min) (((maj) << 16) | (min))
/* SSPP common configuration */
#define _VIG_SBLK(sdma_pri, qseed_ver) \
#define _VIG_SBLK(scaler_ver) \
{ \
.maxdwnscale = MAX_DOWNSCALE_RATIO, \
.maxupscale = MAX_UPSCALE_RATIO, \
.smart_dma_priority = sdma_pri, \
.scaler_blk = {.name = "scaler", \
.id = qseed_ver, \
.version = scaler_ver, \
.base = 0xa00, .len = 0xa0,}, \
.csc_blk = {.name = "csc", \
.id = DPU_SSPP_CSC_10BIT, \
.base = 0x1a00, .len = 0x100,}, \
.format_list = plane_formats_yuv, \
.num_formats = ARRAY_SIZE(plane_formats_yuv), \
@ -268,16 +294,14 @@ static const uint32_t wb2_formats[] = {
.rotation_cfg = NULL, \
}
#define _VIG_SBLK_ROT(sdma_pri, qseed_ver, rot_cfg) \
#define _VIG_SBLK_ROT(scaler_ver, rot_cfg) \
{ \
.maxdwnscale = MAX_DOWNSCALE_RATIO, \
.maxupscale = MAX_UPSCALE_RATIO, \
.smart_dma_priority = sdma_pri, \
.scaler_blk = {.name = "scaler", \
.id = qseed_ver, \
.version = scaler_ver, \
.base = 0xa00, .len = 0xa0,}, \
.csc_blk = {.name = "csc", \
.id = DPU_SSPP_CSC_10BIT, \
.base = 0x1a00, .len = 0x100,}, \
.format_list = plane_formats_yuv, \
.num_formats = ARRAY_SIZE(plane_formats_yuv), \
@ -286,91 +310,64 @@ static const uint32_t wb2_formats[] = {
.rotation_cfg = rot_cfg, \
}
#define _DMA_SBLK(sdma_pri) \
#define _VIG_SBLK_NOSCALE() \
{ \
.maxdwnscale = SSPP_UNITY_SCALE, \
.maxupscale = SSPP_UNITY_SCALE, \
.format_list = plane_formats_yuv, \
.num_formats = ARRAY_SIZE(plane_formats_yuv), \
.virt_format_list = plane_formats, \
.virt_num_formats = ARRAY_SIZE(plane_formats), \
}
#define _DMA_SBLK() \
{ \
.maxdwnscale = SSPP_UNITY_SCALE, \
.maxupscale = SSPP_UNITY_SCALE, \
.smart_dma_priority = sdma_pri, \
.format_list = plane_formats, \
.num_formats = ARRAY_SIZE(plane_formats), \
.virt_format_list = plane_formats, \
.virt_num_formats = ARRAY_SIZE(plane_formats), \
}
static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 =
_VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3);
static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 =
_VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3);
static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 =
_VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3);
static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 =
_VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3);
static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = {
.rot_maxheight = 1088,
.rot_num_formats = ARRAY_SIZE(rotation_v2_formats),
.rot_format_list = rotation_v2_formats,
};
static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 =
_VIG_SBLK(5, DPU_SSPP_SCALER_QSEED3);
static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 =
_VIG_SBLK(6, DPU_SSPP_SCALER_QSEED3);
static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 =
_VIG_SBLK(7, DPU_SSPP_SCALER_QSEED3);
static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 =
_VIG_SBLK(8, DPU_SSPP_SCALER_QSEED3);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_noscale =
_VIG_SBLK_NOSCALE();
static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK(1);
static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK(2);
static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK(3);
static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK(4);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_2 =
_VIG_SBLK(SSPP_SCALER_VER(1, 2));
static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 =
_VIG_SBLK(4, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_3 =
_VIG_SBLK(SSPP_SCALER_VER(1, 3));
static const struct dpu_sspp_sub_blks sc7280_vig_sblk_0 =
_VIG_SBLK_ROT(4, DPU_SSPP_SCALER_QSEED4, &dpu_rot_sc7280_cfg_v2);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_4 =
_VIG_SBLK(SSPP_SCALER_VER(1, 4));
static const struct dpu_sspp_sub_blks sm6115_vig_sblk_0 =
_VIG_SBLK(2, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_2_4 =
_VIG_SBLK(SSPP_SCALER_VER(2, 4));
static const struct dpu_sspp_sub_blks sm6125_vig_sblk_0 =
_VIG_SBLK(3, DPU_SSPP_SCALER_QSEED3LITE);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0 =
_VIG_SBLK(SSPP_SCALER_VER(3, 0));
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 =
_VIG_SBLK(5, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 =
_VIG_SBLK(6, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 =
_VIG_SBLK(7, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 =
_VIG_SBLK(8, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0_rot_v2 =
_VIG_SBLK_ROT(SSPP_SCALER_VER(3, 0),
&dpu_rot_sc7280_cfg_v2);
static const struct dpu_sspp_sub_blks sm8550_vig_sblk_0 =
_VIG_SBLK(7, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks sm8550_vig_sblk_1 =
_VIG_SBLK(8, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks sm8550_vig_sblk_2 =
_VIG_SBLK(9, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks sm8550_vig_sblk_3 =
_VIG_SBLK(10, DPU_SSPP_SCALER_QSEED4);
static const struct dpu_sspp_sub_blks sm8550_dma_sblk_4 = _DMA_SBLK(5);
static const struct dpu_sspp_sub_blks sm8550_dma_sblk_5 = _DMA_SBLK(6);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_1 =
_VIG_SBLK(SSPP_SCALER_VER(3, 1));
#define _VIG_SBLK_NOSCALE(sdma_pri) \
{ \
.maxdwnscale = SSPP_UNITY_SCALE, \
.maxupscale = SSPP_UNITY_SCALE, \
.smart_dma_priority = sdma_pri, \
.format_list = plane_formats_yuv, \
.num_formats = ARRAY_SIZE(plane_formats_yuv), \
.virt_format_list = plane_formats, \
.virt_num_formats = ARRAY_SIZE(plane_formats), \
}
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_2 =
_VIG_SBLK(SSPP_SCALER_VER(3, 2));
static const struct dpu_sspp_sub_blks qcm2290_vig_sblk_0 = _VIG_SBLK_NOSCALE(2);
static const struct dpu_sspp_sub_blks qcm2290_dma_sblk_0 = _DMA_SBLK(1);
static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_3 =
_VIG_SBLK(SSPP_SCALER_VER(3, 3));
static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();
/*************************************************************
* MIXER sub blocks config
@ -422,12 +419,12 @@ static const struct dpu_lm_sub_blks qcm2290_lm_sblk = {
* DSPP sub blocks config
*************************************************************/
static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = {
.pcc = {.name = "pcc", .id = DPU_DSPP_PCC, .base = 0x1700,
.pcc = {.name = "pcc", .base = 0x1700,
.len = 0x90, .version = 0x10007},
};
static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = {
.pcc = {.name = "pcc", .id = DPU_DSPP_PCC, .base = 0x1700,
.pcc = {.name = "pcc", .base = 0x1700,
.len = 0x90, .version = 0x40000},
};
@ -435,19 +432,19 @@ static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = {
* PINGPONG sub blocks config
*************************************************************/
static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = {
.te2 = {.name = "te2", .id = DPU_PINGPONG_TE2, .base = 0x2000, .len = 0x0,
.te2 = {.name = "te2", .base = 0x2000, .len = 0x0,
.version = 0x1},
.dither = {.name = "dither", .id = DPU_PINGPONG_DITHER, .base = 0x30e0,
.dither = {.name = "dither", .base = 0x30e0,
.len = 0x20, .version = 0x10000},
};
static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
.dither = {.name = "dither", .id = DPU_PINGPONG_DITHER, .base = 0x30e0,
.dither = {.name = "dither", .base = 0x30e0,
.len = 0x20, .version = 0x10000},
};
static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
.dither = {.name = "dither", .id = DPU_PINGPONG_DITHER, .base = 0xe0,
.dither = {.name = "dither", .base = 0xe0,
.len = 0x20, .version = 0x20000},
};
@ -464,6 +461,16 @@ static const struct dpu_dsc_sub_blks dsc_sblk_1 = {
.ctl = {.name = "ctl", .base = 0xF80, .len = 0x10},
};
/*************************************************************
* CDM block config
*************************************************************/
static const struct dpu_cdm_cfg sc7280_cdm = {
.name = "cdm_0",
.id = CDM_0,
.len = 0x228,
.base = 0x79200,
};
/*************************************************************
* VBIF sub blocks config
*************************************************************/
@ -472,6 +479,7 @@ static const u32 msm8998_rt_pri_lvl[] = {1, 2, 2, 2};
static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1};
static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3};
static const u32 sm8650_rt_pri_lvl[] = {4, 4, 5, 5, 5, 5, 5, 6};
static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = {
{
@ -558,6 +566,26 @@ static const struct dpu_vbif_cfg sm8550_vbif[] = {
},
};
static const struct dpu_vbif_cfg sm8650_vbif[] = {
{
.name = "vbif_rt", .id = VBIF_RT,
.base = 0, .len = 0x1074,
.features = BIT(DPU_VBIF_QOS_REMAP),
.xin_halt_timeout = 0x4000,
.qos_rp_remap_size = 0x40,
.qos_rt_tbl = {
.npriority_lvl = ARRAY_SIZE(sm8650_rt_pri_lvl),
.priority_lvl = sm8650_rt_pri_lvl,
},
.qos_nrt_tbl = {
.npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
.priority_lvl = sdm845_nrt_pri_lvl,
},
.memtype_count = 16,
.memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
},
};
/*************************************************************
* PERF data config
*************************************************************/
@ -654,6 +682,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
#include "catalog/dpu_3_0_msm8998.h"
#include "catalog/dpu_4_0_sdm845.h"
#include "catalog/dpu_4_1_sdm670.h"
#include "catalog/dpu_5_0_sm8150.h"
#include "catalog/dpu_5_1_sc8180x.h"
@ -673,3 +702,5 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
#include "catalog/dpu_8_1_sm8450.h"
#include "catalog/dpu_9_0_sm8550.h"
#include "catalog/dpu_10_0_sm8650.h"

View file

@ -51,9 +51,7 @@ enum {
/**
* SSPP sub-blocks/features
* @DPU_SSPP_SCALER_QSEED2, QSEED2 algorithm support
* @DPU_SSPP_SCALER_QSEED3, QSEED3 alogorithm support
* @DPU_SSPP_SCALER_QSEED3LITE, QSEED3 Lite alogorithm support
* @DPU_SSPP_SCALER_QSEED4, QSEED4 algorithm support
* @DPU_SSPP_SCALER_QSEED3_COMPATIBLE, QSEED3-compatible alogorithm support (includes QSEED3, QSEED3LITE and QSEED4)
* @DPU_SSPP_SCALER_RGB, RGB Scaler, supported by RGB pipes
* @DPU_SSPP_CSC, Support of Color space converion
* @DPU_SSPP_CSC_10BIT, Support of 10-bit Color space conversion
@ -71,9 +69,7 @@ enum {
*/
enum {
DPU_SSPP_SCALER_QSEED2 = 0x1,
DPU_SSPP_SCALER_QSEED3,
DPU_SSPP_SCALER_QSEED3LITE,
DPU_SSPP_SCALER_QSEED4,
DPU_SSPP_SCALER_QSEED3_COMPATIBLE,
DPU_SSPP_SCALER_RGB,
DPU_SSPP_CSC,
DPU_SSPP_CSC_10BIT,
@ -248,50 +244,51 @@ enum {
u32 len; \
unsigned long features
/**
* MACRO DPU_HW_SUBBLK_INFO - information of HW sub-block inside DPU
* @name: string name for debug purposes
* @id: enum identifying this sub-block
* @base: offset of this sub-block relative to the block
* offset
* @len register block length of this sub-block
*/
#define DPU_HW_SUBBLK_INFO \
char name[DPU_HW_BLK_NAME_LEN]; \
u32 id; \
u32 base; \
u32 len
/**
* struct dpu_scaler_blk: Scaler information
* @info: HW register and features supported by this sub-blk
* @version: qseed block revision
* @name: string name for debug purposes
* @base: offset of this sub-block relative to the block offset
* @len: register block length of this sub-block
* @version: qseed block revision, on QSEED3+ platforms this is the value of
* scaler_blk.base + QSEED3_HW_VERSION registers.
*/
struct dpu_scaler_blk {
DPU_HW_SUBBLK_INFO;
char name[DPU_HW_BLK_NAME_LEN];
u32 base;
u32 len;
u32 version;
};
struct dpu_csc_blk {
DPU_HW_SUBBLK_INFO;
char name[DPU_HW_BLK_NAME_LEN];
u32 base;
u32 len;
};
/**
* struct dpu_pp_blk : Pixel processing sub-blk information
* @info: HW register and features supported by this sub-blk
* @name: string name for debug purposes
* @base: offset of this sub-block relative to the block offset
* @len: register block length of this sub-block
* @version: HW Algorithm version
*/
struct dpu_pp_blk {
DPU_HW_SUBBLK_INFO;
char name[DPU_HW_BLK_NAME_LEN];
u32 base;
u32 len;
u32 version;
};
/**
* struct dpu_dsc_blk - DSC Encoder sub-blk information
* @info: HW register and features supported by this sub-blk
* @name: string name for debug purposes
* @base: offset of this sub-block relative to the block offset
* @len: register block length of this sub-block
*/
struct dpu_dsc_blk {
DPU_HW_SUBBLK_INFO;
char name[DPU_HW_BLK_NAME_LEN];
u32 base;
u32 len;
};
/**
@ -341,7 +338,6 @@ struct dpu_rotation_cfg {
* @max_mixer_width max layer mixer line width support.
* @max_mixer_blendstages max layer mixer blend stages or
* supported z order
* @qseed_type qseed2 or qseed3 support.
* @has_src_split source split feature status
* @has_dim_layer dim layer feature status
* @has_idle_pc indicate if idle power collapse feature is supported
@ -354,7 +350,6 @@ struct dpu_rotation_cfg {
struct dpu_caps {
u32 max_mixer_width;
u32 max_mixer_blendstages;
u32 qseed_type;
bool has_src_split;
bool has_dim_layer;
bool has_idle_pc;
@ -371,7 +366,6 @@ struct dpu_caps {
* common: Pointer to common configurations shared by sub blocks
* @maxdwnscale: max downscale ratio supported(without DECIMATION)
* @maxupscale: maxupscale ratio supported
* @smart_dma_priority: hw priority of rect1 of multirect pipe
* @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps
* @qseed_ver: qseed version
* @scaler_blk:
@ -385,7 +379,6 @@ struct dpu_caps {
struct dpu_sspp_sub_blks {
u32 maxdwnscale;
u32 maxupscale;
u32 smart_dma_priority;
u32 max_per_pipe_bw;
u32 qseed_ver;
struct dpu_scaler_blk scaler_blk;
@ -689,6 +682,17 @@ struct dpu_vbif_cfg {
u32 memtype[MAX_XIN_COUNT];
};
/**
* struct dpu_cdm_cfg - information of chroma down blocks
* @name string name for debug purposes
* @id enum identifying this block
* @base register offset of this block
* @features bit mask identifying sub-blocks/features
*/
struct dpu_cdm_cfg {
DPU_HW_BLK_INFO;
};
/**
* Define CDP use cases
* @DPU_PERF_CDP_UDAGE_RT: real-time use cases
@ -812,6 +816,8 @@ struct dpu_mdss_cfg {
u32 wb_count;
const struct dpu_wb_cfg *wb;
const struct dpu_cdm_cfg *cdm;
u32 ad_count;
u32 dspp_count;
@ -827,6 +833,7 @@ struct dpu_mdss_cfg {
extern const struct dpu_mdss_cfg dpu_msm8998_cfg;
extern const struct dpu_mdss_cfg dpu_sdm845_cfg;
extern const struct dpu_mdss_cfg dpu_sdm670_cfg;
extern const struct dpu_mdss_cfg dpu_sm8150_cfg;
extern const struct dpu_mdss_cfg dpu_sc8180x_cfg;
extern const struct dpu_mdss_cfg dpu_sm8250_cfg;
@ -841,5 +848,6 @@ extern const struct dpu_mdss_cfg dpu_sc7280_cfg;
extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg;
extern const struct dpu_mdss_cfg dpu_sm8450_cfg;
extern const struct dpu_mdss_cfg dpu_sm8550_cfg;
extern const struct dpu_mdss_cfg dpu_sm8650_cfg;
#endif /* _DPU_HW_CATALOG_H */

View file

@ -0,0 +1,247 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2023, The Linux Foundation. All rights reserved.
*/
#include <linux/bitfield.h>
#include <drm/drm_managed.h>
#include "dpu_hw_mdss.h"
#include "dpu_hw_util.h"
#include "dpu_hw_catalog.h"
#include "dpu_hw_cdm.h"
#include "dpu_kms.h"
#define CDM_CSC_10_OPMODE 0x000
#define CDM_CSC_10_BASE 0x004
#define CDM_CDWN2_OP_MODE 0x100
#define CDM_CDWN2_CLAMP_OUT 0x104
#define CDM_CDWN2_PARAMS_3D_0 0x108
#define CDM_CDWN2_PARAMS_3D_1 0x10C
#define CDM_CDWN2_COEFF_COSITE_H_0 0x110
#define CDM_CDWN2_COEFF_COSITE_H_1 0x114
#define CDM_CDWN2_COEFF_COSITE_H_2 0x118
#define CDM_CDWN2_COEFF_OFFSITE_H_0 0x11C
#define CDM_CDWN2_COEFF_OFFSITE_H_1 0x120
#define CDM_CDWN2_COEFF_OFFSITE_H_2 0x124
#define CDM_CDWN2_COEFF_COSITE_V 0x128
#define CDM_CDWN2_COEFF_OFFSITE_V 0x12C
#define CDM_CDWN2_OUT_SIZE 0x130
#define CDM_HDMI_PACK_OP_MODE 0x200
#define CDM_CSC_10_MATRIX_COEFF_0 0x004
#define CDM_MUX 0x224
/* CDM CDWN2 sub-block bit definitions */
#define CDM_CDWN2_OP_MODE_EN BIT(0)
#define CDM_CDWN2_OP_MODE_ENABLE_H BIT(1)
#define CDM_CDWN2_OP_MODE_ENABLE_V BIT(2)
#define CDM_CDWN2_OP_MODE_BITS_OUT_8BIT BIT(7)
#define CDM_CDWN2_V_PIXEL_METHOD_MASK GENMASK(6, 5)
#define CDM_CDWN2_H_PIXEL_METHOD_MASK GENMASK(4, 3)
/* CDM CSC10 sub-block bit definitions */
#define CDM_CSC10_OP_MODE_EN BIT(0)
#define CDM_CSC10_OP_MODE_SRC_FMT_YUV BIT(1)
#define CDM_CSC10_OP_MODE_DST_FMT_YUV BIT(2)
/* CDM HDMI pack sub-block bit definitions */
#define CDM_HDMI_PACK_OP_MODE_EN BIT(0)
/*
* Horizontal coefficients for cosite chroma downscale
* s13 representation of coefficients
*/
static u32 cosite_h_coeff[] = {0x00000016, 0x000001cc, 0x0100009e};
/*
* Horizontal coefficients for offsite chroma downscale
*/
static u32 offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046};
/*
* Vertical coefficients for cosite chroma downscale
*/
static u32 cosite_v_coeff[] = {0x00080004};
/*
* Vertical coefficients for offsite chroma downscale
*/
static u32 offsite_v_coeff[] = {0x00060002};
static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx, struct dpu_hw_cdm_cfg *cfg)
{
struct dpu_hw_blk_reg_map *c = &ctx->hw;
u32 opmode;
u32 out_size;
switch (cfg->h_cdwn_type) {
case CDM_CDWN_DISABLE:
opmode = 0;
break;
case CDM_CDWN_PIXEL_DROP:
opmode = CDM_CDWN2_OP_MODE_ENABLE_H |
FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK,
CDM_CDWN2_METHOD_PIXEL_DROP);
break;
case CDM_CDWN_AVG:
opmode = CDM_CDWN2_OP_MODE_ENABLE_H |
FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK,
CDM_CDWN2_METHOD_AVG);
break;
case CDM_CDWN_COSITE:
opmode = CDM_CDWN2_OP_MODE_ENABLE_H |
FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK,
CDM_CDWN2_METHOD_COSITE);
DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_0,
cosite_h_coeff[0]);
DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_1,
cosite_h_coeff[1]);
DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_2,
cosite_h_coeff[2]);
break;
case CDM_CDWN_OFFSITE:
opmode = CDM_CDWN2_OP_MODE_ENABLE_H |
FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK, CDM_CDWN2_METHOD_OFFSITE);
DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_0,
offsite_h_coeff[0]);
DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_1,
offsite_h_coeff[1]);
DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_2,
offsite_h_coeff[2]);
break;
default:
DPU_ERROR("%s invalid horz down sampling type\n", __func__);
return -EINVAL;
}
switch (cfg->v_cdwn_type) {
case CDM_CDWN_DISABLE:
/* if its only Horizontal downsample, we dont need to do anything here */
break;
case CDM_CDWN_PIXEL_DROP:
opmode |= CDM_CDWN2_OP_MODE_ENABLE_V |
FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK,
CDM_CDWN2_METHOD_PIXEL_DROP);
break;
case CDM_CDWN_AVG:
opmode |= CDM_CDWN2_OP_MODE_ENABLE_V |
FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK,
CDM_CDWN2_METHOD_AVG);
break;
case CDM_CDWN_COSITE:
opmode |= CDM_CDWN2_OP_MODE_ENABLE_V |
FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK,
CDM_CDWN2_METHOD_COSITE);
DPU_REG_WRITE(c,
CDM_CDWN2_COEFF_COSITE_V,
cosite_v_coeff[0]);
break;
case CDM_CDWN_OFFSITE:
opmode |= CDM_CDWN2_OP_MODE_ENABLE_V |
FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK,
CDM_CDWN2_METHOD_OFFSITE);
DPU_REG_WRITE(c,
CDM_CDWN2_COEFF_OFFSITE_V,
offsite_v_coeff[0]);
break;
default:
return -EINVAL;
}
if (cfg->output_bit_depth != CDM_CDWN_OUTPUT_10BIT)
opmode |= CDM_CDWN2_OP_MODE_BITS_OUT_8BIT;
if (cfg->v_cdwn_type || cfg->h_cdwn_type)
opmode |= CDM_CDWN2_OP_MODE_EN; /* EN CDWN module */
else
opmode &= ~CDM_CDWN2_OP_MODE_EN;
out_size = (cfg->output_width & 0xFFFF) | ((cfg->output_height & 0xFFFF) << 16);
DPU_REG_WRITE(c, CDM_CDWN2_OUT_SIZE, out_size);
DPU_REG_WRITE(c, CDM_CDWN2_OP_MODE, opmode);
DPU_REG_WRITE(c, CDM_CDWN2_CLAMP_OUT, ((0x3FF << 16) | 0x0));
return 0;
}
static int dpu_hw_cdm_enable(struct dpu_hw_cdm *ctx, struct dpu_hw_cdm_cfg *cdm)
{
struct dpu_hw_blk_reg_map *c = &ctx->hw;
const struct dpu_format *fmt;
u32 opmode = 0;
u32 csc = 0;
if (!ctx || !cdm)
return -EINVAL;
fmt = cdm->output_fmt;
if (!DPU_FORMAT_IS_YUV(fmt))
return -EINVAL;
dpu_hw_csc_setup(&ctx->hw, CDM_CSC_10_MATRIX_COEFF_0, cdm->csc_cfg, true);
dpu_hw_cdm_setup_cdwn(ctx, cdm);
if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) {
if (fmt->chroma_sample != DPU_CHROMA_H1V2)
return -EINVAL; /*unsupported format */
opmode = CDM_HDMI_PACK_OP_MODE_EN;
opmode |= (fmt->chroma_sample << 1);
}
csc |= CDM_CSC10_OP_MODE_DST_FMT_YUV;
csc &= ~CDM_CSC10_OP_MODE_SRC_FMT_YUV;
csc |= CDM_CSC10_OP_MODE_EN;
if (ctx && ctx->ops.bind_pingpong_blk)
ctx->ops.bind_pingpong_blk(ctx, cdm->pp_id);
DPU_REG_WRITE(c, CDM_CSC_10_OPMODE, csc);
DPU_REG_WRITE(c, CDM_HDMI_PACK_OP_MODE, opmode);
return 0;
}
static void dpu_hw_cdm_bind_pingpong_blk(struct dpu_hw_cdm *ctx, const enum dpu_pingpong pp)
{
struct dpu_hw_blk_reg_map *c;
int mux_cfg;
c = &ctx->hw;
mux_cfg = DPU_REG_READ(c, CDM_MUX);
mux_cfg &= ~0xf;
if (pp)
mux_cfg |= (pp - PINGPONG_0) & 0x7;
else
mux_cfg |= 0xf;
DPU_REG_WRITE(c, CDM_MUX, mux_cfg);
}
struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev,
const struct dpu_cdm_cfg *cfg, void __iomem *addr,
const struct dpu_mdss_version *mdss_rev)
{
struct dpu_hw_cdm *c;
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
c->hw.blk_addr = addr + cfg->base;
c->hw.log_mask = DPU_DBG_MASK_CDM;
/* Assign ops */
c->idx = cfg->id;
c->caps = cfg;
c->ops.enable = dpu_hw_cdm_enable;
if (mdss_rev->core_major_ver >= 5)
c->ops.bind_pingpong_blk = dpu_hw_cdm_bind_pingpong_blk;
return c;
}

View file

@ -0,0 +1,142 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023, The Linux Foundation. All rights reserved.
*/
#ifndef _DPU_HW_CDM_H
#define _DPU_HW_CDM_H
#include "dpu_hw_mdss.h"
#include "dpu_hw_top.h"
struct dpu_hw_cdm;
/**
* struct dpu_hw_cdm_cfg : current configuration of CDM block
*
* @output_width: output ROI width of CDM block
* @output_height: output ROI height of CDM block
* @output_bit_depth: output bit-depth of CDM block
* @h_cdwn_type: downsample type used for horizontal pixels
* @v_cdwn_type: downsample type used for vertical pixels
* @output_fmt: handle to dpu_format of CDM block
* @csc_cfg: handle to CSC matrix programmed for CDM block
* @output_type: interface to which CDM is paired (HDMI/WB)
* @pp_id: ping-pong block to which CDM is bound to
*/
struct dpu_hw_cdm_cfg {
u32 output_width;
u32 output_height;
u32 output_bit_depth;
u32 h_cdwn_type;
u32 v_cdwn_type;
const struct dpu_format *output_fmt;
const struct dpu_csc_cfg *csc_cfg;
u32 output_type;
int pp_id;
};
/*
* These values are used indicate which type of downsample is used
* in the horizontal/vertical direction for the CDM block.
*/
enum dpu_hw_cdwn_type {
CDM_CDWN_DISABLE,
CDM_CDWN_PIXEL_DROP,
CDM_CDWN_AVG,
CDM_CDWN_COSITE,
CDM_CDWN_OFFSITE,
};
/*
* CDM block can be paired with WB or HDMI block. These values match
* the input with which the CDM block is paired.
*/
enum dpu_hw_cdwn_output_type {
CDM_CDWN_OUTPUT_HDMI,
CDM_CDWN_OUTPUT_WB,
};
/*
* CDM block can give an 8-bit or 10-bit output. These values
* are used to indicate the output bit depth of CDM block
*/
enum dpu_hw_cdwn_output_bit_depth {
CDM_CDWN_OUTPUT_8BIT,
CDM_CDWN_OUTPUT_10BIT,
};
/*
* CDM block can downsample using different methods. These values
* are used to indicate the downsample method which can be used
* either in the horizontal or vertical direction.
*/
enum dpu_hw_cdwn_op_mode_method_h_v {
CDM_CDWN2_METHOD_PIXEL_DROP,
CDM_CDWN2_METHOD_AVG,
CDM_CDWN2_METHOD_COSITE,
CDM_CDWN2_METHOD_OFFSITE
};
/**
* struct dpu_hw_cdm_ops : Interface to the chroma down Hw driver functions
* Assumption is these functions will be called after
* clocks are enabled
* @enable: Enables the output to interface and programs the
* output packer
* @bind_pingpong_blk: enable/disable the connection with pingpong which
* will feed pixels to this cdm
*/
struct dpu_hw_cdm_ops {
/**
* Enable the CDM module
* @cdm Pointer to chroma down context
*/
int (*enable)(struct dpu_hw_cdm *cdm, struct dpu_hw_cdm_cfg *cfg);
/**
* Enable/disable the connection with pingpong
* @cdm Pointer to chroma down context
* @pp pingpong block id.
*/
void (*bind_pingpong_blk)(struct dpu_hw_cdm *cdm, const enum dpu_pingpong pp);
};
/**
* struct dpu_hw_cdm - cdm description
* @base: Hardware block base structure
* @hw: Block hardware details
* @idx: CDM index
* @caps: Pointer to cdm_cfg
* @ops: handle to operations possible for this CDM
*/
struct dpu_hw_cdm {
struct dpu_hw_blk base;
struct dpu_hw_blk_reg_map hw;
/* chroma down */
const struct dpu_cdm_cfg *caps;
enum dpu_cdm idx;
/* ops */
struct dpu_hw_cdm_ops ops;
};
/**
* dpu_hw_cdm_init - initializes the cdm hw driver object.
* should be called once before accessing every cdm.
* @dev: DRM device handle
* @cdm: CDM catalog entry for which driver object is required
* @addr : mapped register io address of MDSS
* @mdss_rev: mdss hw core revision
*/
struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev,
const struct dpu_cdm_cfg *cdm, void __iomem *addr,
const struct dpu_mdss_version *mdss_rev);
static inline struct dpu_hw_cdm *to_dpu_hw_cdm(struct dpu_hw_blk *hw)
{
return container_of(hw, struct dpu_hw_cdm, base);
}
#endif /*_DPU_HW_CDM_H */

View file

@ -4,6 +4,9 @@
*/
#include <linux/delay.h>
#include <drm/drm_managed.h>
#include "dpu_hwio.h"
#include "dpu_hw_ctl.h"
#include "dpu_kms.h"
@ -29,11 +32,13 @@
#define CTL_DSC_ACTIVE 0x0E8
#define CTL_WB_ACTIVE 0x0EC
#define CTL_INTF_ACTIVE 0x0F4
#define CTL_CDM_ACTIVE 0x0F8
#define CTL_FETCH_PIPE_ACTIVE 0x0FC
#define CTL_MERGE_3D_FLUSH 0x100
#define CTL_DSC_FLUSH 0x104
#define CTL_WB_FLUSH 0x108
#define CTL_INTF_FLUSH 0x110
#define CTL_CDM_FLUSH 0x114
#define CTL_INTF_MASTER 0x134
#define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4))
@ -43,6 +48,7 @@
#define DPU_REG_RESET_TIMEOUT_US 2000
#define MERGE_3D_IDX 23
#define DSC_IDX 22
#define CDM_IDX 26
#define INTF_IDX 31
#define WB_IDX 16
#define DSPP_IDX 29 /* From DPU hw rev 7.x.x */
@ -104,6 +110,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
ctx->pending_wb_flush_mask = 0;
ctx->pending_merge_3d_flush_mask = 0;
ctx->pending_dsc_flush_mask = 0;
ctx->pending_cdm_flush_mask = 0;
memset(ctx->pending_dspp_flush_mask, 0,
sizeof(ctx->pending_dspp_flush_mask));
@ -148,6 +155,10 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
ctx->pending_dsc_flush_mask);
if (ctx->pending_flush_mask & BIT(CDM_IDX))
DPU_REG_WRITE(&ctx->hw, CTL_CDM_FLUSH,
ctx->pending_cdm_flush_mask);
DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
}
@ -279,6 +290,13 @@ static void dpu_hw_ctl_update_pending_flush_wb(struct dpu_hw_ctl *ctx,
}
}
static void dpu_hw_ctl_update_pending_flush_cdm(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num)
{
/* update pending flush only if CDM_0 is flushed */
if (cdm_num == CDM_0)
ctx->pending_flush_mask |= BIT(CDM_IDX);
}
static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
enum dpu_wb wb)
{
@ -307,6 +325,12 @@ static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx,
ctx->pending_flush_mask |= BIT(DSC_IDX);
}
static void dpu_hw_ctl_update_pending_flush_cdm_v1(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num)
{
ctx->pending_cdm_flush_mask |= BIT(cdm_num - CDM_0);
ctx->pending_flush_mask |= BIT(CDM_IDX);
}
static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
enum dpu_dspp dspp, u32 dspp_sub_blk)
{
@ -540,6 +564,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
if (cfg->dsc)
DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
if (cfg->cdm)
DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm);
}
static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
@ -583,6 +610,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
u32 wb_active = 0;
u32 merge3d_active = 0;
u32 dsc_active;
u32 cdm_active;
/*
* This API resets each portion of the CTL path namely,
@ -618,6 +646,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
dsc_active &= ~cfg->dsc;
DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
}
if (cfg->cdm) {
cdm_active = DPU_REG_READ(c, CTL_CDM_ACTIVE);
cdm_active &= ~cfg->cdm;
DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cdm_active);
}
}
static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx,
@ -651,12 +685,14 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
ops->update_pending_flush_dsc =
dpu_hw_ctl_update_pending_flush_dsc_v1;
ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1;
} else {
ops->trigger_flush = dpu_hw_ctl_trigger_flush;
ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
ops->update_pending_flush_intf =
dpu_hw_ctl_update_pending_flush_intf;
ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb;
ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm;
}
ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush;
ops->update_pending_flush = dpu_hw_ctl_update_pending_flush;
@ -680,14 +716,15 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
};
struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg,
void __iomem *addr,
u32 mixer_count,
const struct dpu_lm_cfg *mixer)
struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev,
const struct dpu_ctl_cfg *cfg,
void __iomem *addr,
u32 mixer_count,
const struct dpu_lm_cfg *mixer)
{
struct dpu_hw_ctl *c;
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -702,8 +739,3 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg,
return c;
}
void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx)
{
kfree(ctx);
}

View file

@ -39,6 +39,7 @@ struct dpu_hw_stage_cfg {
* @mode_3d: 3d mux configuration
* @merge_3d: 3d merge block used
* @intf_mode_sel: Interface mode, cmd / vid
* @cdm: CDM block used
* @stream_sel: Stream selection for multi-stream interfaces
* @dsc: DSC BIT masks used
*/
@ -48,6 +49,7 @@ struct dpu_hw_intf_cfg {
enum dpu_3d_blend_mode mode_3d;
enum dpu_merge_3d merge_3d;
enum dpu_ctl_mode_sel intf_mode_sel;
enum dpu_cdm cdm;
int stream_sel;
unsigned int dsc;
};
@ -166,6 +168,14 @@ struct dpu_hw_ctl_ops {
void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx,
enum dpu_dsc blk);
/**
* OR in the given flushbits to the cached pending_(cdm_)flush_mask
* No effect on hardware
* @ctx: ctl path ctx pointer
* @cdm_num: idx of cdm to be flushed
*/
void (*update_pending_flush_cdm)(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num);
/**
* Write the value of the pending_flush_mask to hardware
* @ctx : ctl path ctx pointer
@ -239,6 +249,7 @@ struct dpu_hw_ctl_ops {
* @pending_intf_flush_mask: pending INTF flush
* @pending_wb_flush_mask: pending WB flush
* @pending_dsc_flush_mask: pending DSC flush
* @pending_cdm_flush_mask: pending CDM flush
* @ops: operation list
*/
struct dpu_hw_ctl {
@ -256,6 +267,7 @@ struct dpu_hw_ctl {
u32 pending_merge_3d_flush_mask;
u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
u32 pending_dsc_flush_mask;
u32 pending_cdm_flush_mask;
/* ops */
struct dpu_hw_ctl_ops ops;
@ -274,20 +286,16 @@ static inline struct dpu_hw_ctl *to_dpu_hw_ctl(struct dpu_hw_blk *hw)
/**
* dpu_hw_ctl_init() - Initializes the ctl_path hw driver object.
* Should be called before accessing any ctl_path register.
* @dev: Corresponding device for devres management
* @cfg: ctl_path catalog entry for which driver object is required
* @addr: mapped register io address of MDP
* @mixer_count: Number of mixers in @mixer
* @mixer: Pointer to an array of Layer Mixers defined in the catalog
*/
struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg,
void __iomem *addr,
u32 mixer_count,
const struct dpu_lm_cfg *mixer);
/**
* dpu_hw_ctl_destroy(): Destroys ctl driver context
* should be called to free the context
*/
void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx);
struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev,
const struct dpu_ctl_cfg *cfg,
void __iomem *addr,
u32 mixer_count,
const struct dpu_lm_cfg *mixer);
#endif /*_DPU_HW_CTL_H */

View file

@ -3,6 +3,8 @@
* Copyright (c) 2020-2022, Linaro Limited
*/
#include <drm/drm_managed.h>
#include <drm/display/drm_dsc_helper.h>
#include "dpu_kms.h"
@ -188,12 +190,13 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops,
ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk;
};
struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg,
struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev,
const struct dpu_dsc_cfg *cfg,
void __iomem *addr)
{
struct dpu_hw_dsc *c;
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -206,8 +209,3 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg,
return c;
}
void dpu_hw_dsc_destroy(struct dpu_hw_dsc *dsc)
{
kfree(dsc);
}

View file

@ -64,20 +64,24 @@ struct dpu_hw_dsc {
/**
* dpu_hw_dsc_init() - Initializes the DSC hw driver object.
* @dev: Corresponding device for devres management
* @cfg: DSC catalog entry for which driver object is required
* @addr: Mapped register io address of MDP
* Return: Error code or allocated dpu_hw_dsc context
*/
struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg,
void __iomem *addr);
struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev,
const struct dpu_dsc_cfg *cfg,
void __iomem *addr);
/**
* dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object
* @dev: Corresponding device for devres management
* @cfg: DSC catalog entry for which driver object is required
* @addr: Mapped register io address of MDP
* Returns: Error code or allocated dpu_hw_dsc context
*/
struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev,
const struct dpu_dsc_cfg *cfg,
void __iomem *addr);
/**

View file

@ -4,6 +4,8 @@
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
*/
#include <drm/drm_managed.h>
#include <drm/display/drm_dsc_helper.h>
#include "dpu_kms.h"
@ -367,12 +369,13 @@ static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops,
ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
}
struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev,
const struct dpu_dsc_cfg *cfg,
void __iomem *addr)
{
struct dpu_hw_dsc *c;
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);

View file

@ -2,6 +2,8 @@
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
#include <drm/drm_managed.h>
#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
#include "dpu_hw_lm.h"
@ -68,15 +70,16 @@ static void _setup_dspp_ops(struct dpu_hw_dspp *c,
c->ops.setup_pcc = dpu_setup_dspp_pcc;
}
struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg,
void __iomem *addr)
struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev,
const struct dpu_dspp_cfg *cfg,
void __iomem *addr)
{
struct dpu_hw_dspp *c;
if (!addr)
return ERR_PTR(-EINVAL);
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -90,10 +93,3 @@ struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg,
return c;
}
void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp)
{
kfree(dspp);
}

View file

@ -81,18 +81,14 @@ static inline struct dpu_hw_dspp *to_dpu_hw_dspp(struct dpu_hw_blk *hw)
/**
* dpu_hw_dspp_init() - Initializes the DSPP hw driver object.
* should be called once before accessing every DSPP.
* @dev: Corresponding device for devres management
* @cfg: DSPP catalog entry for which driver object is required
* @addr: Mapped register io address of MDP
* Return: pointer to structure or ERR_PTR
*/
struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg,
void __iomem *addr);
/**
* dpu_hw_dspp_destroy(): Destroys DSPP driver context
* @dspp: Pointer to DSPP driver context
*/
void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp);
struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev,
const struct dpu_dspp_cfg *cfg,
void __iomem *addr);
#endif /*_DPU_HW_DSPP_H */

View file

@ -6,6 +6,8 @@
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <drm/drm_managed.h>
#include "dpu_core_irq.h"
#include "dpu_kms.h"
#include "dpu_hw_interrupts.h"
@ -472,8 +474,9 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms,
return intr_status;
}
struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
const struct dpu_mdss_cfg *m)
struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev,
void __iomem *addr,
const struct dpu_mdss_cfg *m)
{
struct dpu_hw_intr *intr;
unsigned int i;
@ -481,7 +484,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
if (!addr || !m)
return ERR_PTR(-EINVAL);
intr = kzalloc(sizeof(*intr), GFP_KERNEL);
intr = drmm_kzalloc(dev, sizeof(*intr), GFP_KERNEL);
if (!intr)
return ERR_PTR(-ENOMEM);
@ -512,11 +515,6 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
return intr;
}
void dpu_hw_intr_destroy(struct dpu_hw_intr *intr)
{
kfree(intr);
}
int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms,
unsigned int irq_idx,
void (*irq_cb)(void *arg),

View file

@ -70,15 +70,12 @@ struct dpu_hw_intr {
/**
* dpu_hw_intr_init(): Initializes the interrupts hw object
* @dev: Corresponding device for devres management
* @addr: mapped register io address of MDP
* @m: pointer to MDSS catalog data
*/
struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
const struct dpu_mdss_cfg *m);
struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev,
void __iomem *addr,
const struct dpu_mdss_cfg *m);
/**
* dpu_hw_intr_destroy(): Cleanup interrutps hw object
* @intr: pointer to interrupts hw object
*/
void dpu_hw_intr_destroy(struct dpu_hw_intr *intr);
#endif

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
@ -12,6 +12,8 @@
#include <linux/iopoll.h>
#include <drm/drm_managed.h>
#define INTF_TIMING_ENGINE_EN 0x000
#define INTF_CONFIG 0x004
#define INTF_HSYNC_CTL 0x008
@ -318,9 +320,9 @@ static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf)
return DPU_REG_READ(c, INTF_LINE_COUNT);
}
static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, u32 frame_count)
static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf)
{
dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, enable, frame_count);
dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, 0x1);
}
static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value)
@ -527,8 +529,10 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *ctx,
DPU_REG_WRITE(&ctx->hw, INTF_CONFIG2, intf_cfg2);
}
struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg,
void __iomem *addr, const struct dpu_mdss_version *mdss_rev)
struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev,
const struct dpu_intf_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_version *mdss_rev)
{
struct dpu_hw_intf *c;
@ -537,7 +541,7 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg,
return NULL;
}
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -581,9 +585,3 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg,
return c;
}
void dpu_hw_intf_destroy(struct dpu_hw_intf *intf)
{
kfree(intf);
}

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
@ -95,7 +95,7 @@ struct dpu_hw_intf_ops {
void (*bind_pingpong_blk)(struct dpu_hw_intf *intf,
const enum dpu_pingpong pp);
void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count);
void (*setup_misr)(struct dpu_hw_intf *intf);
int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value);
// Tearcheck on INTF since DPU 5.0.0
@ -131,17 +131,14 @@ struct dpu_hw_intf {
/**
* dpu_hw_intf_init() - Initializes the INTF driver for the passed
* interface catalog entry.
* @dev: Corresponding device for devres management
* @cfg: interface catalog entry for which driver object is required
* @addr: mapped register io address of MDP
* @mdss_rev: dpu core's major and minor versions
*/
struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg,
void __iomem *addr, const struct dpu_mdss_version *mdss_rev);
/**
* dpu_hw_intf_destroy(): Destroys INTF driver context
* @intf: Pointer to INTF driver context
*/
void dpu_hw_intf_destroy(struct dpu_hw_intf *intf);
struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev,
const struct dpu_intf_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_version *mdss_rev);
#endif /*_DPU_HW_INTF_H */

View file

@ -1,9 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
*/
#include <drm/drm_managed.h>
#include "dpu_kms.h"
#include "dpu_hw_catalog.h"
#include "dpu_hwio.h"
@ -81,9 +83,9 @@ static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx,
}
}
static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count)
static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx)
{
dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, enable, frame_count);
dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0);
}
static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value)
@ -156,8 +158,9 @@ static void _setup_mixer_ops(struct dpu_hw_lm_ops *ops,
ops->collect_misr = dpu_hw_lm_collect_misr;
}
struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg,
void __iomem *addr)
struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev,
const struct dpu_lm_cfg *cfg,
void __iomem *addr)
{
struct dpu_hw_mixer *c;
@ -166,7 +169,7 @@ struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg,
return NULL;
}
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -180,8 +183,3 @@ struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg,
return c;
}
void dpu_hw_lm_destroy(struct dpu_hw_mixer *lm)
{
kfree(lm);
}

View file

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
*/
@ -57,7 +58,7 @@ struct dpu_hw_lm_ops {
/**
* setup_misr: Enable/disable MISR
*/
void (*setup_misr)(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count);
void (*setup_misr)(struct dpu_hw_mixer *ctx);
/**
* collect_misr: Read MISR signature
@ -95,16 +96,12 @@ static inline struct dpu_hw_mixer *to_dpu_hw_mixer(struct dpu_hw_blk *hw)
/**
* dpu_hw_lm_init() - Initializes the mixer hw driver object.
* should be called once before accessing every mixer.
* @dev: Corresponding device for devres management
* @cfg: mixer catalog entry for which driver object is required
* @addr: mapped register io address of MDP
*/
struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg,
void __iomem *addr);
/**
* dpu_hw_lm_destroy(): Destroys layer mixer driver context
* @lm: Pointer to LM driver context
*/
void dpu_hw_lm_destroy(struct dpu_hw_mixer *lm);
struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev,
const struct dpu_lm_cfg *cfg,
void __iomem *addr);
#endif /*_DPU_HW_LM_H */

View file

@ -98,6 +98,7 @@ enum dpu_hw_blk_type {
DPU_HW_BLK_DSPP,
DPU_HW_BLK_MERGE_3D,
DPU_HW_BLK_DSC,
DPU_HW_BLK_CDM,
DPU_HW_BLK_MAX,
};
@ -185,6 +186,11 @@ enum dpu_dsc {
DSC_MAX
};
enum dpu_cdm {
CDM_0 = 1,
CDM_MAX
};
enum dpu_pingpong {
PINGPONG_NONE,
PINGPONG_0,
@ -195,6 +201,8 @@ enum dpu_pingpong {
PINGPONG_5,
PINGPONG_6,
PINGPONG_7,
PINGPONG_8,
PINGPONG_9,
PINGPONG_S0,
PINGPONG_MAX
};
@ -204,6 +212,7 @@ enum dpu_merge_3d {
MERGE_3D_1,
MERGE_3D_2,
MERGE_3D_3,
MERGE_3D_4,
MERGE_3D_MAX
};
@ -458,6 +467,7 @@ struct dpu_mdss_color {
#define DPU_DBG_MASK_ROT (1 << 9)
#define DPU_DBG_MASK_DSPP (1 << 10)
#define DPU_DBG_MASK_DSC (1 << 11)
#define DPU_DBG_MASK_CDM (1 << 12)
/**
* struct dpu_hw_tear_check - Struct contains parameters to configure

View file

@ -4,6 +4,8 @@
#include <linux/iopoll.h>
#include <drm/drm_managed.h>
#include "dpu_hw_mdss.h"
#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
@ -37,12 +39,13 @@ static void _setup_merge_3d_ops(struct dpu_hw_merge_3d *c,
c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode;
};
struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg,
void __iomem *addr)
struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev,
const struct dpu_merge_3d_cfg *cfg,
void __iomem *addr)
{
struct dpu_hw_merge_3d *c;
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -55,8 +58,3 @@ struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg,
return c;
}
void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *hw)
{
kfree(hw);
}

View file

@ -48,18 +48,13 @@ static inline struct dpu_hw_merge_3d *to_dpu_hw_merge_3d(struct dpu_hw_blk *hw)
/**
* dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed
* merge3d catalog entry.
* @dev: Corresponding device for devres management
* @cfg: Pingpong catalog entry for which driver object is required
* @addr: Mapped register io address of MDP
* Return: Error code or allocated dpu_hw_merge_3d context
*/
struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg,
void __iomem *addr);
/**
* dpu_hw_merge_3d_destroy - destroys merge_3d driver context
* should be called to free the context
* @pp: Pointer to PP driver context returned by dpu_hw_merge_3d_init
*/
void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *pp);
struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev,
const struct dpu_merge_3d_cfg *cfg,
void __iomem *addr);
#endif /*_DPU_HW_MERGE3D_H */

View file

@ -4,6 +4,8 @@
#include <linux/iopoll.h>
#include <drm/drm_managed.h>
#include "dpu_hw_mdss.h"
#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
@ -281,12 +283,14 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp)
return 0;
}
struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg,
void __iomem *addr, const struct dpu_mdss_version *mdss_rev)
struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev,
const struct dpu_pingpong_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_version *mdss_rev)
{
struct dpu_hw_pingpong *c;
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -317,8 +321,3 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg,
return c;
}
void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp)
{
kfree(pp);
}

View file

@ -121,19 +121,15 @@ static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw)
/**
* dpu_hw_pingpong_init() - initializes the pingpong driver for the passed
* pingpong catalog entry.
* @dev: Corresponding device for devres management
* @cfg: Pingpong catalog entry for which driver object is required
* @addr: Mapped register io address of MDP
* @mdss_rev: dpu core's major and minor versions
* Return: Error code or allocated dpu_hw_pingpong context
*/
struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg,
void __iomem *addr, const struct dpu_mdss_version *mdss_rev);
/**
* dpu_hw_pingpong_destroy - destroys pingpong driver context
* should be called to free the context
* @pp: Pointer to PP driver context returned by dpu_hw_pingpong_init
*/
void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp);
struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev,
const struct dpu_pingpong_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_version *mdss_rev);
#endif /*_DPU_HW_PINGPONG_H */

View file

@ -11,6 +11,7 @@
#include "msm_mdss.h"
#include <drm/drm_file.h>
#include <drm/drm_managed.h>
#define DPU_FETCH_CONFIG_RESET_VALUE 0x00000087
@ -395,15 +396,6 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
format);
}
static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
{
if (!ctx)
return 0;
return dpu_hw_get_scaler3_ver(&ctx->hw,
ctx->cap->sblk->scaler_blk.base);
}
/*
* dpu_hw_sspp_setup_rects()
*/
@ -614,12 +606,8 @@ static void _setup_layer_ops(struct dpu_hw_sspp *c,
test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features))
c->ops.setup_multirect = dpu_hw_sspp_setup_multirect;
if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) ||
test_bit(DPU_SSPP_SCALER_QSEED3LITE, &features) ||
test_bit(DPU_SSPP_SCALER_QSEED4, &features)) {
if (test_bit(DPU_SSPP_SCALER_QSEED3_COMPATIBLE, &features))
c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3;
c->ops.get_scaler_ver = _dpu_hw_sspp_get_scaler3_ver;
}
if (test_bit(DPU_SSPP_CDP, &features))
c->ops.setup_cdp = dpu_hw_sspp_setup_cdp;
@ -654,10 +642,7 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
cfg->len,
kms);
if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) ||
cfg->features & BIT(DPU_SSPP_SCALER_QSEED3LITE) ||
cfg->features & BIT(DPU_SSPP_SCALER_QSEED2) ||
cfg->features & BIT(DPU_SSPP_SCALER_QSEED4))
if (sblk->scaler_blk.len)
dpu_debugfs_create_regset32("scaler_blk", 0400,
debugfs_root,
sblk->scaler_blk.base + cfg->base,
@ -685,16 +670,18 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
}
#endif
struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg,
void __iomem *addr, const struct msm_mdss_data *mdss_data,
const struct dpu_mdss_version *mdss_rev)
struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev,
const struct dpu_sspp_cfg *cfg,
void __iomem *addr,
const struct msm_mdss_data *mdss_data,
const struct dpu_mdss_version *mdss_rev)
{
struct dpu_hw_sspp *hw_pipe;
if (!addr)
return ERR_PTR(-EINVAL);
hw_pipe = kzalloc(sizeof(*hw_pipe), GFP_KERNEL);
hw_pipe = drmm_kzalloc(dev, sizeof(*hw_pipe), GFP_KERNEL);
if (!hw_pipe)
return ERR_PTR(-ENOMEM);
@ -709,9 +696,3 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg,
return hw_pipe;
}
void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx)
{
kfree(ctx);
}

View file

@ -21,21 +21,6 @@ struct dpu_hw_sspp;
#define DPU_SSPP_ROT_90 BIT(3)
#define DPU_SSPP_SOLID_FILL BIT(4)
/**
* Define all scaler feature bits in catalog
*/
#define DPU_SSPP_SCALER (BIT(DPU_SSPP_SCALER_RGB) | \
BIT(DPU_SSPP_SCALER_QSEED2) | \
BIT(DPU_SSPP_SCALER_QSEED3) | \
BIT(DPU_SSPP_SCALER_QSEED3LITE) | \
BIT(DPU_SSPP_SCALER_QSEED4))
/*
* Define all CSC feature bits in catalog
*/
#define DPU_SSPP_CSC_ANY (BIT(DPU_SSPP_CSC) | \
BIT(DPU_SSPP_CSC_10BIT))
/**
* Component indices
*/
@ -296,12 +281,6 @@ struct dpu_hw_sspp_ops {
struct dpu_hw_scaler3_cfg *scaler3_cfg,
const struct dpu_format *format);
/**
* get_scaler_ver - get scaler h/w version
* @ctx: Pointer to pipe context
*/
u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx);
/**
* setup_cdp - setup client driven prefetch
* @pipe: Pointer to software pipe context
@ -339,21 +318,17 @@ struct dpu_kms;
/**
* dpu_hw_sspp_init() - Initializes the sspp hw driver object.
* Should be called once before accessing every pipe.
* @dev: Corresponding device for devres management
* @cfg: Pipe catalog entry for which driver object is required
* @addr: Mapped register io address of MDP
* @mdss_data: UBWC / MDSS configuration data
* @mdss_rev: dpu core's major and minor versions
*/
struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg,
void __iomem *addr, const struct msm_mdss_data *mdss_data,
const struct dpu_mdss_version *mdss_rev);
/**
* dpu_hw_sspp_destroy(): Destroys SSPP driver context
* should be called during Hw pipe cleanup.
* @ctx: Pointer to SSPP driver context returned by dpu_hw_sspp_init
*/
void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev,
const struct dpu_sspp_cfg *cfg,
void __iomem *addr,
const struct msm_mdss_data *mdss_data,
const struct dpu_mdss_version *mdss_rev);
int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
struct dentry *entry);

View file

@ -2,6 +2,8 @@
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
#include <drm/drm_managed.h>
#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
#include "dpu_hw_top.h"
@ -247,16 +249,17 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
ops->intf_audio_select = dpu_hw_intf_audio_select;
}
struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_cfg *m)
struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
const struct dpu_mdp_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_cfg *m)
{
struct dpu_hw_mdp *mdp;
if (!addr)
return ERR_PTR(-EINVAL);
mdp = kzalloc(sizeof(*mdp), GFP_KERNEL);
mdp = drmm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
if (!mdp)
return ERR_PTR(-ENOMEM);
@ -271,9 +274,3 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg,
return mdp;
}
void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp)
{
kfree(mdp);
}

View file

@ -145,13 +145,15 @@ struct dpu_hw_mdp {
/**
* dpu_hw_mdptop_init - initializes the top driver for the passed config
* @dev: Corresponding device for devres management
* @cfg: MDP TOP configuration from catalog
* @addr: Mapped register io address of MDP
* @m: Pointer to mdss catalog data
*/
struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_cfg *m);
struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
const struct dpu_mdp_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_cfg *m);
void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp);

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
@ -381,12 +381,6 @@ void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c,
DPU_REG_WRITE(c, QSEED3_OP_MODE + scaler_offset, op_mode);
}
u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c,
u32 scaler_offset)
{
return DPU_REG_READ(c, QSEED3_HW_VERSION + scaler_offset);
}
void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
u32 csc_reg_off,
const struct dpu_csc_cfg *data, bool csc10)
@ -481,9 +475,11 @@ void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset,
cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0);
}
/*
* note: Aside from encoders, input_sel should be set to 0x0 by default
*/
void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c,
u32 misr_ctrl_offset,
bool enable, u32 frame_count)
u32 misr_ctrl_offset, u8 input_sel)
{
u32 config = 0;
@ -492,15 +488,9 @@ void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c,
/* Clear old MISR value (in case it's read before a new value is calculated)*/
wmb();
if (enable) {
config = (frame_count & MISR_FRAME_COUNT_MASK) |
MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK;
DPU_REG_WRITE(c, misr_ctrl_offset, config);
} else {
DPU_REG_WRITE(c, misr_ctrl_offset, 0);
}
config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK |
((input_sel & 0xF) << 24);
DPU_REG_WRITE(c, misr_ctrl_offset, config);
}
int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c,
@ -567,3 +557,47 @@ bool dpu_hw_clk_force_ctrl(struct dpu_hw_blk_reg_map *c,
return clk_forced_on;
}
#define TO_S15D16(_x_)((_x_) << 7)
const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
{
/* S15.16 format */
0x00012A00, 0x00000000, 0x00019880,
0x00012A00, 0xFFFF9B80, 0xFFFF3000,
0x00012A00, 0x00020480, 0x00000000,
},
/* signed bias */
{ 0xfff0, 0xff80, 0xff80,},
{ 0x0, 0x0, 0x0,},
/* unsigned clamp */
{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
};
const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
{
/* S15.16 format */
0x00012A00, 0x00000000, 0x00019880,
0x00012A00, 0xFFFF9B80, 0xFFFF3000,
0x00012A00, 0x00020480, 0x00000000,
},
/* signed bias */
{ 0xffc0, 0xfe00, 0xfe00,},
{ 0x0, 0x0, 0x0,},
/* unsigned clamp */
{ 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,},
{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
};
const struct dpu_csc_cfg dpu_csc10_rgb2yuv_601l = {
{
TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032),
TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1),
TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc)
},
{ 0x00, 0x00, 0x00 },
{ 0x0040, 0x0200, 0x0200 },
{ 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff },
{ 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 },
};

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
*/
@ -13,12 +13,18 @@
#include "dpu_hw_catalog.h"
#define REG_MASK(n) ((BIT(n)) - 1)
#define MISR_FRAME_COUNT_MASK 0xFF
#define MISR_FRAME_COUNT 0x1
#define MISR_CTRL_ENABLE BIT(8)
#define MISR_CTRL_STATUS BIT(9)
#define MISR_CTRL_STATUS_CLEAR BIT(10)
#define MISR_CTRL_FREE_RUN_MASK BIT(31)
#define TO_S15D16(_x_)((_x_) << 7)
extern const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L;
extern const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L;
extern const struct dpu_csc_cfg dpu_csc10_rgb2yuv_601l;
/*
* This is the common struct maintained by each sub block
* for mapping the register offsets in this block to the
@ -340,9 +346,6 @@ void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c,
u32 scaler_offset, u32 scaler_version,
const struct dpu_format *format);
u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c,
u32 scaler_offset);
void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
u32 csc_reg_off,
const struct dpu_csc_cfg *data, bool csc10);
@ -358,9 +361,7 @@ void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset,
const struct dpu_hw_qos_cfg *cfg);
void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c,
u32 misr_ctrl_offset,
bool enable,
u32 frame_count);
u32 misr_ctrl_offset, u8 input_sel);
int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c,
u32 misr_ctrl_offset,

View file

@ -2,6 +2,8 @@
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
#include <drm/drm_managed.h>
#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
#include "dpu_hw_vbif.h"
@ -211,12 +213,13 @@ static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops,
ops->set_write_gather_en = dpu_hw_set_write_gather_en;
}
struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg,
void __iomem *addr)
struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev,
const struct dpu_vbif_cfg *cfg,
void __iomem *addr)
{
struct dpu_hw_vbif *c;
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -234,8 +237,3 @@ struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg,
return c;
}
void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif)
{
kfree(vbif);
}

View file

@ -108,12 +108,12 @@ struct dpu_hw_vbif {
/**
* dpu_hw_vbif_init() - Initializes the VBIF driver for the passed
* VBIF catalog entry.
* @dev: Corresponding device for devres management
* @cfg: VBIF catalog entry for which driver object is required
* @addr: Mapped register io address of MDSS
*/
struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg,
void __iomem *addr);
void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif);
struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev,
const struct dpu_vbif_cfg *cfg,
void __iomem *addr);
#endif /*_DPU_HW_VBIF_H */

View file

@ -3,6 +3,8 @@
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved
*/
#include <drm/drm_managed.h>
#include "dpu_hw_mdss.h"
#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
@ -87,6 +89,9 @@ static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx,
dst_format |= BIT(14); /* DST_ALPHA_X */
}
if (DPU_FORMAT_IS_YUV(fmt))
dst_format |= BIT(15);
pattern = (fmt->element[3] << 24) |
(fmt->element[2] << 16) |
(fmt->element[1] << 8) |
@ -208,15 +213,17 @@ static void _setup_wb_ops(struct dpu_hw_wb_ops *ops,
ops->setup_clk_force_ctrl = dpu_hw_wb_setup_clk_force_ctrl;
}
struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg,
void __iomem *addr, const struct dpu_mdss_version *mdss_rev)
struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
const struct dpu_wb_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_version *mdss_rev)
{
struct dpu_hw_wb *c;
if (!addr)
return ERR_PTR(-EINVAL);
c = kzalloc(sizeof(*c), GFP_KERNEL);
c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
if (!c)
return ERR_PTR(-ENOMEM);
@ -230,8 +237,3 @@ struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg,
return c;
}
void dpu_hw_wb_destroy(struct dpu_hw_wb *hw_wb)
{
kfree(hw_wb);
}

View file

@ -76,18 +76,15 @@ struct dpu_hw_wb {
/**
* dpu_hw_wb_init() - Initializes the writeback hw driver object.
* @dev: Corresponding device for devres management
* @cfg: wb_path catalog entry for which driver object is required
* @addr: mapped register io address of MDP
* @mdss_rev: dpu core's major and minor versions
* Return: Error code or allocated dpu_hw_wb context
*/
struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg,
void __iomem *addr, const struct dpu_mdss_version *mdss_rev);
/**
* dpu_hw_wb_destroy(): Destroy writeback hw driver object.
* @hw_wb: Pointer to writeback hw driver object
*/
void dpu_hw_wb_destroy(struct dpu_hw_wb *hw_wb);
struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
const struct dpu_wb_cfg *cfg,
void __iomem *addr,
const struct dpu_mdss_version *mdss_rev);
#endif /*_DPU_HW_WB_H */

View file

@ -274,9 +274,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
void *p = dpu_hw_util_get_log_mask_ptr();
struct dentry *entry;
struct drm_device *dev;
struct msm_drm_private *priv;
int i;
if (!p)
return -EINVAL;
@ -285,9 +282,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
if (minor->type != DRM_MINOR_PRIMARY)
return 0;
dev = dpu_kms->dev;
priv = dev->dev_private;
entry = debugfs_create_dir("debug", minor->debugfs_root);
debugfs_create_x32(DPU_DEBUGFS_HWMASKNAME, 0600, entry, p);
@ -297,11 +291,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
dpu_debugfs_core_irq_init(dpu_kms, entry);
dpu_debugfs_sspp_init(dpu_kms, entry);
for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
if (priv->dp[i])
msm_dp_debugfs_init(priv->dp[i], minor);
}
return dpu_core_perf_debugfs_init(dpu_kms, entry);
}
#endif
@ -597,7 +586,6 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev,
rc = msm_dp_modeset_init(priv->dp[i], dev, encoder);
if (rc) {
DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
drm_encoder_cleanup(encoder);
return rc;
}
}
@ -630,7 +618,6 @@ static int _dpu_kms_initialize_hdmi(struct drm_device *dev,
rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder);
if (rc) {
DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
drm_encoder_cleanup(encoder);
return rc;
}
@ -662,7 +649,6 @@ static int _dpu_kms_initialize_writeback(struct drm_device *dev,
n_formats);
if (rc) {
DPU_ERROR("dpu_writeback_init, rc = %d\n", rc);
drm_encoder_cleanup(encoder);
return rc;
}
@ -806,30 +792,17 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
{
int i;
if (dpu_kms->hw_intr)
dpu_hw_intr_destroy(dpu_kms->hw_intr);
dpu_kms->hw_intr = NULL;
/* safe to call these more than once during shutdown */
_dpu_kms_mmu_destroy(dpu_kms);
if (dpu_kms->catalog) {
for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
if (dpu_kms->hw_vbif[i]) {
dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]);
dpu_kms->hw_vbif[i] = NULL;
}
}
for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
dpu_kms->hw_vbif[i] = NULL;
}
if (dpu_kms->rm_init)
dpu_rm_destroy(&dpu_kms->rm);
dpu_kms->rm_init = false;
dpu_kms->catalog = NULL;
if (dpu_kms->hw_mdp)
dpu_hw_mdp_destroy(dpu_kms->hw_mdp);
dpu_kms->hw_mdp = NULL;
}
@ -856,7 +829,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms)
{
struct msm_drm_private *priv;
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
int i;
if (!dpu_kms || !dpu_kms->dev)
return -EINVAL;
@ -865,9 +837,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms)
if (!priv)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(priv->dp); i++)
msm_dp_irq_postinstall(priv->dp[i]);
return 0;
}
@ -975,6 +944,10 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k
}
}
if (cat->cdm)
msm_disp_snapshot_add_block(disp_state, cat->cdm->len,
dpu_kms->mmio + cat->cdm->base, cat->cdm->name);
pm_runtime_put_sync(&dpu_kms->pdev->dev);
}
@ -1078,7 +1051,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
if (!dpu_kms->catalog) {
DPU_ERROR("device config not known!\n");
rc = -EINVAL;
goto power_error;
goto err_pm_put;
}
/*
@ -1088,49 +1061,48 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
rc = _dpu_kms_mmu_init(dpu_kms);
if (rc) {
DPU_ERROR("dpu_kms_mmu_init failed: %d\n", rc);
goto power_error;
goto err_pm_put;
}
dpu_kms->mdss = msm_mdss_get_mdss_data(dpu_kms->pdev->dev.parent);
if (IS_ERR(dpu_kms->mdss)) {
rc = PTR_ERR(dpu_kms->mdss);
DPU_ERROR("failed to get MDSS data: %d\n", rc);
goto power_error;
goto err_pm_put;
}
if (!dpu_kms->mdss) {
rc = -EINVAL;
DPU_ERROR("NULL MDSS data\n");
goto power_error;
goto err_pm_put;
}
rc = dpu_rm_init(&dpu_kms->rm, dpu_kms->catalog, dpu_kms->mdss, dpu_kms->mmio);
rc = dpu_rm_init(dev, &dpu_kms->rm, dpu_kms->catalog, dpu_kms->mdss, dpu_kms->mmio);
if (rc) {
DPU_ERROR("rm init failed: %d\n", rc);
goto power_error;
goto err_pm_put;
}
dpu_kms->rm_init = true;
dpu_kms->hw_mdp = dpu_hw_mdptop_init(dpu_kms->catalog->mdp,
dpu_kms->hw_mdp = dpu_hw_mdptop_init(dev,
dpu_kms->catalog->mdp,
dpu_kms->mmio,
dpu_kms->catalog);
if (IS_ERR(dpu_kms->hw_mdp)) {
rc = PTR_ERR(dpu_kms->hw_mdp);
DPU_ERROR("failed to get hw_mdp: %d\n", rc);
dpu_kms->hw_mdp = NULL;
goto power_error;
goto err_pm_put;
}
for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
struct dpu_hw_vbif *hw;
const struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i];
hw = dpu_hw_vbif_init(vbif, dpu_kms->vbif[vbif->id]);
hw = dpu_hw_vbif_init(dev, vbif, dpu_kms->vbif[vbif->id]);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc);
goto power_error;
goto err_pm_put;
}
dpu_kms->hw_vbif[vbif->id] = hw;
@ -1146,15 +1118,15 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
rc = dpu_core_perf_init(&dpu_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate);
if (rc) {
DPU_ERROR("failed to init perf %d\n", rc);
goto perf_err;
goto err_pm_put;
}
dpu_kms->hw_intr = dpu_hw_intr_init(dpu_kms->mmio, dpu_kms->catalog);
if (IS_ERR_OR_NULL(dpu_kms->hw_intr)) {
dpu_kms->hw_intr = dpu_hw_intr_init(dev, dpu_kms->mmio, dpu_kms->catalog);
if (IS_ERR(dpu_kms->hw_intr)) {
rc = PTR_ERR(dpu_kms->hw_intr);
DPU_ERROR("hw_intr init failed: %d\n", rc);
dpu_kms->hw_intr = NULL;
goto hw_intr_init_err;
goto err_pm_put;
}
dev->mode_config.min_width = 0;
@ -1179,7 +1151,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
rc = _dpu_kms_drm_obj_init(dpu_kms);
if (rc) {
DPU_ERROR("modeset init failed: %d\n", rc);
goto drm_obj_init_err;
goto err_pm_put;
}
dpu_vbif_init_memtypes(dpu_kms);
@ -1188,10 +1160,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
return 0;
drm_obj_init_err:
hw_intr_init_err:
perf_err:
power_error:
err_pm_put:
pm_runtime_put_sync(&dpu_kms->pdev->dev);
error:
_dpu_kms_hw_destroy(dpu_kms);
@ -1349,6 +1318,7 @@ static const struct dev_pm_ops dpu_pm_ops = {
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,sdm670-dpu", .data = &dpu_sdm670_cfg, },
{ .compatible = "qcom,sdm845-dpu", .data = &dpu_sdm845_cfg, },
{ .compatible = "qcom,sc7180-dpu", .data = &dpu_sc7180_cfg, },
{ .compatible = "qcom,sc7280-dpu", .data = &dpu_sc7280_cfg, },
@ -1363,6 +1333,7 @@ static const struct of_device_id dpu_dt_match[] = {
{ .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, },
{ .compatible = "qcom,sm8450-dpu", .data = &dpu_sm8450_cfg, },
{ .compatible = "qcom,sm8550-dpu", .data = &dpu_sm8550_cfg, },
{ .compatible = "qcom,sm8650-dpu", .data = &dpu_sm8650_cfg, },
{}
};
MODULE_DEVICE_TABLE(of, dpu_dt_match);

View file

@ -51,6 +51,7 @@
} while (0)
#define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__)
#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__)
/**
* ktime_compare_safe - compare two ktime structures
@ -88,7 +89,6 @@ struct dpu_kms {
struct drm_private_obj global_state;
struct dpu_rm rm;
bool rm_init;
struct dpu_hw_vbif *hw_vbif[VBIF_MAX];
struct dpu_hw_mdp *hw_mdp;
@ -136,6 +136,7 @@ struct dpu_global_state {
uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
uint32_t dsc_to_enc_id[DSC_MAX - DSC_0];
uint32_t cdm_to_enc_id;
};
struct dpu_global_state

View file

@ -21,6 +21,7 @@
#include "dpu_kms.h"
#include "dpu_formats.h"
#include "dpu_hw_sspp.h"
#include "dpu_hw_util.h"
#include "dpu_trace.h"
#include "dpu_crtc.h"
#include "dpu_vbif.h"
@ -78,8 +79,6 @@ static const uint32_t qcom_compressed_supported_formats[] = {
struct dpu_plane {
struct drm_plane base;
struct mutex lock;
enum dpu_sspp pipe;
uint32_t color_fill;
@ -470,8 +469,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw,
scale_cfg->src_height[i] /= chroma_subsmpl_v;
}
if (pipe_hw->cap->features &
BIT(DPU_SSPP_SCALER_QSEED4)) {
if (pipe_hw->cap->sblk->scaler_blk.version >= 0x3000) {
scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
} else {
@ -511,36 +509,6 @@ static void _dpu_plane_setup_pixel_ext(struct dpu_hw_scaler3_cfg *scale_cfg,
}
}
static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
{
/* S15.16 format */
0x00012A00, 0x00000000, 0x00019880,
0x00012A00, 0xFFFF9B80, 0xFFFF3000,
0x00012A00, 0x00020480, 0x00000000,
},
/* signed bias */
{ 0xfff0, 0xff80, 0xff80,},
{ 0x0, 0x0, 0x0,},
/* unsigned clamp */
{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
};
static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
{
/* S15.16 format */
0x00012A00, 0x00000000, 0x00019880,
0x00012A00, 0xFFFF9B80, 0xFFFF3000,
0x00012A00, 0x00020480, 0x00000000,
},
/* signed bias */
{ 0xffc0, 0xfe00, 0xfe00,},
{ 0x0, 0x0, 0x0,},
/* unsigned clamp */
{ 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,},
{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
};
static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe,
const struct dpu_format *fmt)
{
@ -774,8 +742,8 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
if (DPU_FORMAT_IS_YUV(fmt) &&
(!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
!(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
(!pipe->sspp->cap->sblk->scaler_blk.len ||
!pipe->sspp->cap->sblk->csc_blk.len)) {
DPU_DEBUG_PLANE(pdpu,
"plane doesn't have scaler/csc for yuv\n");
return -EINVAL;
@ -824,6 +792,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
plane);
int ret = 0, min_scale;
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
struct dpu_sw_pipe *pipe = &pstate->pipe;
struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
@ -892,14 +862,16 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
max_linewidth = pdpu->catalog->caps->max_linewidth;
if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
_dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) {
/*
* In parallel multirect case only the half of the usual width
* is supported for tiled formats. If we are here, we know that
* full width is more than max_linewidth, thus each rect is
* wider than allowed.
*/
if (DPU_FORMAT_IS_UBWC(fmt)) {
if (DPU_FORMAT_IS_UBWC(fmt) &&
drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled format\n",
DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
return -E2BIG;
@ -1213,29 +1185,6 @@ static void dpu_plane_atomic_update(struct drm_plane *plane,
}
}
static void dpu_plane_destroy(struct drm_plane *plane)
{
struct dpu_plane *pdpu = plane ? to_dpu_plane(plane) : NULL;
struct dpu_plane_state *pstate;
DPU_DEBUG_PLANE(pdpu, "\n");
if (pdpu) {
pstate = to_dpu_plane_state(plane->state);
_dpu_plane_set_qos_ctrl(plane, &pstate->pipe, false);
if (pstate->r_pipe.sspp)
_dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, false);
mutex_destroy(&pdpu->lock);
/* this will destroy the states as well */
drm_plane_cleanup(plane);
kfree(pdpu);
}
}
static void dpu_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state)
{
@ -1405,7 +1354,6 @@ static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
static const struct drm_plane_funcs dpu_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = dpu_plane_destroy,
.reset = dpu_plane_reset,
.atomic_duplicate_state = dpu_plane_duplicate_state,
.atomic_destroy_state = dpu_plane_destroy_state,
@ -1433,35 +1381,28 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
struct dpu_hw_sspp *pipe_hw;
uint32_t num_formats;
uint32_t supported_rotations;
int ret = -EINVAL;
/* create and zero local structure */
pdpu = kzalloc(sizeof(*pdpu), GFP_KERNEL);
if (!pdpu) {
DPU_ERROR("[%u]failed to allocate local plane struct\n", pipe);
ret = -ENOMEM;
return ERR_PTR(ret);
}
/* cache local stuff for later */
plane = &pdpu->base;
pdpu->pipe = pipe;
int ret;
/* initialize underlying h/w driver */
pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) {
DPU_ERROR("[%u]SSPP is invalid\n", pipe);
goto clean_plane;
return ERR_PTR(-EINVAL);
}
format_list = pipe_hw->cap->sblk->format_list;
num_formats = pipe_hw->cap->sblk->num_formats;
ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
pdpu = drmm_universal_plane_alloc(dev, struct dpu_plane, base,
0xff, &dpu_plane_funcs,
format_list, num_formats,
supported_format_modifiers, type, NULL);
if (ret)
goto clean_plane;
if (IS_ERR(pdpu))
return ERR_CAST(pdpu);
/* cache local stuff for later */
plane = &pdpu->base;
pdpu->pipe = pipe;
pdpu->catalog = kms->catalog;
@ -1488,13 +1429,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
/* success! finalize initialization */
drm_plane_helper_add(plane, &dpu_plane_helper_funcs);
mutex_init(&pdpu->lock);
DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
pipe, plane->base.id);
return plane;
clean_plane:
kfree(pdpu);
return ERR_PTR(ret);
}

View file

@ -8,6 +8,7 @@
#include "dpu_kms.h"
#include "dpu_hw_lm.h"
#include "dpu_hw_ctl.h"
#include "dpu_hw_cdm.h"
#include "dpu_hw_pingpong.h"
#include "dpu_hw_sspp.h"
#include "dpu_hw_intf.h"
@ -34,72 +35,8 @@ struct dpu_rm_requirements {
struct msm_display_topology topology;
};
int dpu_rm_destroy(struct dpu_rm *rm)
{
int i;
for (i = 0; i < ARRAY_SIZE(rm->dspp_blks); i++) {
struct dpu_hw_dspp *hw;
if (rm->dspp_blks[i]) {
hw = to_dpu_hw_dspp(rm->dspp_blks[i]);
dpu_hw_dspp_destroy(hw);
}
}
for (i = 0; i < ARRAY_SIZE(rm->pingpong_blks); i++) {
struct dpu_hw_pingpong *hw;
if (rm->pingpong_blks[i]) {
hw = to_dpu_hw_pingpong(rm->pingpong_blks[i]);
dpu_hw_pingpong_destroy(hw);
}
}
for (i = 0; i < ARRAY_SIZE(rm->merge_3d_blks); i++) {
struct dpu_hw_merge_3d *hw;
if (rm->merge_3d_blks[i]) {
hw = to_dpu_hw_merge_3d(rm->merge_3d_blks[i]);
dpu_hw_merge_3d_destroy(hw);
}
}
for (i = 0; i < ARRAY_SIZE(rm->mixer_blks); i++) {
struct dpu_hw_mixer *hw;
if (rm->mixer_blks[i]) {
hw = to_dpu_hw_mixer(rm->mixer_blks[i]);
dpu_hw_lm_destroy(hw);
}
}
for (i = 0; i < ARRAY_SIZE(rm->ctl_blks); i++) {
struct dpu_hw_ctl *hw;
if (rm->ctl_blks[i]) {
hw = to_dpu_hw_ctl(rm->ctl_blks[i]);
dpu_hw_ctl_destroy(hw);
}
}
for (i = 0; i < ARRAY_SIZE(rm->hw_intf); i++)
dpu_hw_intf_destroy(rm->hw_intf[i]);
for (i = 0; i < ARRAY_SIZE(rm->dsc_blks); i++) {
struct dpu_hw_dsc *hw;
if (rm->dsc_blks[i]) {
hw = to_dpu_hw_dsc(rm->dsc_blks[i]);
dpu_hw_dsc_destroy(hw);
}
}
for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
dpu_hw_wb_destroy(rm->hw_wb[i]);
for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
dpu_hw_sspp_destroy(rm->hw_sspp[i]);
return 0;
}
int dpu_rm_init(struct dpu_rm *rm,
int dpu_rm_init(struct drm_device *dev,
struct dpu_rm *rm,
const struct dpu_mdss_cfg *cat,
const struct msm_mdss_data *mdss_data,
void __iomem *mmio)
@ -119,7 +56,7 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_mixer *hw;
const struct dpu_lm_cfg *lm = &cat->mixer[i];
hw = dpu_hw_lm_init(lm, mmio);
hw = dpu_hw_lm_init(dev, lm, mmio);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed lm object creation: err %d\n", rc);
@ -132,7 +69,7 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_merge_3d *hw;
const struct dpu_merge_3d_cfg *merge_3d = &cat->merge_3d[i];
hw = dpu_hw_merge_3d_init(merge_3d, mmio);
hw = dpu_hw_merge_3d_init(dev, merge_3d, mmio);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed merge_3d object creation: err %d\n",
@ -146,7 +83,7 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_pingpong *hw;
const struct dpu_pingpong_cfg *pp = &cat->pingpong[i];
hw = dpu_hw_pingpong_init(pp, mmio, cat->mdss_ver);
hw = dpu_hw_pingpong_init(dev, pp, mmio, cat->mdss_ver);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed pingpong object creation: err %d\n",
@ -162,7 +99,7 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_intf *hw;
const struct dpu_intf_cfg *intf = &cat->intf[i];
hw = dpu_hw_intf_init(intf, mmio, cat->mdss_ver);
hw = dpu_hw_intf_init(dev, intf, mmio, cat->mdss_ver);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed intf object creation: err %d\n", rc);
@ -175,7 +112,7 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_wb *hw;
const struct dpu_wb_cfg *wb = &cat->wb[i];
hw = dpu_hw_wb_init(wb, mmio, cat->mdss_ver);
hw = dpu_hw_wb_init(dev, wb, mmio, cat->mdss_ver);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed wb object creation: err %d\n", rc);
@ -188,7 +125,7 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_ctl *hw;
const struct dpu_ctl_cfg *ctl = &cat->ctl[i];
hw = dpu_hw_ctl_init(ctl, mmio, cat->mixer_count, cat->mixer);
hw = dpu_hw_ctl_init(dev, ctl, mmio, cat->mixer_count, cat->mixer);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed ctl object creation: err %d\n", rc);
@ -201,7 +138,7 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_dspp *hw;
const struct dpu_dspp_cfg *dspp = &cat->dspp[i];
hw = dpu_hw_dspp_init(dspp, mmio);
hw = dpu_hw_dspp_init(dev, dspp, mmio);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed dspp object creation: err %d\n", rc);
@ -215,9 +152,9 @@ int dpu_rm_init(struct dpu_rm *rm,
const struct dpu_dsc_cfg *dsc = &cat->dsc[i];
if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features))
hw = dpu_hw_dsc_init_1_2(dsc, mmio);
hw = dpu_hw_dsc_init_1_2(dev, dsc, mmio);
else
hw = dpu_hw_dsc_init(dsc, mmio);
hw = dpu_hw_dsc_init(dev, dsc, mmio);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
@ -231,7 +168,7 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_sspp *hw;
const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
hw = dpu_hw_sspp_init(sspp, mmio, mdss_data, cat->mdss_ver);
hw = dpu_hw_sspp_init(dev, sspp, mmio, mdss_data, cat->mdss_ver);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed sspp object creation: err %d\n", rc);
@ -240,11 +177,21 @@ int dpu_rm_init(struct dpu_rm *rm,
rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
}
if (cat->cdm) {
struct dpu_hw_cdm *hw;
hw = dpu_hw_cdm_init(dev, cat->cdm, mmio, cat->mdss_ver);
if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed cdm object creation: err %d\n", rc);
goto fail;
}
rm->cdm_blk = &hw->base;
}
return 0;
fail:
dpu_rm_destroy(rm);
return rc ? rc : -EFAULT;
}
@ -488,6 +435,26 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
return 0;
}
static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
struct dpu_global_state *global_state,
struct drm_encoder *enc)
{
/* try allocating only one CDM block */
if (!rm->cdm_blk) {
DPU_ERROR("CDM block does not exist\n");
return -EIO;
}
if (global_state->cdm_to_enc_id) {
DPU_ERROR("CDM_0 is already allocated\n");
return -EIO;
}
global_state->cdm_to_enc_id = enc->base.id;
return 0;
}
static int _dpu_rm_make_reservation(
struct dpu_rm *rm,
struct dpu_global_state *global_state,
@ -513,6 +480,14 @@ static int _dpu_rm_make_reservation(
if (ret)
return ret;
if (reqs->topology.needs_cdm) {
ret = _dpu_rm_reserve_cdm(rm, global_state, enc);
if (ret) {
DPU_ERROR("unable to find CDM blk\n");
return ret;
}
}
return ret;
}
@ -523,9 +498,9 @@ static int _dpu_rm_populate_requirements(
{
reqs->topology = req_topology;
DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n",
DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d cdm: %d\n",
reqs->topology.num_lm, reqs->topology.num_dsc,
reqs->topology.num_intf);
reqs->topology.num_intf, reqs->topology.needs_cdm);
return 0;
}
@ -554,6 +529,7 @@ void dpu_rm_release(struct dpu_global_state *global_state,
ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
_dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id);
_dpu_rm_clear_mapping(&global_state->cdm_to_enc_id, 1, enc->base.id);
}
int dpu_rm_reserve(
@ -627,6 +603,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
hw_to_enc_id = global_state->dsc_to_enc_id;
max_blks = ARRAY_SIZE(rm->dsc_blks);
break;
case DPU_HW_BLK_CDM:
hw_blks = &rm->cdm_blk;
hw_to_enc_id = &global_state->cdm_to_enc_id;
max_blks = 1;
break;
default:
DPU_ERROR("blk type %d not managed by rm\n", type);
return 0;

View file

@ -22,6 +22,7 @@ struct dpu_global_state;
* @hw_wb: array of wb hardware resources
* @dspp_blks: array of dspp hardware resources
* @hw_sspp: array of sspp hardware resources
* @cdm_blk: cdm hardware resource
*/
struct dpu_rm {
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
@ -33,29 +34,25 @@ struct dpu_rm {
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
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;
};
/**
* dpu_rm_init - Read hardware catalog and create reservation tracking objects
* for all HW blocks.
* @dev: Corresponding device for devres management
* @rm: DPU Resource Manager handle
* @cat: Pointer to hardware catalog
* @mdss_data: Pointer to MDSS / UBWC configuration
* @mmio: mapped register io address of MDP
* @Return: 0 on Success otherwise -ERROR
*/
int dpu_rm_init(struct dpu_rm *rm,
int dpu_rm_init(struct drm_device *dev,
struct dpu_rm *rm,
const struct dpu_mdss_cfg *cat,
const struct msm_mdss_data *mdss_data,
void __iomem *mmio);
/**
* dpu_rm_destroy - Free all memory allocated by dpu_rm_init
* @rm: DPU Resource Manager handle
* @Return: 0 on Success otherwise -ERROR
*/
int dpu_rm_destroy(struct dpu_rm *rm);
/**
* dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze
* the use connections and user requirements, specified through related

View file

@ -6,6 +6,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_flip_work.h>
#include <drm/drm_managed.h>
#include <drm/drm_mode.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@ -123,16 +124,6 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val)
drm_gem_object_put(val);
}
static void mdp4_crtc_destroy(struct drm_crtc *crtc)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
drm_crtc_cleanup(crtc);
drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work);
kfree(mdp4_crtc);
}
/* statically (for now) map planes to mixer stage (z-order): */
static const int idxs[] = {
[VG1] = 1,
@ -269,6 +260,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc,
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
unsigned long flags;
DBG("%s", mdp4_crtc->name);
@ -281,6 +273,14 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc,
mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err);
mdp4_disable(mdp4_kms);
if (crtc->state->event && !crtc->state->active) {
WARN_ON(mdp4_crtc->event);
spin_lock_irqsave(&mdp4_kms->dev->event_lock, flags);
drm_crtc_send_vblank_event(crtc, crtc->state->event);
crtc->state->event = NULL;
spin_unlock_irqrestore(&mdp4_kms->dev->event_lock, flags);
}
mdp4_crtc->enabled = false;
}
@ -475,7 +475,6 @@ static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
static const struct drm_crtc_funcs mdp4_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = mdp4_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
.cursor_set = mdp4_crtc_cursor_set,
.cursor_move = mdp4_crtc_cursor_move,
@ -616,6 +615,13 @@ static const char *dma_names[] = {
"DMA_P", "DMA_S", "DMA_E",
};
static void mdp4_crtc_flip_cleanup(struct drm_device *dev, void *ptr)
{
struct mdp4_crtc *mdp4_crtc = ptr;
drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work);
}
/* initialize crtc */
struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
struct drm_plane *plane, int id, int ovlp_id,
@ -623,10 +629,13 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
{
struct drm_crtc *crtc = NULL;
struct mdp4_crtc *mdp4_crtc;
int ret;
mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL);
if (!mdp4_crtc)
return ERR_PTR(-ENOMEM);
mdp4_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp4_crtc, base,
plane, NULL,
&mdp4_crtc_funcs, NULL);
if (IS_ERR(mdp4_crtc))
return ERR_CAST(mdp4_crtc);
crtc = &mdp4_crtc->base;
@ -648,9 +657,10 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
drm_flip_work_init(&mdp4_crtc->unref_cursor_work,
"unref cursor", unref_cursor_worker);
ret = drmm_add_action_or_reset(dev, mdp4_crtc_flip_cleanup, mdp4_crtc);
if (ret)
return ERR_PTR(ret);
drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs,
NULL);
drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs);
return crtc;

View file

@ -26,18 +26,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder)
return to_mdp4_kms(to_mdp_kms(priv->kms));
}
static void mdp4_dsi_encoder_destroy(struct drm_encoder *encoder)
{
struct mdp4_dsi_encoder *mdp4_dsi_encoder = to_mdp4_dsi_encoder(encoder);
drm_encoder_cleanup(encoder);
kfree(mdp4_dsi_encoder);
}
static const struct drm_encoder_funcs mdp4_dsi_encoder_funcs = {
.destroy = mdp4_dsi_encoder_destroy,
};
static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@ -148,28 +136,18 @@ static const struct drm_encoder_helper_funcs mdp4_dsi_encoder_helper_funcs = {
/* initialize encoder */
struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)
{
struct drm_encoder *encoder = NULL;
struct drm_encoder *encoder;
struct mdp4_dsi_encoder *mdp4_dsi_encoder;
int ret;
mdp4_dsi_encoder = kzalloc(sizeof(*mdp4_dsi_encoder), GFP_KERNEL);
if (!mdp4_dsi_encoder) {
ret = -ENOMEM;
goto fail;
}
mdp4_dsi_encoder = drmm_encoder_alloc(dev, struct mdp4_dsi_encoder, base,
NULL, DRM_MODE_ENCODER_DSI, NULL);
if (IS_ERR(mdp4_dsi_encoder))
return ERR_CAST(mdp4_dsi_encoder);
encoder = &mdp4_dsi_encoder->base;
drm_encoder_init(dev, encoder, &mdp4_dsi_encoder_funcs,
DRM_MODE_ENCODER_DSI, NULL);
drm_encoder_helper_add(encoder, &mdp4_dsi_encoder_helper_funcs);
return encoder;
fail:
if (encoder)
mdp4_dsi_encoder_destroy(encoder);
return ERR_PTR(ret);
}
#endif /* CONFIG_DRM_MSM_DSI */

Some files were not shown because too many files have changed in this diff Show more