Commit 62a05f4a authored by Daniel Vetter's avatar Daniel Vetter

Merge tag 'drm-msm-next-2024-07-04' of https://gitlab.freedesktop.org/drm/msm into drm-next

Updates for v6.11

Core:
- SM7150 support

DPU:
- SM7150 support
- Fix DSC support for DSI panels in video mode
- Fixed TE vsync source support for DSI command-mode panels
- Fix for devices without UBWC in the display controller (ie.
  QCM2290)

DSI:
- Remove unused register-writing wrappers
- Fix DSC support for panels in video mode
- Add support for parsing TE vsync source
- Add support for MSM8937 (28nm DSI PHY)

MDP5:
- Add support for MSM8937
- Fix configuration for MSM8953

GPU:
- Split giant device table into per-gen "hw catalog" similar to
  what is done on the display side of the driver
- Fix a702 UBWC mode
- Fix unused variably warnings
- GPU memory traces
- Add param for userspace to know if raytracing is supported
- Memory barrier cleanup and GBIF unhalt fix
- X185 support (aka gpu in X1 laptop chips)
- a505 support
- fixes
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGvZQpYEHpSCgXGJ2kaHJDK6QFAFfTsfiWm4b2zZOnjXGw@mail.gmail.com
parents d076e2bd fe34394e
......@@ -32,6 +32,7 @@ properties:
- qcom,sm6125-dsi-ctrl
- qcom,sm6350-dsi-ctrl
- qcom,sm6375-dsi-ctrl
- qcom,sm7150-dsi-ctrl
- qcom,sm8150-dsi-ctrl
- qcom,sm8250-dsi-ctrl
- qcom,sm8350-dsi-ctrl
......@@ -162,6 +163,22 @@ properties:
items:
enum: [ 0, 1, 2, 3 ]
qcom,te-source:
$ref: /schemas/types.yaml#/definitions/string
description:
Specifies the source of vsync signal from the panel used for
tearing elimination.
default: mdp_vsync_p
enum:
- mdp_vsync_p
- mdp_vsync_s
- mdp_vsync_e
- timer0
- timer1
- timer2
- timer3
- timer4
required:
- port@0
- port@1
......@@ -332,6 +349,7 @@ allOf:
enum:
- qcom,sc7180-dsi-ctrl
- qcom,sc7280-dsi-ctrl
- qcom,sm7150-dsi-ctrl
- qcom,sm8150-dsi-ctrl
- qcom,sm8250-dsi-ctrl
- qcom,sm8350-dsi-ctrl
......@@ -452,6 +470,7 @@ examples:
dsi0_out: endpoint {
remote-endpoint = <&sn65dsi86_in>;
data-lanes = <0 1 2 3>;
qcom,te-source = "mdp_vsync_e";
};
};
};
......
......@@ -16,6 +16,7 @@ properties:
compatible:
enum:
- qcom,dsi-phy-28nm-8226
- qcom,dsi-phy-28nm-8937
- qcom,dsi-phy-28nm-8960
- qcom,dsi-phy-28nm-hpm
- qcom,dsi-phy-28nm-hpm-fam-b
......
......@@ -23,6 +23,9 @@ properties:
- items:
- pattern: '^qcom,adreno-gmu-[67][0-9][0-9]\.[0-9]$'
- const: qcom,adreno-gmu
- items:
- pattern: '^qcom,adreno-gmu-x[1-9][0-9][0-9]\.[0-9]$'
- const: qcom,adreno-gmu
- const: qcom,adreno-gmu-wrapper
reg:
......@@ -225,6 +228,7 @@ allOf:
- qcom,adreno-gmu-730.1
- qcom,adreno-gmu-740.1
- qcom,adreno-gmu-750.1
- qcom,adreno-gmu-x185.1
then:
properties:
reg:
......
......@@ -10,6 +10,18 @@ title: Adreno or Snapdragon GPUs
maintainers:
- Rob Clark <robdclark@gmail.com>
# dtschema does not select nodes based on pattern+const, so add custom select
# as a work-around:
select:
properties:
compatible:
contains:
enum:
- qcom,adreno
- amd,imageon
required:
- compatible
properties:
compatible:
oneOf:
......@@ -17,7 +29,7 @@ properties:
The driver is parsing the compat string for Adreno to
figure out the chip-id.
items:
- pattern: '^qcom,adreno-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$'
- pattern: '^qcom,adreno-[0-9a-f]{8}$'
- const: qcom,adreno
- description: |
The driver is parsing the compat string for Adreno to
......@@ -32,9 +44,13 @@ properties:
- pattern: '^amd,imageon-200\.[0-1]$'
- const: amd,imageon
clocks: true
clocks:
minItems: 2
maxItems: 7
clock-names: true
clock-names:
minItems: 2
maxItems: 7
reg:
minItems: 1
......@@ -42,7 +58,10 @@ properties:
reg-names:
minItems: 1
maxItems: 3
items:
- const: kgsl_3d0_reg_memory
- const: cx_mem
- const: cx_dbgc
interrupts:
maxItems: 1
......
......@@ -25,6 +25,7 @@ properties:
- qcom,msm8226-mdp5
- qcom,msm8916-mdp5
- qcom,msm8917-mdp5
- qcom,msm8937-mdp5
- qcom,msm8953-mdp5
- qcom,msm8974-mdp5
- qcom,msm8976-mdp5
......
......@@ -126,6 +126,7 @@ patternProperties:
- qcom,dsi-phy-14nm-8953
- qcom,dsi-phy-20nm
- qcom,dsi-phy-28nm-8226
- qcom,dsi-phy-28nm-8937
- qcom,dsi-phy-28nm-hpm
- qcom,dsi-phy-28nm-hpm-fam-b
- qcom,dsi-phy-28nm-lp
......
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,sm7150-dpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SM7150 Display Processing Unit (DPU)
maintainers:
- Danila Tikhonov <danila@jiaxyga.com>
$ref: /schemas/display/msm/dpu-common.yaml#
properties:
compatible:
const: qcom,sm7150-dpu
reg:
items:
- description: Address offset and size for mdp register set
- description: Address offset and size for vbif register set
reg-names:
items:
- const: mdp
- const: vbif
clocks:
items:
- description: Display hf axi clock
- description: Display ahb clock
- description: Display rotator clock
- description: Display lut clock
- description: Display core clock
- description: Display vsync clock
clock-names:
items:
- const: bus
- const: iface
- const: rot
- 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,sm7150-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x2008>;
reg-names = "mdp", "vbif";
clocks = <&gcc_disp_hf_axi_clk>,
<&dispcc_mdss_ahb_clk>,
<&dispcc_mdss_rot_clk>,
<&dispcc_mdss_mdp_lut_clk>,
<&dispcc_mdss_mdp_clk>,
<&dispcc_mdss_vsync_clk>;
clock-names = "bus",
"iface",
"rot",
"lut",
"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_intf1_out: endpoint {
remote-endpoint = <&mdss_dsi0_in>;
};
};
port@1 {
reg = <1>;
dpu_intf2_out: endpoint {
remote-endpoint = <&mdss_dsi1_in>;
};
};
port@2 {
reg = <2>;
dpu_intf0_out: endpoint {
remote-endpoint = <&dp_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-19200000 {
opp-hz = /bits/ 64 <19200000>;
required-opps = <&rpmhpd_opp_min_svs>;
};
opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-344000000 {
opp-hz = /bits/ 64 <344000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-430000000 {
opp-hz = /bits/ 64 <430000000>;
required-opps = <&rpmhpd_opp_nom>;
};
};
};
...
......@@ -1394,6 +1394,20 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
}
EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh);
int qcom_scm_gpu_init_regs(u32 gpu_req)
{
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_GPU,
.cmd = QCOM_SCM_SVC_GPU_INIT_REGS,
.arginfo = QCOM_SCM_ARGS(1),
.args[0] = gpu_req,
.owner = ARM_SMCCC_OWNER_SIP,
};
return qcom_scm_call(__scm->dev, &desc, NULL);
}
EXPORT_SYMBOL_GPL(qcom_scm_gpu_init_regs);
static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
{
struct device_node *tcsr;
......
......@@ -138,6 +138,9 @@ int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
#define QCOM_SCM_WAITQ_RESUME 0x02
#define QCOM_SCM_WAITQ_GET_WQ_CTX 0x03
#define QCOM_SCM_SVC_GPU 0x28
#define QCOM_SCM_SVC_GPU_INIT_REGS 0x01
/* common error codes */
#define QCOM_SCM_V2_EBUSY -12
#define QCOM_SCM_ENOMEM -5
......
......@@ -33,6 +33,7 @@ config DRM_MSM
select PM_OPP
select NVMEM
select PM_GENERIC_DOMAINS
select TRACE_GPU_MEM
help
DRM/KMS driver for MSM/snapdragon.
......
......@@ -8,13 +8,18 @@ ccflags-$(CONFIG_DRM_MSM_DP) += -I $(src)/dp
adreno-y := \
adreno/adreno_device.o \
adreno/adreno_gpu.o \
adreno/a2xx_catalog.o \
adreno/a2xx_gpu.o \
adreno/a2xx_gpummu.o \
adreno/a3xx_catalog.o \
adreno/a3xx_gpu.o \
adreno/a4xx_catalog.o \
adreno/a4xx_gpu.o \
adreno/a5xx_catalog.o \
adreno/a5xx_gpu.o \
adreno/a5xx_power.o \
adreno/a5xx_preempt.o \
adreno/a6xx_catalog.o \
adreno/a6xx_gpu.o \
adreno/a6xx_gmu.o \
adreno/a6xx_hfi.o \
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2013-2014 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
* Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
*/
#include "adreno_gpu.h"
static const struct adreno_info a2xx_gpus[] = {
{
.chip_ids = ADRENO_CHIP_IDS(0x02000000),
.family = ADRENO_2XX_GEN1,
.revn = 200,
.fw = {
[ADRENO_FW_PM4] = "yamato_pm4.fw",
[ADRENO_FW_PFP] = "yamato_pfp.fw",
},
.gmem = SZ_256K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a2xx_gpu_init,
}, { /* a200 on i.mx51 has only 128kib gmem */
.chip_ids = ADRENO_CHIP_IDS(0x02000001),
.family = ADRENO_2XX_GEN1,
.revn = 201,
.fw = {
[ADRENO_FW_PM4] = "yamato_pm4.fw",
[ADRENO_FW_PFP] = "yamato_pfp.fw",
},
.gmem = SZ_128K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a2xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(0x02020000),
.family = ADRENO_2XX_GEN2,
.revn = 220,
.fw = {
[ADRENO_FW_PM4] = "leia_pm4_470.fw",
[ADRENO_FW_PFP] = "leia_pfp_470.fw",
},
.gmem = SZ_512K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a2xx_gpu_init,
}
};
DECLARE_ADRENO_GPULIST(a2xx);
MODULE_FIRMWARE("qcom/leia_pfp_470.fw");
MODULE_FIRMWARE("qcom/leia_pm4_470.fw");
MODULE_FIRMWARE("qcom/yamato_pfp.fw");
MODULE_FIRMWARE("qcom/yamato_pm4.fw");
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2013-2014 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
* Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
*/
#include "adreno_gpu.h"
static const struct adreno_info a3xx_gpus[] = {
{
.chip_ids = ADRENO_CHIP_IDS(0x03000512),
.family = ADRENO_3XX,
.fw = {
[ADRENO_FW_PM4] = "a330_pm4.fw",
[ADRENO_FW_PFP] = "a330_pfp.fw",
},
.gmem = SZ_128K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a3xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(0x03000520),
.family = ADRENO_3XX,
.revn = 305,
.fw = {
[ADRENO_FW_PM4] = "a300_pm4.fw",
[ADRENO_FW_PFP] = "a300_pfp.fw",
},
.gmem = SZ_256K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a3xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(0x03000600),
.family = ADRENO_3XX,
.revn = 307, /* because a305c is revn==306 */
.fw = {
[ADRENO_FW_PM4] = "a300_pm4.fw",
[ADRENO_FW_PFP] = "a300_pfp.fw",
},
.gmem = SZ_128K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a3xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(
0x03020000,
0x03020001,
0x03020002
),
.family = ADRENO_3XX,
.revn = 320,
.fw = {
[ADRENO_FW_PM4] = "a300_pm4.fw",
[ADRENO_FW_PFP] = "a300_pfp.fw",
},
.gmem = SZ_512K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a3xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(
0x03030000,
0x03030001,
0x03030002
),
.family = ADRENO_3XX,
.revn = 330,
.fw = {
[ADRENO_FW_PM4] = "a330_pm4.fw",
[ADRENO_FW_PFP] = "a330_pfp.fw",
},
.gmem = SZ_1M,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a3xx_gpu_init,
}
};
DECLARE_ADRENO_GPULIST(a3xx);
MODULE_FIRMWARE("qcom/a300_pm4.fw");
MODULE_FIRMWARE("qcom/a300_pfp.fw");
MODULE_FIRMWARE("qcom/a330_pm4.fw");
MODULE_FIRMWARE("qcom/a330_pfp.fw");
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2013-2014 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
* Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
*/
#include "adreno_gpu.h"
static const struct adreno_info a4xx_gpus[] = {
{
.chip_ids = ADRENO_CHIP_IDS(0x04000500),
.family = ADRENO_4XX,
.revn = 405,
.fw = {
[ADRENO_FW_PM4] = "a420_pm4.fw",
[ADRENO_FW_PFP] = "a420_pfp.fw",
},
.gmem = SZ_256K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a4xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(0x04020000),
.family = ADRENO_4XX,
.revn = 420,
.fw = {
[ADRENO_FW_PM4] = "a420_pm4.fw",
[ADRENO_FW_PFP] = "a420_pfp.fw",
},
.gmem = (SZ_1M + SZ_512K),
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a4xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(0x04030002),
.family = ADRENO_4XX,
.revn = 430,
.fw = {
[ADRENO_FW_PM4] = "a420_pm4.fw",
[ADRENO_FW_PFP] = "a420_pfp.fw",
},
.gmem = (SZ_1M + SZ_512K),
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.init = a4xx_gpu_init,
}
};
DECLARE_ADRENO_GPULIST(a4xx);
MODULE_FIRMWARE("qcom/a420_pm4.fw");
MODULE_FIRMWARE("qcom/a420_pfp.fw");
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2013-2014 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
* Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
*/
#include "adreno_gpu.h"
static const struct adreno_info a5xx_gpus[] = {
{
.chip_ids = ADRENO_CHIP_IDS(0x05000500),
.family = ADRENO_5XX,
.revn = 505,
.fw = {
[ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
},
.gmem = (SZ_128K + SZ_8K),
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
ADRENO_QUIRK_LMLOADKILL_DISABLE,
.init = a5xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(0x05000600),
.family = ADRENO_5XX,
.revn = 506,
.fw = {
[ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
},
.gmem = (SZ_128K + SZ_8K),
/*
* Increase inactive period to 250 to avoid bouncing
* the GDSC which appears to make it grumpy
*/
.inactive_period = 250,
.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
ADRENO_QUIRK_LMLOADKILL_DISABLE,
.init = a5xx_gpu_init,
.zapfw = "a506_zap.mdt",
}, {
.chip_ids = ADRENO_CHIP_IDS(0x05000800),
.family = ADRENO_5XX,
.revn = 508,
.fw = {
[ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
},
.gmem = (SZ_128K + SZ_8K),
/*
* Increase inactive period to 250 to avoid bouncing
* the GDSC which appears to make it grumpy
*/
.inactive_period = 250,
.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
.init = a5xx_gpu_init,
.zapfw = "a508_zap.mdt",
}, {
.chip_ids = ADRENO_CHIP_IDS(0x05000900),
.family = ADRENO_5XX,
.revn = 509,
.fw = {
[ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
},
.gmem = (SZ_256K + SZ_16K),
/*
* Increase inactive period to 250 to avoid bouncing
* the GDSC which appears to make it grumpy
*/
.inactive_period = 250,
.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
.init = a5xx_gpu_init,
/* Adreno 509 uses the same ZAP as 512 */
.zapfw = "a512_zap.mdt",
}, {
.chip_ids = ADRENO_CHIP_IDS(0x05010000),
.family = ADRENO_5XX,
.revn = 510,
.fw = {
[ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
},
.gmem = SZ_256K,
/*
* Increase inactive period to 250 to avoid bouncing
* the GDSC which appears to make it grumpy
*/
.inactive_period = 250,
.init = a5xx_gpu_init,
}, {
.chip_ids = ADRENO_CHIP_IDS(0x05010200),
.family = ADRENO_5XX,
.revn = 512,
.fw = {
[ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
},
.gmem = (SZ_256K + SZ_16K),
/*
* Increase inactive period to 250 to avoid bouncing
* the GDSC which appears to make it grumpy
*/
.inactive_period = 250,
.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
.init = a5xx_gpu_init,
.zapfw = "a512_zap.mdt",
}, {
.chip_ids = ADRENO_CHIP_IDS(
0x05030002,
0x05030004
),
.family = ADRENO_5XX,
.revn = 530,
.fw = {
[ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
[ADRENO_FW_GPMU] = "a530v3_gpmu.fw2",
},
.gmem = SZ_1M,
/*
* Increase inactive period to 250 to avoid bouncing
* the GDSC which appears to make it grumpy
*/
.inactive_period = 250,
.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
ADRENO_QUIRK_FAULT_DETECT_MASK,
.init = a5xx_gpu_init,
.zapfw = "a530_zap.mdt",
}, {
.chip_ids = ADRENO_CHIP_IDS(0x05040001),
.family = ADRENO_5XX,
.revn = 540,
.fw = {
[ADRENO_FW_PM4] = "a530_pm4.fw",
[ADRENO_FW_PFP] = "a530_pfp.fw",
[ADRENO_FW_GPMU] = "a540_gpmu.fw2",
},
.gmem = SZ_1M,
/*
* Increase inactive period to 250 to avoid bouncing
* the GDSC which appears to make it grumpy
*/
.inactive_period = 250,
.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
.init = a5xx_gpu_init,
.zapfw = "a540_zap.mdt",
}
};
DECLARE_ADRENO_GPULIST(a5xx);
MODULE_FIRMWARE("qcom/a530_pm4.fw");
MODULE_FIRMWARE("qcom/a530_pfp.fw");
MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2");
MODULE_FIRMWARE("qcom/a530_zap.mdt");
MODULE_FIRMWARE("qcom/a530_zap.b00");
MODULE_FIRMWARE("qcom/a530_zap.b01");
MODULE_FIRMWARE("qcom/a530_zap.b02");
MODULE_FIRMWARE("qcom/a540_gpmu.fw2");
......@@ -439,7 +439,8 @@ void a5xx_set_hwcg(struct msm_gpu *gpu, bool state)
const struct adreno_five_hwcg_regs *regs;
unsigned int i, sz;
if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu)) {
if (adreno_is_a505(adreno_gpu) || adreno_is_a506(adreno_gpu) ||
adreno_is_a508(adreno_gpu)) {
regs = a50x_hwcg;
sz = ARRAY_SIZE(a50x_hwcg);
} else if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu)) {
......@@ -483,7 +484,8 @@ static int a5xx_me_init(struct msm_gpu *gpu)
OUT_RING(ring, 0x00000000);
/* Specify workarounds for various microcode issues */
if (adreno_is_a506(adreno_gpu) || adreno_is_a530(adreno_gpu)) {
if (adreno_is_a505(adreno_gpu) || adreno_is_a506(adreno_gpu) ||
adreno_is_a530(adreno_gpu)) {
/* Workaround for token end syncs
* Force a WFI after every direct-render 3D mode draw and every
* 2D mode 3 draw
......@@ -752,10 +754,11 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
0x00100000 + adreno_gpu->info->gmem - 1);
gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000);
if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu) ||
adreno_is_a510(adreno_gpu)) {
if (adreno_is_a505(adreno_gpu) || adreno_is_a506(adreno_gpu) ||
adreno_is_a508(adreno_gpu) || adreno_is_a510(adreno_gpu)) {
gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x20);
if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu))
if (adreno_is_a505(adreno_gpu) || adreno_is_a506(adreno_gpu) ||
adreno_is_a508(adreno_gpu))
gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400);
else
gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x20);
......@@ -771,7 +774,8 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
}
if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu))
if (adreno_is_a505(adreno_gpu) || adreno_is_a506(adreno_gpu) ||
adreno_is_a508(adreno_gpu))
gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL,
(0x100 << 11 | 0x100 << 22));
else if (adreno_is_a509(adreno_gpu) || adreno_is_a510(adreno_gpu) ||
......@@ -789,8 +793,9 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
* Disable the RB sampler datapath DP2 clock gating optimization
* for 1-SP GPUs, as it is enabled by default.
*/
if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu) ||
adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu))
if (adreno_is_a505(adreno_gpu) || adreno_is_a506(adreno_gpu) ||
adreno_is_a508(adreno_gpu) || adreno_is_a509(adreno_gpu) ||
adreno_is_a512(adreno_gpu))
gpu_rmw(gpu, REG_A5XX_RB_DBG_ECO_CNTL, 0, (1 << 9));
/* Disable UCHE global filter as SP can invalidate/flush independently */
......@@ -1345,7 +1350,7 @@ static int a5xx_pm_resume(struct msm_gpu *gpu)
if (ret)
return ret;
/* Adreno 506, 508, 509, 510, 512 needs manual RBBM sus/res control */
/* Adreno 505, 506, 508, 509, 510, 512 needs manual RBBM sus/res control */
if (!(adreno_is_a530(adreno_gpu) || adreno_is_a540(adreno_gpu))) {
/* Halt the sp_input_clk at HM level */
gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0x00000055);
......@@ -1388,9 +1393,9 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu)
u32 mask = 0xf;
int i, ret;
/* A506, A508, A510 have 3 XIN ports in VBIF */
if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu) ||
adreno_is_a510(adreno_gpu))
/* A505, A506, A508, A510 have 3 XIN ports in VBIF */
if (adreno_is_a505(adreno_gpu) || adreno_is_a506(adreno_gpu) ||
adreno_is_a508(adreno_gpu) || adreno_is_a510(adreno_gpu))
mask = 0x7;
/* Clear the VBIF pipe before shutting down */
......
This diff is collapsed.
......@@ -466,9 +466,7 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu)
int ret;
u32 val;
gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1 << 1);
/* Wait for the register to finish posting */
wmb();
gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, BIT(1));
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_RSCC_CONTROL_ACK, val,
val & (1 << 1), 100, 10000);
......@@ -769,8 +767,9 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
{
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
const struct a6xx_info *a6xx_info = adreno_gpu->info->a6xx;
u32 fence_range_lower, fence_range_upper;
u32 chipid, chipid_min = 0;
u32 chipid = 0;
int ret;
/* Vote veto for FAL10 */
......@@ -830,27 +829,8 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
*/
gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052);
/* NOTE: A730 may also fall in this if-condition with a future GMU fw update. */
if (adreno_is_a7xx(adreno_gpu) && !adreno_is_a730(adreno_gpu)) {
/* A7xx GPUs have obfuscated chip IDs. Use constant maj = 7 */
chipid = FIELD_PREP(GENMASK(31, 24), 0x7);
/*
* The min part has a 1-1 mapping for each GPU SKU.
* This chipid that the GMU expects corresponds to the "GENX_Y_Z" naming,
* where X = major, Y = minor, Z = patchlevel, e.g. GEN7_2_1 for prod A740.
*/
if (adreno_is_a740(adreno_gpu))
chipid_min = 2;
else if (adreno_is_a750(adreno_gpu))
chipid_min = 9;
else
return -EINVAL;
chipid |= FIELD_PREP(GENMASK(23, 16), chipid_min);
/* Get the patchid (which may vary) from the device tree */
chipid |= FIELD_PREP(GENMASK(15, 8), adreno_patchid(adreno_gpu));
if (a6xx_info->gmu_chipid) {
chipid = a6xx_info->gmu_chipid;
} else {
/*
* Note that the GMU has a slightly different layout for
......@@ -1329,7 +1309,13 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes,
if (!pri_count)
return -EINVAL;
sec = cmd_db_read_aux_data("mx.lvl", &sec_count);
/*
* Some targets have a separate gfx mxc rail. So try to read that first and then fall back
* to regular mx rail if it is missing
*/
sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count);
if (IS_ERR(sec) && sec != ERR_PTR(-EPROBE_DEFER))
sec = cmd_db_read_aux_data("mx.lvl", &sec_count);
if (IS_ERR(sec))
return PTR_ERR(sec);
......
This diff is collapsed.
......@@ -12,6 +12,18 @@
extern bool hang_debug;
/**
* struct a6xx_info - a6xx specific information from device table
*
* @hwcg: hw clock gating register sequence
* @protect: CP_PROTECT settings
*/
struct a6xx_info {
const struct adreno_reglist *hwcg;
const struct adreno_protect *protect;
u32 gmu_chipid;
};
struct a6xx_gpu {
struct adreno_gpu base;
......
......@@ -8,19 +8,16 @@
#include "a6xx_gpu_state.h"
#include "a6xx_gmu.xml.h"
/* Ignore diagnostics about register tables that we aren't using yet. We don't
* want to modify these headers too much from their original source.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-const-variable"
static const unsigned int *gen7_0_0_external_core_regs[] __always_unused;
static const unsigned int *gen7_2_0_external_core_regs[] __always_unused;
static const unsigned int *gen7_9_0_external_core_regs[] __always_unused;
static struct gen7_sptp_cluster_registers gen7_9_0_sptp_clusters[] __always_unused;
static const u32 gen7_9_0_cx_debugbus_blocks[] __always_unused;
#include "adreno_gen7_0_0_snapshot.h"
#include "adreno_gen7_2_0_snapshot.h"
#include "adreno_gen7_9_0_snapshot.h"
#pragma GCC diagnostic pop
struct a6xx_gpu_state_obj {
const void *handle;
u32 *data;
......
This diff is collapsed.
......@@ -46,7 +46,7 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname,
}
np = of_get_child_by_name(dev->of_node, "zap-shader");
if (!np) {
if (!of_device_is_available(np)) {
zap_available = false;
return -ENODEV;
}
......@@ -376,6 +376,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
case MSM_PARAM_HIGHEST_BANK_BIT:
*value = adreno_gpu->ubwc_config.highest_bank_bit;
return 0;
case MSM_PARAM_RAYTRACING:
*value = adreno_gpu->has_ray_tracing;
return 0;
default:
DBG("%s: invalid param: %u", gpu->name, param);
return -EINVAL;
......@@ -887,6 +890,7 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
drm_printf(p, " - iova: 0x%016llx\n",
state->bos[i].iova);
drm_printf(p, " size: %zd\n", state->bos[i].size);
drm_printf(p, " flags: 0x%x\n", state->bos[i].flags);
drm_printf(p, " name: %-32s\n", state->bos[i].name);
adreno_show_object(p, &state->bos[i].data,
......
......@@ -77,14 +77,13 @@ struct adreno_reglist {
u32 value;
};
extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a702_hwcg[], a730_hwcg[], a740_hwcg[];
struct adreno_speedbin {
uint16_t fuse;
uint16_t speedbin;
};
struct a6xx_info;
struct adreno_info {
const char *machine;
/**
......@@ -101,7 +100,9 @@ struct adreno_info {
struct msm_gpu *(*init)(struct drm_device *dev);
const char *zapfw;
u32 inactive_period;
const struct adreno_reglist *hwcg;
union {
const struct a6xx_info *a6xx;
};
u64 address_space_size;
/**
* @speedbins: Optional table of fuse to speedbin mappings
......@@ -114,6 +115,16 @@ struct adreno_info {
#define ADRENO_CHIP_IDS(tbl...) (uint32_t[]) { tbl, 0 }
struct adreno_gpulist {
const struct adreno_info *gpus;
unsigned gpus_count;
};
#define DECLARE_ADRENO_GPULIST(name) \
const struct adreno_gpulist name ## _gpulist = { \
name ## _gpus, ARRAY_SIZE(name ## _gpus) \
}
/*
* Helper to build a speedbin table, ie. the table:
* fuse | speedbin
......@@ -132,6 +143,19 @@ struct adreno_info {
*/
#define ADRENO_SPEEDBINS(tbl...) (struct adreno_speedbin[]) { tbl {SHRT_MAX, 0} }
struct adreno_protect {
const uint32_t *regs;
uint32_t count;
uint32_t count_max;
};
#define DECLARE_ADRENO_PROTECT(name, __count_max) \
static const struct adreno_protect name = { \
.regs = name ## _regs, \
.count = ARRAY_SIZE(name ## _regs), \
.count_max = __count_max, \
};
struct adreno_gpu {
struct msm_gpu base;
const struct adreno_info *info;
......@@ -182,6 +206,8 @@ struct adreno_gpu {
*/
const unsigned int *reg_offsets;
bool gmu_is_wrapper;
bool has_ray_tracing;
};
#define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
......@@ -298,6 +324,11 @@ static inline int adreno_is_a430(const struct adreno_gpu *gpu)
return adreno_is_revn(gpu, 430);
}
static inline int adreno_is_a505(const struct adreno_gpu *gpu)
{
return adreno_is_revn(gpu, 505);
}
static inline int adreno_is_a506(const struct adreno_gpu *gpu)
{
return adreno_is_revn(gpu, 506);
......@@ -448,6 +479,11 @@ static inline int adreno_is_a750(struct adreno_gpu *gpu)
return gpu->info->chip_ids[0] == 0x43051401;
}
static inline int adreno_is_x185(struct adreno_gpu *gpu)
{
return gpu->info->chip_ids[0] == 0x43050c01;
}
static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
{
if (WARN_ON_ONCE(!gpu->info))
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
*/
#ifndef _DPU_5_2_SM7150_H
#define _DPU_5_2_SM7150_H
static const struct dpu_caps sm7150_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 = 2880,
.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 sm7150_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 },
[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
},
};
static const struct dpu_ctl_cfg sm7150_ctl[] = {
{
.name = "ctl_0", .id = CTL_0,
.base = 0x1000, .len = 0x1e0,
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
}, {
.name = "ctl_1", .id = CTL_1,
.base = 0x1200, .len = 0x1e0,
.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
.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 sm7150_sspp[] = {
{
.name = "sspp_0", .id = SSPP_VIG0,
.base = 0x4000, .len = 0x1f0,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_2_4,
.xin_id = 0,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG0,
}, {
.name = "sspp_1", .id = SSPP_VIG1,
.base = 0x6000, .len = 0x1f0,
.features = VIG_SDM845_MASK,
.sblk = &dpu_vig_sblk_qseed3_2_4,
.xin_id = 4,
.type = SSPP_TYPE_VIG,
.clk_ctrl = DPU_CLK_CTRL_VIG1,
}, {
.name = "sspp_2", .id = SSPP_DMA0,
.base = 0x24000, .len = 0x1f0,
.features = DMA_SDM845_MASK,
.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,
.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,
.sblk = &dpu_dma_sblk,
.xin_id = 9,
.type = SSPP_TYPE_DMA,
.clk_ctrl = DPU_CLK_CTRL_DMA2,
},
};
static const struct dpu_lm_cfg sm7150_lm[] = {
{
.name = "lm_0", .id = LM_0,
.base = 0x44000, .len = 0x320,
.features = MIXER_SDM845_MASK,
.sblk = &sdm845_lm_sblk,
.lm_pair = LM_1,
.pingpong = PINGPONG_0,
.dspp = DSPP_0,
}, {
.name = "lm_1", .id = LM_1,
.base = 0x45000, .len = 0x320,
.features = MIXER_SDM845_MASK,
.sblk = &sdm845_lm_sblk,
.lm_pair = LM_0,
.pingpong = PINGPONG_1,
.dspp = DSPP_1,
}, {
.name = "lm_2", .id = LM_2,
.base = 0x46000, .len = 0x320,
.features = MIXER_SDM845_MASK,
.sblk = &sdm845_lm_sblk,
.lm_pair = LM_3,
.pingpong = PINGPONG_2,
}, {
.name = "lm_3", .id = LM_3,
.base = 0x47000, .len = 0x320,
.features = MIXER_SDM845_MASK,
.sblk = &sdm845_lm_sblk,
.lm_pair = LM_2,
.pingpong = PINGPONG_3,
},
};
static const struct dpu_dspp_cfg sm7150_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,
},
};
static const struct dpu_pingpong_cfg sm7150_pp[] = {
{
.name = "pingpong_0", .id = PINGPONG_0,
.base = 0x70000, .len = 0xd4,
.features = PINGPONG_SM8150_MASK,
.sblk = &sdm845_pp_sblk,
.merge_3d = MERGE_3D_0,
.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,
.merge_3d = MERGE_3D_0,
.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,
.merge_3d = MERGE_3D_1,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
}, {
.name = "pingpong_3", .id = PINGPONG_3,
.base = 0x71800, .len = 0xd4,
.features = PINGPONG_SM8150_MASK,
.sblk = &sdm845_pp_sblk,
.merge_3d = MERGE_3D_1,
.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
},
};
static const struct dpu_merge_3d_cfg sm7150_merge_3d[] = {
{
.name = "merge_3d_0", .id = MERGE_3D_0,
.base = 0x83000, .len = 0x8,
}, {
.name = "merge_3d_1", .id = MERGE_3D_1,
.base = 0x83100, .len = 0x8,
},
};
static const struct dpu_dsc_cfg sm7150_dsc[] = {
{
.name = "dsc_0", .id = DSC_0,
.base = 0x80000, .len = 0x140,
.features = BIT(DPU_DSC_OUTPUT_CTRL),
}, {
.name = "dsc_1", .id = DSC_1,
.base = 0x80400, .len = 0x140,
.features = BIT(DPU_DSC_OUTPUT_CTRL),
},
};
static const struct dpu_intf_cfg sm7150_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 = 0x2bc,
.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_2", .id = INTF_2,
.base = 0x6b000, .len = 0x2bc,
.features = INTF_SC7180_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 = 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_wb_cfg sm7150_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_perf_cfg sm7150_perf_data = {
.max_bw_low = 7100000,
.max_bw_high = 7100000,
.min_core_ib = 2400000,
.min_llcc_ib = 800000,
.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
},
},
.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 sm7150_mdss_ver = {
.core_major_ver = 5,
.core_minor_ver = 2,
};
const struct dpu_mdss_cfg dpu_sm7150_cfg = {
.mdss_ver = &sm7150_mdss_ver,
.caps = &sm7150_dpu_caps,
.mdp = &sm7150_mdp,
.ctl_count = ARRAY_SIZE(sm7150_ctl),
.ctl = sm7150_ctl,
.sspp_count = ARRAY_SIZE(sm7150_sspp),
.sspp = sm7150_sspp,
.mixer_count = ARRAY_SIZE(sm7150_lm),
.mixer = sm7150_lm,
.dspp_count = ARRAY_SIZE(sm7150_dspp),
.dspp = sm7150_dspp,
.pingpong_count = ARRAY_SIZE(sm7150_pp),
.pingpong = sm7150_pp,
.merge_3d_count = ARRAY_SIZE(sm7150_merge_3d),
.merge_3d = sm7150_merge_3d,
.dsc_count = ARRAY_SIZE(sm7150_dsc),
.dsc = sm7150_dsc,
.intf_count = ARRAY_SIZE(sm7150_intf),
.intf = sm7150_intf,
.wb_count = ARRAY_SIZE(sm7150_wb),
.wb = sm7150_wb,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
.vbif = sdm845_vbif,
.perf = &sm7150_perf_data,
};
#endif
......@@ -658,18 +658,18 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work)
DPU_ATRACE_END("crtc_frame_event");
}
/*
* dpu_crtc_frame_event_cb - crtc frame event callback API. CRTC module
* registers this API to encoder for all frame event callbacks like
* frame_error, frame_done, idle_timeout, etc. Encoder may call different events
* from different context - IRQ, user thread, commit_thread, etc. Each event
* should be carefully reviewed and should be processed in proper task context
* to avoid schedulin delay or properly manage the irq context's bottom half
* processing.
/**
* dpu_crtc_frame_event_cb - crtc frame event callback API
* @crtc: Pointer to crtc
* @event: Event to process
*
* Encoder may call this for different events from different context - IRQ,
* user thread, commit_thread, etc. Each event should be carefully reviewed and
* should be processed in proper task context to avoid schedulin delay or
* properly manage the irq context's bottom half processing.
*/
static void dpu_crtc_frame_event_cb(void *data, u32 event)
void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event)
{
struct drm_crtc *crtc = (struct drm_crtc *)data;
struct dpu_crtc *dpu_crtc;
struct msm_drm_private *priv;
struct dpu_crtc_frame_event *fevent;
......@@ -1091,9 +1091,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
dpu_core_perf_crtc_update(crtc, 0);
drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
dpu_encoder_register_frame_event_callback(encoder, NULL, NULL);
memset(cstate->mixers, 0, sizeof(cstate->mixers));
cstate->num_mixers = 0;
......@@ -1132,8 +1129,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
*/
if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
request_bandwidth = true;
dpu_encoder_register_frame_event_callback(encoder,
dpu_crtc_frame_event_cb, (void *)crtc);
}
if (request_bandwidth)
......
......@@ -300,4 +300,6 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type(
return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT;
}
void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
#endif /* _DPU_CRTC_H_ */
......@@ -151,8 +151,6 @@ enum dpu_enc_rc_states {
* @frame_busy_mask: Bitmask tracking which phys_enc we are still
* busy processing current command.
* Bit0 = phys_encs[0] etc.
* @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
......@@ -192,8 +190,6 @@ struct dpu_encoder_virt {
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;
......@@ -428,7 +424,7 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
return -EWOULDBLOCK;
}
if (irq_idx < 0) {
if (irq_idx == 0) {
DRM_DEBUG_KMS("skip irq wait id=%u, callback=%ps\n",
DRMID(phys_enc->parent), func);
return 0;
......@@ -564,7 +560,7 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
return (num_dsc > 0) && (num_dsc > intf_count);
}
static struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
{
struct msm_drm_private *priv = drm_enc->dev->dev_private;
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
......@@ -736,18 +732,14 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
return;
}
if (hw_mdptop->ops.setup_vsync_source &&
disp_info->is_cmd_mode) {
if (hw_mdptop->ops.setup_vsync_source) {
for (i = 0; i < dpu_enc->num_phys_encs; i++)
vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx;
vsync_cfg.pp_count = dpu_enc->num_phys_encs;
vsync_cfg.frame_rate = drm_mode_vrefresh(&dpu_enc->base.crtc->state->adjusted_mode);
if (disp_info->is_te_using_watchdog_timer)
vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0;
else
vsync_cfg.vsync_source = DPU_VSYNC0_SOURCE_GPIO;
vsync_cfg.vsync_source = disp_info->vsync_source;
hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg);
......@@ -1200,6 +1192,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
phys->cached_mode = crtc_state->adjusted_mode;
if (phys->ops.atomic_mode_set)
phys->ops.atomic_mode_set(phys, crtc_state, conn_state);
}
}
......@@ -1226,7 +1220,8 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select(
dpu_enc->cur_master->hw_mdptop);
_dpu_encoder_update_vsync_source(dpu_enc, &dpu_enc->disp_info);
if (dpu_enc->disp_info.is_cmd_mode)
_dpu_encoder_update_vsync_source(dpu_enc, &dpu_enc->disp_info);
if (dpu_enc->disp_info.intf_type == INTF_DSI &&
!WARN_ON(dpu_enc->num_phys_encs == 0)) {
......@@ -1454,28 +1449,6 @@ void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *drm_enc,
}
}
void dpu_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
void (*frame_event_cb)(void *, u32 event),
void *frame_event_cb_data)
{
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
unsigned long lock_flags;
bool enable;
enable = frame_event_cb ? true : false;
if (!drm_enc) {
DPU_ERROR("invalid encoder\n");
return;
}
trace_dpu_enc_frame_event_cb(DRMID(drm_enc), enable);
spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags);
dpu_enc->crtc_frame_event_cb = frame_event_cb;
dpu_enc->crtc_frame_event_cb_data = frame_event_cb_data;
spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
}
void dpu_encoder_frame_done_callback(
struct drm_encoder *drm_enc,
struct dpu_encoder_phys *ready_phys, u32 event)
......@@ -1515,15 +1488,12 @@ void dpu_encoder_frame_done_callback(
dpu_encoder_resource_control(drm_enc,
DPU_ENC_RC_EVENT_FRAME_DONE);
if (dpu_enc->crtc_frame_event_cb)
dpu_enc->crtc_frame_event_cb(
dpu_enc->crtc_frame_event_cb_data,
event);
if (dpu_enc->crtc)
dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
}
} else {
if (dpu_enc->crtc_frame_event_cb)
dpu_enc->crtc_frame_event_cb(
dpu_enc->crtc_frame_event_cb_data, event);
if (dpu_enc->crtc)
dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
}
}
......@@ -1741,8 +1711,7 @@ void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
phys = dpu_enc->phys_encs[i];
ctl = phys->hw_ctl;
if (ctl->ops.clear_pending_flush)
ctl->ops.clear_pending_flush(ctl);
ctl->ops.clear_pending_flush(ctl);
/* update only for command mode primary ctl */
if ((phys == dpu_enc->cur_master) &&
......@@ -2457,7 +2426,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)
return;
}
if (!dpu_enc->frame_busy_mask[0] || !dpu_enc->crtc_frame_event_cb) {
if (!dpu_enc->frame_busy_mask[0] || !dpu_enc->crtc) {
DRM_DEBUG_KMS("id:%u invalid timeout frame_busy_mask=%lu\n",
DRMID(drm_enc), dpu_enc->frame_busy_mask[0]);
return;
......@@ -2473,7 +2442,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t)
event = DPU_ENCODER_FRAME_EVENT_ERROR;
trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event);
dpu_enc->crtc_frame_event_cb(dpu_enc->crtc_frame_event_cb_data, event);
dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
}
static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = {
......
......@@ -26,15 +26,14 @@
* @h_tile_instance: Controller instance used per tile. Number of elements is
* based on num_of_h_tiles
* @is_cmd_mode Boolean to indicate if the CMD mode is requested
* @is_te_using_watchdog_timer: Boolean to indicate watchdog TE is
* used instead of panel TE in cmd mode panels
* @vsync_source: Source of the TE signal for DSI CMD devices
*/
struct msm_display_info {
enum dpu_intf_type intf_type;
uint32_t num_of_h_tiles;
uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
bool is_cmd_mode;
bool is_te_using_watchdog_timer;
enum dpu_vsync_source vsync_source;
};
/**
......@@ -55,16 +54,6 @@ void dpu_encoder_assign_crtc(struct drm_encoder *encoder,
void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *encoder,
struct drm_crtc *crtc, bool enable);
/**
* dpu_encoder_register_frame_event_callback - provide callback to encoder that
* will be called after the request is complete, or other events.
* @encoder: encoder pointer
* @cb: callback pointer, provide NULL to deregister
* @data: user data provided to callback
*/
void dpu_encoder_register_frame_event_callback(struct drm_encoder *encoder,
void (*cb)(void *, u32), void *data);
/**
* dpu_encoder_prepare_for_kickoff - schedule double buffer flip of the ctl
* path (i.e. ctl flush and start) at next appropriate time.
......
......@@ -838,6 +838,7 @@ 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_sm7150_cfg;
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;
......
......@@ -83,7 +83,8 @@ struct dpu_hw_ctl_ops {
/**
* Clear the value of the cached pending_flush_mask
* No effect on hardware
* No effect on hardware.
* Required to be implemented.
* @ctx : ctl path ctx pointer
*/
void (*clear_pending_flush)(struct dpu_hw_ctl *ctx);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment