mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
Merge branch 'msm-next-lumag' of https://gitlab.freedesktop.org/lumag/msm.git
This commit is contained in:
commit
39772e3ec9
@ -30,6 +30,7 @@ properties:
|
||||
- qcom,sdm845-dsi-ctrl
|
||||
- qcom,sm6115-dsi-ctrl
|
||||
- qcom,sm6125-dsi-ctrl
|
||||
- qcom,sm6150-dsi-ctrl
|
||||
- qcom,sm6350-dsi-ctrl
|
||||
- qcom,sm6375-dsi-ctrl
|
||||
- qcom,sm7150-dsi-ctrl
|
||||
@ -349,6 +350,7 @@ allOf:
|
||||
enum:
|
||||
- qcom,sc7180-dsi-ctrl
|
||||
- qcom,sc7280-dsi-ctrl
|
||||
- qcom,sm6150-dsi-ctrl
|
||||
- qcom,sm7150-dsi-ctrl
|
||||
- qcom,sm8150-dsi-ctrl
|
||||
- qcom,sm8250-dsi-ctrl
|
||||
|
@ -20,6 +20,7 @@ properties:
|
||||
- qcom,dsi-phy-14nm-660
|
||||
- qcom,dsi-phy-14nm-8953
|
||||
- qcom,sm6125-dsi-phy-14nm
|
||||
- qcom,sm6150-dsi-phy-14nm
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
@ -0,0 +1,108 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm6150-dpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM6150 Display DPU
|
||||
|
||||
maintainers:
|
||||
- Abhinav Kumar <quic_abhinavk@quicinc.com>
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
$ref: /schemas/display/msm/dpu-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm6150-dpu
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Address offset and size for mdp register set
|
||||
- description: Address offset and size for vbif register set
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mdp
|
||||
- const: vbif
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display ahb clock
|
||||
- description: Display hf axi clock
|
||||
- description: Display core clock
|
||||
- description: Display vsync clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
- const: vsync
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom,rpmhpd.h>
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm6150-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&dispcc_mdss_ahb_clk>,
|
||||
<&gcc_disp_hf_axi_clk>,
|
||||
<&dispcc_mdss_mdp_clk>,
|
||||
<&dispcc_mdss_vsync_clk>;
|
||||
clock-names = "iface", "bus", "core", "vsync";
|
||||
|
||||
assigned-clocks = <&dispcc_mdss_vsync_clk>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd RPMHPD_CX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf0_out: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&mdss_dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-19200000 {
|
||||
opp-hz = /bits/ 64 <19200000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-25600000 {
|
||||
opp-hz = /bits/ 64 <25600000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-307200000 {
|
||||
opp-hz = /bits/ 64 <307200000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -0,0 +1,245 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/display/msm/qcom,sm6150-mdss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM6150 Display MDSS
|
||||
|
||||
maintainers:
|
||||
- Abhinav Kumar <quic_abhinavk@quicinc.com>
|
||||
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
|
||||
description:
|
||||
Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
|
||||
sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree
|
||||
bindings of MDSS are mentioned for SM6150 target.
|
||||
|
||||
$ref: /schemas/display/msm/mdss-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm6150-mdss
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Display AHB clock from gcc
|
||||
- description: Display hf axi clock
|
||||
- description: Display core clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^display-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm6150-dpu
|
||||
|
||||
"^dsi@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: qcom,sm6150-dsi-ctrl
|
||||
- const: qcom,mdss-dsi-ctrl
|
||||
|
||||
"^phy@[0-9a-f]+$":
|
||||
type: object
|
||||
additionalProperties: true
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm6150-dsi-phy-14nm
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interconnect/qcom,icc.h>
|
||||
#include <dt-bindings/interconnect/qcom,qcs615-rpmh.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom,rpmhpd.h>
|
||||
|
||||
display-subsystem@ae00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "qcom,sm6150-mdss";
|
||||
reg = <0x0ae00000 0x1000>;
|
||||
reg-names = "mdss";
|
||||
|
||||
interconnects = <&mmss_noc MASTER_MDP0 QCOM_ICC_TAG_ALWAYS
|
||||
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
|
||||
<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
|
||||
&config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
|
||||
interconnect-names = "mdp0-mem", "cpu-cfg";
|
||||
|
||||
power-domains = <&dispcc_mdss_gdsc>;
|
||||
|
||||
clocks = <&dispcc_mdss_ahb_clk>,
|
||||
<&gcc_disp_hf_axi_clk>,
|
||||
<&dispcc_mdss_mdp_clk>;
|
||||
|
||||
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
iommus = <&apps_smmu 0x800 0x0>;
|
||||
|
||||
ranges;
|
||||
|
||||
display-controller@ae01000 {
|
||||
compatible = "qcom,sm6150-dpu";
|
||||
reg = <0x0ae01000 0x8f000>,
|
||||
<0x0aeb0000 0x2008>;
|
||||
reg-names = "mdp", "vbif";
|
||||
|
||||
clocks = <&dispcc_mdss_ahb_clk>,
|
||||
<&gcc_disp_hf_axi_clk>,
|
||||
<&dispcc_mdss_mdp_clk>,
|
||||
<&dispcc_mdss_vsync_clk>;
|
||||
clock-names = "iface", "bus", "core", "vsync";
|
||||
|
||||
assigned-clocks = <&dispcc_mdss_vsync_clk>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
operating-points-v2 = <&mdp_opp_table>;
|
||||
power-domains = <&rpmhpd RPMHPD_CX>;
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
dpu_intf0_out: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
dpu_intf1_out: endpoint {
|
||||
remote-endpoint = <&mdss_dsi0_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdp_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-19200000 {
|
||||
opp-hz = /bits/ 64 <19200000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-25600000 {
|
||||
opp-hz = /bits/ 64 <25600000>;
|
||||
required-opps = <&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-307200000 {
|
||||
opp-hz = /bits/ 64 <307200000>;
|
||||
required-opps = <&rpmhpd_opp_nom>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi@ae94000 {
|
||||
compatible = "qcom,sm6150-dsi-ctrl",
|
||||
"qcom,mdss-dsi-ctrl";
|
||||
reg = <0x0ae94000 0x400>;
|
||||
reg-names = "dsi_ctrl";
|
||||
|
||||
interrupt-parent = <&mdss>;
|
||||
interrupts = <4>;
|
||||
|
||||
clocks = <&dispcc_mdss_byte0_clk>,
|
||||
<&dispcc_mdss_byte0_intf_clk>,
|
||||
<&dispcc_mdss_pclk0_clk>,
|
||||
<&dispcc_mdss_esc0_clk>,
|
||||
<&dispcc_mdss_ahb_clk>,
|
||||
<&gcc_disp_hf_axi_clk>;
|
||||
clock-names = "byte",
|
||||
"byte_intf",
|
||||
"pixel",
|
||||
"core",
|
||||
"iface",
|
||||
"bus";
|
||||
|
||||
assigned-clocks = <&dispcc_mdss_byte0_clk_src>,
|
||||
<&dispcc_mdss_pclk0_clk_src>;
|
||||
assigned-clock-parents = <&mdss_dsi0_phy 0>,
|
||||
<&mdss_dsi0_phy 1>;
|
||||
|
||||
operating-points-v2 = <&dsi0_opp_table>;
|
||||
|
||||
phys = <&mdss_dsi0_phy>;
|
||||
|
||||
#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 {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dsi0_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-164000000 {
|
||||
opp-hz = /bits/ 64 <164000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdss_dsi0_phy: phy@ae94400 {
|
||||
compatible = "qcom,sm6150-dsi-phy-14nm";
|
||||
reg = <0x0ae94400 0x100>,
|
||||
<0x0ae94500 0x300>,
|
||||
<0x0ae94800 0x188>;
|
||||
reg-names = "dsi_phy",
|
||||
"dsi_phy_lane",
|
||||
"dsi_pll";
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
clocks = <&dispcc_mdss_ahb_clk>,
|
||||
<&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "iface", "ref";
|
||||
};
|
||||
};
|
||||
...
|
254
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h
Normal file
254
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h
Normal file
@ -0,0 +1,254 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DPU_5_3_SM6150_H
|
||||
#define _DPU_5_3_SM6150_H
|
||||
|
||||
static const struct dpu_caps sm6150_dpu_caps = {
|
||||
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
|
||||
.max_mixer_blendstages = 0x9,
|
||||
.has_dim_layer = true,
|
||||
.has_idle_pc = true,
|
||||
.max_linewidth = 2160,
|
||||
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
|
||||
.max_hdeci_exp = MAX_HORZ_DECIMATION,
|
||||
.max_vdeci_exp = MAX_VERT_DECIMATION,
|
||||
};
|
||||
|
||||
static const struct dpu_mdp_cfg sm6150_mdp = {
|
||||
.name = "top_0",
|
||||
.base = 0x0, .len = 0x45c,
|
||||
.features = 0,
|
||||
.clk_ctrls = {
|
||||
[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .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 },
|
||||
[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_ctl_cfg sm6150_ctl[] = {
|
||||
{
|
||||
.name = "ctl_0", .id = CTL_0,
|
||||
.base = 0x1000, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
|
||||
}, {
|
||||
.name = "ctl_1", .id = CTL_1,
|
||||
.base = 0x1200, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
|
||||
}, {
|
||||
.name = "ctl_2", .id = CTL_2,
|
||||
.base = 0x1400, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
|
||||
}, {
|
||||
.name = "ctl_3", .id = CTL_3,
|
||||
.base = 0x1600, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
|
||||
}, {
|
||||
.name = "ctl_4", .id = CTL_4,
|
||||
.base = 0x1800, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
|
||||
}, {
|
||||
.name = "ctl_5", .id = CTL_5,
|
||||
.base = 0x1a00, .len = 0x1e0,
|
||||
.features = BIT(DPU_CTL_ACTIVE_CFG),
|
||||
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_sspp_cfg sm6150_sspp[] = {
|
||||
{
|
||||
.name = "sspp_0", .id = SSPP_VIG0,
|
||||
.base = 0x4000, .len = 0x1f0,
|
||||
.features = VIG_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_vig_sblk_qseed3_2_4,
|
||||
.xin_id = 0,
|
||||
.type = SSPP_TYPE_VIG,
|
||||
.clk_ctrl = DPU_CLK_CTRL_VIG0,
|
||||
}, {
|
||||
.name = "sspp_8", .id = SSPP_DMA0,
|
||||
.base = 0x24000, .len = 0x1f0,
|
||||
.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 = 0x1f0,
|
||||
.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 = 0x1f0,
|
||||
.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 = 0x1f0,
|
||||
.features = DMA_CURSOR_SDM845_MASK_SDMA,
|
||||
.sblk = &dpu_dma_sblk,
|
||||
.xin_id = 13,
|
||||
.type = SSPP_TYPE_DMA,
|
||||
.clk_ctrl = DPU_CLK_CTRL_DMA3,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_lm_cfg sm6150_lm[] = {
|
||||
{
|
||||
.name = "lm_0", .id = LM_0,
|
||||
.base = 0x44000, .len = 0x320,
|
||||
.features = MIXER_QCM2290_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.pingpong = PINGPONG_0,
|
||||
.dspp = DSPP_0,
|
||||
.lm_pair = LM_1,
|
||||
}, {
|
||||
.name = "lm_1", .id = LM_1,
|
||||
.base = 0x45000, .len = 0x320,
|
||||
.features = MIXER_QCM2290_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.pingpong = PINGPONG_1,
|
||||
.lm_pair = LM_0,
|
||||
}, {
|
||||
.name = "lm_2", .id = LM_2,
|
||||
.base = 0x46000, .len = 0x320,
|
||||
.features = MIXER_QCM2290_MASK,
|
||||
.sblk = &sdm845_lm_sblk,
|
||||
.pingpong = PINGPONG_2,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_dspp_cfg sm6150_dspp[] = {
|
||||
{
|
||||
.name = "dspp_0", .id = DSPP_0,
|
||||
.base = 0x54000, .len = 0x1800,
|
||||
.features = DSPP_SC7180_MASK,
|
||||
.sblk = &sdm845_dspp_sblk,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_pingpong_cfg sm6150_pp[] = {
|
||||
{
|
||||
.name = "pingpong_0", .id = PINGPONG_0,
|
||||
.base = 0x70000, .len = 0xd4,
|
||||
.features = PINGPONG_SM8150_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
|
||||
}, {
|
||||
.name = "pingpong_1", .id = PINGPONG_1,
|
||||
.base = 0x70800, .len = 0xd4,
|
||||
.features = PINGPONG_SM8150_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
|
||||
}, {
|
||||
.name = "pingpong_2", .id = PINGPONG_2,
|
||||
.base = 0x71000, .len = 0xd4,
|
||||
.features = PINGPONG_SM8150_MASK,
|
||||
.sblk = &sdm845_pp_sblk,
|
||||
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dpu_intf_cfg sm6150_intf[] = {
|
||||
{
|
||||
.name = "intf_0", .id = INTF_0,
|
||||
.base = 0x6a000, .len = 0x280,
|
||||
.features = INTF_SC7180_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 = 0x6a800, .len = 0x2c0,
|
||||
.features = INTF_SC7180_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_3", .id = INTF_3,
|
||||
.base = 0x6b800, .len = 0x280,
|
||||
.features = INTF_SC7180_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 sm6150_perf_data = {
|
||||
.max_bw_low = 4800000,
|
||||
.max_bw_high = 4800000,
|
||||
.min_core_ib = 2400000,
|
||||
.min_llcc_ib = 0,
|
||||
.min_dram_ib = 800000,
|
||||
.min_prefill_lines = 24,
|
||||
.danger_lut_tbl = {0xf, 0xffff, 0x0},
|
||||
.safe_lut_tbl = {0xfff8, 0xf000, 0xffff},
|
||||
.qos_lut_tbl = {
|
||||
{.nentry = ARRAY_SIZE(sm8150_qos_linear),
|
||||
.entries = sm8150_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 sm6150_mdss_ver = {
|
||||
.core_major_ver = 5,
|
||||
.core_minor_ver = 3,
|
||||
};
|
||||
|
||||
const struct dpu_mdss_cfg dpu_sm6150_cfg = {
|
||||
.mdss_ver = &sm6150_mdss_ver,
|
||||
.caps = &sm6150_dpu_caps,
|
||||
.mdp = &sm6150_mdp,
|
||||
.ctl_count = ARRAY_SIZE(sm6150_ctl),
|
||||
.ctl = sm6150_ctl,
|
||||
.sspp_count = ARRAY_SIZE(sm6150_sspp),
|
||||
.sspp = sm6150_sspp,
|
||||
.mixer_count = ARRAY_SIZE(sm6150_lm),
|
||||
.mixer = sm6150_lm,
|
||||
.dspp_count = ARRAY_SIZE(sm6150_dspp),
|
||||
.dspp = sm6150_dspp,
|
||||
.pingpong_count = ARRAY_SIZE(sm6150_pp),
|
||||
.pingpong = sm6150_pp,
|
||||
.intf_count = ARRAY_SIZE(sm6150_intf),
|
||||
.intf = sm6150_intf,
|
||||
.vbif_count = ARRAY_SIZE(sdm845_vbif),
|
||||
.vbif = sdm845_vbif,
|
||||
.perf = &sm6150_perf_data,
|
||||
};
|
||||
|
||||
#endif
|
@ -732,6 +732,13 @@ static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc,
|
||||
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
|
||||
int i;
|
||||
|
||||
/* if we cannot merge 2 LMs (no 3d mux) better to fail earlier
|
||||
* before even checking the width after the split
|
||||
*/
|
||||
if (!dpu_kms->catalog->caps->has_3d_merge &&
|
||||
adj_mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width)
|
||||
return -E2BIG;
|
||||
|
||||
for (i = 0; i < cstate->num_mixers; i++) {
|
||||
struct drm_rect *r = &cstate->lm_bounds[i];
|
||||
r->x1 = crtc_split_width * i;
|
||||
@ -1182,6 +1189,49 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
|
||||
{
|
||||
int total_planes = crtc->dev->mode_config.num_total_plane;
|
||||
struct drm_atomic_state *state = crtc_state->state;
|
||||
struct dpu_global_state *global_state;
|
||||
struct drm_plane_state **states;
|
||||
struct drm_plane *plane;
|
||||
int ret;
|
||||
|
||||
global_state = dpu_kms_get_global_state(crtc_state->state);
|
||||
if (IS_ERR(global_state))
|
||||
return PTR_ERR(global_state);
|
||||
|
||||
dpu_rm_release_all_sspp(global_state, crtc);
|
||||
|
||||
if (!crtc_state->enable)
|
||||
return 0;
|
||||
|
||||
states = kcalloc(total_planes, sizeof(*states), GFP_KERNEL);
|
||||
if (!states)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
|
||||
struct drm_plane_state *plane_state =
|
||||
drm_atomic_get_plane_state(state, plane);
|
||||
|
||||
if (IS_ERR(plane_state)) {
|
||||
ret = PTR_ERR(plane_state);
|
||||
goto done;
|
||||
}
|
||||
|
||||
states[plane_state->normalized_zpos] = plane_state;
|
||||
}
|
||||
|
||||
ret = dpu_assign_plane_resources(global_state, state, crtc, states, total_planes);
|
||||
|
||||
done:
|
||||
kfree(states);
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
@ -1197,6 +1247,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
|
||||
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
|
||||
|
||||
if (dpu_use_virtual_planes &&
|
||||
(crtc_state->planes_changed || crtc_state->zpos_changed)) {
|
||||
rc = dpu_crtc_reassign_planes(crtc, crtc_state);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!crtc_state->enable || !drm_atomic_crtc_effectively_active(crtc_state)) {
|
||||
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
|
||||
crtc->base.id, crtc_state->enable,
|
||||
@ -1251,6 +1308,12 @@ static enum drm_mode_status dpu_crtc_mode_valid(struct drm_crtc *crtc,
|
||||
{
|
||||
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
|
||||
|
||||
/* if there is no 3d_mux block we cannot merge LMs so we cannot
|
||||
* split the large layer into 2 LMs, filter out such modes
|
||||
*/
|
||||
if (!dpu_kms->catalog->caps->has_3d_merge &&
|
||||
mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width)
|
||||
return MODE_BAD_HVALUE;
|
||||
/*
|
||||
* max crtc width is equal to the max mixer width * 2 and max height is 4K
|
||||
*/
|
||||
|
@ -765,6 +765,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
|
||||
#include "catalog/dpu_5_0_sm8150.h"
|
||||
#include "catalog/dpu_5_1_sc8180x.h"
|
||||
#include "catalog/dpu_5_2_sm7150.h"
|
||||
#include "catalog/dpu_5_3_sm6150.h"
|
||||
#include "catalog/dpu_5_4_sm6125.h"
|
||||
|
||||
#include "catalog/dpu_6_0_sm8250.h"
|
||||
|
@ -839,6 +839,7 @@ extern const struct dpu_mdss_cfg dpu_sm8250_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sc7180_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sm6115_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sm6125_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sm6150_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sm6350_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_qcm2290_cfg;
|
||||
extern const struct dpu_mdss_cfg dpu_sm6375_cfg;
|
||||
|
@ -51,6 +51,9 @@
|
||||
#define DPU_DEBUGFS_DIR "msm_dpu"
|
||||
#define DPU_DEBUGFS_HWMASKNAME "hw_log_mask"
|
||||
|
||||
bool dpu_use_virtual_planes;
|
||||
module_param(dpu_use_virtual_planes, bool, 0);
|
||||
|
||||
static int dpu_kms_hw_init(struct msm_kms *kms);
|
||||
static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms);
|
||||
|
||||
@ -829,8 +832,11 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
|
||||
type, catalog->sspp[i].features,
|
||||
catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR));
|
||||
|
||||
plane = dpu_plane_init(dev, catalog->sspp[i].id, type,
|
||||
(1UL << max_crtc_count) - 1);
|
||||
if (dpu_use_virtual_planes)
|
||||
plane = dpu_plane_init_virtual(dev, type, (1UL << max_crtc_count) - 1);
|
||||
else
|
||||
plane = dpu_plane_init(dev, catalog->sspp[i].id, type,
|
||||
(1UL << max_crtc_count) - 1);
|
||||
if (IS_ERR(plane)) {
|
||||
DPU_ERROR("dpu_plane_init failed\n");
|
||||
ret = PTR_ERR(plane);
|
||||
@ -1024,6 +1030,14 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k
|
||||
msm_disp_snapshot_add_block(disp_state, cat->cdm->len,
|
||||
dpu_kms->mmio + cat->cdm->base, cat->cdm->name);
|
||||
|
||||
for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
|
||||
const struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i];
|
||||
|
||||
msm_disp_snapshot_add_block(disp_state, vbif->len,
|
||||
dpu_kms->vbif[vbif->id] + vbif->base,
|
||||
vbif->name);
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(&dpu_kms->pdev->dev);
|
||||
}
|
||||
|
||||
@ -1478,6 +1492,7 @@ static const struct of_device_id dpu_dt_match[] = {
|
||||
{ .compatible = "qcom,sc8280xp-dpu", .data = &dpu_sc8280xp_cfg, },
|
||||
{ .compatible = "qcom,sm6115-dpu", .data = &dpu_sm6115_cfg, },
|
||||
{ .compatible = "qcom,sm6125-dpu", .data = &dpu_sm6125_cfg, },
|
||||
{ .compatible = "qcom,sm6150-dpu", .data = &dpu_sm6150_cfg, },
|
||||
{ .compatible = "qcom,sm6350-dpu", .data = &dpu_sm6350_cfg, },
|
||||
{ .compatible = "qcom,sm6375-dpu", .data = &dpu_sm6375_cfg, },
|
||||
{ .compatible = "qcom,sm7150-dpu", .data = &dpu_sm7150_cfg, },
|
||||
|
@ -54,6 +54,8 @@
|
||||
#define ktime_compare_safe(A, B) \
|
||||
ktime_compare(ktime_sub((A), (B)), ktime_set(0, 0))
|
||||
|
||||
extern bool dpu_use_virtual_planes;
|
||||
|
||||
struct dpu_kms {
|
||||
struct msm_kms base;
|
||||
struct drm_device *dev;
|
||||
@ -128,6 +130,8 @@ struct dpu_global_state {
|
||||
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;
|
||||
|
||||
uint32_t sspp_to_crtc_id[SSPP_MAX - SSPP_NONE];
|
||||
};
|
||||
|
||||
struct dpu_global_state
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "msm_drv.h"
|
||||
#include "msm_mdss.h"
|
||||
#include "dpu_kms.h"
|
||||
#include "dpu_formats.h"
|
||||
#include "dpu_hw_sspp.h"
|
||||
#include "dpu_hw_util.h"
|
||||
#include "dpu_trace.h"
|
||||
@ -878,7 +877,7 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
|
||||
drm_rect_rotate_inv(&pipe_cfg->src_rect,
|
||||
new_plane_state->fb->width, new_plane_state->fb->height,
|
||||
new_plane_state->rotation);
|
||||
if (r_pipe_cfg->src_rect.x1 != 0)
|
||||
if (drm_rect_width(&r_pipe_cfg->src_rect) != 0)
|
||||
drm_rect_rotate_inv(&r_pipe_cfg->src_rect,
|
||||
new_plane_state->fb->width, new_plane_state->fb->height,
|
||||
new_plane_state->rotation);
|
||||
@ -888,6 +887,32 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp,
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg,
|
||||
const struct msm_format *fmt,
|
||||
uint32_t max_linewidth)
|
||||
{
|
||||
if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) ||
|
||||
drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect))
|
||||
return false;
|
||||
|
||||
if (pipe_cfg->rotation & DRM_MODE_ROTATE_90)
|
||||
return false;
|
||||
|
||||
if (MSM_FORMAT_IS_YUV(fmt))
|
||||
return false;
|
||||
|
||||
if (MSM_FORMAT_IS_UBWC(fmt) &&
|
||||
drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
|
||||
return false;
|
||||
|
||||
if (!test_bit(DPU_SSPP_SMART_DMA_V1, &sspp->cap->features) &&
|
||||
!test_bit(DPU_SSPP_SMART_DMA_V2, &sspp->cap->features))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state,
|
||||
const struct drm_crtc_state *crtc_state)
|
||||
@ -901,7 +926,6 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
|
||||
const struct msm_format *fmt;
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
|
||||
struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
|
||||
uint32_t max_linewidth;
|
||||
uint32_t supported_rotations;
|
||||
const struct dpu_sspp_cfg *pipe_hw_caps;
|
||||
const struct dpu_sspp_sub_blks *sblk;
|
||||
@ -923,8 +947,6 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
|
||||
|
||||
fmt = msm_framebuffer_format(new_plane_state->fb);
|
||||
|
||||
max_linewidth = pdpu->catalog->caps->max_linewidth;
|
||||
|
||||
supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
|
||||
|
||||
if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
|
||||
@ -940,41 +962,6 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
|
||||
return ret;
|
||||
|
||||
if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) {
|
||||
/*
|
||||
* 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 (MSM_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;
|
||||
}
|
||||
|
||||
if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) ||
|
||||
drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect) ||
|
||||
(!test_bit(DPU_SSPP_SMART_DMA_V1, &pipe->sspp->cap->features) &&
|
||||
!test_bit(DPU_SSPP_SMART_DMA_V2, &pipe->sspp->cap->features)) ||
|
||||
pipe_cfg->rotation & DRM_MODE_ROTATE_90 ||
|
||||
MSM_FORMAT_IS_YUV(fmt)) {
|
||||
DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, can't use split source\n",
|
||||
DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use multirect for wide plane. We do not support dynamic
|
||||
* assignment of SSPPs, so we know the configuration.
|
||||
*/
|
||||
pipe->multirect_index = DPU_SSPP_RECT_0;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
|
||||
|
||||
r_pipe->sspp = pipe->sspp;
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_1;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
|
||||
|
||||
ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt,
|
||||
&crtc_state->adjusted_mode);
|
||||
if (ret)
|
||||
@ -984,6 +971,36 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool dpu_plane_try_multirect_parallel(struct dpu_sw_pipe *pipe, struct dpu_sw_pipe_cfg *pipe_cfg,
|
||||
struct dpu_sw_pipe *r_pipe, struct dpu_sw_pipe_cfg *r_pipe_cfg,
|
||||
struct dpu_hw_sspp *sspp, const struct msm_format *fmt,
|
||||
uint32_t max_linewidth)
|
||||
{
|
||||
r_pipe->sspp = NULL;
|
||||
|
||||
pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
|
||||
if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) {
|
||||
if (!dpu_plane_is_multirect_parallel_capable(pipe->sspp, pipe_cfg, fmt, max_linewidth) ||
|
||||
!dpu_plane_is_multirect_parallel_capable(pipe->sspp, r_pipe_cfg, fmt, max_linewidth))
|
||||
return false;
|
||||
|
||||
r_pipe->sspp = pipe->sspp;
|
||||
|
||||
pipe->multirect_index = DPU_SSPP_RECT_0;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
|
||||
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_1;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int dpu_plane_atomic_check(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
@ -995,14 +1012,19 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
|
||||
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
|
||||
struct dpu_sw_pipe *pipe = &pstate->pipe;
|
||||
struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
|
||||
struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
|
||||
const struct drm_crtc_state *crtc_state = NULL;
|
||||
uint32_t max_linewidth = dpu_kms->catalog->caps->max_linewidth;
|
||||
|
||||
if (new_plane_state->crtc)
|
||||
crtc_state = drm_atomic_get_new_crtc_state(state,
|
||||
new_plane_state->crtc);
|
||||
|
||||
pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
|
||||
r_pipe->sspp = NULL;
|
||||
|
||||
if (!pipe->sspp)
|
||||
return -EINVAL;
|
||||
|
||||
ret = dpu_plane_atomic_check_nosspp(plane, new_plane_state, crtc_state);
|
||||
if (ret)
|
||||
@ -1011,14 +1033,155 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
|
||||
if (!new_plane_state->visible)
|
||||
return 0;
|
||||
|
||||
pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
|
||||
pipe->sspp,
|
||||
msm_framebuffer_format(new_plane_state->fb),
|
||||
max_linewidth)) {
|
||||
DPU_DEBUG_PLANE(pdpu, "invalid " DRM_RECT_FMT " /" DRM_RECT_FMT
|
||||
" max_line:%u, can't use split source\n",
|
||||
DRM_RECT_ARG(&pipe_cfg->src_rect),
|
||||
DRM_RECT_ARG(&r_pipe_cfg->src_rect),
|
||||
max_linewidth);
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
|
||||
}
|
||||
|
||||
static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_plane_state *plane_state =
|
||||
drm_atomic_get_plane_state(state, plane);
|
||||
struct drm_plane_state *old_plane_state =
|
||||
drm_atomic_get_old_plane_state(state, plane);
|
||||
struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state);
|
||||
struct drm_crtc_state *crtc_state;
|
||||
int ret;
|
||||
|
||||
if (plane_state->crtc)
|
||||
crtc_state = drm_atomic_get_new_crtc_state(state,
|
||||
plane_state->crtc);
|
||||
|
||||
ret = dpu_plane_atomic_check_nosspp(plane, plane_state, crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!plane_state->visible) {
|
||||
/*
|
||||
* resources are freed by dpu_crtc_assign_plane_resources(),
|
||||
* but clean them here.
|
||||
*/
|
||||
pstate->pipe.sspp = NULL;
|
||||
pstate->r_pipe.sspp = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force resource reallocation if the format of FB or src/dst have
|
||||
* changed. We might need to allocate different SSPP or SSPPs for this
|
||||
* plane than the one used previously.
|
||||
*/
|
||||
if (!old_plane_state || !old_plane_state->fb ||
|
||||
old_plane_state->src_w != plane_state->src_w ||
|
||||
old_plane_state->src_h != plane_state->src_h ||
|
||||
old_plane_state->src_w != plane_state->src_w ||
|
||||
old_plane_state->crtc_h != plane_state->crtc_h ||
|
||||
msm_framebuffer_format(old_plane_state->fb) !=
|
||||
msm_framebuffer_format(plane_state->fb))
|
||||
crtc_state->planes_changed = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc,
|
||||
struct dpu_global_state *global_state,
|
||||
struct drm_atomic_state *state,
|
||||
struct drm_plane_state *plane_state)
|
||||
{
|
||||
const struct drm_crtc_state *crtc_state = NULL;
|
||||
struct drm_plane *plane = plane_state->plane;
|
||||
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
|
||||
struct dpu_rm_sspp_requirements reqs;
|
||||
struct dpu_plane_state *pstate;
|
||||
struct dpu_sw_pipe *pipe;
|
||||
struct dpu_sw_pipe *r_pipe;
|
||||
struct dpu_sw_pipe_cfg *pipe_cfg;
|
||||
struct dpu_sw_pipe_cfg *r_pipe_cfg;
|
||||
const struct msm_format *fmt;
|
||||
|
||||
if (plane_state->crtc)
|
||||
crtc_state = drm_atomic_get_new_crtc_state(state,
|
||||
plane_state->crtc);
|
||||
|
||||
pstate = to_dpu_plane_state(plane_state);
|
||||
pipe = &pstate->pipe;
|
||||
r_pipe = &pstate->r_pipe;
|
||||
pipe_cfg = &pstate->pipe_cfg;
|
||||
r_pipe_cfg = &pstate->r_pipe_cfg;
|
||||
|
||||
pipe->sspp = NULL;
|
||||
r_pipe->sspp = NULL;
|
||||
|
||||
if (!plane_state->fb)
|
||||
return -EINVAL;
|
||||
|
||||
fmt = msm_framebuffer_format(plane_state->fb);
|
||||
reqs.yuv = MSM_FORMAT_IS_YUV(fmt);
|
||||
reqs.scale = (plane_state->src_w >> 16 != plane_state->crtc_w) ||
|
||||
(plane_state->src_h >> 16 != plane_state->crtc_h);
|
||||
|
||||
reqs.rot90 = drm_rotation_90_or_270(plane_state->rotation);
|
||||
|
||||
pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
|
||||
if (!pipe->sspp)
|
||||
return -ENODEV;
|
||||
|
||||
if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg,
|
||||
pipe->sspp,
|
||||
msm_framebuffer_format(plane_state->fb),
|
||||
dpu_kms->catalog->caps->max_linewidth)) {
|
||||
/* multirect is not possible, use two SSPP blocks */
|
||||
r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs);
|
||||
if (!r_pipe->sspp)
|
||||
return -ENODEV;
|
||||
|
||||
pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
|
||||
r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
|
||||
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
|
||||
}
|
||||
|
||||
return dpu_plane_atomic_check_sspp(plane, state, crtc_state);
|
||||
}
|
||||
|
||||
int dpu_assign_plane_resources(struct dpu_global_state *global_state,
|
||||
struct drm_atomic_state *state,
|
||||
struct drm_crtc *crtc,
|
||||
struct drm_plane_state **states,
|
||||
unsigned int num_planes)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < num_planes; i++) {
|
||||
struct drm_plane_state *plane_state = states[i];
|
||||
|
||||
if (!plane_state ||
|
||||
!plane_state->visible)
|
||||
continue;
|
||||
|
||||
ret = dpu_plane_virtual_assign_resources(crtc, global_state,
|
||||
state, plane_state);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
|
||||
{
|
||||
const struct msm_format *format =
|
||||
@ -1436,39 +1599,29 @@ static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = {
|
||||
.atomic_update = dpu_plane_atomic_update,
|
||||
};
|
||||
|
||||
/**
|
||||
* dpu_plane_init - create new dpu plane for the given pipe
|
||||
* @dev: Pointer to DRM device
|
||||
* @pipe: dpu hardware pipe identifier
|
||||
* @type: Plane type - PRIMARY/OVERLAY/CURSOR
|
||||
* @possible_crtcs: bitmask of crtc that can be attached to the given pipe
|
||||
*
|
||||
* Initialize the plane.
|
||||
*/
|
||||
struct drm_plane *dpu_plane_init(struct drm_device *dev,
|
||||
uint32_t pipe, enum drm_plane_type type,
|
||||
unsigned long possible_crtcs)
|
||||
static const struct drm_plane_helper_funcs dpu_plane_virtual_helper_funcs = {
|
||||
.prepare_fb = dpu_plane_prepare_fb,
|
||||
.cleanup_fb = dpu_plane_cleanup_fb,
|
||||
.atomic_check = dpu_plane_virtual_atomic_check,
|
||||
.atomic_update = dpu_plane_atomic_update,
|
||||
};
|
||||
|
||||
/* initialize plane */
|
||||
static struct drm_plane *dpu_plane_init_common(struct drm_device *dev,
|
||||
enum drm_plane_type type,
|
||||
unsigned long possible_crtcs,
|
||||
bool inline_rotation,
|
||||
const uint32_t *format_list,
|
||||
uint32_t num_formats,
|
||||
enum dpu_sspp pipe)
|
||||
{
|
||||
struct drm_plane *plane = NULL;
|
||||
const uint32_t *format_list;
|
||||
struct dpu_plane *pdpu;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct dpu_kms *kms = to_dpu_kms(priv->kms);
|
||||
struct dpu_hw_sspp *pipe_hw;
|
||||
uint32_t num_formats;
|
||||
uint32_t supported_rotations;
|
||||
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);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
format_list = pipe_hw->cap->sblk->format_list;
|
||||
num_formats = pipe_hw->cap->sblk->num_formats;
|
||||
|
||||
pdpu = drmm_universal_plane_alloc(dev, struct dpu_plane, base,
|
||||
0xff, &dpu_plane_funcs,
|
||||
format_list, num_formats,
|
||||
@ -1494,7 +1647,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
|
||||
|
||||
supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
|
||||
|
||||
if (pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
|
||||
if (inline_rotation)
|
||||
supported_rotations |= DRM_MODE_ROTATE_MASK;
|
||||
|
||||
drm_plane_create_rotation_property(plane,
|
||||
@ -1502,10 +1655,98 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
|
||||
|
||||
drm_plane_enable_fb_damage_clips(plane);
|
||||
|
||||
/* success! finalize initialization */
|
||||
drm_plane_helper_add(plane, &dpu_plane_helper_funcs);
|
||||
|
||||
DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
|
||||
pipe, plane->base.id);
|
||||
return plane;
|
||||
}
|
||||
|
||||
/**
|
||||
* dpu_plane_init - create new dpu plane for the given pipe
|
||||
* @dev: Pointer to DRM device
|
||||
* @pipe: dpu hardware pipe identifier
|
||||
* @type: Plane type - PRIMARY/OVERLAY/CURSOR
|
||||
* @possible_crtcs: bitmask of crtc that can be attached to the given pipe
|
||||
*
|
||||
* Initialize the plane.
|
||||
*/
|
||||
struct drm_plane *dpu_plane_init(struct drm_device *dev,
|
||||
uint32_t pipe, enum drm_plane_type type,
|
||||
unsigned long possible_crtcs)
|
||||
{
|
||||
struct drm_plane *plane = NULL;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct dpu_kms *kms = to_dpu_kms(priv->kms);
|
||||
struct dpu_hw_sspp *pipe_hw;
|
||||
|
||||
/* 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);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
|
||||
plane = dpu_plane_init_common(dev, type, possible_crtcs,
|
||||
pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION),
|
||||
pipe_hw->cap->sblk->format_list,
|
||||
pipe_hw->cap->sblk->num_formats,
|
||||
pipe);
|
||||
if (IS_ERR(plane))
|
||||
return plane;
|
||||
|
||||
drm_plane_helper_add(plane, &dpu_plane_helper_funcs);
|
||||
|
||||
DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
|
||||
pipe, plane->base.id);
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
/**
|
||||
* dpu_plane_init_virtual - create new virtualized DPU plane
|
||||
* @dev: Pointer to DRM device
|
||||
* @type: Plane type - PRIMARY/OVERLAY/CURSOR
|
||||
* @possible_crtcs: bitmask of crtc that can be attached to the given pipe
|
||||
*
|
||||
* Initialize the virtual plane with no backing SSPP / pipe.
|
||||
*/
|
||||
struct drm_plane *dpu_plane_init_virtual(struct drm_device *dev,
|
||||
enum drm_plane_type type,
|
||||
unsigned long possible_crtcs)
|
||||
{
|
||||
struct drm_plane *plane = NULL;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct dpu_kms *kms = to_dpu_kms(priv->kms);
|
||||
bool has_inline_rotation = false;
|
||||
const u32 *format_list = NULL;
|
||||
u32 num_formats = 0;
|
||||
int i;
|
||||
|
||||
/* Determine the largest configuration that we can implement */
|
||||
for (i = 0; i < kms->catalog->sspp_count; i++) {
|
||||
const struct dpu_sspp_cfg *cfg = &kms->catalog->sspp[i];
|
||||
|
||||
if (test_bit(DPU_SSPP_INLINE_ROTATION, &cfg->features))
|
||||
has_inline_rotation = true;
|
||||
|
||||
if (!format_list ||
|
||||
cfg->sblk->csc_blk.len) {
|
||||
format_list = cfg->sblk->format_list;
|
||||
num_formats = cfg->sblk->num_formats;
|
||||
}
|
||||
}
|
||||
|
||||
plane = dpu_plane_init_common(dev, type, possible_crtcs,
|
||||
has_inline_rotation,
|
||||
format_list,
|
||||
num_formats,
|
||||
SSPP_NONE);
|
||||
if (IS_ERR(plane))
|
||||
return plane;
|
||||
|
||||
drm_plane_helper_add(plane, &dpu_plane_virtual_helper_funcs);
|
||||
|
||||
DPU_DEBUG("%s created virtual id:%u\n", plane->name, plane->base.id);
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
@ -62,10 +62,23 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
|
||||
uint32_t pipe, enum drm_plane_type type,
|
||||
unsigned long possible_crtcs);
|
||||
|
||||
struct drm_plane *dpu_plane_init_virtual(struct drm_device *dev,
|
||||
enum drm_plane_type type,
|
||||
unsigned long possible_crtcs);
|
||||
|
||||
int dpu_plane_color_fill(struct drm_plane *plane,
|
||||
uint32_t color, uint32_t alpha);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable);
|
||||
#else
|
||||
static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {}
|
||||
#endif
|
||||
|
||||
int dpu_assign_plane_resources(struct dpu_global_state *global_state,
|
||||
struct drm_atomic_state *state,
|
||||
struct drm_crtc *crtc,
|
||||
struct drm_plane_state **states,
|
||||
unsigned int num_planes);
|
||||
|
||||
#endif /* _DPU_PLANE_H_ */
|
||||
|
@ -725,6 +725,88 @@ int dpu_rm_reserve(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dpu_hw_sspp *dpu_rm_try_sspp(struct dpu_rm *rm,
|
||||
struct dpu_global_state *global_state,
|
||||
struct drm_crtc *crtc,
|
||||
struct dpu_rm_sspp_requirements *reqs,
|
||||
unsigned int type)
|
||||
{
|
||||
uint32_t crtc_id = crtc->base.id;
|
||||
struct dpu_hw_sspp *hw_sspp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++) {
|
||||
if (!rm->hw_sspp[i])
|
||||
continue;
|
||||
|
||||
if (global_state->sspp_to_crtc_id[i])
|
||||
continue;
|
||||
|
||||
hw_sspp = rm->hw_sspp[i];
|
||||
|
||||
if (hw_sspp->cap->type != type)
|
||||
continue;
|
||||
|
||||
if (reqs->scale && !hw_sspp->cap->sblk->scaler_blk.len)
|
||||
continue;
|
||||
|
||||
// TODO: QSEED2 and RGB scalers are not yet supported
|
||||
if (reqs->scale && !hw_sspp->ops.setup_scaler)
|
||||
continue;
|
||||
|
||||
if (reqs->yuv && !hw_sspp->cap->sblk->csc_blk.len)
|
||||
continue;
|
||||
|
||||
if (reqs->rot90 && !(hw_sspp->cap->features & DPU_SSPP_INLINE_ROTATION))
|
||||
continue;
|
||||
|
||||
global_state->sspp_to_crtc_id[i] = crtc_id;
|
||||
|
||||
return rm->hw_sspp[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* dpu_rm_reserve_sspp - Reserve the required SSPP for the provided CRTC
|
||||
* @rm: DPU Resource Manager handle
|
||||
* @global_state: private global state
|
||||
* @crtc: DRM CRTC handle
|
||||
* @reqs: SSPP required features
|
||||
*/
|
||||
struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm,
|
||||
struct dpu_global_state *global_state,
|
||||
struct drm_crtc *crtc,
|
||||
struct dpu_rm_sspp_requirements *reqs)
|
||||
{
|
||||
struct dpu_hw_sspp *hw_sspp = NULL;
|
||||
|
||||
if (!reqs->scale && !reqs->yuv)
|
||||
hw_sspp = dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_DMA);
|
||||
if (!hw_sspp && reqs->scale)
|
||||
hw_sspp = dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_RGB);
|
||||
if (!hw_sspp)
|
||||
hw_sspp = dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_VIG);
|
||||
|
||||
return hw_sspp;
|
||||
}
|
||||
|
||||
/**
|
||||
* dpu_rm_release_all_sspp - Given the CRTC, release all SSPP
|
||||
* blocks previously reserved for that use case.
|
||||
* @global_state: resources shared across multiple kms objects
|
||||
* @crtc: DRM CRTC handle
|
||||
*/
|
||||
void dpu_rm_release_all_sspp(struct dpu_global_state *global_state,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
uint32_t crtc_id = crtc->base.id;
|
||||
|
||||
_dpu_rm_clear_mapping(global_state->sspp_to_crtc_id,
|
||||
ARRAY_SIZE(global_state->sspp_to_crtc_id), crtc_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* dpu_rm_get_assigned_resources - Get hw resources of the given type that are
|
||||
* assigned to this encoder
|
||||
@ -859,4 +941,11 @@ void dpu_rm_print_state(struct drm_printer *p,
|
||||
dpu_rm_print_state_helper(p, rm->cdm_blk,
|
||||
global_state->cdm_to_enc_id);
|
||||
drm_puts(p, "\n");
|
||||
|
||||
drm_puts(p, "\tsspp=");
|
||||
/* skip SSPP_NONE and start from the next index */
|
||||
for (i = SSPP_NONE + 1; i < ARRAY_SIZE(global_state->sspp_to_crtc_id); i++)
|
||||
dpu_rm_print_state_helper(p, rm->hw_sspp[i] ? &rm->hw_sspp[i]->base : NULL,
|
||||
global_state->sspp_to_crtc_id[i]);
|
||||
drm_puts(p, "\n");
|
||||
}
|
||||
|
@ -37,6 +37,12 @@ struct dpu_rm {
|
||||
struct dpu_hw_blk *cdm_blk;
|
||||
};
|
||||
|
||||
struct dpu_rm_sspp_requirements {
|
||||
bool yuv;
|
||||
bool scale;
|
||||
bool rot90;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct msm_display_topology - defines a display topology pipeline
|
||||
* @num_lm: number of layer mixers used
|
||||
@ -68,6 +74,14 @@ int dpu_rm_reserve(struct dpu_rm *rm,
|
||||
void dpu_rm_release(struct dpu_global_state *global_state,
|
||||
struct drm_encoder *enc);
|
||||
|
||||
struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm,
|
||||
struct dpu_global_state *global_state,
|
||||
struct drm_crtc *crtc,
|
||||
struct dpu_rm_sspp_requirements *reqs);
|
||||
|
||||
void dpu_rm_release_all_sspp(struct dpu_global_state *global_state,
|
||||
struct drm_crtc *crtc);
|
||||
|
||||
int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
|
||||
struct dpu_global_state *global_state, uint32_t enc_id,
|
||||
enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
|
||||
|
@ -286,6 +286,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
|
||||
&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
|
||||
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_3_0,
|
||||
&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
|
||||
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_3_1,
|
||||
&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
|
||||
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_4_0,
|
||||
&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
|
||||
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_4_1,
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_2_0 0x20000000
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_2_1 0x20020001
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_3_0 0x20030000
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_3_1 0x20030001
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_4_0 0x20040000
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_4_1 0x20040001
|
||||
#define MSM_DSI_6G_VER_MINOR_V2_5_0 0x20050000
|
||||
|
@ -567,6 +567,8 @@ static const struct of_device_id dsi_phy_dt_match[] = {
|
||||
.data = &dsi_phy_14nm_8953_cfgs },
|
||||
{ .compatible = "qcom,sm6125-dsi-phy-14nm",
|
||||
.data = &dsi_phy_14nm_2290_cfgs },
|
||||
{ .compatible = "qcom,sm6150-dsi-phy-14nm",
|
||||
.data = &dsi_phy_14nm_6150_cfgs },
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_MSM_DSI_10NM_PHY
|
||||
{ .compatible = "qcom,dsi-phy-10nm",
|
||||
|
@ -46,6 +46,7 @@ extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8937_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_14nm_6150_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs;
|
||||
extern const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs;
|
||||
|
@ -1032,6 +1032,10 @@ static const struct regulator_bulk_data dsi_phy_14nm_73p4mA_regulators[] = {
|
||||
{ .supply = "vcca", .init_load_uA = 73400 },
|
||||
};
|
||||
|
||||
static const struct regulator_bulk_data dsi_phy_14nm_36mA_regulators[] = {
|
||||
{ .supply = "vdda", .init_load_uA = 36000 },
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_14nm_17mA_regulators,
|
||||
@ -1097,3 +1101,20 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs = {
|
||||
.io_start = { 0x5e94400 },
|
||||
.num_dsi_phy = 1,
|
||||
};
|
||||
|
||||
const struct msm_dsi_phy_cfg dsi_phy_14nm_6150_cfgs = {
|
||||
.has_phy_lane = true,
|
||||
.regulator_data = dsi_phy_14nm_36mA_regulators,
|
||||
.num_regulators = ARRAY_SIZE(dsi_phy_14nm_36mA_regulators),
|
||||
.ops = {
|
||||
.enable = dsi_14nm_phy_enable,
|
||||
.disable = dsi_14nm_phy_disable,
|
||||
.pll_init = dsi_pll_14nm_init,
|
||||
.save_pll_state = dsi_14nm_pll_save_state,
|
||||
.restore_pll_state = dsi_14nm_pll_restore_state,
|
||||
},
|
||||
.min_pll_rate = VCO_MIN_RATE,
|
||||
.max_pll_rate = VCO_MAX_RATE,
|
||||
.io_start = { 0xae94400 },
|
||||
.num_dsi_phy = 1,
|
||||
};
|
||||
|
@ -166,22 +166,32 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss)
|
||||
static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss)
|
||||
{
|
||||
const struct msm_mdss_data *data = msm_mdss->mdss_data;
|
||||
u32 value = MDSS_UBWC_STATIC_UBWC_SWIZZLE(data->ubwc_swizzle) |
|
||||
MDSS_UBWC_STATIC_HIGHEST_BANK_BIT(data->highest_bank_bit);
|
||||
|
||||
writel_relaxed(data->ubwc_static, msm_mdss->mmio + REG_MDSS_UBWC_STATIC);
|
||||
if (data->ubwc_bank_spread)
|
||||
value |= MDSS_UBWC_STATIC_UBWC_BANK_SPREAD;
|
||||
|
||||
if (data->ubwc_enc_version == UBWC_1_0)
|
||||
value |= MDSS_UBWC_STATIC_UBWC_MIN_ACC_LEN(1);
|
||||
|
||||
writel_relaxed(value, msm_mdss->mmio + REG_MDSS_UBWC_STATIC);
|
||||
}
|
||||
|
||||
static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss)
|
||||
{
|
||||
const struct msm_mdss_data *data = msm_mdss->mdss_data;
|
||||
u32 value = (data->ubwc_swizzle & 0x1) |
|
||||
(data->highest_bank_bit & 0x3) << 4 |
|
||||
(data->macrotile_mode & 0x1) << 12;
|
||||
u32 value = MDSS_UBWC_STATIC_UBWC_SWIZZLE(data->ubwc_swizzle & 0x1) |
|
||||
MDSS_UBWC_STATIC_HIGHEST_BANK_BIT(data->highest_bank_bit);
|
||||
|
||||
if (data->macrotile_mode)
|
||||
value |= MDSS_UBWC_STATIC_MACROTILE_MODE;
|
||||
|
||||
if (data->ubwc_enc_version == UBWC_3_0)
|
||||
value |= BIT(10);
|
||||
value |= MDSS_UBWC_STATIC_UBWC_AMSBC;
|
||||
|
||||
if (data->ubwc_enc_version == UBWC_1_0)
|
||||
value |= BIT(8);
|
||||
value |= MDSS_UBWC_STATIC_UBWC_MIN_ACC_LEN(1);
|
||||
|
||||
writel_relaxed(value, msm_mdss->mmio + REG_MDSS_UBWC_STATIC);
|
||||
}
|
||||
@ -189,10 +199,14 @@ static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss)
|
||||
static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss)
|
||||
{
|
||||
const struct msm_mdss_data *data = msm_mdss->mdss_data;
|
||||
u32 value = (data->ubwc_swizzle & 0x7) |
|
||||
(data->ubwc_static & 0x1) << 3 |
|
||||
(data->highest_bank_bit & 0x7) << 4 |
|
||||
(data->macrotile_mode & 0x1) << 12;
|
||||
u32 value = MDSS_UBWC_STATIC_UBWC_SWIZZLE(data->ubwc_swizzle) |
|
||||
MDSS_UBWC_STATIC_HIGHEST_BANK_BIT(data->highest_bank_bit);
|
||||
|
||||
if (data->ubwc_bank_spread)
|
||||
value |= MDSS_UBWC_STATIC_UBWC_BANK_SPREAD;
|
||||
|
||||
if (data->macrotile_mode)
|
||||
value |= MDSS_UBWC_STATIC_MACROTILE_MODE;
|
||||
|
||||
writel_relaxed(value, msm_mdss->mmio + REG_MDSS_UBWC_STATIC);
|
||||
|
||||
@ -572,16 +586,17 @@ static const struct msm_mdss_data sa8775p_data = {
|
||||
.ubwc_enc_version = UBWC_4_0,
|
||||
.ubwc_dec_version = UBWC_4_0,
|
||||
.ubwc_swizzle = 4,
|
||||
.ubwc_static = 1,
|
||||
.ubwc_bank_spread = true,
|
||||
.highest_bank_bit = 0,
|
||||
.macrotile_mode = 1,
|
||||
.macrotile_mode = true,
|
||||
.reg_bus_bw = 74000,
|
||||
};
|
||||
|
||||
static const struct msm_mdss_data sc7180_data = {
|
||||
.ubwc_enc_version = UBWC_2_0,
|
||||
.ubwc_dec_version = UBWC_2_0,
|
||||
.ubwc_static = 0x1e,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_bank_spread = true,
|
||||
.highest_bank_bit = 0x1,
|
||||
.reg_bus_bw = 76800,
|
||||
};
|
||||
@ -590,9 +605,9 @@ static const struct msm_mdss_data sc7280_data = {
|
||||
.ubwc_enc_version = UBWC_3_0,
|
||||
.ubwc_dec_version = UBWC_4_0,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_static = 1,
|
||||
.ubwc_bank_spread = true,
|
||||
.highest_bank_bit = 1,
|
||||
.macrotile_mode = 1,
|
||||
.macrotile_mode = true,
|
||||
.reg_bus_bw = 74000,
|
||||
};
|
||||
|
||||
@ -600,7 +615,7 @@ static const struct msm_mdss_data sc8180x_data = {
|
||||
.ubwc_enc_version = UBWC_3_0,
|
||||
.ubwc_dec_version = UBWC_3_0,
|
||||
.highest_bank_bit = 3,
|
||||
.macrotile_mode = 1,
|
||||
.macrotile_mode = true,
|
||||
.reg_bus_bw = 76800,
|
||||
};
|
||||
|
||||
@ -608,9 +623,9 @@ static const struct msm_mdss_data sc8280xp_data = {
|
||||
.ubwc_enc_version = UBWC_4_0,
|
||||
.ubwc_dec_version = UBWC_4_0,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_static = 1,
|
||||
.ubwc_bank_spread = true,
|
||||
.highest_bank_bit = 3,
|
||||
.macrotile_mode = 1,
|
||||
.macrotile_mode = true,
|
||||
.reg_bus_bw = 76800,
|
||||
};
|
||||
|
||||
@ -632,7 +647,7 @@ static const struct msm_mdss_data sm6350_data = {
|
||||
.ubwc_enc_version = UBWC_2_0,
|
||||
.ubwc_dec_version = UBWC_2_0,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_static = 0x1e,
|
||||
.ubwc_bank_spread = true,
|
||||
.highest_bank_bit = 1,
|
||||
.reg_bus_bw = 76800,
|
||||
};
|
||||
@ -655,7 +670,7 @@ static const struct msm_mdss_data sm6115_data = {
|
||||
.ubwc_enc_version = UBWC_1_0,
|
||||
.ubwc_dec_version = UBWC_2_0,
|
||||
.ubwc_swizzle = 7,
|
||||
.ubwc_static = 0x11f,
|
||||
.ubwc_bank_spread = true,
|
||||
.highest_bank_bit = 0x1,
|
||||
.reg_bus_bw = 76800,
|
||||
};
|
||||
@ -667,14 +682,21 @@ static const struct msm_mdss_data sm6125_data = {
|
||||
.highest_bank_bit = 1,
|
||||
};
|
||||
|
||||
static const struct msm_mdss_data sm6150_data = {
|
||||
.ubwc_enc_version = UBWC_2_0,
|
||||
.ubwc_dec_version = UBWC_2_0,
|
||||
.highest_bank_bit = 1,
|
||||
.reg_bus_bw = 76800,
|
||||
};
|
||||
|
||||
static const struct msm_mdss_data sm8250_data = {
|
||||
.ubwc_enc_version = UBWC_4_0,
|
||||
.ubwc_dec_version = UBWC_4_0,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_static = 1,
|
||||
.ubwc_bank_spread = true,
|
||||
/* TODO: highest_bank_bit = 2 for LP_DDR4 */
|
||||
.highest_bank_bit = 3,
|
||||
.macrotile_mode = 1,
|
||||
.macrotile_mode = true,
|
||||
.reg_bus_bw = 76800,
|
||||
};
|
||||
|
||||
@ -682,10 +704,10 @@ static const struct msm_mdss_data sm8350_data = {
|
||||
.ubwc_enc_version = UBWC_4_0,
|
||||
.ubwc_dec_version = UBWC_4_0,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_static = 1,
|
||||
.ubwc_bank_spread = true,
|
||||
/* TODO: highest_bank_bit = 2 for LP_DDR4 */
|
||||
.highest_bank_bit = 3,
|
||||
.macrotile_mode = 1,
|
||||
.macrotile_mode = true,
|
||||
.reg_bus_bw = 74000,
|
||||
};
|
||||
|
||||
@ -693,10 +715,10 @@ static const struct msm_mdss_data sm8550_data = {
|
||||
.ubwc_enc_version = UBWC_4_0,
|
||||
.ubwc_dec_version = UBWC_4_3,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_static = 1,
|
||||
.ubwc_bank_spread = true,
|
||||
/* TODO: highest_bank_bit = 2 for LP_DDR4 */
|
||||
.highest_bank_bit = 3,
|
||||
.macrotile_mode = 1,
|
||||
.macrotile_mode = true,
|
||||
.reg_bus_bw = 57000,
|
||||
};
|
||||
|
||||
@ -704,10 +726,10 @@ static const struct msm_mdss_data x1e80100_data = {
|
||||
.ubwc_enc_version = UBWC_4_0,
|
||||
.ubwc_dec_version = UBWC_4_3,
|
||||
.ubwc_swizzle = 6,
|
||||
.ubwc_static = 1,
|
||||
.ubwc_bank_spread = true,
|
||||
/* TODO: highest_bank_bit = 2 for LP_DDR4 */
|
||||
.highest_bank_bit = 3,
|
||||
.macrotile_mode = 1,
|
||||
.macrotile_mode = true,
|
||||
/* TODO: Add reg_bus_bw with real value */
|
||||
};
|
||||
|
||||
@ -724,6 +746,7 @@ static const struct of_device_id mdss_dt_match[] = {
|
||||
{ .compatible = "qcom,sc8280xp-mdss", .data = &sc8280xp_data },
|
||||
{ .compatible = "qcom,sm6115-mdss", .data = &sm6115_data },
|
||||
{ .compatible = "qcom,sm6125-mdss", .data = &sm6125_data },
|
||||
{ .compatible = "qcom,sm6150-mdss", .data = &sm6150_data },
|
||||
{ .compatible = "qcom,sm6350-mdss", .data = &sm6350_data },
|
||||
{ .compatible = "qcom,sm6375-mdss", .data = &sm6350_data },
|
||||
{ .compatible = "qcom,sm7150-mdss", .data = &sm7150_data },
|
||||
|
@ -11,9 +11,9 @@ struct msm_mdss_data {
|
||||
/* can be read from register 0x58 */
|
||||
u32 ubwc_dec_version;
|
||||
u32 ubwc_swizzle;
|
||||
u32 ubwc_static;
|
||||
u32 highest_bank_bit;
|
||||
u32 macrotile_mode;
|
||||
bool ubwc_bank_spread;
|
||||
bool macrotile_mode;
|
||||
u32 reg_bus_bw;
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,16 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
|
||||
|
||||
<reg32 offset="0x00058" name="UBWC_DEC_HW_VERSION"/>
|
||||
|
||||
<reg32 offset="0x00144" name="UBWC_STATIC"/>
|
||||
<reg32 offset="0x00144" name="UBWC_STATIC">
|
||||
<bitfield name="UBWC_SWIZZLE" low="0" high="2"/>
|
||||
<bitfield name="UBWC_BANK_SPREAD" pos="3"/>
|
||||
<!-- high=5 for UBWC < 4.0 -->
|
||||
<bitfield name="HIGHEST_BANK_BIT" low="4" high="6"/>
|
||||
<bitfield name="UBWC_MIN_ACC_LEN" low="8" high="9"/>
|
||||
<bitfield name="UBWC_AMSBC" pos="10"/>
|
||||
<bitfield name="MACROTILE_MODE" pos="12"/>
|
||||
</reg32>
|
||||
|
||||
<reg32 offset="0x00150" name="UBWC_CTRL_2"/>
|
||||
<reg32 offset="0x00154" name="UBWC_PREDICTION_MODE"/>
|
||||
</domain>
|
||||
|
Loading…
Reference in New Issue
Block a user