Merge tag 'drm-msm-next-2026-05-30' of https://gitlab.freedesktop.org/drm/msm into drm-next

Changes for v7.2

Core:
- Fixed documentation for msm_gem_shrinker functions
- IFPC related enablement/fixes for gen8
- PERFCNTR_CONFIG ioctl support

GPU
- Reworked handling of UBWC configuration
- a810 suppport

MDSS:
- Added Milos platform support
- Reworked handling of UBWC configuration

DisplayPort:
- Reworked HPD handling, preparing for the MST support

DPU:
- Added Milos platform support
- Reworked handling of UBWC configuration

DSI:
- Added Milos platform support

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rob Clark <rob.clark@oss.qualcomm.com>
Link: https://patch.msgid.link/CACSVV00DXZcvFH2-C3fouve5DGs0DGa-vvsJPuaRmUZZVNKOfg@mail.gmail.com
This commit is contained in:
Dave Airlie
2026-06-04 06:41:22 +10:00
68 changed files with 7401 additions and 2954 deletions
@@ -16,6 +16,7 @@ properties:
- enum:
- qcom,apq8064-dsi-ctrl
- qcom,kaanapali-dsi-ctrl
- qcom,milos-dsi-ctrl
- qcom,msm8226-dsi-ctrl
- qcom,msm8916-dsi-ctrl
- qcom,msm8953-dsi-ctrl
@@ -339,6 +340,7 @@ allOf:
compatible:
contains:
enum:
- qcom,milos-dsi-ctrl
- qcom,msm8998-dsi-ctrl
- qcom,sa8775p-dsi-ctrl
- qcom,sar2130p-dsi-ctrl
@@ -300,6 +300,36 @@ allOf:
required:
- qcom,qmp
- if:
properties:
compatible:
contains:
const: qcom,adreno-gmu-810.0
then:
properties:
reg:
items:
- description: Core GMU registers
reg-names:
items:
- const: gmu
clocks:
items:
- description: GPU AHB clock
- description: GMU clock
- description: GPU CX clock
- description: GPU AXI clock
- description: GPU MEMNOC clock
- description: GMU HUB clock
clock-names:
items:
- const: ahb
- const: gmu
- const: cxo
- const: axi
- const: memnoc
- const: hub
- if:
properties:
compatible:
@@ -411,6 +411,23 @@ allOf:
- clocks
- clock-names
- if:
properties:
compatible:
contains:
enum:
- qcom,adreno-44010000
- qcom,adreno-44070001
then:
properties:
reg:
minItems: 2
maxItems: 2
reg-names:
minItems: 2
maxItems: 2
- if:
properties:
compatible:
@@ -434,6 +451,8 @@ allOf:
- qcom,adreno-43050a01
- qcom,adreno-43050c01
- qcom,adreno-43051401
- qcom,adreno-44010000
- qcom,adreno-44070001
then: # Starting with A6xx, the clocks are usually defined in the GMU node
properties:
@@ -0,0 +1,286 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/msm/qcom,milos-mdss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Milos Display MDSS
maintainers:
- Luca Weiss <luca.weiss@fairphone.com>
description:
Milos MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like
DPU display controller, DSI and DP interfaces etc.
$ref: /schemas/display/msm/mdss-common.yaml#
properties:
compatible:
const: qcom,milos-mdss
clocks:
items:
- description: Display AHB
- description: Display hf AXI
- description: Display core
iommus:
maxItems: 1
interconnects:
items:
- description: Interconnect path from mdp0 port to the data bus
- description: Interconnect path from CPU to the reg bus
interconnect-names:
items:
- const: mdp0-mem
- const: cpu-cfg
patternProperties:
"^display-controller@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,milos-dpu
"^displayport-controller@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,milos-dp
"^dsi@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
contains:
const: qcom,milos-dsi-ctrl
"^phy@[0-9a-f]+$":
type: object
additionalProperties: true
properties:
compatible:
const: qcom,milos-dsi-phy-4nm
required:
- compatible
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,dsi-phy-28nm.h>
#include <dt-bindings/clock/qcom,milos-dispcc.h>
#include <dt-bindings/clock/qcom,milos-gcc.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,milos-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-subsystem@ae00000 {
compatible = "qcom,milos-mdss";
reg = <0x0ae00000 0x1000>;
reg-names = "mdss";
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>;
resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
&cnoc_main SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
interconnect-names = "mdp0-mem",
"cpu-cfg";
power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>;
iommus = <&apps_smmu 0x1c00 0x2>;
interrupt-controller;
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
display-controller@ae01000 {
compatible = "qcom,milos-dpu";
reg = <0x0ae01000 0x8f000>,
<0x0aeb0000 0x3000>;
reg-names = "mdp",
"vbif";
interrupts-extended = <&mdss 0>;
clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>,
<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
clock-names = "nrt_bus",
"iface",
"lut",
"core",
"vsync";
assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd RPMHPD_CX>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
dpu_intf1_out: endpoint {
remote-endpoint = <&mdss_dsi0_in>;
};
};
};
mdp_opp_table: opp-table {
compatible = "operating-points-v2";
opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-342000000 {
opp-hz = /bits/ 64 <342000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-402000000 {
opp-hz = /bits/ 64 <402000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
opp-535000000 {
opp-hz = /bits/ 64 <535000000>;
required-opps = <&rpmhpd_opp_nom>;
};
opp-600000000 {
opp-hz = /bits/ 64 <600000000>;
required-opps = <&rpmhpd_opp_nom_l1>;
};
opp-630000000 {
opp-hz = /bits/ 64 <630000000>;
required-opps = <&rpmhpd_opp_turbo>;
};
};
};
dsi@ae94000 {
compatible = "qcom,milos-dsi-ctrl", "qcom,mdss-dsi-ctrl";
reg = <0x0ae94000 0x1000>;
reg-names = "dsi_ctrl";
interrupts-extended = <&mdss 4>;
clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
<&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
<&dispcc DISP_CC_MDSS_PCLK0_CLK>,
<&dispcc DISP_CC_MDSS_ESC0_CLK>,
<&dispcc DISP_CC_MDSS_AHB_CLK>,
<&gcc GCC_DISP_HF_AXI_CLK>;
clock-names = "byte",
"byte_intf",
"pixel",
"core",
"iface",
"bus";
assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
<&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>;
assigned-clock-parents = <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>,
<&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>;
operating-points-v2 = <&mdss_dsi_opp_table>;
power-domains = <&rpmhpd RPMHPD_CX>;
phys = <&mdss_dsi0_phy>;
phy-names = "dsi";
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
mdss_dsi0_in: endpoint {
remote-endpoint = <&dpu_intf1_out>;
};
};
port@1 {
reg = <1>;
mdss_dsi0_out: endpoint {
};
};
};
mdss_dsi_opp_table: opp-table {
compatible = "operating-points-v2";
opp-187500000 {
opp-hz = /bits/ 64 <187500000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
opp-300000000 {
opp-hz = /bits/ 64 <300000000>;
required-opps = <&rpmhpd_opp_svs>;
};
opp-358000000 {
opp-hz = /bits/ 64 <358000000>;
required-opps = <&rpmhpd_opp_svs_l1>;
};
};
};
mdss_dsi0_phy: phy@ae95000 {
compatible = "qcom,milos-dsi-phy-4nm";
reg = <0x0ae95000 0x200>,
<0x0ae95200 0x300>,
<0x0ae95500 0x400>;
reg-names = "dsi_phy",
"dsi_phy_lane",
"dsi_pll";
clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>;
clock-names = "iface",
"ref";
#clock-cells = <1>;
#phy-cells = <0>;
};
};
...
@@ -18,6 +18,7 @@ properties:
- qcom,eliza-dpu
- qcom,glymur-dpu
- qcom,kaanapali-dpu
- qcom,milos-dpu
- qcom,sa8775p-dpu
- qcom,sm8650-dpu
- qcom,sm8750-dpu
@@ -20,6 +20,7 @@ properties:
- qcom,dsi-phy-7nm
- qcom,dsi-phy-7nm-8150
- qcom,kaanapali-dsi-phy-3nm
- qcom,milos-dsi-phy-4nm
- qcom,sa8775p-dsi-phy-5nm
- qcom,sar2130p-dsi-phy-5nm
- qcom,sc7280-dsi-phy-7nm
+4
View File
@@ -386,6 +386,10 @@ linkcheck-docs:
rules:
- when: never
mr-label-maker-test:
rules:
- when: never
test-docs:
rules:
- when: never
+26 -3
View File
@@ -122,7 +122,7 @@ msm-y += \
msm_gpu_devfreq.o \
msm_io_utils.o \
msm_iommu.o \
msm_perf.o \
msm_perfcntr.o \
msm_rd.o \
msm_ringbuffer.o \
msm_submitqueue.o \
@@ -177,6 +177,11 @@ quiet_cmd_headergen = GENHDR $@
cmd_headergen = mkdir -p $(obj)/generated && $(PYTHON3) $(src)/registers/gen_header.py \
$(headergen-opts) --rnn $(src)/registers --xml $< c-defines > $@
# TODO how to do this for a2xx/a5xx which have different .xml arg?
quiet_cmd_headergen_json = GENHDRJSN $@
cmd_headergen_json = mkdir -p $(obj)/generated && $(PYTHON3) $(src)/registers/gen_header.py \
$(headergen-opts) --rnn $(src)/registers --xml $(filter %.xml,$^) perfcntrs --json $< > $@
$(obj)/generated/%.xml.h: $(src)/registers/adreno/%.xml \
$(src)/registers/adreno/adreno_common.xml \
$(src)/registers/adreno/adreno_pm4.xml \
@@ -193,6 +198,24 @@ $(obj)/generated/%.xml.h: $(src)/registers/display/%.xml \
FORCE
$(call if_changed,headergen)
ADRENO_PERFCNTRS =
define adreno_perfcntrs
ADRENO_PERFCNTRS += generated/$(1)_perfcntrs.json.c
$$(obj)/generated/$(1)_perfcntrs.json.c: $$(src)/registers/adreno/$(1)_perfcntrs.json \
$$(src)/registers/adreno/$(2).xml \
FORCE
$$(call if_changed,headergen_json)
endef
$(eval $(call adreno_perfcntrs,a2xx,a2xx))
$(eval $(call adreno_perfcntrs,a5xx,a5xx))
$(eval $(call adreno_perfcntrs,a6xx,a6xx))
$(eval $(call adreno_perfcntrs,a7xx,a6xx))
$(eval $(call adreno_perfcntrs,a8xx,a6xx))
adreno-y += $(ADRENO_PERFCNTRS:.c=.o)
ADRENO_HEADERS = \
generated/a2xx.xml.h \
generated/a3xx.xml.h \
@@ -224,7 +247,7 @@ DISPLAY_HEADERS = \
generated/mdss.xml.h \
generated/sfpb.xml.h
$(addprefix $(obj)/,$(adreno-y)): $(addprefix $(obj)/,$(ADRENO_HEADERS))
$(addprefix $(obj)/,$(msm-y)): $(addprefix $(obj)/,$(ADRENO_HEADERS))
$(addprefix $(obj)/,$(msm-display-y)): $(addprefix $(obj)/,$(DISPLAY_HEADERS))
targets += $(ADRENO_HEADERS) $(DISPLAY_HEADERS)
targets += $(ADRENO_HEADERS) $(DISPLAY_HEADERS) $(ADRENO_PERFCNTRS)
-7
View File
@@ -489,10 +489,6 @@ static u32 a2xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
return ring->memptrs->rptr;
}
static const struct msm_gpu_perfcntr perfcntrs[] = {
/* TODO */
};
static struct msm_gpu *a2xx_gpu_init(struct drm_device *dev)
{
struct a2xx_gpu *a2xx_gpu = NULL;
@@ -518,9 +514,6 @@ static struct msm_gpu *a2xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a2xx_gpu->base;
gpu = &adreno_gpu->base;
gpu->perfcntrs = perfcntrs;
gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
ret = adreno_gpu_init(dev, pdev, adreno_gpu, config->info->funcs, 1);
if (ret)
goto fail;
-16
View File
@@ -266,12 +266,6 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
/* Turn on performance counters: */
gpu_write(gpu, REG_A3XX_RBBM_PERFCTR_CTL, 0x01);
/* Enable the perfcntrs that we use.. */
for (i = 0; i < gpu->num_perfcntrs; i++) {
const struct msm_gpu_perfcntr *perfcntr = &gpu->perfcntrs[i];
gpu_write(gpu, perfcntr->select_reg, perfcntr->select_val);
}
gpu_write(gpu, REG_A3XX_RBBM_INT_0_MASK, A3XX_INT0_MASK);
ret = adreno_hw_init(gpu);
@@ -508,13 +502,6 @@ static u32 a3xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
return ring->memptrs->rptr;
}
static const struct msm_gpu_perfcntr perfcntrs[] = {
{ REG_A3XX_SP_PERFCOUNTER6_SELECT, REG_A3XX_RBBM_PERFCTR_SP_6_LO,
SP_ALU_ACTIVE_CYCLES, "ALUACTIVE" },
{ REG_A3XX_SP_PERFCOUNTER7_SELECT, REG_A3XX_RBBM_PERFCTR_SP_7_LO,
SP_FS_FULL_ALU_INSTRUCTIONS, "ALUFULL" },
};
static struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
{
struct a3xx_gpu *a3xx_gpu = NULL;
@@ -542,9 +529,6 @@ static struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a3xx_gpu->base;
gpu = &adreno_gpu->base;
gpu->perfcntrs = perfcntrs;
gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
adreno_gpu->registers = a3xx_registers;
ret = adreno_gpu_init(dev, pdev, adreno_gpu, config->info->funcs, 1);
-3
View File
@@ -652,9 +652,6 @@ static struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a4xx_gpu->base;
gpu = &adreno_gpu->base;
gpu->perfcntrs = NULL;
gpu->num_perfcntrs = 0;
ret = adreno_gpu_init(dev, pdev, adreno_gpu, config->info->funcs, 1);
if (ret)
goto fail;
+8 -19
View File
@@ -752,17 +752,13 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_A5XX_UCHE_CACHE_WAYS, 0x02);
/* Disable L2 bypass in the UCHE */
gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_LO, lower_32_bits(adreno_gpu->uche_trap_base));
gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_HI, upper_32_bits(adreno_gpu->uche_trap_base));
gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_LO, lower_32_bits(adreno_gpu->uche_trap_base));
gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_HI, upper_32_bits(adreno_gpu->uche_trap_base));
gpu_write64(gpu, REG_A5XX_UCHE_TRAP_BASE, adreno_gpu->uche_trap_base);
gpu_write64(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE, adreno_gpu->uche_trap_base);
/* Set the GMEM VA range (0 to gpu->gmem) */
gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_LO, 0x00100000);
gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_HI, 0x00000000);
gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_LO,
gpu_write64(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN, 0x00100000);
gpu_write64(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX,
0x00100000 + adreno_gpu->info->gmem - 1);
gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000);
if (adreno_is_a505(adreno_gpu) || adreno_is_a506(adreno_gpu) ||
adreno_is_a508(adreno_gpu) || adreno_is_a510(adreno_gpu)) {
@@ -1217,9 +1213,7 @@ static void a5xx_rbbm_err_irq(struct msm_gpu *gpu, u32 status)
static void a5xx_uche_err_irq(struct msm_gpu *gpu)
{
uint64_t addr = (uint64_t) gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_HI);
addr |= gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_LO);
uint64_t addr = gpu_read64(gpu, REG_A5XX_UCHE_TRAP_LOG);
dev_err_ratelimited(gpu->dev->dev, "UCHE | Out of bounds access | addr=0x%llX\n",
addr);
@@ -1725,7 +1719,6 @@ static struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
struct msm_drm_private *priv = dev->dev_private;
struct platform_device *pdev = priv->gpu_pdev;
struct adreno_platform_config *config = pdev->dev.platform_data;
const struct qcom_ubwc_cfg_data *common_cfg;
struct a5xx_gpu *a5xx_gpu = NULL;
struct adreno_gpu *adreno_gpu;
struct msm_gpu *gpu;
@@ -1769,13 +1762,9 @@ static struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
a5xx_preempt_init(gpu);
/* Inherit the common config and make some necessary fixups */
common_cfg = qcom_ubwc_config_get_data();
if (IS_ERR(common_cfg))
return ERR_CAST(common_cfg);
/* Copy the data into the internal struct to drop the const qualifier (temporarily) */
adreno_gpu->_ubwc_config = *common_cfg;
adreno_gpu->ubwc_config = &adreno_gpu->_ubwc_config;
adreno_gpu->ubwc_config = qcom_ubwc_config_get_data();
if (IS_ERR(adreno_gpu->ubwc_config))
return ERR_CAST(adreno_gpu->ubwc_config);
adreno_gpu->uche_trap_base = 0x0001ffffffff0000ull;
+298
View File
@@ -1799,6 +1799,261 @@ static const struct adreno_reglist_pipe x285_dyn_pwrup_reglist_regs[] = {
};
DECLARE_ADRENO_REGLIST_PIPE_LIST(x285_dyn_pwrup_reglist);
static const struct adreno_reglist_pipe a810_nonctxt_regs[] = {
{ REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) },
{ REG_A8XX_GRAS_DBG_ECO_CNTL, 0x00f80800, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A6XX_PC_AUTO_VERTEX_STRIDE, 0x00000001, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_VIS_STREAM_CNTL, 0x10010000, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_CONTEXT_SWITCH_STABILIZE_CNTL_1, 0x00000002, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_CHICKEN_BITS_1, 0x00000003, BIT(PIPE_BR) },
{ REG_A8XX_PC_CHICKEN_BITS_1, 0x00000023, BIT(PIPE_BV) }, /* Avoid partial waves at VFD */
{ REG_A8XX_PC_CHICKEN_BITS_2, 0x00000200, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_CHICKEN_BITS_3, 0x00500000, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_CHICKEN_BITS_4, 0x00500050, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A7XX_RB_CCU_CNTL, 0x00000068, BIT(PIPE_BR) },
/* Partially enable perf clear, Disable DINT to c/z be data forwarding */
{ REG_A7XX_RB_CCU_DBG_ECO_CNTL, 0x00002200, BIT(PIPE_BR) },
{ REG_A8XX_RB_RESOLVE_PREFETCH_CNTL, 0x00000007, BIT(PIPE_BR) },
{ REG_A8XX_RB_CMP_DBG_ECO_CNTL, 0x00004000, BIT(PIPE_BR) },
{ REG_A8XX_RBBM_NC_MODE_CNTL, 0x00000001, BIT(PIPE_NONE) },
{ REG_A8XX_RBBM_SLICE_NC_MODE_CNTL, 0x00000001, BIT(PIPE_NONE) },
{ REG_A8XX_RBBM_WAIT_IDLE_CLOCKS_CNTL, 0x00000030, BIT(PIPE_NONE) },
{ REG_A8XX_RBBM_WAIT_IDLE_CLOCKS_CNTL2, 0x00000030, BIT(PIPE_NONE) },
{ REG_A8XX_UCHE_GBIF_GX_CONFIG, 0x010240e0, BIT(PIPE_NONE) },
{ REG_A8XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x22122212, BIT(PIPE_NONE) },
{ REG_A8XX_RBBM_CGC_P2S_CNTL, 0x00000040, BIT(PIPE_NONE) },
/*
* BIT(22): Disable PS out of order retire
* BIT(23): Enable half wave mode and MM instruction src&dst is half precision
*/
{ REG_A7XX_SP_CHICKEN_BITS_2, BIT(22) | BIT(23), BIT(PIPE_NONE) },
{ REG_A7XX_SP_CHICKEN_BITS_3, 0x00300000, BIT(PIPE_NONE) },
{ REG_A6XX_SP_PERFCTR_SHADER_MASK, 0x0000003f, BIT(PIPE_NONE) },
{ REG_A7XX_SP_HLSQ_TIMEOUT_THRESHOLD_DP, 0x00000080, BIT(PIPE_NONE) },
{ REG_A6XX_TPL1_DBG_ECO_CNTL, 0x10100000, BIT(PIPE_NONE) },
{ REG_A6XX_TPL1_DBG_ECO_CNTL1, 0x04000724, BIT(PIPE_NONE) },
{ REG_A6XX_UCHE_MODE_CNTL, 0x00020000, BIT(PIPE_NONE) },
{ REG_A8XX_UCHE_CCHE_MODE_CNTL, 0x00001000, BIT(PIPE_NONE) },
{ REG_A8XX_UCHE_CCHE_CACHE_WAYS, 0x00000800, BIT(PIPE_NONE) },
/* Disable write slow pointer in data phase queue */
{ REG_A8XX_UCHE_HW_DBG_CNTL, BIT(8), BIT(PIPE_NONE) },
{ REG_A8XX_UCHE_VARB_IDLE_TIMEOUT, 0x00000020, BIT(PIPE_NONE) },
{ REG_A7XX_VFD_DBG_ECO_CNTL, 0x00008000, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_VFD_CB_BV_THRESHOLD, 0x00500050, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_VFD_CB_BR_THRESHOLD, 0x00600060, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_VFD_CB_BUSY_REQ_CNT, 0x00200020, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_VFD_CB_LP_REQ_CNT, 0x00100020, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_VPC_FLATSHADE_MODE_CNTL, 0x00000001, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_RB_GC_GMEM_PROTECT, 0x00900000, BIT(PIPE_BR) },
{ },
};
static const u32 a810_protect_regs[] = {
A6XX_PROTECT_RDONLY(0x00000, 0x03a3),
A6XX_PROTECT_RDONLY(0x003b4, 0x008b),
A6XX_PROTECT_NORDWR(0x00440, 0x001f),
A6XX_PROTECT_RDONLY(0x00580, 0x005f),
A6XX_PROTECT_NORDWR(0x005e0, 0x011f),
A6XX_PROTECT_RDONLY(0x0074a, 0x0005),
A6XX_PROTECT_RDONLY(0x00759, 0x0026),
A6XX_PROTECT_RDONLY(0x00789, 0x0000),
A6XX_PROTECT_RDONLY(0x0078c, 0x0013),
A6XX_PROTECT_NORDWR(0x00800, 0x0029),
A6XX_PROTECT_NORDWR(0x00837, 0x00af),
A6XX_PROTECT_RDONLY(0x008e7, 0x00c9),
A6XX_PROTECT_NORDWR(0x008ec, 0x00c3),
A6XX_PROTECT_NORDWR(0x009b1, 0x0250),
A6XX_PROTECT_RDONLY(0x00ce0, 0x0001),
A6XX_PROTECT_RDONLY(0x00df0, 0x0000),
A6XX_PROTECT_NORDWR(0x00df1, 0x0000),
A6XX_PROTECT_NORDWR(0x00e01, 0x0000),
A6XX_PROTECT_NORDWR(0x00e03, 0x1fff),
A6XX_PROTECT_NORDWR(0x03c00, 0x00c5),
A6XX_PROTECT_RDONLY(0x03cc6, 0x1fff),
A6XX_PROTECT_NORDWR(0x08600, 0x01ff),
A6XX_PROTECT_NORDWR(0x08e00, 0x00ff),
A6XX_PROTECT_RDONLY(0x08f00, 0x0000),
A6XX_PROTECT_NORDWR(0x08f01, 0x01be),
A6XX_PROTECT_NORDWR(0x09600, 0x01ff),
A6XX_PROTECT_RDONLY(0x0981a, 0x02e5),
A6XX_PROTECT_NORDWR(0x09e00, 0x01ff),
A6XX_PROTECT_NORDWR(0x0a600, 0x01ff),
A6XX_PROTECT_NORDWR(0x0ae00, 0x0006),
A6XX_PROTECT_NORDWR(0x0ae08, 0x0006),
A6XX_PROTECT_NORDWR(0x0ae10, 0x036f),
A6XX_PROTECT_NORDWR(0x0b600, 0x1fff),
A6XX_PROTECT_NORDWR(0x0dc00, 0x1fff),
A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
A6XX_PROTECT_NORDWR(0x18400, 0x003f),
A6XX_PROTECT_RDONLY(0x18440, 0x013f),
A6XX_PROTECT_NORDWR(0x18580, 0x1fff),
A6XX_PROTECT_NORDWR(0x1b400, 0x1fff),
A6XX_PROTECT_NORDWR(0x1f400, 0x0477),
A6XX_PROTECT_RDONLY(0x1f878, 0x0787),
A6XX_PROTECT_NORDWR(0x1f930, 0x0329),
A6XX_PROTECT_NORDWR(0x20000, 0x1fff),
A6XX_PROTECT_NORDWR(0x27800, 0x007f),
A6XX_PROTECT_RDONLY(0x27880, 0x0381),
A6XX_PROTECT_NORDWR(0x27882, 0x0001),
A6XX_PROTECT_NORDWR(0x27c02, 0x0000),
};
DECLARE_ADRENO_PROTECT(a810_protect, 64);
static const uint32_t a810_pwrup_reglist_regs[] = {
REG_A6XX_UCHE_MODE_CNTL,
REG_A8XX_UCHE_VARB_IDLE_TIMEOUT,
REG_A8XX_UCHE_GBIF_GX_CONFIG,
REG_A8XX_UCHE_CACHE_WAYS,
REG_A8XX_UCHE_CCHE_MODE_CNTL,
REG_A8XX_UCHE_CCHE_CACHE_WAYS,
REG_A8XX_UCHE_CCHE_GC_GMEM_RANGE_MIN,
REG_A8XX_UCHE_CCHE_GC_GMEM_RANGE_MIN + 1,
REG_A8XX_UCHE_CCHE_TRAP_BASE,
REG_A8XX_UCHE_CCHE_TRAP_BASE + 1,
REG_A8XX_UCHE_CCHE_WRITE_THRU_BASE,
REG_A8XX_UCHE_CCHE_WRITE_THRU_BASE + 1,
REG_A8XX_UCHE_HW_DBG_CNTL,
REG_A8XX_UCHE_WRITE_THRU_BASE,
REG_A8XX_UCHE_WRITE_THRU_BASE + 1,
REG_A8XX_UCHE_TRAP_BASE,
REG_A8XX_UCHE_TRAP_BASE + 1,
REG_A8XX_UCHE_CLIENT_PF,
REG_A8XX_RB_CMP_NC_MODE_CNTL,
REG_A7XX_SP_HLSQ_TIMEOUT_THRESHOLD_DP,
REG_A8XX_SP_HLSQ_GC_GMEM_RANGE_MIN,
REG_A8XX_SP_HLSQ_GC_GMEM_RANGE_MIN + 1,
REG_A7XX_SP_READ_SEL,
REG_A6XX_TPL1_NC_MODE_CNTL,
REG_A6XX_TPL1_DBG_ECO_CNTL,
REG_A6XX_TPL1_DBG_ECO_CNTL1,
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(1),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(2),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(3),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(4),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(5),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(6),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(7),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(8),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(9),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(10),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(11),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(12),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(13),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(14),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(15),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(16),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(17),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(18),
REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(19),
};
DECLARE_ADRENO_REGLIST_LIST(a810_pwrup_reglist);
static const u32 a810_ifpc_reglist_regs[] = {
REG_A8XX_RBBM_NC_MODE_CNTL,
REG_A8XX_RBBM_PERFCTR_CNTL,
REG_A8XX_RBBM_SLICE_INTERFACE_HANG_INT_CNTL,
REG_A8XX_RBBM_SLICE_NC_MODE_CNTL,
REG_A6XX_SP_NC_MODE_CNTL,
REG_A7XX_SP_CHICKEN_BITS_2,
REG_A7XX_SP_CHICKEN_BITS_3,
REG_A6XX_SP_PERFCTR_SHADER_MASK,
REG_A8XX_CP_PROTECT_GLOBAL(0),
REG_A8XX_CP_PROTECT_GLOBAL(1),
REG_A8XX_CP_PROTECT_GLOBAL(2),
REG_A8XX_CP_PROTECT_GLOBAL(3),
REG_A8XX_CP_PROTECT_GLOBAL(4),
REG_A8XX_CP_PROTECT_GLOBAL(5),
REG_A8XX_CP_PROTECT_GLOBAL(6),
REG_A8XX_CP_PROTECT_GLOBAL(7),
REG_A8XX_CP_PROTECT_GLOBAL(8),
REG_A8XX_CP_PROTECT_GLOBAL(9),
REG_A8XX_CP_PROTECT_GLOBAL(10),
REG_A8XX_CP_PROTECT_GLOBAL(11),
REG_A8XX_CP_PROTECT_GLOBAL(12),
REG_A8XX_CP_PROTECT_GLOBAL(13),
REG_A8XX_CP_PROTECT_GLOBAL(14),
REG_A8XX_CP_PROTECT_GLOBAL(15),
REG_A8XX_CP_PROTECT_GLOBAL(16),
REG_A8XX_CP_PROTECT_GLOBAL(17),
REG_A8XX_CP_PROTECT_GLOBAL(18),
REG_A8XX_CP_PROTECT_GLOBAL(19),
REG_A8XX_CP_PROTECT_GLOBAL(20),
REG_A8XX_CP_PROTECT_GLOBAL(21),
REG_A8XX_CP_PROTECT_GLOBAL(22),
REG_A8XX_CP_PROTECT_GLOBAL(23),
REG_A8XX_CP_PROTECT_GLOBAL(24),
REG_A8XX_CP_PROTECT_GLOBAL(25),
REG_A8XX_CP_PROTECT_GLOBAL(26),
REG_A8XX_CP_PROTECT_GLOBAL(27),
REG_A8XX_CP_PROTECT_GLOBAL(28),
REG_A8XX_CP_PROTECT_GLOBAL(29),
REG_A8XX_CP_PROTECT_GLOBAL(30),
REG_A8XX_CP_PROTECT_GLOBAL(31),
REG_A8XX_CP_PROTECT_GLOBAL(32),
REG_A8XX_CP_PROTECT_GLOBAL(33),
REG_A8XX_CP_PROTECT_GLOBAL(34),
REG_A8XX_CP_PROTECT_GLOBAL(35),
REG_A8XX_CP_PROTECT_GLOBAL(36),
REG_A8XX_CP_PROTECT_GLOBAL(37),
REG_A8XX_CP_PROTECT_GLOBAL(38),
REG_A8XX_CP_PROTECT_GLOBAL(39),
REG_A8XX_CP_PROTECT_GLOBAL(40),
REG_A8XX_CP_PROTECT_GLOBAL(41),
REG_A8XX_CP_PROTECT_GLOBAL(42),
REG_A8XX_CP_PROTECT_GLOBAL(43),
REG_A8XX_CP_PROTECT_GLOBAL(44),
REG_A8XX_CP_PROTECT_GLOBAL(45),
REG_A8XX_CP_PROTECT_GLOBAL(46),
REG_A8XX_CP_PROTECT_GLOBAL(47),
REG_A8XX_CP_PROTECT_GLOBAL(48),
REG_A8XX_CP_PROTECT_GLOBAL(49),
REG_A8XX_CP_PROTECT_GLOBAL(50),
REG_A8XX_CP_PROTECT_GLOBAL(51),
REG_A8XX_CP_PROTECT_GLOBAL(52),
REG_A8XX_CP_PROTECT_GLOBAL(53),
REG_A8XX_CP_PROTECT_GLOBAL(54),
REG_A8XX_CP_PROTECT_GLOBAL(55),
REG_A8XX_CP_PROTECT_GLOBAL(56),
REG_A8XX_CP_PROTECT_GLOBAL(57),
REG_A8XX_CP_PROTECT_GLOBAL(58),
REG_A8XX_CP_PROTECT_GLOBAL(59),
REG_A8XX_CP_PROTECT_GLOBAL(60),
REG_A8XX_CP_PROTECT_GLOBAL(61),
REG_A8XX_CP_PROTECT_GLOBAL(62),
REG_A8XX_CP_PROTECT_GLOBAL(63),
};
DECLARE_ADRENO_REGLIST_LIST(a810_ifpc_reglist);
static const struct adreno_reglist_pipe a810_dyn_pwrup_reglist_regs[] = {
{ REG_A8XX_CP_PROTECT_CNTL_PIPE, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
{ REG_A8XX_CP_PROTECT_PIPE(15), 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
{ REG_A8XX_GRAS_TSEFE_DBG_ECO_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_GRAS_NC_MODE_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_GRAS_DBG_ECO_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A7XX_RB_CCU_CNTL, 0, BIT(PIPE_BR) },
{ REG_A7XX_RB_CCU_DBG_ECO_CNTL, 0, BIT(PIPE_BR) },
{ REG_A8XX_RB_CCU_NC_MODE_CNTL, 0, BIT(PIPE_BR) },
{ REG_A8XX_RB_CMP_NC_MODE_CNTL, 0, BIT(PIPE_BR) },
{ REG_A8XX_RB_RESOLVE_PREFETCH_CNTL, 0, BIT(PIPE_BR) },
{ REG_A8XX_RB_CMP_DBG_ECO_CNTL, 0, BIT(PIPE_BR) },
{ REG_A8XX_RB_GC_GMEM_PROTECT, 0, BIT(PIPE_BR) },
{ REG_A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE_ENABLE, 0, BIT(PIPE_BR) },
{ REG_A8XX_VPC_FLATSHADE_MODE_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_CHICKEN_BITS_1, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_CHICKEN_BITS_2, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_CHICKEN_BITS_3, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_PC_CHICKEN_BITS_4, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A6XX_PC_AUTO_VERTEX_STRIDE, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
{ REG_A8XX_PC_VIS_STREAM_CNTL, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
{ REG_A8XX_PC_CONTEXT_SWITCH_STABILIZE_CNTL_1, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
{ REG_A8XX_VFD_CB_BV_THRESHOLD, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_VFD_CB_BR_THRESHOLD, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_VFD_CB_BUSY_REQ_CNT, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A8XX_VFD_CB_LP_REQ_CNT, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
{ REG_A7XX_VFD_DBG_ECO_CNTL, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
};
DECLARE_ADRENO_REGLIST_PIPE_LIST(a810_dyn_pwrup_reglist);
static const struct adreno_reglist_pipe a840_nonctxt_regs[] = {
{ REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) },
{ REG_A8XX_GRAS_DBG_ECO_CNTL, 0x00000800, BIT(PIPE_BV) | BIT(PIPE_BR) },
@@ -2193,6 +2448,48 @@ static const struct adreno_info a8xx_gpus[] = {
{ 252, 2 },
{ 221, 3 },
),
}, {
.chip_ids = ADRENO_CHIP_IDS(0x44010000),
.family = ADRENO_8XX_GEN1,
.fw = {
[ADRENO_FW_SQE] = "gen80300_sqe.fw",
[ADRENO_FW_GMU] = "gen80300_gmu.bin",
},
.gmem = SZ_512K + SZ_64K,
.inactive_period = DRM_MSM_INACTIVE_PERIOD,
.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
ADRENO_QUIRK_HAS_HW_APRIV |
ADRENO_QUIRK_PREEMPTION |
ADRENO_QUIRK_IFPC,
.funcs = &a8xx_gpu_funcs,
.zapfw = "gen80300_zap.mbn",
.a6xx = &(const struct a6xx_info) {
.protect = &a810_protect,
.nonctxt_reglist = a810_nonctxt_regs,
.pwrup_reglist = &a810_pwrup_reglist,
.dyn_pwrup_reglist = &a810_dyn_pwrup_reglist,
.ifpc_reglist = &a810_ifpc_reglist,
.gbif_cx = a840_gbif,
.max_slices = 1,
.gmu_chipid = 0x8030000,
.bcms = (const struct a6xx_bcm[]) {
{ .name = "SH0", .buswidth = 16 },
{ .name = "MC0", .buswidth = 4 },
{
.name = "ACV",
.fixed = true,
.perfmode = BIT(2),
.perfmode_bw = 10687500,
},
{ /* sentinel */ },
},
},
.preempt_record_size = 4558 * SZ_1K,
.speedbins = ADRENO_SPEEDBINS(
{ 0, 0 },
{ 242, 1 },
{ 221, 2 },
),
}
};
@@ -2205,4 +2502,5 @@ static inline __always_unused void __build_asserts(void)
BUILD_BUG_ON(a660_protect.count > a660_protect.count_max);
BUILD_BUG_ON(a690_protect.count > a690_protect.count_max);
BUILD_BUG_ON(a730_protect.count > a730_protect.count_max);
BUILD_BUG_ON(a810_protect.count > a810_protect.count_max);
}
+68 -21
View File
@@ -947,7 +947,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
/* Turn on TCM (Tightly Coupled Memory) retention */
if (adreno_is_a7xx(adreno_gpu))
a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL, 1);
a6xx_cx_misc_write(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL, 1);
else if (!adreno_is_a8xx(adreno_gpu))
gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);
@@ -1215,7 +1215,7 @@ static int a6xx_gmu_secure_init(struct a6xx_gpu *a6xx_gpu)
if (!qcom_scm_is_available()) {
dev_warn_once(gpu->dev->dev,
"SCM is not available, poking fuse register\n");
a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
a6xx_cx_misc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
@@ -1236,7 +1236,7 @@ static int a6xx_gmu_secure_init(struct a6xx_gpu *a6xx_gpu)
* firmware, find out whether that's the case. The scm call
* above sets the fuse register.
*/
fuse_val = a6xx_llc_read(a6xx_gpu,
fuse_val = a6xx_cx_misc_read(a6xx_gpu,
REG_A7XX_CX_MISC_SW_FUSE_VALUE);
adreno_gpu->has_ray_tracing =
!!(fuse_val & A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING);
@@ -1250,6 +1250,56 @@ done:
return 0;
}
static int a6xx_gmu_gxpd_get(struct a6xx_gmu *gmu)
{
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
if (IS_ERR_OR_NULL(gmu->gxpd))
return 0;
/*
* On A8xx HW, GX GDSC is moved to a new clk controller block under GX
* power domain. The clock driver for this new block keeps the GX rail
* voted when gxpd is voted. So, use the gxpd only during gpu recovery.
*/
if (adreno_gpu->info->family >= ADRENO_8XX_GEN1)
return 0;
/*
* On A6x/A7x, "enable" the GX power domain which won't actually do
* anything but it will make sure that the refcounting is correct in
* case we need to bring down the GX after a GMU failure
*/
return pm_runtime_get_sync(gmu->gxpd);
}
static int a6xx_gmu_gxpd_put(struct a6xx_gmu *gmu)
{
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
if (IS_ERR_OR_NULL(gmu->gxpd))
return 0;
if (adreno_gpu->info->family < ADRENO_8XX_GEN1)
return pm_runtime_put_sync(gmu->gxpd);
/*
* On A8x, GX GDSC collapse should be triggered only when it is stuck ON
*/
if (adreno_gpu->funcs->gx_is_on(adreno_gpu)) {
pm_runtime_get_sync(gmu->gxpd);
/*
* Hint to gfxclkctl driver to do a hw collapse during the next
* RPM PUT. This is a special behavior in the gfxclkctl driver
*/
dev_pm_genpd_synced_poweroff(gmu->gxpd);
pm_runtime_put_sync(gmu->gxpd);
}
return 0;
}
int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
{
@@ -1266,13 +1316,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
/* Turn on the resources */
pm_runtime_get_sync(gmu->dev);
/*
* "enable" the GX power domain which won't actually do anything but it
* will make sure that the refcounting is correct in case we need to
* bring down the GX after a GMU failure
*/
if (!IS_ERR_OR_NULL(gmu->gxpd))
pm_runtime_get_sync(gmu->gxpd);
a6xx_gmu_gxpd_get(gmu);
/* Use a known rate to bring up the GMU */
clk_set_rate(gmu->core_clk, 200000000);
@@ -1299,7 +1343,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
/* Check to see if we are doing a cold or warm boot */
if (adreno_is_a7xx(adreno_gpu) || adreno_is_a8xx(adreno_gpu)) {
status = a6xx_llc_read(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL) == 1 ?
status = a6xx_cx_misc_read(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL) == 1 ?
GMU_WARM_BOOT : GMU_COLD_BOOT;
} else if (gmu->legacy) {
status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ?
@@ -1339,7 +1383,8 @@ disable_irq:
disable_clk:
clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks);
rpm_put:
pm_runtime_put(gmu->gxpd);
a6xx_gmu_gxpd_put(gmu);
pm_runtime_put(gmu->dev);
return ret;
@@ -1455,8 +1500,7 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
* domain. Usually the GMU does this but only if the shutdown sequence
* was successful
*/
if (!IS_ERR_OR_NULL(gmu->gxpd))
pm_runtime_put_sync(gmu->gxpd);
a6xx_gmu_gxpd_put(gmu);
clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks);
@@ -2034,12 +2078,12 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
return irq;
}
void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu)
void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu, bool force_on)
{
bool sysprof = msm_gpu_sysprof_no_ifpc(gpu) || force_on;
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
unsigned int sysprof_active;
/* Nothing to do if GPU is suspended. We will handle this during GMU resume */
if (!pm_runtime_get_if_active(&gpu->pdev->dev))
@@ -2047,15 +2091,13 @@ void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu)
mutex_lock(&gmu->lock);
sysprof_active = refcount_read(&gpu->sysprof_active);
/*
* 'Perfcounter select' register values are lost during IFPC collapse. To avoid that,
* use the currently unused perfcounter oob vote to block IFPC when sysprof is active
*/
if ((sysprof_active > 1) && !test_and_set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
if (sysprof && !test_and_set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
a6xx_gmu_set_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
else if ((sysprof_active == 1) && test_and_clear_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
else if (!sysprof && test_and_clear_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status))
a6xx_gmu_clear_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
mutex_unlock(&gmu->lock);
@@ -2357,7 +2399,12 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
goto err_mmio;
}
} else if (adreno_is_a8xx(adreno_gpu)) {
gmu->rscc = gmu->mmio + 0x19000;
/*
* On a8xx , RSCC lives at GPU base + 0x50000, which falls
* inside the GPU's kgsl_3d0_reg_memory range rather than the
* GMU's.
*/
gmu->rscc = gpu->mmio + 0x50000;
} else {
gmu->rscc = gmu->mmio + 0x23000;
}
File diff suppressed because it is too large Load Diff
+21 -9
View File
@@ -21,17 +21,19 @@ struct cpu_gpu_lock {
uint32_t cpu_req;
uint32_t turn;
union {
/* a6xx: */
struct {
uint16_t list_length;
uint16_t list_offset;
};
/* a7xx+: */
struct {
uint8_t ifpc_list_len;
uint8_t preemption_list_len;
uint16_t dynamic_list_len;
};
};
uint64_t regs[62];
uint64_t regs[];
};
/**
@@ -96,13 +98,21 @@ struct a6xx_gpu {
uint32_t *shadow;
struct drm_gem_object *pwrup_reglist_bo;
#define PWRUP_REGLIST_SIZE (2 * PAGE_SIZE)
void *pwrup_reglist_ptr;
uint64_t pwrup_reglist_iova;
bool pwrup_reglist_emitted;
/*
* Offset of start of SEL regs appended to pwrup_reglist. This
* is equal to lock->dynamic_list_len if no SEL regs are appended
* to the end of the dynamic reglist.
*/
uint16_t dynamic_sel_reglist_offset;
bool has_whereami;
void __iomem *llc_mmio;
void __iomem *cx_misc_mmio;
void *llc_slice;
void *htw_llc_slice;
bool have_mmu500;
@@ -240,19 +250,19 @@ static inline bool a6xx_has_gbif(struct adreno_gpu *gpu)
return true;
}
static inline void a6xx_llc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or)
static inline void a6xx_cx_misc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or)
{
return msm_rmw(a6xx_gpu->llc_mmio + (reg << 2), mask, or);
return msm_rmw(a6xx_gpu->cx_misc_mmio + (reg << 2), mask, or);
}
static inline u32 a6xx_llc_read(struct a6xx_gpu *a6xx_gpu, u32 reg)
static inline u32 a6xx_cx_misc_read(struct a6xx_gpu *a6xx_gpu, u32 reg)
{
return readl(a6xx_gpu->llc_mmio + (reg << 2));
return readl(a6xx_gpu->cx_misc_mmio + (reg << 2));
}
static inline void a6xx_llc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value)
static inline void a6xx_cx_misc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value)
{
writel(value, a6xx_gpu->llc_mmio + (reg << 2));
writel(value, a6xx_gpu->cx_misc_mmio + (reg << 2));
}
#define shadowptr(_a6xx_gpu, _ring) ((_a6xx_gpu)->shadow_iova + \
@@ -271,7 +281,7 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu);
void a6xx_gmu_sysprof_setup(struct msm_gpu *gpu, bool force_on);
void a6xx_preempt_init(struct msm_gpu *gpu);
void a6xx_preempt_hw_init(struct msm_gpu *gpu);
@@ -317,6 +327,7 @@ void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_
void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert);
int a6xx_fenced_write(struct a6xx_gpu *gpu, u32 offset, u64 value, u32 mask, bool is_64b);
void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
void a6xx_flush_yield(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
int a6xx_zap_shader_init(struct msm_gpu *gpu);
void a8xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off);
@@ -333,5 +344,6 @@ void a8xx_preempt_hw_init(struct msm_gpu *gpu);
void a8xx_preempt_trigger(struct msm_gpu *gpu);
void a8xx_preempt_irq(struct msm_gpu *gpu);
bool a8xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
void a8xx_perfcntr_flush(struct msm_gpu *gpu);
void a8xx_recover(struct msm_gpu *gpu);
#endif /* __A6XX_GPU_H__ */
+1 -1
View File
@@ -261,7 +261,7 @@ void a6xx_preempt_trigger(struct msm_gpu *gpu)
mod_timer(&a6xx_gpu->preempt_timer, jiffies + msecs_to_jiffies(10000));
/* Enable or disable postamble as needed */
sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
sysprof = msm_gpu_sysprof_no_perfcntr_zap(gpu);
if (!sysprof && !a6xx_gpu->postamble_enabled)
preempt_prepare_postamble(a6xx_gpu);
+60 -46
View File
@@ -104,7 +104,7 @@ void a8xx_gpu_get_slice_info(struct msm_gpu *gpu)
return;
}
slice_mask &= a6xx_llc_read(a6xx_gpu,
slice_mask &= a6xx_cx_misc_read(a6xx_gpu,
REG_A8XX_CX_MISC_SLICE_ENABLE_FINAL);
a6xx_gpu->slice_mask = slice_mask;
@@ -265,8 +265,8 @@ static void a8xx_set_cp_protect(struct msm_gpu *gpu)
* Last span feature is only supported on PIPE specific register.
* So update those here
*/
a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_CP_PROTECT_PIPE(protect->count_max), final_cfg);
a8xx_write_pipe(gpu, PIPE_BV, REG_A8XX_CP_PROTECT_PIPE(protect->count_max), final_cfg);
a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_CP_PROTECT_PIPE(15), final_cfg);
a8xx_write_pipe(gpu, PIPE_BV, REG_A8XX_CP_PROTECT_PIPE(15), final_cfg);
a8xx_aperture_clear(gpu);
}
@@ -275,41 +275,37 @@ static void a8xx_set_ubwc_config(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
const struct qcom_ubwc_cfg_data *cfg = adreno_gpu->ubwc_config;
u32 level2_swizzling_dis = !(cfg->ubwc_swizzle & UBWC_SWIZZLE_ENABLE_LVL2);
u32 level3_swizzling_dis = !(cfg->ubwc_swizzle & UBWC_SWIZZLE_ENABLE_LVL3);
u32 level2_swizzling_dis = !(qcom_ubwc_swizzle(cfg) & UBWC_SWIZZLE_ENABLE_LVL2);
u32 level3_swizzling_dis = !(qcom_ubwc_swizzle(cfg) & UBWC_SWIZZLE_ENABLE_LVL3);
bool rgba8888_lossless = false, fp16compoptdis = false;
bool yuvnotcomptofc = false, min_acc_len_64b = false;
bool rgb565_predicator = false, amsbc = false;
bool rgb565_predicator = false;
bool amsbc = qcom_ubwc_enable_amsbc(cfg);
bool ubwc_mode = qcom_ubwc_get_ubwc_mode(cfg);
u32 ubwc_version = cfg->ubwc_enc_version;
u32 hbb, hbb_hi, hbb_lo, mode = 1;
u32 hbb, hbb_hi, hbb_lo, mode;
u8 uavflagprd_inv = 2;
switch (ubwc_version) {
case UBWC_6_0:
yuvnotcomptofc = true;
mode = 5;
break;
case UBWC_5_0:
amsbc = true;
rgb565_predicator = true;
mode = 4;
break;
case UBWC_4_0:
amsbc = true;
rgb565_predicator = true;
fp16compoptdis = true;
rgba8888_lossless = true;
mode = 2;
break;
case UBWC_3_0:
amsbc = true;
mode = 1;
break;
default:
if (ubwc_version > UBWC_6_0)
dev_err(&gpu->pdev->dev, "Unknown UBWC version: 0x%x\n", ubwc_version);
break;
}
if (ubwc_version == UBWC_6_0)
yuvnotcomptofc = true;
if (ubwc_version < UBWC_5_0 &&
ubwc_version >= UBWC_4_0)
rgba8888_lossless = true;
if (ubwc_version < UBWC_4_3)
fp16compoptdis = true;
if (cfg->ubwc_enc_version >= UBWC_4_0)
rgb565_predicator = true;
if (ubwc_version < UBWC_3_0)
dev_err(&gpu->pdev->dev, "Unsupported UBWC version: 0x%x\n", ubwc_version);
mode = qcom_ubwc_version_tag(cfg);
/*
* We subtract 13 from the highest bank bit (13 is the minimum value
@@ -468,6 +464,7 @@ static void a8xx_patch_pwrup_reglist(struct msm_gpu *gpu)
}
lock->dynamic_list_len = dyn_pwrup_reglist_count;
a6xx_gpu->dynamic_sel_reglist_offset = dyn_pwrup_reglist_count;
done:
a8xx_aperture_clear(gpu);
@@ -488,15 +485,7 @@ static int a8xx_preempt_start(struct msm_gpu *gpu)
a6xx_emit_set_pseudo_reg(ring, a6xx_gpu, NULL);
/* Yield the floor on command completion */
OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4);
OUT_RING(ring, 0x00);
OUT_RING(ring, 0x00);
OUT_RING(ring, 0x00);
/* Generate interrupt on preemption completion */
OUT_RING(ring, 0x00);
a6xx_flush(gpu, ring);
a6xx_flush_yield(gpu, ring);
return a8xx_idle(gpu, ring) ? 0 : -EINVAL;
}
@@ -849,7 +838,7 @@ out:
*/
a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
if (!ret && (refcount_read(&gpu->sysprof_active) > 1)) {
if (!ret && msm_gpu_sysprof_no_perfcntr_zap(gpu)) {
ret = a6xx_gmu_set_oob(gmu, GMU_OOB_PERFCOUNTER_SET);
if (!ret)
set_bit(GMU_STATUS_OOB_PERF_SET, &gmu->status);
@@ -886,17 +875,22 @@ void a8xx_recover(struct msm_gpu *gpu)
adreno_dump_info(gpu);
if (hang_debug)
a8xx_dump(gpu);
/*
* To handle recovery specific sequences during the rpm suspend we are
* about to trigger
*/
a6xx_gpu->hung = true;
/* Halt SQE first */
gpu_write(gpu, REG_A8XX_CP_SQE_CNTL, 3);
if (adreno_gpu->funcs->gx_is_on(adreno_gpu)) {
/*
* Sometimes crashstate capture is skipped, so SQE should be
* halted here again
*/
gpu_write(gpu, REG_A8XX_CP_SQE_CNTL, 3);
if (hang_debug)
a8xx_dump(gpu);
}
pm_runtime_dont_use_autosuspend(&gpu->pdev->dev);
@@ -1353,3 +1347,23 @@ bool a8xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
{
return true;
}
void a8xx_perfcntr_flush(struct msm_gpu *gpu)
{
u32 val;
/*
* Flush delta counters (both perf counters and pipe stats) present in
* RBBM_S and RBBM_US to perf RAM logic to get the latest data.
*/
gpu_write(gpu, REG_A8XX_RBBM_PERFCTR_FLUSH_HOST_CMD, BIT(0));
gpu_write(gpu, REG_A8XX_RBBM_SLICE_PERFCTR_FLUSH_HOST_CMD, BIT(0));
/* Ensure all writes are posted before polling status register */
wmb();
if (gpu_poll_timeout(gpu, REG_A8XX_RBBM_PERFCTR_FLUSH_HOST_STATUS, val,
val & BIT(0), 100, 100 * 1000)) {
dev_err(&gpu->pdev->dev, "Perfcounter flush timed out: status=0x%08x\n", val);
}
}
+1 -1
View File
@@ -242,7 +242,7 @@ void a8xx_preempt_trigger(struct msm_gpu *gpu)
mod_timer(&a6xx_gpu->preempt_timer, jiffies + msecs_to_jiffies(10000));
/* Enable or disable postamble as needed */
sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
sysprof = msm_gpu_sysprof_no_perfcntr_zap(gpu);
if (!sysprof && !a6xx_gpu->postamble_enabled)
preempt_prepare_postamble(a6xx_gpu);
+6 -2
View File
@@ -307,8 +307,10 @@ MODULE_DEVICE_TABLE(of, dt_match);
static int adreno_runtime_resume(struct device *dev)
{
struct msm_gpu *gpu = dev_to_gpu(dev);
return gpu->funcs->pm_resume(gpu);
int ret = gpu->funcs->pm_resume(gpu);
if (!ret)
ret = msm_perfcntr_resume(gpu);
return ret;
}
static int adreno_runtime_suspend(struct device *dev)
@@ -322,6 +324,8 @@ static int adreno_runtime_suspend(struct device *dev)
*/
WARN_ON_ONCE(gpu->active_submits);
msm_perfcntr_suspend(gpu);
return gpu->funcs->pm_suspend(gpu);
}

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