MALI: rockchip: upgrade bifrost DDK to g25p0-00eac0, from g24p0-00eac0
mali_csffw.bin from Valhall DDK g25(r50) is included. Change-Id: Ic454428c384456a14b29d9651f537eb59c11284d Signed-off-by: Zhen Chen <chenzhen@rock-chips.com>
This commit is contained in:
parent
4cedc115fd
commit
d1b62d2e45
132 changed files with 5331 additions and 3263 deletions
|
|
@ -0,0 +1,163 @@
|
|||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2022-2024 ARM Limited. All rights reserved.
|
||||
#
|
||||
# This program is free software and is provided to you under the terms of the
|
||||
# GNU General Public License version 2 as published by the Free Software
|
||||
# Foundation, and any use by you of this program is subject to the terms
|
||||
# of such GNU license.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
#
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/arm/arm,coresight-mali-source.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ARM CoreSight Mali Source integration
|
||||
|
||||
maintainers:
|
||||
- ARM Ltd.
|
||||
|
||||
description: |
|
||||
See Documentation/trace/coresight/coresight.rst for detailed information
|
||||
about Coresight.
|
||||
|
||||
This documentation will cover Mali specific devicetree integration.
|
||||
|
||||
References to Sink ports are given as examples. Access to Sink is specific
|
||||
to an implementation and would require dedicated kernel modules.
|
||||
|
||||
Arm Mali GPU are supporting 3 different sources: ITM, ETM, ELA
|
||||
|
||||
ELA source configuration via SysFS entries:
|
||||
|
||||
The register values used by CoreSight for ELA can be configured using SysFS
|
||||
interfaces. This implicitly includes configuring the ELA for independent or
|
||||
shared JCN request and response channels.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- arm,coresight-mali-source-itm
|
||||
- arm,coresight-mali-source-etm
|
||||
- arm,coresight-mali-source-ela
|
||||
|
||||
gpu:
|
||||
minItems: 1
|
||||
maxItems: 1
|
||||
description:
|
||||
Phandle to a Mali GPU definition
|
||||
|
||||
port:
|
||||
description:
|
||||
Output connection to CoreSight Sink Trace bus.
|
||||
|
||||
Legacy binding between Coresight Sources and CoreSight Sink.
|
||||
For Linux kernel < v4.20.
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
out-ports:
|
||||
description:
|
||||
Binding between Coresight Sources and CoreSight Sink.
|
||||
For Linux kernel >= v4.20.
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port:
|
||||
description: Output connection to CoreSight Sink Trace bus.
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- gpu
|
||||
- port
|
||||
- out-ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
# A Sink node without legacy CoreSight connections
|
||||
- |
|
||||
mali-source-itm {
|
||||
compatible = "arm,coresight-mali-source-itm";
|
||||
gpu = <&gpu>;
|
||||
|
||||
out-ports {
|
||||
port {
|
||||
mali_source_itm_out_port0: endpoint {
|
||||
remote-endpoint = <&mali_sink_in_port0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mali-source-ela {
|
||||
compatible = "arm,coresight-mali-source-ela";
|
||||
gpu = <&gpu>;
|
||||
|
||||
out-ports {
|
||||
port {
|
||||
mali_source_ela_out_port0: endpoint {
|
||||
remote-endpoint = <&mali_sink_in_port1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mali-source-etm {
|
||||
compatible = "arm,coresight-mali-source-etm";
|
||||
gpu = <&gpu>;
|
||||
|
||||
out-ports {
|
||||
port {
|
||||
mali_source_etm_out_port0: endpoint {
|
||||
remote-endpoint = <&mali_sink_in_port2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# A Sink node with legacy CoreSight connections
|
||||
- |
|
||||
mali-source-itm {
|
||||
compatible = "arm,coresight-mali-source-itm";
|
||||
gpu = <&gpu>;
|
||||
|
||||
port {
|
||||
mali_source_itm_out_port0: endpoint {
|
||||
remote-endpoint = <&mali_sink_in_port0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mali-source-etm {
|
||||
compatible = "arm,coresight-mali-source-etm";
|
||||
gpu = <&gpu>;
|
||||
|
||||
port {
|
||||
mali_source_etm_out_port0: endpoint {
|
||||
remote-endpoint = <&mali_sink_in_port1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mali-source-ela {
|
||||
compatible = "arm,coresight-mali-source-ela";
|
||||
gpu = <&gpu>;
|
||||
|
||||
port {
|
||||
mali_source_ela_out_port0: endpoint {
|
||||
remote-endpoint = <&mali_sink_in_port2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2013-2023 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 2013-2024 ARM Limited. All rights reserved.
|
||||
#
|
||||
# This program is free software and is provided to you under the terms of the
|
||||
# GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -132,6 +132,10 @@ for details.
|
|||
set and the setting coresponding to the SYSC_ALLOC register.
|
||||
- propagate-bits: Used to write to L2_CONFIG.PBHA_HWU. This bitset establishes which
|
||||
PBHA bits are propagated on the AXI bus.
|
||||
- mma-wa-id: Sets the PBHA ID to be used for the PBHA override based MMA violation workaround.
|
||||
The read and write allocation override bits for the PBHA are set to NONCACHEABLE
|
||||
and the driver encodes the PBHA ID in the PTEs where this workaround is to be applied.
|
||||
Valid values are from 1 to 15.
|
||||
|
||||
|
||||
Example for a Mali GPU with 1 clock and 1 regulator:
|
||||
|
|
@ -241,6 +245,7 @@ gpu@0xfc010000 {
|
|||
pbha {
|
||||
int-id-override = <2 0x32>, <9 0x05>, <16 0x32>;
|
||||
propagate-bits = /bits/ 8 <0x03>;
|
||||
mma-wa-id = <2>;
|
||||
};
|
||||
...
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2021-2023 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 2021-2024 ARM Limited. All rights reserved.
|
||||
#
|
||||
# This program is free software and is provided to you under the terms of the
|
||||
# GNU General Public License version 2 as published by the Free Software
|
||||
|
|
|
|||
|
|
@ -299,7 +299,8 @@ static int example_mgm_get_import_memory_id(struct memory_group_manager_device *
|
|||
}
|
||||
|
||||
static u64 example_mgm_update_gpu_pte(struct memory_group_manager_device *const mgm_dev,
|
||||
unsigned int const group_id, int const mmu_level, u64 pte)
|
||||
unsigned int const group_id, unsigned int const pbha_id,
|
||||
unsigned int pte_flags, int const mmu_level, u64 pte)
|
||||
{
|
||||
struct mgm_groups *const data = mgm_dev->data;
|
||||
|
||||
|
|
@ -309,7 +310,10 @@ static u64 example_mgm_update_gpu_pte(struct memory_group_manager_device *const
|
|||
if (WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
|
||||
return pte;
|
||||
|
||||
pte |= ((u64)group_id << PTE_PBHA_SHIFT) & PTE_PBHA_MASK;
|
||||
if (pte_flags & BIT(MMA_VIOLATION)) {
|
||||
pr_warn_once("MMA violation! Applying PBHA override workaround to PTE\n");
|
||||
pte |= ((u64)pbha_id << PTE_PBHA_SHIFT) & PTE_PBHA_MASK;
|
||||
}
|
||||
|
||||
/* Address could be translated into a different bus address here */
|
||||
pte |= ((u64)1 << PTE_RES_BIT_MULTI_AS_SHIFT);
|
||||
|
|
@ -362,6 +366,16 @@ static vm_fault_t example_mgm_vmf_insert_pfn_prot(struct memory_group_manager_de
|
|||
return fault;
|
||||
}
|
||||
|
||||
static bool example_mgm_get_import_memory_cached_access_permitted(
|
||||
struct memory_group_manager_device *mgm_dev,
|
||||
struct memory_group_manager_import_data *import_data)
|
||||
{
|
||||
CSTD_UNUSED(mgm_dev);
|
||||
CSTD_UNUSED(import_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int mgm_initialize_data(struct mgm_groups *mgm_data)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -408,6 +422,8 @@ static int memory_group_manager_probe(struct platform_device *pdev)
|
|||
mgm_dev->ops.mgm_vmf_insert_pfn_prot = example_mgm_vmf_insert_pfn_prot;
|
||||
mgm_dev->ops.mgm_update_gpu_pte = example_mgm_update_gpu_pte;
|
||||
mgm_dev->ops.mgm_pte_to_original_pte = example_mgm_pte_to_original_pte;
|
||||
mgm_dev->ops.mgm_get_import_memory_cached_access_permitted =
|
||||
example_mgm_get_import_memory_cached_access_permitted;
|
||||
|
||||
mgm_data = kzalloc(sizeof(*mgm_data), GFP_KERNEL);
|
||||
if (!mgm_data) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2012-2023 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 2012-2024 ARM Limited. All rights reserved.
|
||||
#
|
||||
# This program is free software and is provided to you under the terms of the
|
||||
# GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -69,7 +69,7 @@ endif
|
|||
#
|
||||
|
||||
# Driver version string which is returned to userspace via an ioctl
|
||||
MALI_RELEASE_NAME ?= '"g24p0-00eac0"'
|
||||
MALI_RELEASE_NAME ?= '"g25p0-00eac0"'
|
||||
# Set up defaults if not defined by build system
|
||||
ifeq ($(CONFIG_MALI_BIFROST_DEBUG), y)
|
||||
MALI_UNIT_TEST = 1
|
||||
|
|
@ -104,7 +104,6 @@ endif
|
|||
#
|
||||
# Experimental features must default to disabled, e.g.:
|
||||
# MALI_EXPERIMENTAL_FEATURE ?= 0
|
||||
MALI_INCREMENTAL_RENDERING_JM ?= 0
|
||||
|
||||
#
|
||||
# ccflags
|
||||
|
|
@ -117,7 +116,6 @@ ccflags-y = \
|
|||
-DMALI_COVERAGE=$(MALI_COVERAGE) \
|
||||
-DMALI_RELEASE_NAME=$(MALI_RELEASE_NAME) \
|
||||
-DMALI_JIT_PRESSURE_LIMIT_BASE=$(MALI_JIT_PRESSURE_LIMIT_BASE) \
|
||||
-DMALI_INCREMENTAL_RENDERING_JM=$(MALI_INCREMENTAL_RENDERING_JM) \
|
||||
-DMALI_PLATFORM_DIR=$(MALI_PLATFORM_DIR)
|
||||
|
||||
|
||||
|
|
@ -212,6 +210,7 @@ endif
|
|||
|
||||
|
||||
INCLUDE_SUBDIR = \
|
||||
$(src)/arbiter/Kbuild \
|
||||
$(src)/context/Kbuild \
|
||||
$(src)/debug/Kbuild \
|
||||
$(src)/device/Kbuild \
|
||||
|
|
@ -228,9 +227,6 @@ ifeq ($(CONFIG_MALI_CSF_SUPPORT),y)
|
|||
INCLUDE_SUBDIR += $(src)/csf/Kbuild
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MALI_ARBITER_SUPPORT),y)
|
||||
INCLUDE_SUBDIR += $(src)/arbiter/Kbuild
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MALI_BIFROST_DEVFREQ),y)
|
||||
ifeq ($(CONFIG_DEVFREQ_THERMAL),y)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ config MALI_BIFROST_NO_MALI
|
|||
All calls to the simulated hardware will complete immediately as if the hardware
|
||||
completed the task.
|
||||
|
||||
endchoice
|
||||
|
||||
config MALI_NO_MALI_DEFAULT_GPU
|
||||
string "Default GPU for No Mali"
|
||||
depends on MALI_BIFROST_NO_MALI
|
||||
|
|
@ -70,7 +72,12 @@ config MALI_NO_MALI_DEFAULT_GPU
|
|||
help
|
||||
This option sets the default GPU to identify as for No Mali builds.
|
||||
|
||||
endchoice
|
||||
config MALI_IS_FPGA
|
||||
bool "Enable build of Mali kernel driver for FPGA"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
help
|
||||
This is the default HW backend.
|
||||
|
||||
menu "Platform specific options"
|
||||
source "$(MALI_KCONFIG_EXT_PREFIX)drivers/gpu/arm/bifrost/platform/Kconfig"
|
||||
|
|
@ -340,7 +347,7 @@ config MALI_PWRSOFT_765
|
|||
changes have been backported say Y to avoid compilation errors.
|
||||
|
||||
config MALI_HW_ERRATA_1485982_NOT_AFFECTED
|
||||
bool "Disable workaround for BASE_HW_ISSUE_GPU2017_1336"
|
||||
bool "Disable workaround for KBASE_HW_ISSUE_GPU2017_1336"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
|
|
@ -352,7 +359,7 @@ config MALI_HW_ERRATA_1485982_NOT_AFFECTED
|
|||
coherency mode requires the L2 to be turned off.
|
||||
|
||||
config MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE
|
||||
bool "Use alternative workaround for BASE_HW_ISSUE_GPU2017_1336"
|
||||
bool "Use alternative workaround for KBASE_HW_ISSUE_GPU2017_1336"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT && !MALI_HW_ERRATA_1485982_NOT_AFFECTED
|
||||
default n
|
||||
help
|
||||
|
|
|
|||
|
|
@ -156,7 +156,6 @@ ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
|
|||
CONFIG_MALI_BIFROST \
|
||||
CONFIG_MALI_CSF_SUPPORT \
|
||||
CONFIG_MALI_BIFROST_GATOR_SUPPORT \
|
||||
CONFIG_MALI_ARBITER_SUPPORT \
|
||||
CONFIG_MALI_ARBITRATION \
|
||||
CONFIG_MALI_PARTITION_MANAGER \
|
||||
CONFIG_MALI_REAL_HW \
|
||||
|
|
@ -170,6 +169,7 @@ ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
|
|||
CONFIG_MALI_PWRSOFT_765 \
|
||||
CONFIG_MALI_JOB_DUMP \
|
||||
CONFIG_MALI_BIFROST_NO_MALI \
|
||||
CONFIG_MALI_IS_FPGA \
|
||||
CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED \
|
||||
CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE \
|
||||
CONFIG_MALI_PRFCNT_SET_PRIMARY \
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ static void on_gpu_stop(struct device *dev)
|
|||
}
|
||||
|
||||
KBASE_TLSTREAM_TL_ARBITER_STOP_REQUESTED(kbdev, kbdev);
|
||||
KBASE_KTRACE_ADD(kbdev, ARB_GPU_STOP_REQUESTED, NULL, 0);
|
||||
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_STOP_EVT);
|
||||
}
|
||||
|
||||
|
|
@ -133,6 +134,7 @@ static void on_gpu_granted(struct device *dev)
|
|||
}
|
||||
|
||||
KBASE_TLSTREAM_TL_ARBITER_GRANTED(kbdev, kbdev);
|
||||
KBASE_KTRACE_ADD(kbdev, ARB_GPU_GRANTED, NULL, 0);
|
||||
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_GRANTED_EVT);
|
||||
}
|
||||
|
||||
|
|
@ -156,7 +158,8 @@ static void on_gpu_lost(struct device *dev)
|
|||
dev_err(dev, "%s(): kbdev is NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
KBASE_TLSTREAM_TL_ARBITER_LOST(kbdev, kbdev);
|
||||
KBASE_KTRACE_ADD(kbdev, ARB_GPU_LOST, NULL, 0);
|
||||
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_LOST_EVT);
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +181,7 @@ static int kbase_arbif_of_init(struct kbase_device *kbdev)
|
|||
if (!arbiter_if_node)
|
||||
arbiter_if_node = of_parse_phandle(kbdev->dev->of_node, "arbiter_if", 0);
|
||||
if (!arbiter_if_node) {
|
||||
dev_dbg(kbdev->dev, "No arbiter_if in Device Tree\n");
|
||||
dev_dbg(kbdev->dev, "No arbiter_if in Device Tree");
|
||||
/* no arbiter interface defined in device tree */
|
||||
kbdev->arb.arb_dev = NULL;
|
||||
kbdev->arb.arb_if = NULL;
|
||||
|
|
@ -187,19 +190,19 @@ static int kbase_arbif_of_init(struct kbase_device *kbdev)
|
|||
|
||||
pdev = of_find_device_by_node(arbiter_if_node);
|
||||
if (!pdev) {
|
||||
dev_err(kbdev->dev, "Failed to find arbiter_if device\n");
|
||||
dev_err(kbdev->dev, "Failed to find arbiter_if device");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
if (!pdev->dev.driver || !try_module_get(pdev->dev.driver->owner)) {
|
||||
dev_err(kbdev->dev, "arbiter_if driver not available\n");
|
||||
dev_err(kbdev->dev, "arbiter_if driver not available");
|
||||
put_device(&pdev->dev);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
kbdev->arb.arb_dev = &pdev->dev;
|
||||
arb_if = platform_get_drvdata(pdev);
|
||||
if (!arb_if) {
|
||||
dev_err(kbdev->dev, "arbiter_if driver not ready\n");
|
||||
dev_err(kbdev->dev, "arbiter_if driver not ready");
|
||||
module_put(pdev->dev.driver->owner);
|
||||
put_device(&pdev->dev);
|
||||
return -EPROBE_DEFER;
|
||||
|
|
@ -243,6 +246,10 @@ int kbase_arbif_init(struct kbase_device *kbdev)
|
|||
/* Tries to init with 'arbiter-if' if present in devicetree */
|
||||
err = kbase_arbif_of_init(kbdev);
|
||||
|
||||
if (err == -ENODEV) {
|
||||
/* devicetree does not support arbitration */
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
|
@ -260,19 +267,19 @@ int kbase_arbif_init(struct kbase_device *kbdev)
|
|||
arb_if = kbdev->arb.arb_if;
|
||||
|
||||
if (arb_if == NULL) {
|
||||
dev_err(kbdev->dev, "No arbiter interface present\n");
|
||||
dev_err(kbdev->dev, "No arbiter interface present");
|
||||
goto failure_term;
|
||||
}
|
||||
|
||||
if (!arb_if->vm_ops.vm_arb_register_dev) {
|
||||
dev_err(kbdev->dev, "arbiter_if registration callback not present\n");
|
||||
dev_err(kbdev->dev, "arbiter_if registration callback not present");
|
||||
goto failure_term;
|
||||
}
|
||||
|
||||
/* register kbase arbiter_if callbacks */
|
||||
err = arb_if->vm_ops.vm_arb_register_dev(arb_if, kbdev->dev, &ops);
|
||||
if (err) {
|
||||
dev_err(kbdev->dev, "Failed to register with arbiter. (err = %d)\n", err);
|
||||
dev_err(kbdev->dev, "Failed to register with arbiter. (err = %d)", err);
|
||||
goto failure_term;
|
||||
}
|
||||
|
||||
|
|
@ -333,6 +340,7 @@ void kbase_arbif_gpu_request(struct kbase_device *kbdev)
|
|||
|
||||
if (arb_if && arb_if->vm_ops.vm_arb_gpu_request) {
|
||||
KBASE_TLSTREAM_TL_ARBITER_REQUESTED(kbdev, kbdev);
|
||||
KBASE_KTRACE_ADD(kbdev, ARB_GPU_REQUESTED, NULL, 0);
|
||||
arb_if->vm_ops.vm_arb_gpu_request(arb_if);
|
||||
}
|
||||
}
|
||||
|
|
@ -349,8 +357,11 @@ void kbase_arbif_gpu_stopped(struct kbase_device *kbdev, u8 gpu_required)
|
|||
|
||||
if (arb_if && arb_if->vm_ops.vm_arb_gpu_stopped) {
|
||||
KBASE_TLSTREAM_TL_ARBITER_STOPPED(kbdev, kbdev);
|
||||
if (gpu_required)
|
||||
KBASE_KTRACE_ADD(kbdev, ARB_GPU_STOPPED, NULL, 0);
|
||||
if (gpu_required) {
|
||||
KBASE_TLSTREAM_TL_ARBITER_REQUESTED(kbdev, kbdev);
|
||||
KBASE_KTRACE_ADD(kbdev, ARB_GPU_REQUESTED, NULL, 0);
|
||||
}
|
||||
arb_if->vm_ops.vm_arb_gpu_stopped(arb_if, gpu_required);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ static void kbase_arbiter_pm_resume_wq(struct work_struct *data)
|
|||
arb_vm_state->vm_arb_starting = false;
|
||||
mutex_unlock(&arb_vm_state->vm_state_lock);
|
||||
KBASE_TLSTREAM_TL_ARBITER_STARTED(kbdev, kbdev);
|
||||
KBASE_KTRACE_ADD(kbdev, ARB_GPU_STARTED, NULL, 0);
|
||||
dev_dbg(kbdev->dev, "<%s\n", __func__);
|
||||
}
|
||||
|
||||
|
|
@ -295,11 +296,13 @@ int kbase_arbiter_pm_early_init(struct kbase_device *kbdev)
|
|||
|
||||
err = kbase_arbif_init(kbdev);
|
||||
if (err) {
|
||||
dev_err(kbdev->dev, "Failed to initialise arbif module. (err = %d)\n", err);
|
||||
if (err != -EPERM)
|
||||
dev_err(kbdev->dev, "Failed to initialise arbif module. (err = %d)", err);
|
||||
|
||||
goto arbif_init_fail;
|
||||
}
|
||||
|
||||
if (kbdev->arb.arb_if) {
|
||||
if (kbase_has_arbiter(kbdev)) {
|
||||
kbase_arbif_gpu_request(kbdev);
|
||||
dev_dbg(kbdev->dev, "Waiting for initial GPU assignment...\n");
|
||||
|
||||
|
|
@ -345,6 +348,9 @@ void kbase_arbiter_pm_early_term(struct kbase_device *kbdev)
|
|||
if (arb_vm_state == NULL)
|
||||
return;
|
||||
|
||||
if (!kbase_has_arbiter(kbdev))
|
||||
return;
|
||||
|
||||
kbase_arbiter_pm_release_interrupts(kbdev);
|
||||
|
||||
cancel_request_timer(kbdev);
|
||||
|
|
@ -475,6 +481,12 @@ int kbase_arbiter_pm_gpu_assigned(struct kbase_device *kbdev)
|
|||
if (!kbdev)
|
||||
return result;
|
||||
|
||||
/* If there is no Arbiter, then there is no virtualization
|
||||
* and current VM always has access to GPU.
|
||||
*/
|
||||
if (!kbase_has_arbiter(kbdev))
|
||||
return 1;
|
||||
|
||||
/* First check the GPU_LOST state */
|
||||
kbase_pm_lock(kbdev);
|
||||
if (kbase_pm_is_gpu_lost(kbdev)) {
|
||||
|
|
@ -688,7 +700,7 @@ static inline bool kbase_arbiter_pm_vm_os_suspend_ready_state(struct kbase_devic
|
|||
* @kbdev: The kbase device structure for the device
|
||||
*
|
||||
* Prepares OS to be in suspend state until it receives GRANT message
|
||||
* from Arbiter asynchronously.
|
||||
* from Arbiter asynchronously. This function assumes there is an active Arbiter.
|
||||
*/
|
||||
static void kbase_arbiter_pm_vm_os_prepare_suspend(struct kbase_device *kbdev)
|
||||
{
|
||||
|
|
@ -696,10 +708,8 @@ static void kbase_arbiter_pm_vm_os_prepare_suspend(struct kbase_device *kbdev)
|
|||
enum kbase_vm_state prev_state;
|
||||
|
||||
lockdep_assert_held(&arb_vm_state->vm_state_lock);
|
||||
if (kbdev->arb.arb_if) {
|
||||
if (kbdev->pm.arb_vm_state->vm_state == KBASE_VM_STATE_SUSPENDED)
|
||||
return;
|
||||
}
|
||||
if (kbdev->pm.arb_vm_state->vm_state == KBASE_VM_STATE_SUSPENDED)
|
||||
return;
|
||||
/* Block suspend OS function until we are in a stable state
|
||||
* with vm_state_lock
|
||||
*/
|
||||
|
|
@ -791,7 +801,7 @@ void kbase_arbiter_pm_vm_event(struct kbase_device *kbdev, enum kbase_arbif_evt
|
|||
{
|
||||
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
|
||||
|
||||
if (!kbdev->arb.arb_if)
|
||||
if (!kbase_has_arbiter(kbdev))
|
||||
return;
|
||||
|
||||
mutex_lock(&arb_vm_state->vm_state_lock);
|
||||
|
|
@ -911,7 +921,8 @@ static inline bool kbase_arbiter_pm_vm_gpu_assigned_locked(struct kbase_device *
|
|||
*
|
||||
* This function handles a suspend event from the driver,
|
||||
* communicating with the arbiter and waiting synchronously for the GPU
|
||||
* to be granted again depending on the VM state.
|
||||
* to be granted again depending on the VM state. Returns immediately
|
||||
* with success if there is no Arbiter.
|
||||
*
|
||||
* Return: 0 on success else 1 suspend handler isn not possible.
|
||||
*/
|
||||
|
|
@ -921,58 +932,58 @@ int kbase_arbiter_pm_ctx_active_handle_suspend(struct kbase_device *kbdev,
|
|||
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
|
||||
int res = 0;
|
||||
|
||||
if (kbdev->arb.arb_if) {
|
||||
mutex_lock(&arb_vm_state->vm_state_lock);
|
||||
while (!kbase_arbiter_pm_vm_gpu_assigned_locked(kbdev)) {
|
||||
/* Update VM state since we have GPU work to do */
|
||||
if (arb_vm_state->vm_state == KBASE_VM_STATE_STOPPING_IDLE)
|
||||
kbase_arbiter_pm_vm_set_state(kbdev,
|
||||
KBASE_VM_STATE_STOPPING_ACTIVE);
|
||||
else if (arb_vm_state->vm_state == KBASE_VM_STATE_STOPPED) {
|
||||
kbase_arbiter_pm_vm_set_state(kbdev,
|
||||
KBASE_VM_STATE_STOPPED_GPU_REQUESTED);
|
||||
kbase_arbif_gpu_request(kbdev);
|
||||
start_request_timer(kbdev);
|
||||
} else if (arb_vm_state->vm_state == KBASE_VM_STATE_INITIALIZING_WITH_GPU)
|
||||
if (!kbase_has_arbiter(kbdev))
|
||||
return res;
|
||||
|
||||
mutex_lock(&arb_vm_state->vm_state_lock);
|
||||
while (!kbase_arbiter_pm_vm_gpu_assigned_locked(kbdev)) {
|
||||
/* Update VM state since we have GPU work to do */
|
||||
if (arb_vm_state->vm_state == KBASE_VM_STATE_STOPPING_IDLE)
|
||||
kbase_arbiter_pm_vm_set_state(kbdev, KBASE_VM_STATE_STOPPING_ACTIVE);
|
||||
else if (arb_vm_state->vm_state == KBASE_VM_STATE_STOPPED) {
|
||||
kbase_arbiter_pm_vm_set_state(kbdev, KBASE_VM_STATE_STOPPED_GPU_REQUESTED);
|
||||
kbase_arbif_gpu_request(kbdev);
|
||||
start_request_timer(kbdev);
|
||||
} else if (arb_vm_state->vm_state == KBASE_VM_STATE_INITIALIZING_WITH_GPU)
|
||||
break;
|
||||
|
||||
if (suspend_handler != KBASE_PM_SUSPEND_HANDLER_NOT_POSSIBLE) {
|
||||
/* In case of GPU lost, even if
|
||||
* active_count > 0, we no longer have GPU
|
||||
* access
|
||||
*/
|
||||
if (kbase_pm_is_gpu_lost(kbdev))
|
||||
res = 1;
|
||||
|
||||
switch (suspend_handler) {
|
||||
case KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE:
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
if (suspend_handler != KBASE_PM_SUSPEND_HANDLER_NOT_POSSIBLE) {
|
||||
/* In case of GPU lost, even if
|
||||
* active_count > 0, we no longer have GPU
|
||||
* access
|
||||
*/
|
||||
if (kbase_pm_is_gpu_lost(kbdev))
|
||||
case KBASE_PM_SUSPEND_HANDLER_DONT_REACTIVATE:
|
||||
if (kbdev->pm.active_count == 0)
|
||||
res = 1;
|
||||
|
||||
switch (suspend_handler) {
|
||||
case KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE:
|
||||
res = 1;
|
||||
break;
|
||||
case KBASE_PM_SUSPEND_HANDLER_DONT_REACTIVATE:
|
||||
if (kbdev->pm.active_count == 0)
|
||||
res = 1;
|
||||
break;
|
||||
case KBASE_PM_SUSPEND_HANDLER_VM_GPU_GRANTED:
|
||||
break;
|
||||
default:
|
||||
WARN(1, "Unknown suspend_handler\n");
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KBASE_PM_SUSPEND_HANDLER_VM_GPU_GRANTED:
|
||||
break;
|
||||
default:
|
||||
WARN(1, "Unknown suspend_handler\n");
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Need to synchronously wait for GPU assignment */
|
||||
atomic_inc(&kbdev->pm.gpu_users_waiting);
|
||||
mutex_unlock(&arb_vm_state->vm_state_lock);
|
||||
kbase_pm_unlock(kbdev);
|
||||
kbase_arbiter_pm_vm_wait_gpu_assignment(kbdev);
|
||||
kbase_pm_lock(kbdev);
|
||||
mutex_lock(&arb_vm_state->vm_state_lock);
|
||||
atomic_dec(&kbdev->pm.gpu_users_waiting);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Need to synchronously wait for GPU assignment */
|
||||
atomic_inc(&kbdev->pm.gpu_users_waiting);
|
||||
mutex_unlock(&arb_vm_state->vm_state_lock);
|
||||
kbase_pm_unlock(kbdev);
|
||||
kbase_arbiter_pm_vm_wait_gpu_assignment(kbdev);
|
||||
kbase_pm_lock(kbdev);
|
||||
mutex_lock(&arb_vm_state->vm_state_lock);
|
||||
atomic_dec(&kbdev->pm.gpu_users_waiting);
|
||||
}
|
||||
mutex_unlock(&arb_vm_state->vm_state_lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2020-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -50,14 +50,22 @@ static struct kbase_clk_rate_trace_op_conf *
|
|||
get_clk_rate_trace_callbacks(__maybe_unused struct kbase_device *kbdev)
|
||||
{
|
||||
/* base case */
|
||||
const void *arbiter_if_node;
|
||||
struct kbase_clk_rate_trace_op_conf *callbacks =
|
||||
(struct kbase_clk_rate_trace_op_conf *)CLK_RATE_TRACE_OPS;
|
||||
#if defined(CONFIG_MALI_ARBITER_SUPPORT) && defined(CONFIG_OF)
|
||||
const void *arbiter_if_node;
|
||||
|
||||
/* Nothing left to do here if there is no Arbiter/virtualization or if
|
||||
* CONFIG_OF is not enabled.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_OF))
|
||||
return callbacks;
|
||||
|
||||
if (WARN_ON(!kbdev) || WARN_ON(!kbdev->dev))
|
||||
return callbacks;
|
||||
|
||||
if (!kbase_has_arbiter(kbdev))
|
||||
return callbacks;
|
||||
|
||||
arbiter_if_node = of_get_property(kbdev->dev->of_node, "arbiter-if", NULL);
|
||||
if (!arbiter_if_node)
|
||||
arbiter_if_node = of_get_property(kbdev->dev->of_node, "arbiter_if", NULL);
|
||||
|
|
@ -69,8 +77,6 @@ get_clk_rate_trace_callbacks(__maybe_unused struct kbase_device *kbdev)
|
|||
dev_dbg(kbdev->dev,
|
||||
"Arbitration supported but disabled by platform. Leaving clk rate callbacks as default.\n");
|
||||
|
||||
#endif
|
||||
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -48,7 +48,7 @@ int kbase_backend_gpuprops_get(struct kbase_device *kbdev, struct kbasep_gpuprop
|
|||
/* Not a valid register on TMIX */
|
||||
|
||||
/* TGOx specific register */
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_THREAD_TLS_ALLOC))
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_THREAD_TLS_ALLOC))
|
||||
regdump->thread_tls_alloc =
|
||||
kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(THREAD_TLS_ALLOC));
|
||||
#endif /* !MALI_USE_CSF */
|
||||
|
|
@ -64,7 +64,7 @@ int kbase_backend_gpuprops_get(struct kbase_device *kbdev, struct kbasep_gpuprop
|
|||
/* AMBA_FEATURES enum is mapped to COHERENCY_FEATURES enum */
|
||||
regdump->coherency_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(COHERENCY_FEATURES));
|
||||
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_CORE_FEATURES))
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_CORE_FEATURES))
|
||||
regdump->core_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(CORE_FEATURES));
|
||||
|
||||
#if MALI_USE_CSF
|
||||
|
|
@ -116,7 +116,7 @@ int kbase_backend_gpuprops_get_curr_config(struct kbase_device *kbdev,
|
|||
int kbase_backend_gpuprops_get_l2_features(struct kbase_device *kbdev,
|
||||
struct kbasep_gpuprops_regdump *regdump)
|
||||
{
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_L2_CONFIG)) {
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_L2_CONFIG)) {
|
||||
regdump->l2_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(L2_FEATURES));
|
||||
regdump->l2_config = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(L2_CONFIG));
|
||||
|
||||
|
|
|
|||
|
|
@ -98,82 +98,6 @@ static u64 kbase_job_write_affinity(struct kbase_device *kbdev, base_jd_core_req
|
|||
return affinity;
|
||||
}
|
||||
|
||||
/**
|
||||
* select_job_chain() - Select which job chain to submit to the GPU
|
||||
* @katom: Pointer to the atom about to be submitted to the GPU
|
||||
*
|
||||
* Selects one of the fragment job chains attached to the special atom at the
|
||||
* end of a renderpass, or returns the address of the single job chain attached
|
||||
* to any other type of atom.
|
||||
*
|
||||
* Which job chain is selected depends upon whether the tiling phase of the
|
||||
* renderpass completed normally or was soft-stopped because it used too
|
||||
* much memory. It also depends upon whether one of the fragment job chains
|
||||
* has already been run as part of the same renderpass.
|
||||
*
|
||||
* Return: GPU virtual address of the selected job chain
|
||||
*/
|
||||
static u64 select_job_chain(struct kbase_jd_atom *katom)
|
||||
{
|
||||
struct kbase_context *const kctx = katom->kctx;
|
||||
u64 jc = katom->jc;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
|
||||
lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
|
||||
|
||||
if (!(katom->core_req & BASE_JD_REQ_END_RENDERPASS))
|
||||
return jc;
|
||||
|
||||
compiletime_assert((1ull << (sizeof(katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[katom->renderpass_id];
|
||||
/* We can read a subset of renderpass state without holding
|
||||
* higher-level locks (but not end_katom, for example).
|
||||
* If the end-of-renderpass atom is running with as-yet indeterminate
|
||||
* OOM state then assume that the start atom was not soft-stopped.
|
||||
*/
|
||||
switch (rp->state) {
|
||||
case KBASE_JD_RP_OOM:
|
||||
/* Tiling ran out of memory.
|
||||
* Start of incremental rendering, used once.
|
||||
*/
|
||||
jc = katom->jc_fragment.norm_read_forced_write;
|
||||
break;
|
||||
case KBASE_JD_RP_START:
|
||||
case KBASE_JD_RP_PEND_OOM:
|
||||
/* Tiling completed successfully first time.
|
||||
* Single-iteration rendering, used once.
|
||||
*/
|
||||
jc = katom->jc_fragment.norm_read_norm_write;
|
||||
break;
|
||||
case KBASE_JD_RP_RETRY_OOM:
|
||||
/* Tiling ran out of memory again.
|
||||
* Continuation of incremental rendering, used as
|
||||
* many times as required.
|
||||
*/
|
||||
jc = katom->jc_fragment.forced_read_forced_write;
|
||||
break;
|
||||
case KBASE_JD_RP_RETRY:
|
||||
case KBASE_JD_RP_RETRY_PEND_OOM:
|
||||
/* Tiling completed successfully this time.
|
||||
* End of incremental rendering, used once.
|
||||
*/
|
||||
jc = katom->jc_fragment.forced_read_norm_write;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "Selected job chain 0x%llx for end atom %pK in state %d\n", jc,
|
||||
(void *)katom, (int)rp->state);
|
||||
|
||||
katom->jc = jc;
|
||||
return jc;
|
||||
}
|
||||
|
||||
static inline bool kbasep_jm_wait_js_free(struct kbase_device *kbdev, unsigned int js,
|
||||
struct kbase_context *kctx)
|
||||
{
|
||||
|
|
@ -196,7 +120,7 @@ int kbase_job_hw_submit(struct kbase_device *kbdev, struct kbase_jd_atom *katom,
|
|||
{
|
||||
struct kbase_context *kctx;
|
||||
u32 cfg;
|
||||
u64 const jc_head = select_job_chain(katom);
|
||||
u64 jc_head = katom->jc;
|
||||
u64 affinity;
|
||||
struct slot_rb *ptr_slot_rb = &kbdev->hwaccess.backend.slot_rb[js];
|
||||
|
||||
|
|
@ -220,21 +144,21 @@ int kbase_job_hw_submit(struct kbase_device *kbdev, struct kbase_jd_atom *katom,
|
|||
*/
|
||||
cfg = (u32)kctx->as_nr;
|
||||
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_FLUSH_REDUCTION) &&
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_FLUSH_REDUCTION) &&
|
||||
!(kbdev->serialize_jobs & KBASE_SERIALIZE_RESET))
|
||||
cfg |= JS_CONFIG_ENABLE_FLUSH_REDUCTION;
|
||||
|
||||
if (0 != (katom->core_req & BASE_JD_REQ_SKIP_CACHE_START)) {
|
||||
/* Force a cache maintenance operation if the newly submitted
|
||||
* katom to the slot is from a different kctx. For a JM GPU
|
||||
* that has the feature BASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER,
|
||||
* that has the feature KBASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER,
|
||||
* applies a FLUSH_INV_SHADER_OTHER. Otherwise, do a
|
||||
* FLUSH_CLEAN_INVALIDATE.
|
||||
*/
|
||||
u64 tagged_kctx = ptr_slot_rb->last_kctx_tagged;
|
||||
|
||||
if (tagged_kctx != SLOT_RB_NULL_TAG_VAL && tagged_kctx != SLOT_RB_TAG_KCTX(kctx)) {
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER))
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER))
|
||||
cfg |= JS_CONFIG_START_FLUSH_INV_SHADER_OTHER;
|
||||
else
|
||||
cfg |= JS_CONFIG_START_FLUSH_CLEAN_INVALIDATE;
|
||||
|
|
@ -246,15 +170,14 @@ int kbase_job_hw_submit(struct kbase_device *kbdev, struct kbase_jd_atom *katom,
|
|||
if (0 != (katom->core_req & BASE_JD_REQ_SKIP_CACHE_END) &&
|
||||
!(kbdev->serialize_jobs & KBASE_SERIALIZE_RESET))
|
||||
cfg |= JS_CONFIG_END_FLUSH_NO_ACTION;
|
||||
else if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_CLEAN_ONLY_SAFE))
|
||||
else if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE))
|
||||
cfg |= JS_CONFIG_END_FLUSH_CLEAN;
|
||||
else
|
||||
cfg |= JS_CONFIG_END_FLUSH_CLEAN_INVALIDATE;
|
||||
|
||||
cfg |= JS_CONFIG_THREAD_PRI(8);
|
||||
|
||||
if ((katom->atom_flags & KBASE_KATOM_FLAG_PROTECTED) ||
|
||||
(katom->core_req & BASE_JD_REQ_END_RENDERPASS))
|
||||
if (katom->atom_flags & KBASE_KATOM_FLAG_PROTECTED)
|
||||
cfg |= JS_CONFIG_DISABLE_DESCRIPTOR_WR_BK;
|
||||
|
||||
if (!ptr_slot_rb->job_chain_flag) {
|
||||
|
|
@ -268,7 +191,7 @@ int kbase_job_hw_submit(struct kbase_device *kbdev, struct kbase_jd_atom *katom,
|
|||
|
||||
kbase_reg_write32(kbdev, JOB_SLOT_OFFSET(js, CONFIG_NEXT), cfg);
|
||||
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_FLUSH_REDUCTION))
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_FLUSH_REDUCTION))
|
||||
kbase_reg_write32(kbdev, JOB_SLOT_OFFSET(js, FLUSH_ID_NEXT), katom->flush_id);
|
||||
|
||||
/* Write an approximate start timestamp.
|
||||
|
|
@ -440,7 +363,7 @@ void kbase_job_done(struct kbase_device *kbdev, u32 done)
|
|||
* jobs to hang. Reset GPU before allowing
|
||||
* any other jobs on the slot to continue.
|
||||
*/
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TTRX_3076)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TTRX_3076)) {
|
||||
if (completion_code == BASE_JD_EVENT_JOB_BUS_FAULT) {
|
||||
if (kbase_prepare_to_reset_gpu_locked(
|
||||
kbdev, RESET_FLAGS_NONE))
|
||||
|
|
@ -740,66 +663,6 @@ void kbase_job_slot_ctx_priority_check_locked(struct kbase_context *kctx,
|
|||
}
|
||||
}
|
||||
|
||||
static int softstop_start_rp_nolock(struct kbase_context *kctx, struct kbase_va_region *reg)
|
||||
{
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
struct kbase_jd_atom *katom;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
katom = kbase_gpu_inspect(kbdev, 1, 0);
|
||||
|
||||
if (!katom) {
|
||||
dev_dbg(kctx->kbdev->dev, "No atom on job slot\n");
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
if (!(katom->core_req & BASE_JD_REQ_START_RENDERPASS)) {
|
||||
dev_dbg(kctx->kbdev->dev, "Atom %pK on job slot is not start RP\n", (void *)katom);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
compiletime_assert((1ull << (sizeof(katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[katom->renderpass_id];
|
||||
if (WARN_ON(rp->state != KBASE_JD_RP_START && rp->state != KBASE_JD_RP_RETRY))
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "OOM in state %d with region %pK\n", (int)rp->state, (void *)reg);
|
||||
|
||||
if (WARN_ON(katom != rp->start_katom))
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "Adding region %pK to list %pK\n", (void *)reg,
|
||||
(void *)&rp->oom_reg_list);
|
||||
list_move_tail(®->link, &rp->oom_reg_list);
|
||||
dev_dbg(kctx->kbdev->dev, "Added region to list\n");
|
||||
|
||||
rp->state = (rp->state == KBASE_JD_RP_START ? KBASE_JD_RP_PEND_OOM :
|
||||
KBASE_JD_RP_RETRY_PEND_OOM);
|
||||
|
||||
kbase_job_slot_softstop(kbdev, 1, katom);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kbase_job_slot_softstop_start_rp(struct kbase_context *const kctx,
|
||||
struct kbase_va_region *const reg)
|
||||
{
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
int err;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
err = softstop_start_rp_nolock(kctx, reg);
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void kbase_jm_wait_for_zero_jobs(struct kbase_context *kctx)
|
||||
{
|
||||
struct kbase_device *kbdev = kctx->kbdev;
|
||||
|
|
@ -839,7 +702,7 @@ u32 kbase_backend_get_current_flush_id(struct kbase_device *kbdev)
|
|||
{
|
||||
u32 flush_id = 0;
|
||||
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_FLUSH_REDUCTION)) {
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_FLUSH_REDUCTION)) {
|
||||
mutex_lock(&kbdev->pm.lock);
|
||||
if (kbdev->pm.backend.gpu_powered)
|
||||
flush_id = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(LATEST_FLUSH));
|
||||
|
|
@ -1085,7 +948,7 @@ static void kbasep_reset_timeout_worker(struct work_struct *data)
|
|||
/* The flush has completed so reset the active indicator */
|
||||
kbdev->irq_reset_flush = false;
|
||||
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TMIX_8463)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TMIX_8463)) {
|
||||
u64 val;
|
||||
const u32 timeout_us =
|
||||
kbase_get_timeout_ms(kbdev, KBASE_CLEAN_CACHE_TIMEOUT) * USEC_PER_MSEC;
|
||||
|
|
@ -1268,14 +1131,12 @@ bool kbase_prepare_to_reset_gpu_locked(struct kbase_device *kbdev, unsigned int
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (kbase_pm_is_gpu_lost(kbdev)) {
|
||||
/* GPU access has been removed, reset will be done by
|
||||
* Arbiter instead
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags & RESET_FLAGS_HWC_UNRECOVERABLE_ERROR)
|
||||
kbase_instr_hwcnt_on_unrecoverable_error(kbdev);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -425,7 +425,7 @@ static void kbase_gpu_release_atom(struct kbase_device *kbdev, struct kbase_jd_a
|
|||
}
|
||||
}
|
||||
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TGOX_R1_1234)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TGOX_R1_1234)) {
|
||||
if (katom->atom_flags & KBASE_KATOM_FLAG_HOLDING_L2_REF_PROT) {
|
||||
kbase_pm_protected_l2_override(kbdev, false);
|
||||
katom->atom_flags &= ~KBASE_KATOM_FLAG_HOLDING_L2_REF_PROT;
|
||||
|
|
@ -698,7 +698,7 @@ static int kbase_jm_enter_protected_mode(struct kbase_device *kbdev, struct kbas
|
|||
|
||||
kbase_pm_protected_entry_override_disable(kbdev);
|
||||
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TGOX_R1_1234)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TGOX_R1_1234)) {
|
||||
/*
|
||||
* Power on L2 caches; this will also result in the
|
||||
* correct value written to coherency enable register.
|
||||
|
|
@ -714,13 +714,13 @@ static int kbase_jm_enter_protected_mode(struct kbase_device *kbdev, struct kbas
|
|||
|
||||
katom[idx]->protected_state.enter = KBASE_ATOM_ENTER_PROTECTED_FINISHED;
|
||||
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TGOX_R1_1234))
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TGOX_R1_1234))
|
||||
return -EAGAIN;
|
||||
|
||||
/* ***TRANSITION TO HIGHER STATE*** */
|
||||
fallthrough;
|
||||
case KBASE_ATOM_ENTER_PROTECTED_FINISHED:
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TGOX_R1_1234)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TGOX_R1_1234)) {
|
||||
/*
|
||||
* Check that L2 caches are powered and, if so,
|
||||
* enter protected mode.
|
||||
|
|
@ -864,11 +864,7 @@ void kbase_backend_slot_update(struct kbase_device *kbdev)
|
|||
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (kbase_reset_gpu_is_active(kbdev) || kbase_is_gpu_removed(kbdev))
|
||||
#else
|
||||
if (kbase_reset_gpu_is_active(kbdev))
|
||||
#endif
|
||||
if (kbase_reset_gpu_is_active(kbdev) || (kbase_is_gpu_removed(kbdev)))
|
||||
return;
|
||||
|
||||
for (js = 0; js < kbdev->gpu_props.num_job_slots; js++) {
|
||||
|
|
@ -896,7 +892,7 @@ void kbase_backend_slot_update(struct kbase_device *kbdev)
|
|||
break;
|
||||
|
||||
case KBASE_ATOM_GPU_RB_WAITING_BLOCKED:
|
||||
if (kbase_js_atom_blocked_on_x_dep(katom[idx]))
|
||||
if (katom[idx]->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED)
|
||||
break;
|
||||
|
||||
katom[idx]->gpu_rb_state =
|
||||
|
|
@ -1236,7 +1232,7 @@ void kbase_gpu_complete_hw(struct kbase_device *kbdev, unsigned int js, u32 comp
|
|||
* When a hard-stop is followed close after a soft-stop, the completion
|
||||
* code may be set to STOPPED, even though the job is terminated
|
||||
*/
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TMIX_8438)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TMIX_8438)) {
|
||||
if (completion_code == BASE_JD_EVENT_STOPPED &&
|
||||
(katom->atom_flags & KBASE_KATOM_FLAG_BEEN_HARD_STOPPED)) {
|
||||
completion_code = BASE_JD_EVENT_TERMINATED;
|
||||
|
|
@ -1331,6 +1327,9 @@ void kbase_gpu_complete_hw(struct kbase_device *kbdev, unsigned int js, u32 comp
|
|||
dev_dbg(kbdev->dev, "Update job chain address of atom %pK to resume from 0x%llx\n",
|
||||
(void *)katom, job_tail);
|
||||
|
||||
/* Some of the job has been executed, so we update the job chain address to where
|
||||
* we should resume from
|
||||
*/
|
||||
katom->jc = job_tail;
|
||||
KBASE_KTRACE_ADD_JM_SLOT(kbdev, JM_UPDATE_HEAD, katom->kctx, katom, job_tail, js);
|
||||
}
|
||||
|
|
@ -1381,6 +1380,8 @@ void kbase_gpu_complete_hw(struct kbase_device *kbdev, unsigned int js, u32 comp
|
|||
dev_dbg(kbdev->dev, "Cross-slot dependency %pK has become runnable.\n",
|
||||
(void *)katom);
|
||||
|
||||
/* Cross-slot dependency has now become runnable. Try to submit it. */
|
||||
|
||||
/* Check if there are lower priority jobs to soft stop */
|
||||
kbase_job_slot_ctx_priority_check_locked(kctx, katom);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -46,7 +46,7 @@ static inline bool timer_callback_should_run(struct kbase_device *kbdev, int nr_
|
|||
}
|
||||
#endif /* CONFIG_MALI_BIFROST_DEBUG */
|
||||
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_9435)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_9435)) {
|
||||
/* Timeouts would have to be 4x longer (due to micro-
|
||||
* architectural design) to support OpenCL conformance tests, so
|
||||
* only run the timer when there's:
|
||||
|
|
@ -100,7 +100,7 @@ static enum hrtimer_restart timer_callback(struct hrtimer *timer)
|
|||
/* The current version of the model doesn't support
|
||||
* Soft-Stop
|
||||
*/
|
||||
if (!kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_5736)) {
|
||||
if (!kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_5736)) {
|
||||
u32 ticks = atom->ticks++;
|
||||
|
||||
#if !defined(CONFIG_MALI_JOB_DUMP) && !defined(CONFIG_MALI_VECTOR_DUMP)
|
||||
|
|
|
|||
|
|
@ -1953,7 +1953,8 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
|
|||
*value = dummy->control_reg_values->gpu_features_lo;
|
||||
} else if (addr == GPU_CONTROL_REG(GPU_FEATURES_HI)) {
|
||||
*value = dummy->control_reg_values->gpu_features_hi;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
model_error_log(
|
||||
KBASE_CORE,
|
||||
"Dummy model register access: Reading unsupported register 0x%x. Returning 0\n",
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@
|
|||
#include <linux/version_compat_defs.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <mali_kbase_reset_gpu.h>
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
#include <csf/mali_kbase_csf_scheduler.h>
|
||||
#endif /* !CONFIG_MALI_ARBITER_SUPPORT */
|
||||
#endif /* !MALI_USE_CSF */
|
||||
#include <hwcnt/mali_kbase_hwcnt_context.h>
|
||||
#include <backend/gpu/mali_kbase_pm_internal.h>
|
||||
|
|
@ -100,10 +98,8 @@ void kbase_pm_register_access_enable(struct kbase_device *kbdev)
|
|||
if (callbacks)
|
||||
callbacks->power_on_callback(kbdev);
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (WARN_ON(kbase_pm_is_gpu_lost(kbdev)))
|
||||
dev_err(kbdev->dev, "Attempting to power on while GPU lost\n");
|
||||
#endif
|
||||
|
||||
kbdev->pm.backend.gpu_powered = true;
|
||||
}
|
||||
|
|
@ -136,9 +132,7 @@ int kbase_hwaccess_pm_init(struct kbase_device *kbdev)
|
|||
INIT_WORK(&kbdev->pm.backend.gpu_poweroff_wait_work, kbase_pm_gpu_poweroff_wait_wq);
|
||||
|
||||
kbdev->pm.backend.ca_cores_enabled = ~0ull;
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
kbase_pm_set_gpu_lost(kbdev, false);
|
||||
#endif
|
||||
init_waitqueue_head(&kbdev->pm.backend.gpu_in_desired_state_wait);
|
||||
|
||||
#if !MALI_USE_CSF
|
||||
|
|
@ -180,15 +174,18 @@ int kbase_hwaccess_pm_init(struct kbase_device *kbdev)
|
|||
kbase_hwcnt_context_disable(kbdev->hwcnt_gpu_ctx);
|
||||
|
||||
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
|
||||
kbdev->pm.backend.gpu_sleep_supported =
|
||||
kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_GPU_SLEEP) &&
|
||||
!kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TURSEHW_1997) &&
|
||||
kbdev->pm.backend.callback_power_runtime_gpu_active &&
|
||||
kbdev->pm.backend.callback_power_runtime_gpu_idle;
|
||||
kbdev->pm.backend.gpu_sleep_allowed = 0;
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GPU_SLEEP) &&
|
||||
!kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TURSEHW_1997) &&
|
||||
kbdev->pm.backend.callback_power_runtime_gpu_active &&
|
||||
kbdev->pm.backend.callback_power_runtime_gpu_idle)
|
||||
set_bit(KBASE_GPU_SUPPORTS_GPU_SLEEP, &kbdev->pm.backend.gpu_sleep_allowed);
|
||||
|
||||
kbdev->pm.backend.apply_hw_issue_TITANHW_2938_wa =
|
||||
kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TITANHW_2938) &&
|
||||
kbdev->pm.backend.gpu_sleep_supported;
|
||||
kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TITANHW_2938) &&
|
||||
test_bit(KBASE_GPU_SUPPORTS_GPU_SLEEP, &kbdev->pm.backend.gpu_sleep_allowed);
|
||||
|
||||
/* FW Sleep-on-Idle is feature is kept disabled */
|
||||
#endif
|
||||
|
||||
if (IS_ENABLED(CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED))
|
||||
|
|
@ -196,14 +193,14 @@ int kbase_hwaccess_pm_init(struct kbase_device *kbdev)
|
|||
|
||||
/* WA1: L2 always_on for GPUs being affected by GPU2017-1336 */
|
||||
if (!IS_ENABLED(CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE)) {
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_GPU2017_1336))
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_GPU2017_1336))
|
||||
kbdev->pm.backend.l2_always_on = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* WA3: Clock slow down for GPUs being affected by GPU2017-1336 */
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_GPU2017_1336)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_GPU2017_1336)) {
|
||||
kbdev->pm.backend.gpu_clock_slow_down_wa = true;
|
||||
kbdev->pm.backend.gpu_clock_slow_down_desired = true;
|
||||
INIT_WORK(&kbdev->pm.backend.gpu_clock_control_work,
|
||||
|
|
@ -348,13 +345,11 @@ static void pm_handle_power_off(struct kbase_device *kbdev)
|
|||
*/
|
||||
wait_for_mmu_fault_handling_in_gpu_poweroff_wait_wq(kbdev);
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
/* poweron_required may have changed while pm lock
|
||||
* was released.
|
||||
*/
|
||||
if (kbase_pm_is_gpu_lost(kbdev))
|
||||
backend->poweron_required = false;
|
||||
#endif
|
||||
|
||||
/* Turn off clock now that fault have been handled. We
|
||||
* dropped locks so poweron_required may have changed -
|
||||
|
|
@ -948,13 +943,11 @@ void kbase_hwaccess_pm_resume(struct kbase_device *kbdev)
|
|||
/* System resume callback has begun */
|
||||
kbdev->pm.resuming = true;
|
||||
kbdev->pm.suspending = false;
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (kbase_pm_is_gpu_lost(kbdev)) {
|
||||
dev_dbg(kbdev->dev, "%s: GPU lost in progress\n", __func__);
|
||||
kbase_pm_unlock(kbdev);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
kbase_pm_do_poweron(kbdev, true);
|
||||
|
||||
#if !MALI_USE_CSF
|
||||
|
|
@ -964,7 +957,6 @@ void kbase_hwaccess_pm_resume(struct kbase_device *kbdev)
|
|||
kbase_pm_unlock(kbdev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
void kbase_pm_handle_gpu_lost(struct kbase_device *kbdev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
|
@ -975,8 +967,10 @@ void kbase_pm_handle_gpu_lost(struct kbase_device *kbdev)
|
|||
#endif
|
||||
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
|
||||
|
||||
if (!kbdev->arb.arb_if)
|
||||
if (!kbase_has_arbiter(kbdev)) {
|
||||
dev_warn(kbdev->dev, "%s called with no active arbiter!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&kbdev->pm.lock);
|
||||
mutex_lock(&arb_vm_state->vm_state_lock);
|
||||
|
|
@ -991,7 +985,8 @@ void kbase_pm_handle_gpu_lost(struct kbase_device *kbdev)
|
|||
|
||||
#if MALI_USE_CSF
|
||||
/* Full GPU reset will have been done by hypervisor, so cancel */
|
||||
kbase_reset_gpu_prevent_and_wait(kbdev);
|
||||
if (kbase_reset_gpu_prevent_and_wait(kbdev))
|
||||
dev_warn(kbdev->dev, "Failed to prevent GPU reset.");
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags_sched);
|
||||
|
|
@ -1041,7 +1036,6 @@ void kbase_pm_handle_gpu_lost(struct kbase_device *kbdev)
|
|||
mutex_unlock(&arb_vm_state->vm_state_lock);
|
||||
mutex_unlock(&kbdev->pm.lock);
|
||||
}
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
|
||||
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
|
||||
int kbase_pm_force_mcu_wakeup_after_sleep(struct kbase_device *kbdev)
|
||||
|
|
@ -1253,4 +1247,5 @@ out:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2013-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2013-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -55,11 +55,18 @@ void kbase_devfreq_set_core_mask(struct kbase_device *kbdev, u64 core_mask)
|
|||
unsigned long flags;
|
||||
#if MALI_USE_CSF
|
||||
u64 old_core_mask = 0;
|
||||
#endif
|
||||
bool mmu_sync_needed = false;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI) &&
|
||||
kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_GPU2019_3901)) {
|
||||
mmu_sync_needed = true;
|
||||
down_write(&kbdev->csf.mmu_sync_sem);
|
||||
}
|
||||
#endif
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
#if MALI_USE_CSF
|
||||
|
||||
if (!(core_mask & kbdev->pm.debug_core_mask)) {
|
||||
dev_err(kbdev->dev,
|
||||
"OPP core mask 0x%llX does not intersect with debug mask 0x%llX\n",
|
||||
|
|
@ -98,6 +105,9 @@ void kbase_devfreq_set_core_mask(struct kbase_device *kbdev, u64 core_mask)
|
|||
old_core_mask, core_mask);
|
||||
}
|
||||
}
|
||||
|
||||
if (mmu_sync_needed)
|
||||
up_write(&kbdev->csf.mmu_sync_sem);
|
||||
#endif
|
||||
|
||||
dev_dbg(kbdev->dev, "Devfreq policy : new core mask=%llX\n", pm_backend->ca_cores_enabled);
|
||||
|
|
@ -105,6 +115,10 @@ void kbase_devfreq_set_core_mask(struct kbase_device *kbdev, u64 core_mask)
|
|||
return;
|
||||
unlock:
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
#if MALI_USE_CSF
|
||||
if (mmu_sync_needed)
|
||||
up_write(&kbdev->csf.mmu_sync_sem);
|
||||
#endif
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_devfreq_set_core_mask);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -114,6 +114,27 @@ enum kbase_pm_runtime_suspend_abort_reason {
|
|||
ABORT_REASON_NON_IDLE_CGS
|
||||
};
|
||||
|
||||
/* The following indices point to the corresponding bits stored in
|
||||
* &kbase_pm_backend_data.gpu_sleep_allowed. They denote the conditions that
|
||||
* would be checked against to determine the level of support for GPU sleep
|
||||
* and firmware sleep-on-idle.
|
||||
*/
|
||||
#define KBASE_GPU_SUPPORTS_GPU_SLEEP ((uint8_t)0)
|
||||
#define KBASE_GPU_SUPPORTS_FW_SLEEP_ON_IDLE ((uint8_t)1)
|
||||
#define KBASE_GPU_PERF_COUNTERS_COLLECTION_ENABLED ((uint8_t)2)
|
||||
#define KBASE_GPU_IGNORE_IDLE_EVENT ((uint8_t)3)
|
||||
#define KBASE_GPU_NON_IDLE_OFF_SLOT_GROUPS_AVAILABLE ((uint8_t)4)
|
||||
|
||||
/* FW sleep-on-idle could be enabled if
|
||||
* &kbase_pm_backend_data.gpu_sleep_allowed is equal to this value.
|
||||
*/
|
||||
#define KBASE_GPU_FW_SLEEP_ON_IDLE_ALLOWED \
|
||||
((uint8_t)((1 << KBASE_GPU_SUPPORTS_GPU_SLEEP) | \
|
||||
(1 << KBASE_GPU_SUPPORTS_FW_SLEEP_ON_IDLE) | \
|
||||
(0 << KBASE_GPU_PERF_COUNTERS_COLLECTION_ENABLED) | \
|
||||
(0 << KBASE_GPU_IGNORE_IDLE_EVENT) | \
|
||||
(0 << KBASE_GPU_NON_IDLE_OFF_SLOT_GROUPS_AVAILABLE)))
|
||||
|
||||
/**
|
||||
* struct kbasep_pm_metrics - Metrics data collected for use by the power
|
||||
* management framework.
|
||||
|
|
@ -304,7 +325,7 @@ union kbase_pm_policy_data {
|
|||
* called previously.
|
||||
* See &struct kbase_pm_callback_conf.
|
||||
* @ca_cores_enabled: Cores that are currently available
|
||||
* @apply_hw_issue_TITANHW_2938_wa: Indicates if the workaround for BASE_HW_ISSUE_TITANHW_2938
|
||||
* @apply_hw_issue_TITANHW_2938_wa: Indicates if the workaround for KBASE_HW_ISSUE_TITANHW_2938
|
||||
* needs to be applied when unmapping memory from GPU.
|
||||
* @mcu_state: The current state of the micro-control unit, only applicable
|
||||
* to GPUs that have such a component
|
||||
|
|
@ -350,10 +371,9 @@ union kbase_pm_policy_data {
|
|||
* @core_idle_work: Work item used to wait for undesired cores to become inactive.
|
||||
* The work item is enqueued when Host controls the power for
|
||||
* shader cores and down scaling of cores is performed.
|
||||
* @gpu_sleep_supported: Flag to indicate that if GPU sleep feature can be
|
||||
* supported by the kernel driver or not. If this
|
||||
* flag is not set, then HW state is directly saved
|
||||
* when GPU idle notification is received.
|
||||
* @gpu_sleep_allowed: Bitmask to indicate the conditions that would be
|
||||
* used to determine what support for GPU sleep is
|
||||
* available.
|
||||
* @gpu_sleep_mode_active: Flag to indicate that the GPU needs to be in sleep
|
||||
* mode. It is set when the GPU idle notification is
|
||||
* received and is cleared when HW state has been
|
||||
|
|
@ -497,7 +517,7 @@ struct kbase_pm_backend_data {
|
|||
struct work_struct core_idle_work;
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
bool gpu_sleep_supported;
|
||||
unsigned long gpu_sleep_allowed;
|
||||
bool gpu_sleep_mode_active;
|
||||
bool exit_gpu_sleep_mode;
|
||||
bool gpu_idled;
|
||||
|
|
|
|||
|
|
@ -47,9 +47,7 @@
|
|||
#include <backend/gpu/mali_kbase_pm_internal.h>
|
||||
#include <backend/gpu/mali_kbase_l2_mmu_config.h>
|
||||
#include <mali_kbase_dummy_job_wa.h>
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
#include <arbiter/mali_kbase_arbiter_pm.h>
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
|
||||
#if MALI_USE_CSF
|
||||
#include <linux/delay.h>
|
||||
|
|
@ -615,11 +613,11 @@ static void kbase_pm_l2_config_override(struct kbase_device *kbdev)
|
|||
/*
|
||||
* Skip if it is not supported
|
||||
*/
|
||||
if (!kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_L2_CONFIG))
|
||||
if (!kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_L2_CONFIG))
|
||||
return;
|
||||
|
||||
#if MALI_USE_CSF
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_PBHA_HWU)) {
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_PBHA_HWU)) {
|
||||
val = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(L2_CONFIG));
|
||||
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(L2_CONFIG),
|
||||
L2_CONFIG_PBHA_HWU_SET(val, kbdev->pbha_propagate_bits));
|
||||
|
|
@ -743,16 +741,8 @@ bool kbase_pm_is_mcu_inactive(struct kbase_device *kbdev, enum kbase_mcu_state s
|
|||
}
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
/**
|
||||
* kbase_pm_enable_mcu_db_notification - Enable the Doorbell notification on
|
||||
* MCU side
|
||||
*
|
||||
* @kbdev: Pointer to the device.
|
||||
*
|
||||
* This function is called to re-enable the Doorbell notification on MCU side
|
||||
* when MCU needs to beome active again.
|
||||
*/
|
||||
static void kbase_pm_enable_mcu_db_notification(struct kbase_device *kbdev)
|
||||
|
||||
void kbase_pm_enable_mcu_db_notification(struct kbase_device *kbdev)
|
||||
{
|
||||
u32 val = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(MCU_CONTROL));
|
||||
|
||||
|
|
@ -778,7 +768,7 @@ static void wait_mcu_as_inactive(struct kbase_device *kbdev)
|
|||
kbase_get_timeout_ms(kbdev, KBASE_AS_INACTIVE_TIMEOUT) * USEC_PER_MSEC;
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
if (!kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TURSEHW_2716))
|
||||
if (!kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TURSEHW_2716))
|
||||
return;
|
||||
|
||||
/* Wait for the AS_ACTIVE_INT bit to become 0 for the AS used by MCU FW */
|
||||
|
|
@ -927,6 +917,18 @@ static int kbase_pm_mcu_update_state(struct kbase_device *kbdev)
|
|||
if (kbase_pm_is_mcu_desired(kbdev) &&
|
||||
!backend->policy_change_clamp_state_to_off &&
|
||||
backend->l2_state == KBASE_L2_ON) {
|
||||
kbdev->csf.mcu_halted = false;
|
||||
|
||||
/* Ensure that FW would not go to sleep immediately after
|
||||
* resumption.
|
||||
*/
|
||||
kbase_csf_firmware_global_input_mask(&kbdev->csf.global_iface,
|
||||
GLB_REQ,
|
||||
GLB_REQ_REQ_IDLE_DISABLE,
|
||||
GLB_REQ_IDLE_DISABLE_MASK);
|
||||
atomic_set(&kbdev->csf.scheduler.gpu_idle_timer_enabled, false);
|
||||
atomic_set(&kbdev->csf.scheduler.fw_soi_enabled, false);
|
||||
|
||||
kbase_csf_firmware_trigger_reload(kbdev);
|
||||
backend->mcu_state = KBASE_MCU_PEND_ON_RELOAD;
|
||||
}
|
||||
|
|
@ -1005,7 +1007,6 @@ static int kbase_pm_mcu_update_state(struct kbase_device *kbdev)
|
|||
|
||||
case KBASE_MCU_ON:
|
||||
backend->shaders_desired_mask = kbase_pm_ca_get_core_mask(kbdev);
|
||||
|
||||
if (!kbase_pm_is_mcu_desired(kbdev))
|
||||
backend->mcu_state = KBASE_MCU_ON_HWCNT_DISABLE;
|
||||
else if (kbdev->csf.firmware_hctl_core_pwr) {
|
||||
|
|
@ -1185,7 +1186,7 @@ static int kbase_pm_mcu_update_state(struct kbase_device *kbdev)
|
|||
break;
|
||||
|
||||
case KBASE_MCU_POWER_DOWN:
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TITANHW_2922)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TITANHW_2922)) {
|
||||
if (!kbdev->csf.firmware_hctl_core_pwr)
|
||||
kbasep_pm_toggle_power_interrupt(kbdev, true);
|
||||
backend->mcu_state = KBASE_MCU_OFF;
|
||||
|
|
@ -1206,7 +1207,20 @@ static int kbase_pm_mcu_update_state(struct kbase_device *kbdev)
|
|||
#ifdef KBASE_PM_RUNTIME
|
||||
case KBASE_MCU_ON_SLEEP_INITIATE:
|
||||
if (!kbase_pm_is_mcu_desired(kbdev)) {
|
||||
kbase_csf_firmware_trigger_mcu_sleep(kbdev);
|
||||
bool db_notif_disabled = false;
|
||||
|
||||
if (likely(test_bit(KBASE_GPU_SUPPORTS_FW_SLEEP_ON_IDLE,
|
||||
&kbdev->pm.backend.gpu_sleep_allowed)))
|
||||
db_notif_disabled =
|
||||
kbase_reg_read32(kbdev,
|
||||
GPU_CONTROL_ENUM(MCU_CONTROL)) &
|
||||
MCU_CNTRL_DOORBELL_DISABLE_MASK;
|
||||
|
||||
/* If DB notification is enabled on FW side then send a sleep
|
||||
* request to FW.
|
||||
*/
|
||||
if (!db_notif_disabled)
|
||||
kbase_csf_firmware_trigger_mcu_sleep(kbdev);
|
||||
backend->mcu_state = KBASE_MCU_ON_PEND_SLEEP;
|
||||
} else
|
||||
backend->mcu_state = KBASE_MCU_ON_HWCNT_ENABLE;
|
||||
|
|
@ -1240,6 +1254,16 @@ static int kbase_pm_mcu_update_state(struct kbase_device *kbdev)
|
|||
case KBASE_MCU_IN_SLEEP:
|
||||
if (kbase_pm_is_mcu_desired(kbdev) && backend->l2_state == KBASE_L2_ON) {
|
||||
wait_mcu_as_inactive(kbdev);
|
||||
/* Ensure that FW would not go to sleep immediately after
|
||||
* resumption.
|
||||
*/
|
||||
kbase_csf_firmware_global_input_mask(&kbdev->csf.global_iface,
|
||||
GLB_REQ,
|
||||
GLB_REQ_REQ_IDLE_DISABLE,
|
||||
GLB_REQ_IDLE_DISABLE_MASK);
|
||||
atomic_set(&kbdev->csf.scheduler.gpu_idle_timer_enabled, false);
|
||||
atomic_set(&kbdev->csf.scheduler.fw_soi_enabled, false);
|
||||
|
||||
KBASE_TLSTREAM_TL_KBASE_CSFFW_FW_REQUEST_WAKEUP(
|
||||
kbdev, kbase_backend_get_cycle_cnt(kbdev));
|
||||
kbase_pm_enable_mcu_db_notification(kbdev);
|
||||
|
|
@ -1384,20 +1408,6 @@ static bool need_tiler_control(struct kbase_device *kbdev)
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* hctl_l2_power_down - Initiate power down of L2 cache
|
||||
*
|
||||
* @kbdev: The kbase device structure for the device.
|
||||
*
|
||||
* This function initiates the power down of L2 cache when Host controls the power
|
||||
* for Tiler block. The function expects that power down of Tiler to already have
|
||||
* been initiated and it triggers the L2 power down only after the power down for
|
||||
* Tiler is complete.
|
||||
* The function shall be called only if L2 is in ready state.
|
||||
*/
|
||||
static void hctl_l2_power_down(struct kbase_device *kbdev)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* hctl_tiler_power_up_done - Check and/or initiate power up of Tiler
|
||||
|
|
@ -1444,7 +1454,6 @@ static int kbase_pm_l2_update_state(struct kbase_device *kbdev)
|
|||
u64 l2_trans = kbase_pm_get_trans_cores(kbdev, KBASE_PM_CORE_L2);
|
||||
u64 l2_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_L2);
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
/*
|
||||
* kbase_pm_get_ready_cores and kbase_pm_get_trans_cores
|
||||
* are vulnerable to corruption if gpu is lost
|
||||
|
|
@ -1473,7 +1482,6 @@ static int kbase_pm_l2_update_state(struct kbase_device *kbdev)
|
|||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* mask off ready from trans in case transitions finished
|
||||
* between the register reads
|
||||
|
|
@ -1574,7 +1582,7 @@ static int kbase_pm_l2_update_state(struct kbase_device *kbdev)
|
|||
|
||||
case KBASE_L2_RESTORE_CLOCKS:
|
||||
/* We always assume only GPUs being affected by
|
||||
* BASE_HW_ISSUE_GPU2017_1336 fall into this state
|
||||
* KBASE_HW_ISSUE_GPU2017_1336 fall into this state
|
||||
*/
|
||||
WARN_ON_ONCE(!kbdev->pm.backend.gpu_clock_slow_down_wa);
|
||||
|
||||
|
|
@ -1676,7 +1684,7 @@ static int kbase_pm_l2_update_state(struct kbase_device *kbdev)
|
|||
|
||||
case KBASE_L2_SLOW_DOWN_CLOCKS:
|
||||
/* We always assume only GPUs being affected by
|
||||
* BASE_HW_ISSUE_GPU2017_1336 fall into this state
|
||||
* KBASE_HW_ISSUE_GPU2017_1336 fall into this state
|
||||
*/
|
||||
WARN_ON_ONCE(!kbdev->pm.backend.gpu_clock_slow_down_wa);
|
||||
|
||||
|
|
@ -1725,11 +1733,6 @@ static int kbase_pm_l2_update_state(struct kbase_device *kbdev)
|
|||
|
||||
case KBASE_L2_PEND_OFF:
|
||||
if (likely(!backend->l2_always_on)) {
|
||||
if (need_tiler_control(kbdev) && l2_ready) {
|
||||
hctl_l2_power_down(kbdev);
|
||||
break;
|
||||
}
|
||||
|
||||
if (l2_trans || l2_ready)
|
||||
break;
|
||||
} else if (kbdev->cache_clean_in_progress)
|
||||
|
|
@ -1744,11 +1747,10 @@ static int kbase_pm_l2_update_state(struct kbase_device *kbdev)
|
|||
}
|
||||
#endif
|
||||
/* Disabling MCU after L2 cache power down is to address
|
||||
* BASE_HW_ISSUE_TITANHW_2922 hardware issue.
|
||||
* KBASE_HW_ISSUE_TITANHW_2922 hardware issue.
|
||||
*/
|
||||
if (backend->l2_force_off_after_mcu_halt) {
|
||||
kbase_csf_firmware_disable_mcu(kbdev);
|
||||
kbase_csf_firmware_disable_mcu_wait(kbdev);
|
||||
kbase_csf_stop_firmware_and_wait(kbdev);
|
||||
WARN_ON_ONCE(backend->mcu_state != KBASE_MCU_OFF);
|
||||
backend->l2_force_off_after_mcu_halt = false;
|
||||
}
|
||||
|
|
@ -1895,12 +1897,7 @@ static int kbase_pm_shaders_update_state(struct kbase_device *kbdev)
|
|||
* kbase_pm_get_ready_cores and kbase_pm_get_trans_cores
|
||||
* are vulnerable to corruption if gpu is lost
|
||||
*/
|
||||
if (kbase_is_gpu_removed(kbdev)
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
|| kbase_pm_is_gpu_lost(kbdev)) {
|
||||
#else
|
||||
) {
|
||||
#endif
|
||||
if (kbase_is_gpu_removed(kbdev) || kbase_pm_is_gpu_lost(kbdev)) {
|
||||
backend->shaders_state = KBASE_SHADERS_OFF_CORESTACK_OFF;
|
||||
dev_dbg(kbdev->dev, "GPU lost has occurred - shaders off\n");
|
||||
break;
|
||||
|
|
@ -2005,9 +2002,8 @@ static int kbase_pm_shaders_update_state(struct kbase_device *kbdev)
|
|||
kbdev, KBASE_PM_POLICY_EVENT_IDLE);
|
||||
|
||||
if (kbdev->pm.backend.protected_transition_override ||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
kbase_pm_is_suspending(kbdev) || kbase_pm_is_gpu_lost(kbdev) ||
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
(kbase_has_arbiter(kbdev) && (kbase_pm_is_suspending(kbdev) ||
|
||||
kbase_pm_is_gpu_lost(kbdev))) ||
|
||||
!stt->configured_ticks || WARN_ON(stt->cancel_queued)) {
|
||||
backend->shaders_state =
|
||||
KBASE_SHADERS_WAIT_FINISHED_CORESTACK_ON;
|
||||
|
|
@ -2074,10 +2070,9 @@ static int kbase_pm_shaders_update_state(struct kbase_device *kbdev)
|
|||
kbdev, KBASE_PM_POLICY_EVENT_TIMER_MISS);
|
||||
|
||||
backend->shaders_state = KBASE_SHADERS_WAIT_FINISHED_CORESTACK_ON;
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
} else if (kbase_pm_is_suspending(kbdev) || kbase_pm_is_gpu_lost(kbdev)) {
|
||||
} else if (kbase_has_arbiter(kbdev) &&
|
||||
(kbase_pm_is_suspending(kbdev) || kbase_pm_is_gpu_lost(kbdev))) {
|
||||
backend->shaders_state = KBASE_SHADERS_WAIT_FINISHED_CORESTACK_ON;
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -2096,7 +2091,7 @@ static int kbase_pm_shaders_update_state(struct kbase_device *kbdev)
|
|||
if (!backend->partial_shaderoff)
|
||||
shader_poweroff_timer_queue_cancel(kbdev);
|
||||
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TTRX_921)) {
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TTRX_921)) {
|
||||
kbase_gpu_start_cache_clean_nolock(kbdev,
|
||||
GPU_COMMAND_CACHE_CLN_INV_L2);
|
||||
backend->shaders_state = KBASE_SHADERS_L2_FLUSHING_CORESTACK_ON;
|
||||
|
|
@ -2446,6 +2441,9 @@ void kbase_pm_reset_complete(struct kbase_device *kbdev)
|
|||
backend->in_reset = false;
|
||||
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
|
||||
backend->gpu_wakeup_override = false;
|
||||
backend->db_mirror_interrupt_enabled = false;
|
||||
backend->gpu_sleep_mode_active = false;
|
||||
backend->exit_gpu_sleep_mode = false;
|
||||
#endif
|
||||
kbase_pm_update_state(kbdev);
|
||||
|
||||
|
|
@ -2670,12 +2668,9 @@ static int pm_wait_for_poweroff_work_complete(struct kbase_device *kbdev, bool k
|
|||
const long timeout = kbase_csf_timeout_in_jiffies(
|
||||
kbase_get_timeout_ms(kbdev, CSF_PM_TIMEOUT) + extra_wait_time_ms);
|
||||
#else
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
/* Handling of timeout error isn't supported for arbiter builds */
|
||||
const long timeout = MAX_SCHEDULE_TIMEOUT;
|
||||
#else
|
||||
const long timeout = (long)msecs_to_jiffies(PM_TIMEOUT_MS);
|
||||
#endif
|
||||
const long timeout = kbase_has_arbiter(kbdev) ? MAX_SCHEDULE_TIMEOUT :
|
||||
(long)msecs_to_jiffies(PM_TIMEOUT_MS);
|
||||
#endif
|
||||
int err = 0;
|
||||
|
||||
|
|
@ -2796,7 +2791,8 @@ static void update_user_reg_page_mapping(struct kbase_device *kbdev)
|
|||
* when the context (user process) needs to access to the page.
|
||||
*/
|
||||
unmap_mapping_range(kbdev->csf.user_reg.filp->f_inode->i_mapping,
|
||||
kctx->csf.user_reg.file_offset << PAGE_SHIFT, PAGE_SIZE, 1);
|
||||
(loff_t)kctx->csf.user_reg.file_offset << PAGE_SHIFT, PAGE_SIZE,
|
||||
1);
|
||||
list_del_init(&kctx->csf.user_reg.link);
|
||||
dev_dbg(kbdev->dev, "Updated USER Reg page mapping of ctx %d_%d", kctx->tgid,
|
||||
kctx->id);
|
||||
|
|
@ -2823,12 +2819,10 @@ void kbase_pm_clock_on(struct kbase_device *kbdev, bool is_resume)
|
|||
#endif /* !MALI_USE_CSF */
|
||||
lockdep_assert_held(&kbdev->pm.lock);
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (WARN_ON(kbase_pm_is_gpu_lost(kbdev))) {
|
||||
dev_err(kbdev->dev, "%s: Cannot power up while GPU lost", __func__);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (backend->gpu_powered) {
|
||||
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
|
||||
|
|
@ -2876,10 +2870,8 @@ void kbase_pm_clock_on(struct kbase_device *kbdev, bool is_resume)
|
|||
* consistent state
|
||||
*/
|
||||
kbase_pm_init_hw(kbdev, PM_ENABLE_IRQS);
|
||||
}
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
else {
|
||||
if (kbdev->arb.arb_if) {
|
||||
} else {
|
||||
if (kbase_has_arbiter(kbdev)) {
|
||||
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
|
||||
|
||||
/* In the case that the GPU has just been granted by
|
||||
|
|
@ -2895,8 +2887,8 @@ void kbase_pm_clock_on(struct kbase_device *kbdev, bool is_resume)
|
|||
* that a repartitioning occurred. In this case the current config
|
||||
* should be read again.
|
||||
*/
|
||||
kbase_gpuprops_get_curr_config_props(kbdev, &kbdev->gpu_props.curr_config);
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
if (kbase_has_arbiter(kbdev))
|
||||
kbase_gpuprops_get_curr_config_props(kbdev, &kbdev->gpu_props.curr_config);
|
||||
|
||||
mutex_lock(&kbdev->mmu_hw_mutex);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
|
@ -2988,12 +2980,7 @@ bool kbase_pm_clock_off(struct kbase_device *kbdev)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (kbase_is_gpu_removed(kbdev)
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
|| kbase_pm_is_gpu_lost(kbdev)) {
|
||||
#else
|
||||
) {
|
||||
#endif
|
||||
if (kbase_is_gpu_removed(kbdev) || kbase_pm_is_gpu_lost(kbdev)) {
|
||||
/* Ensure we unblock any threads that are stuck waiting
|
||||
* for the GPU
|
||||
*/
|
||||
|
|
@ -3011,10 +2998,7 @@ bool kbase_pm_clock_off(struct kbase_device *kbdev)
|
|||
/* GPU is about to be turned off, switch to dummy page */
|
||||
update_user_reg_page_mapping(kbdev);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_IDLE_EVENT);
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
|
||||
if (kbdev->pm.backend.callback_power_off)
|
||||
kbdev->pm.backend.callback_power_off(kbdev);
|
||||
|
|
@ -3068,6 +3052,7 @@ static enum hrtimer_restart kbasep_reset_timeout(struct hrtimer *timer)
|
|||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
|
||||
static int kbase_set_gpu_quirks(struct kbase_device *kbdev)
|
||||
{
|
||||
#if MALI_USE_CSF
|
||||
|
|
@ -3097,7 +3082,7 @@ static int kbase_set_gpu_quirks(struct kbase_device *kbdev)
|
|||
kbdev->hw_quirks_gpu = hw_quirks_gpu;
|
||||
|
||||
#endif /* !MALI_USE_CSF */
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_IDVS_GROUP_SIZE)) {
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_IDVS_GROUP_SIZE)) {
|
||||
u32 default_idvs_group_size = 0xF;
|
||||
u32 group_size = 0;
|
||||
|
||||
|
|
@ -3131,10 +3116,10 @@ static int kbase_set_sc_quirks(struct kbase_device *kbdev)
|
|||
if (kbase_is_gpu_removed(kbdev))
|
||||
return -EIO;
|
||||
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TTRX_2968_TTRX_3162))
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162))
|
||||
hw_quirks_sc |= SC_VAR_ALGORITHM;
|
||||
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_TLS_HASHING))
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_TLS_HASHING))
|
||||
hw_quirks_sc |= SC_TLS_HASH_ENABLE;
|
||||
|
||||
kbdev->hw_quirks_sc = hw_quirks_sc;
|
||||
|
|
@ -3153,7 +3138,7 @@ static int kbase_set_tiler_quirks(struct kbase_device *kbdev)
|
|||
return -EIO;
|
||||
|
||||
/* Set tiler clock gate override if required */
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_T76X_3953))
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_T76X_3953))
|
||||
hw_quirks_tiler |= TC_CLOCK_GATE_OVERRIDE;
|
||||
|
||||
kbdev->hw_quirks_tiler = hw_quirks_tiler;
|
||||
|
|
@ -3370,9 +3355,8 @@ static int kbase_pm_do_reset(struct kbase_device *kbdev)
|
|||
/* The GPU doesn't seem to be responding to the reset so try a hard
|
||||
* reset, but only when NOT in arbitration mode.
|
||||
*/
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (!kbdev->arb.arb_if) {
|
||||
#endif
|
||||
|
||||
if (!kbase_has_arbiter(kbdev)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Failed to soft-reset GPU (timed out after %d ms), now attempting a hard reset\n",
|
||||
RESET_TIMEOUT);
|
||||
|
|
@ -3402,9 +3386,7 @@ static int kbase_pm_do_reset(struct kbase_device *kbdev)
|
|||
|
||||
dev_err(kbdev->dev, "Failed to hard-reset the GPU (timed out after %d ms)\n",
|
||||
RESET_TIMEOUT);
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
}
|
||||
#endif
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -3487,6 +3469,7 @@ int kbase_pm_init_hw(struct kbase_device *kbdev, unsigned int flags)
|
|||
kbase_amba_set_shareable_cache_support(kbdev);
|
||||
#if MALI_USE_CSF
|
||||
kbase_backend_update_gpu_timestamp_offset(kbdev);
|
||||
kbdev->csf.compute_progress_timeout_cc = 0;
|
||||
#endif
|
||||
|
||||
/* Sanity check protected mode was left after reset */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2010-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -821,6 +821,21 @@ bool kbase_pm_is_mcu_desired(struct kbase_device *kbdev);
|
|||
*/
|
||||
bool kbase_pm_is_mcu_inactive(struct kbase_device *kbdev, enum kbase_mcu_state state);
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
|
||||
/**
|
||||
* kbase_pm_enable_mcu_db_notification - Enable the Doorbell notification on
|
||||
* MCU side
|
||||
*
|
||||
* @kbdev: Pointer to the device.
|
||||
*
|
||||
* This function is called to re-enable the Doorbell notification on MCU side
|
||||
* when MCU needs to beome active again.
|
||||
*/
|
||||
void kbase_pm_enable_mcu_db_notification(struct kbase_device *kbdev);
|
||||
|
||||
#endif /* KBASE_PM_RUNTIME */
|
||||
|
||||
/**
|
||||
* kbase_pm_idle_groups_sched_suspendable - Check whether the scheduler can be
|
||||
* suspended to low power state when all
|
||||
|
|
@ -963,11 +978,29 @@ static inline bool kbase_pm_gpu_sleep_allowed(struct kbase_device *kbdev)
|
|||
* A high positive value of autosuspend_delay can be used to keep the
|
||||
* GPU in sleep state for a long time.
|
||||
*/
|
||||
if (unlikely(!kbdev->dev->power.autosuspend_delay ||
|
||||
(kbdev->dev->power.autosuspend_delay < 0)))
|
||||
if (unlikely(kbdev->dev->power.autosuspend_delay <= 0))
|
||||
return false;
|
||||
|
||||
return kbdev->pm.backend.gpu_sleep_supported;
|
||||
return test_bit(KBASE_GPU_SUPPORTS_GPU_SLEEP, &kbdev->pm.backend.gpu_sleep_allowed);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_pm_fw_sleep_on_idle_allowed - Check if FW sleep-on-idle could be enabled
|
||||
*
|
||||
* @kbdev: Device pointer
|
||||
*
|
||||
* This function should be called whenever the conditions that impact
|
||||
* FW sleep-on-idle support change so that it could be enabled/disabled
|
||||
* accordingly.
|
||||
*
|
||||
* Return: true if FW sleep-on-idle is allowed
|
||||
*/
|
||||
static inline bool kbase_pm_fw_sleep_on_idle_allowed(struct kbase_device *kbdev)
|
||||
{
|
||||
if (unlikely(kbdev->dev->power.autosuspend_delay <= 0))
|
||||
return false;
|
||||
|
||||
return kbdev->pm.backend.gpu_sleep_allowed == KBASE_GPU_FW_SLEEP_ON_IDLE_ALLOWED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -77,7 +77,16 @@ void kbase_pm_policy_init(struct kbase_device *kbdev)
|
|||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
kbdev->pm.backend.pm_current_policy = default_policy;
|
||||
kbdev->pm.backend.csf_pm_sched_flags = default_policy->pm_sched_flags;
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
if (kbase_pm_idle_groups_sched_suspendable(kbdev))
|
||||
clear_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
|
||||
else
|
||||
set_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
|
||||
#endif /* KBASE_PM_RUNTIME */
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
#else
|
||||
CSTD_UNUSED(flags);
|
||||
kbdev->pm.backend.pm_current_policy = default_policy;
|
||||
|
|
@ -400,6 +409,13 @@ void kbase_pm_set_policy(struct kbase_device *kbdev, const struct kbase_pm_polic
|
|||
/* New policy in place, release the clamping on mcu/L2 off state */
|
||||
kbdev->pm.backend.policy_change_clamp_state_to_off = false;
|
||||
kbase_pm_update_state(kbdev);
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
if (kbase_pm_idle_groups_sched_suspendable(kbdev))
|
||||
clear_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
|
||||
else
|
||||
set_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
|
||||
#endif /* KBASE_PM_RUNTIME */
|
||||
#endif
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ static struct kbase_timeout_info timeout_info[KBASE_TIMEOUT_SELECTOR_COUNT] = {
|
|||
CSF_FIRMWARE_PING_TIMEOUT_CYCLES) },
|
||||
[CSF_PM_TIMEOUT] = { "CSF_PM_TIMEOUT", CSF_PM_TIMEOUT_CYCLES },
|
||||
[CSF_GPU_RESET_TIMEOUT] = { "CSF_GPU_RESET_TIMEOUT", CSF_GPU_RESET_TIMEOUT_CYCLES },
|
||||
[CSF_CSG_SUSPEND_TIMEOUT] = { "CSF_CSG_SUSPEND_TIMEOUT", CSF_CSG_SUSPEND_TIMEOUT_CYCLES },
|
||||
[CSF_CSG_TERM_TIMEOUT] = { "CSF_CSG_TERM_TIMEOUT", CSF_CSG_TERM_TIMEOUT_CYCLES },
|
||||
[CSF_FIRMWARE_BOOT_TIMEOUT] = { "CSF_FIRMWARE_BOOT_TIMEOUT",
|
||||
CSF_FIRMWARE_BOOT_TIMEOUT_CYCLES },
|
||||
|
|
@ -236,6 +235,15 @@ void kbase_device_set_timeout_ms(struct kbase_device *kbdev, enum kbase_timeout_
|
|||
}
|
||||
selector_str = timeout_info[selector].selector_str;
|
||||
|
||||
#if MALI_USE_CSF
|
||||
if (IS_ENABLED(CONFIG_MALI_REAL_HW) && !IS_ENABLED(CONFIG_MALI_IS_FPGA) &&
|
||||
unlikely(timeout_ms >= MAX_TIMEOUT_MS)) {
|
||||
dev_warn(kbdev->dev, "%s is capped from %dms to %dms\n",
|
||||
timeout_info[selector].selector_str, timeout_ms, MAX_TIMEOUT_MS);
|
||||
timeout_ms = MAX_TIMEOUT_MS;
|
||||
}
|
||||
#endif
|
||||
|
||||
kbdev->backend_time.device_scaled_timeouts[selector] = timeout_ms;
|
||||
dev_dbg(kbdev->dev, "\t%-35s: %ums\n", selector_str, timeout_ms);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ bob_defaults {
|
|||
mali_hw_errata_1485982_use_clock_alternative: {
|
||||
kbuild_options: ["CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE=y"],
|
||||
},
|
||||
platform_is_fpga: {
|
||||
mali_is_fpga: {
|
||||
kbuild_options: ["CONFIG_MALI_IS_FPGA=y"],
|
||||
},
|
||||
mali_coresight: {
|
||||
|
|
@ -148,7 +148,6 @@ bob_defaults {
|
|||
// is an umbrella feature that would be open for inappropriate use
|
||||
// (catch-all for experimental CS code without separating it into
|
||||
// different features).
|
||||
"MALI_INCREMENTAL_RENDERING_JM={{.incremental_rendering_jm}}",
|
||||
"MALI_BASE_CSF_PERFORMANCE_TESTS={{.base_csf_performance_tests}}",
|
||||
],
|
||||
}
|
||||
|
|
@ -162,6 +161,9 @@ bob_kernel_module {
|
|||
"*.c",
|
||||
"*.h",
|
||||
"Kbuild",
|
||||
"arbiter/*.c",
|
||||
"arbiter/*.h",
|
||||
"arbiter/Kbuild",
|
||||
"backend/gpu/*.c",
|
||||
"backend/gpu/*.h",
|
||||
"backend/gpu/Kbuild",
|
||||
|
|
@ -257,13 +259,6 @@ bob_kernel_module {
|
|||
"ipa/backend/*_csf.h",
|
||||
],
|
||||
},
|
||||
mali_arbiter_support: {
|
||||
srcs: [
|
||||
"arbiter/*.c",
|
||||
"arbiter/*.h",
|
||||
"arbiter/Kbuild",
|
||||
],
|
||||
},
|
||||
kbuild_options: [
|
||||
"CONFIG_MALI_BIFROST=m",
|
||||
"CONFIG_MALI_KUTF=n",
|
||||
|
|
|
|||
|
|
@ -186,17 +186,15 @@ void kbase_destroy_context(struct kbase_context *kctx)
|
|||
* Customer side that a hang could occur if context termination is
|
||||
* not blocked until the resume of GPU device.
|
||||
*/
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
atomic_inc(&kbdev->pm.gpu_users_waiting);
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
if (kbase_has_arbiter(kbdev))
|
||||
atomic_inc(&kbdev->pm.gpu_users_waiting);
|
||||
while (kbase_pm_context_active_handle_suspend(kbdev,
|
||||
KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE)) {
|
||||
dev_dbg(kbdev->dev, "Suspend in progress when destroying context");
|
||||
wait_event(kbdev->pm.resume_wait, !kbase_pm_is_suspending(kbdev));
|
||||
}
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
atomic_dec(&kbdev->pm.gpu_users_waiting);
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
if (kbase_has_arbiter(kbdev))
|
||||
atomic_dec(&kbdev->pm.gpu_users_waiting);
|
||||
|
||||
/* Have synchronized against the System suspend and incremented the
|
||||
* pm.active_count. So any subsequent invocation of System suspend
|
||||
|
|
|
|||
|
|
@ -231,14 +231,13 @@ void kbase_destroy_context(struct kbase_context *kctx)
|
|||
if (WARN_ON(!kbdev))
|
||||
return;
|
||||
|
||||
/* Context termination could happen whilst the system suspend of
|
||||
/* Context termination could happen whilst the system suspend of
|
||||
* the GPU device is ongoing or has completed. It has been seen on
|
||||
* Customer side that a hang could occur if context termination is
|
||||
* not blocked until the resume of GPU device.
|
||||
*/
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
atomic_inc(&kbdev->pm.gpu_users_waiting);
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
if (kbase_has_arbiter(kbdev))
|
||||
atomic_inc(&kbdev->pm.gpu_users_waiting);
|
||||
while (kbase_pm_context_active_handle_suspend(kbdev,
|
||||
KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE)) {
|
||||
dev_dbg(kbdev->dev, "Suspend in progress when destroying context");
|
||||
|
|
@ -255,9 +254,8 @@ void kbase_destroy_context(struct kbase_context *kctx)
|
|||
*/
|
||||
wait_event(kbdev->pm.resume_wait, !kbase_pm_is_resuming(kbdev));
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
atomic_dec(&kbdev->pm.gpu_users_waiting);
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
if (kbase_has_arbiter(kbdev))
|
||||
atomic_dec(&kbdev->pm.gpu_users_waiting);
|
||||
|
||||
kbase_mem_pool_group_mark_dying(&kctx->mem_pools);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2018-2023 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
|
||||
#
|
||||
# This program is free software and is provided to you under the terms of the
|
||||
# GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -48,8 +48,10 @@ bifrost_kbase-y += \
|
|||
|
||||
ifeq ($(CONFIG_MALI_BIFROST_NO_MALI),y)
|
||||
bifrost_kbase-y += csf/mali_kbase_csf_firmware_no_mali.o
|
||||
bifrost_kbase-y += csf/mali_kbase_csf_fw_io_no_mali.o
|
||||
else
|
||||
bifrost_kbase-y += csf/mali_kbase_csf_firmware.o
|
||||
bifrost_kbase-y += csf/mali_kbase_csf_fw_io.o
|
||||
endif
|
||||
|
||||
bifrost_kbase-$(CONFIG_DEBUG_FS) += csf/mali_kbase_debug_csf_fault.o
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2020-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -943,6 +943,8 @@ void kbase_ipa_control_protm_entered(struct kbase_device *kbdev)
|
|||
struct kbase_ipa_control *ipa_ctrl = &kbdev->csf.ipa_control;
|
||||
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
|
||||
ipa_ctrl->protm_start = ktime_get_raw_ns();
|
||||
}
|
||||
|
||||
|
|
@ -955,6 +957,7 @@ void kbase_ipa_control_protm_exited(struct kbase_device *kbdev)
|
|||
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
|
||||
for (i = 0; i < KBASE_IPA_CONTROL_MAX_SESSIONS; i++) {
|
||||
struct kbase_ipa_control_session *session = &ipa_ctrl->sessions[i];
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@
|
|||
#define CS_RING_BUFFER_MAX_SIZE ((uint32_t)(1 << 31)) /* 2GiB */
|
||||
#define CS_RING_BUFFER_MIN_SIZE ((uint32_t)4096)
|
||||
|
||||
/* 0.2 second assuming 600 MHz GPU clock, which is double of iterator disabling timeout */
|
||||
#define MAX_PROGRESS_TIMEOUT_EVENT_DELAY ((u32)120000000)
|
||||
|
||||
#define PROTM_ALLOC_MAX_RETRIES ((u8)5)
|
||||
|
||||
const u8 kbasep_csf_queue_group_priority_to_relative[BASE_QUEUE_GROUP_PRIORITY_COUNT] = {
|
||||
|
|
@ -1261,6 +1264,7 @@ static int create_queue_group(struct kbase_context *const kctx,
|
|||
INIT_LIST_HEAD(&group->error_fatal.link);
|
||||
INIT_WORK(&group->timer_event_work, timer_event_worker);
|
||||
INIT_LIST_HEAD(&group->protm_event_work);
|
||||
group->progress_timer_state = 0;
|
||||
atomic_set(&group->pending_protm_event_work, 0);
|
||||
bitmap_zero(group->protm_pending_bitmap, MAX_SUPPORTED_STREAMS_PER_GROUP);
|
||||
|
||||
|
|
@ -1306,12 +1310,6 @@ int kbase_csf_queue_group_create(struct kbase_context *const kctx,
|
|||
const u32 tiler_count = hweight64(create->in.tiler_mask);
|
||||
const u32 fragment_count = hweight64(create->in.fragment_mask);
|
||||
const u32 compute_count = hweight64(create->in.compute_mask);
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(create->in.padding); i++) {
|
||||
if (create->in.padding[i] != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&kctx->csf.lock);
|
||||
|
||||
|
|
@ -2178,19 +2176,74 @@ static void timer_event_worker(struct work_struct *data)
|
|||
}
|
||||
|
||||
/**
|
||||
* handle_progress_timer_event() - Progress timer timeout event handler.
|
||||
* handle_progress_timer_events() - Progress timer timeout events handler.
|
||||
*
|
||||
* @group: Pointer to GPU queue group for which the timeout event is received.
|
||||
* @kbdev: Instance of a GPU platform device that implements a CSF interface.
|
||||
* @slot_mask: Bitmap reflecting the slots on which progress timer timeouts happen.
|
||||
*
|
||||
* Notify a waiting user space client of the timeout.
|
||||
* Enqueue a work item to terminate the group and notify the event notification
|
||||
* thread of progress timeout fault for the GPU command queue group.
|
||||
* Ignore fragment timeout if it is following a compute timeout.
|
||||
*/
|
||||
static void handle_progress_timer_event(struct kbase_queue_group *const group)
|
||||
static void handle_progress_timer_events(struct kbase_device *const kbdev, unsigned long *slot_mask)
|
||||
{
|
||||
kbase_debug_csf_fault_notify(group->kctx->kbdev, group->kctx, DF_PROGRESS_TIMER_TIMEOUT);
|
||||
u32 max_csg_slots = kbdev->csf.global_iface.group_num;
|
||||
u32 csg_nr;
|
||||
struct kbase_queue_group *group = NULL;
|
||||
struct kbase_csf_cmd_stream_group_info *ginfo;
|
||||
|
||||
queue_work(group->kctx->csf.wq, &group->timer_event_work);
|
||||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
if (likely(bitmap_empty(slot_mask, MAX_SUPPORTED_CSGS)))
|
||||
return;
|
||||
|
||||
/* Log each timeout and Update timestamp of compute progress timeout */
|
||||
for_each_set_bit(csg_nr, slot_mask, max_csg_slots) {
|
||||
group = kbdev->csf.scheduler.csg_slots[csg_nr].resident_group;
|
||||
ginfo = &kbdev->csf.global_iface.groups[csg_nr];
|
||||
group->progress_timer_state =
|
||||
kbase_csf_firmware_csg_output(ginfo, CSG_PROGRESS_TIMER_STATE);
|
||||
|
||||
dev_info(
|
||||
kbdev->dev,
|
||||
"[%llu] Iterator PROGRESS_TIMER timeout notification received for group %u of ctx %d_%d on slot %u with state %x",
|
||||
kbase_backend_get_cycle_cnt(kbdev), group->handle, group->kctx->tgid,
|
||||
group->kctx->id, csg_nr, group->progress_timer_state);
|
||||
|
||||
if (CSG_PROGRESS_TIMER_STATE_GET(group->progress_timer_state) ==
|
||||
CSG_PROGRESS_TIMER_STATE_COMPUTE)
|
||||
kbdev->csf.compute_progress_timeout_cc = kbase_backend_get_cycle_cnt(kbdev);
|
||||
}
|
||||
|
||||
/* Ignore fragment timeout if it is following a compute timeout.
|
||||
* Otherwise, terminate the command stream group.
|
||||
*/
|
||||
for_each_set_bit(csg_nr, slot_mask, max_csg_slots) {
|
||||
group = kbdev->csf.scheduler.csg_slots[csg_nr].resident_group;
|
||||
|
||||
/* Check if it is a fragment timeout right after another compute timeout.
|
||||
* In such case, kill compute CSG and give fragment CSG a second chance
|
||||
*/
|
||||
if (CSG_PROGRESS_TIMER_STATE_GET(group->progress_timer_state) ==
|
||||
CSG_PROGRESS_TIMER_STATE_FRAGMENT) {
|
||||
u64 cycle_counter = kbase_backend_get_cycle_cnt(kbdev);
|
||||
u64 compute_progress_timeout_cc = kbdev->csf.compute_progress_timeout_cc;
|
||||
|
||||
if (compute_progress_timeout_cc <= cycle_counter &&
|
||||
cycle_counter <= compute_progress_timeout_cc +
|
||||
MAX_PROGRESS_TIMEOUT_EVENT_DELAY) {
|
||||
dev_info(
|
||||
kbdev->dev,
|
||||
"Ignored Fragment iterator timeout for group %d on slot %d",
|
||||
group->handle, group->csg_nr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
kbase_debug_csf_fault_notify(group->kctx->kbdev, group->kctx,
|
||||
DF_PROGRESS_TIMER_TIMEOUT);
|
||||
queue_work(group->kctx->csf.wq, &group->timer_event_work);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2291,14 +2344,14 @@ static void handle_fault_event(struct kbase_queue *const queue, const u32 cs_ack
|
|||
const u8 cs_fault_exception_type = CS_FAULT_EXCEPTION_TYPE_GET(cs_fault);
|
||||
const u32 cs_fault_exception_data = CS_FAULT_EXCEPTION_DATA_GET(cs_fault);
|
||||
const u64 cs_fault_info_exception_data = CS_FAULT_INFO_EXCEPTION_DATA_GET(cs_fault_info);
|
||||
bool use_old_log_format = true;
|
||||
bool has_trace_info = false;
|
||||
bool skip_fault_report = kbase_ctx_flag(queue->kctx, KCTX_PAGE_FAULT_REPORT_SKIP);
|
||||
|
||||
|
||||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
|
||||
|
||||
if (use_old_log_format && !skip_fault_report)
|
||||
if (!has_trace_info && !skip_fault_report)
|
||||
dev_warn(kbdev->dev,
|
||||
"Ctx %d_%d Group %d CSG %d CSI: %d\n"
|
||||
"CS_FAULT.EXCEPTION_TYPE: 0x%x (%s)\n"
|
||||
|
|
@ -2478,13 +2531,13 @@ static void handle_fatal_event(struct kbase_queue *const queue,
|
|||
const u32 cs_fatal_exception_type = CS_FATAL_EXCEPTION_TYPE_GET(cs_fatal);
|
||||
const u32 cs_fatal_exception_data = CS_FATAL_EXCEPTION_DATA_GET(cs_fatal);
|
||||
const u64 cs_fatal_info_exception_data = CS_FATAL_INFO_EXCEPTION_DATA_GET(cs_fatal_info);
|
||||
bool use_old_log_format = true;
|
||||
bool has_trace_info = false;
|
||||
bool skip_fault_report = kbase_ctx_flag(queue->kctx, KCTX_PAGE_FAULT_REPORT_SKIP);
|
||||
|
||||
|
||||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
|
||||
if (use_old_log_format && !skip_fault_report)
|
||||
if (!has_trace_info && !skip_fault_report)
|
||||
dev_warn(kbdev->dev,
|
||||
"Ctx %d_%d Group %d CSG %d CSI: %d\n"
|
||||
"CS_FATAL.EXCEPTION_TYPE: 0x%x (%s)\n"
|
||||
|
|
@ -2649,6 +2702,8 @@ static void process_cs_interrupts(struct kbase_queue_group *const group,
|
|||
* @csg_nr: CSG number.
|
||||
* @track: Pointer that tracks the highest idle CSG and the newly possible viable
|
||||
* protected mode requesting group, in current IRQ context.
|
||||
* @progress_timeout_slot_mask: slot mask to indicate on which slot progress timeout
|
||||
* happens.
|
||||
*
|
||||
* Handles interrupts for a CSG and for CSs within it.
|
||||
*
|
||||
|
|
@ -2660,7 +2715,8 @@ static void process_cs_interrupts(struct kbase_queue_group *const group,
|
|||
* See process_cs_interrupts() for details of per-stream interrupt handling.
|
||||
*/
|
||||
static void process_csg_interrupts(struct kbase_device *const kbdev, u32 const csg_nr,
|
||||
struct irq_idle_and_protm_track *track)
|
||||
struct irq_idle_and_protm_track *track,
|
||||
unsigned long *progress_timeout_slot_mask)
|
||||
{
|
||||
struct kbase_csf_cmd_stream_group_info *ginfo;
|
||||
struct kbase_queue_group *group = NULL;
|
||||
|
|
@ -2747,13 +2803,9 @@ static void process_csg_interrupts(struct kbase_device *const kbdev, u32 const c
|
|||
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_INTERRUPT_PROGRESS_TIMER_EVENT, group,
|
||||
req ^ ack);
|
||||
dev_info(
|
||||
kbdev->dev,
|
||||
"[%llu] Iterator PROGRESS_TIMER timeout notification received for group %u of ctx %d_%d on slot %u\n",
|
||||
kbase_backend_get_cycle_cnt(kbdev), group->handle, group->kctx->tgid,
|
||||
group->kctx->id, csg_nr);
|
||||
|
||||
handle_progress_timer_event(group);
|
||||
set_bit(csg_nr, progress_timeout_slot_mask);
|
||||
|
||||
}
|
||||
|
||||
process_cs_interrupts(group, ginfo, irqreq, irqack, track);
|
||||
|
|
@ -2863,6 +2915,7 @@ static inline void check_protm_enter_req_complete(struct kbase_device *kbdev, u3
|
|||
dev_dbg(kbdev->dev, "Protected mode entry interrupt received");
|
||||
|
||||
kbdev->protected_mode = true;
|
||||
|
||||
kbase_ipa_protection_mode_switch_event(kbdev);
|
||||
kbase_ipa_control_protm_entered(kbdev);
|
||||
kbase_hwcnt_backend_csf_protm_entered(&kbdev->hwcnt_gpu_iface);
|
||||
|
|
@ -3047,18 +3100,25 @@ void kbase_csf_interrupt(struct kbase_device *kbdev, u32 val)
|
|||
struct irq_idle_and_protm_track track = { .protm_grp = NULL,
|
||||
.idle_seq = U32_MAX,
|
||||
.idle_slot = S8_MAX };
|
||||
DECLARE_BITMAP(progress_timeout_csgs, MAX_SUPPORTED_CSGS) = { 0 };
|
||||
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags);
|
||||
/* Looping through and track the highest idle and protm groups */
|
||||
/* Looping through and track the highest idle and protm groups.
|
||||
* Also track the groups for which progress timer timeout happened.
|
||||
*/
|
||||
while (csg_interrupts != 0) {
|
||||
u32 const csg_nr = (u32)ffs((int)csg_interrupts) - 1;
|
||||
|
||||
process_csg_interrupts(kbdev, csg_nr, &track);
|
||||
process_csg_interrupts(kbdev, csg_nr, &track,
|
||||
progress_timeout_csgs);
|
||||
csg_interrupts &= ~(1U << csg_nr);
|
||||
}
|
||||
|
||||
/* Handle protm from the tracked information */
|
||||
process_tracked_info_for_protm(kbdev, &track);
|
||||
/* Handle pending progress timeout(s) */
|
||||
handle_progress_timer_events(kbdev, progress_timeout_csgs);
|
||||
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
}
|
||||
|
||||
|
|
@ -3087,11 +3147,28 @@ void kbase_csf_interrupt(struct kbase_device *kbdev, u32 val)
|
|||
|
||||
/* Handle IDLE Hysteresis notification event */
|
||||
if ((glb_req ^ glb_ack) & GLB_REQ_IDLE_EVENT_MASK) {
|
||||
u32 const glb_idle_timer_cfg =
|
||||
kbase_csf_firmware_global_input_read(
|
||||
global_iface, GLB_IDLE_TIMER_CONFIG);
|
||||
|
||||
dev_dbg(kbdev->dev, "Idle-hysteresis event flagged");
|
||||
kbase_csf_firmware_global_input_mask(
|
||||
global_iface, GLB_REQ, glb_ack,
|
||||
GLB_REQ_IDLE_EVENT_MASK);
|
||||
|
||||
if (glb_idle_timer_cfg &
|
||||
GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_MASK) {
|
||||
/* The FW is going to sleep, we shall:
|
||||
* - Enable fast GPU idle handling to avoid
|
||||
* confirming CSGs status in gpu_idle_worker().
|
||||
* - Enable doorbell mirroring to minimise the
|
||||
* chance of KBase raising kernel doorbells which
|
||||
* would cause the FW to be woken up.
|
||||
*/
|
||||
kbdev->csf.scheduler.fast_gpu_idle_handling = true;
|
||||
kbase_pm_enable_db_mirror_interrupt(kbdev);
|
||||
}
|
||||
|
||||
glb_idle_irq_received = true;
|
||||
/* Defer handling this IRQ to account for a race condition
|
||||
* where the idle worker could be executed before we have
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -28,6 +28,8 @@
|
|||
#include <mali_kbase.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/version_compat_defs.h>
|
||||
#include <mali_kbase_reset_gpu.h>
|
||||
#include <mali_kbase_config_defaults.h>
|
||||
|
||||
#define MAX_SCHED_STATE_STRING_LEN (16)
|
||||
/**
|
||||
|
|
@ -268,6 +270,87 @@ static const struct file_operations kbasep_csf_debugfs_scheduler_state_fops = {
|
|||
.open = simple_open,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
static int kbasep_csf_debugfs_eviction_timeout_get(void *data, u64 *val)
|
||||
{
|
||||
struct kbase_device *const kbdev = data;
|
||||
unsigned long flags;
|
||||
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags);
|
||||
*val = kbdev->csf.csg_suspend_timeout_ms - CSG_SUSPEND_TIMEOUT_HOST_ADDED_MS;
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kbasep_csf_debugfs_eviction_timeout_set(void *data, u64 val)
|
||||
{
|
||||
struct kbase_device *const kbdev = data;
|
||||
unsigned long flags_schd, flags_hw;
|
||||
u64 dur_ms = val;
|
||||
int ret = 0;
|
||||
|
||||
if (unlikely(dur_ms < CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MIN ||
|
||||
dur_ms > CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MAX)) {
|
||||
dev_err(kbdev->dev, "Invalid CSG suspend timeout input (%llu)", dur_ms);
|
||||
return -EFAULT;
|
||||
}
|
||||
dur_ms = dur_ms + CSG_SUSPEND_TIMEOUT_HOST_ADDED_MS;
|
||||
|
||||
/* The 'fw_load_lock' is taken to synchronize against the deferred
|
||||
* loading of FW, update will take effect after firmware gets loaded.
|
||||
*/
|
||||
mutex_lock(&kbdev->fw_load_lock);
|
||||
if (unlikely(!kbdev->csf.firmware_inited)) {
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags_schd);
|
||||
kbdev->csf.csg_suspend_timeout_ms = (unsigned int)dur_ms;
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags_schd);
|
||||
mutex_unlock(&kbdev->fw_load_lock);
|
||||
dev_info(kbdev->dev, "CSF set csg suspend timeout deferred till fw is loaded");
|
||||
goto end;
|
||||
}
|
||||
mutex_unlock(&kbdev->fw_load_lock);
|
||||
|
||||
/* Firmware reloading is triggered by silent reset, and then update will take effect.
|
||||
*/
|
||||
kbase_csf_scheduler_pm_active(kbdev);
|
||||
if (kbase_csf_scheduler_killable_wait_mcu_active(kbdev)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Unable to activate the MCU, the csg suspend timeout value shall remain unchanged");
|
||||
kbase_csf_scheduler_pm_idle(kbdev);
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags_hw);
|
||||
if (kbase_reset_gpu_silent(kbdev)) {
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags_hw);
|
||||
dev_err(kbdev->dev, "CSF set csg suspend timeout pending reset, try again");
|
||||
kbase_csf_scheduler_pm_idle(kbdev);
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
/* GPU reset is placed and it will take place only after hwaccess_lock is released,
|
||||
* update on host side should be done after GPU reset is placed and before it takes place.
|
||||
*/
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags_schd);
|
||||
kbdev->csf.csg_suspend_timeout_ms = (unsigned int)dur_ms;
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags_schd);
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags_hw);
|
||||
/* Keep PM active until reset finished to allow FW reloading to take place,
|
||||
* and then update request will be sent to FW during initialization.
|
||||
*/
|
||||
kbase_reset_gpu_wait(kbdev);
|
||||
kbase_csf_scheduler_pm_idle(kbdev);
|
||||
|
||||
end:
|
||||
dev_info(kbdev->dev, "CSF set csg suspend timeout: %u ms", (unsigned int)dur_ms);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(kbasep_csf_debugfs_eviction_timeout_fops,
|
||||
&kbasep_csf_debugfs_eviction_timeout_get,
|
||||
&kbasep_csf_debugfs_eviction_timeout_set, "%llu\n");
|
||||
|
||||
void kbase_csf_debugfs_init(struct kbase_device *kbdev)
|
||||
{
|
||||
|
|
@ -280,6 +363,8 @@ void kbase_csf_debugfs_init(struct kbase_device *kbdev)
|
|||
&kbasep_csf_debugfs_scheduling_timer_kick_fops);
|
||||
debugfs_create_file("scheduler_state", 0644, kbdev->mali_debugfs_directory, kbdev,
|
||||
&kbasep_csf_debugfs_scheduler_state_fops);
|
||||
debugfs_create_file("eviction_timeout_ms", 0644, kbdev->mali_debugfs_directory, kbdev,
|
||||
&kbasep_csf_debugfs_eviction_timeout_fops);
|
||||
|
||||
kbase_csf_tl_reader_debugfs_init(kbdev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "mali_kbase_csf_firmware.h"
|
||||
#include "mali_kbase_csf_event.h"
|
||||
#include <uapi/gpu/arm/bifrost/csf/mali_kbase_csf_errors_dumpfault.h>
|
||||
#include "mali_kbase_csf_fw_io.h"
|
||||
|
||||
#include <linux/version_compat_defs.h>
|
||||
|
||||
|
|
@ -267,7 +268,6 @@ enum kbase_queue_group_priority {
|
|||
* @CSF_PM_TIMEOUT: Timeout for GPU Power Management to reach the desired
|
||||
* Shader, L2 and MCU state.
|
||||
* @CSF_GPU_RESET_TIMEOUT: Waiting timeout for GPU reset to complete.
|
||||
* @CSF_CSG_SUSPEND_TIMEOUT: Timeout given for a CSG to be suspended.
|
||||
* @CSF_CSG_TERM_TIMEOUT: Timeout given for a CSG to be terminated.
|
||||
* @CSF_FIRMWARE_BOOT_TIMEOUT: Maximum time to wait for firmware to boot.
|
||||
* @CSF_FIRMWARE_PING_TIMEOUT: Maximum time to wait for firmware to respond
|
||||
|
|
@ -290,7 +290,6 @@ enum kbase_timeout_selector {
|
|||
CSF_FIRMWARE_TIMEOUT,
|
||||
CSF_PM_TIMEOUT,
|
||||
CSF_GPU_RESET_TIMEOUT,
|
||||
CSF_CSG_SUSPEND_TIMEOUT,
|
||||
CSF_CSG_TERM_TIMEOUT,
|
||||
CSF_FIRMWARE_BOOT_TIMEOUT,
|
||||
CSF_FIRMWARE_PING_TIMEOUT,
|
||||
|
|
@ -554,6 +553,8 @@ struct kbase_protected_suspend_buffer {
|
|||
* returned to userspace if such an error has occurred.
|
||||
* @timer_event_work: Work item to handle the progress timeout fatal event
|
||||
* for the group.
|
||||
* @progress_timer_state: Value of CSG_PROGRESS_TIMER_STATE register when progress
|
||||
* timer timeout is reported for the group.
|
||||
* @deschedule_deferred_cnt: Counter keeping a track of the number of threads
|
||||
* that tried to deschedule the group and had to defer
|
||||
* the descheduling due to the dump on fault.
|
||||
|
|
@ -610,6 +611,7 @@ struct kbase_queue_group {
|
|||
struct kbase_csf_notification error_fatal;
|
||||
|
||||
struct work_struct timer_event_work;
|
||||
u32 progress_timer_state;
|
||||
|
||||
/**
|
||||
* @dvs_buf: Address and size of scratch memory.
|
||||
|
|
@ -931,13 +933,11 @@ struct kbase_csf_reset_gpu {
|
|||
* of CSG slots.
|
||||
* @resident_group: pointer to the queue group that is resident on the CSG slot.
|
||||
* @state: state of the slot as per enum @kbase_csf_csg_slot_state.
|
||||
* @trigger_jiffies: value of jiffies when change in slot state is recorded.
|
||||
* @priority: dynamic priority assigned to CSG slot.
|
||||
*/
|
||||
struct kbase_csf_csg_slot {
|
||||
struct kbase_queue_group *resident_group;
|
||||
atomic_t state;
|
||||
unsigned long trigger_jiffies;
|
||||
u8 priority;
|
||||
};
|
||||
|
||||
|
|
@ -1137,6 +1137,8 @@ struct kbase_csf_mcu_shared_regions {
|
|||
* @gpuq_kthread: Dedicated thread primarily used to handle
|
||||
* latency-sensitive tasks such as GPU queue
|
||||
* submissions.
|
||||
* @gpu_idle_timer_enabled: Tracks whether the GPU idle timer is enabled or disabled.
|
||||
* @fw_soi_enabled: True if FW Sleep-on-Idle is currently enabled.
|
||||
*/
|
||||
struct kbase_csf_scheduler {
|
||||
struct mutex lock;
|
||||
|
|
@ -1214,6 +1216,8 @@ struct kbase_csf_scheduler {
|
|||
*/
|
||||
spinlock_t gpu_metrics_lock;
|
||||
#endif /* CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD */
|
||||
atomic_t gpu_idle_timer_enabled;
|
||||
atomic_t fw_soi_enabled;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -1677,6 +1681,7 @@ struct kbase_csf_user_reg {
|
|||
* @gpu_idle_dur_count_no_modifier: Update csffw_glb_req_idle_enable to make the shr(10)
|
||||
* modifier conditional on the new flag
|
||||
* in GLB_IDLE_TIMER_CONFIG.
|
||||
* @csg_suspend_timeout_ms: Timeout given for a CSG to be suspended.
|
||||
* for any request sent to the firmware.
|
||||
* @hwcnt: Contain members required for handling the dump of
|
||||
* HW counters.
|
||||
|
|
@ -1695,8 +1700,21 @@ struct kbase_csf_user_reg {
|
|||
* kbase_queue.pending_kick_link.
|
||||
* @quirks_ext: Pointer to an allocated buffer containing the firmware
|
||||
* workarounds configuration.
|
||||
* @mmu_sync_sem: RW Semaphore to defer MMU operations till the P.Mode entrance
|
||||
* or DCS request has been completed.
|
||||
* @pmode_sync_sem: RW Semaphore to prevent MMU operations during P.Mode entrance.
|
||||
* @gpu_idle_timer_enabled: Tracks whether the GPU idle timer is enabled or disabled.
|
||||
* @page_fault_cnt_ptr_address: GPU VA of the location in FW data memory, extracted from the
|
||||
* FW image header, that will store the GPU VA of FW visible
|
||||
* memory location where the @page_fault_cnt value will be written to.
|
||||
* @page_fault_cnt_ptr: CPU VA of the FW visible memory location where the @page_fault_cnt
|
||||
* value will be written to.
|
||||
* @page_fault_cnt: Counter that is incremented on every GPU page fault, just before the
|
||||
* MMU is unblocked to retry the memory transaction that caused the GPU
|
||||
* page fault. The access to counter is serialized appropriately.
|
||||
* @mcu_halted: Flag to inform MCU FSM that the MCU has already halted.
|
||||
* @fw_io: Firmware I/O interface.
|
||||
* @compute_progress_timeout_cc: Value of GPU cycle count register when progress
|
||||
* timer timeout is reported for the compute iterator.
|
||||
*/
|
||||
struct kbase_csf_device {
|
||||
struct kbase_mmu_table mcu_mmu;
|
||||
|
|
@ -1734,6 +1752,7 @@ struct kbase_csf_device {
|
|||
u64 gpu_idle_hysteresis_ns;
|
||||
u32 gpu_idle_dur_count;
|
||||
u32 gpu_idle_dur_count_no_modifier;
|
||||
u32 csg_suspend_timeout_ms;
|
||||
struct kbase_csf_hwcnt hwcnt;
|
||||
struct kbase_csf_mcu_fw fw;
|
||||
struct kbase_csf_firmware_log fw_log;
|
||||
|
|
@ -1752,8 +1771,14 @@ struct kbase_csf_device {
|
|||
struct list_head pending_gpuq_kick_queues[KBASE_QUEUE_GROUP_PRIORITY_COUNT];
|
||||
spinlock_t pending_gpuq_kick_queues_lock;
|
||||
u32 *quirks_ext;
|
||||
struct rw_semaphore mmu_sync_sem;
|
||||
struct rw_semaphore pmode_sync_sem;
|
||||
bool gpu_idle_timer_enabled;
|
||||
u32 page_fault_cnt_ptr_address;
|
||||
u32 *page_fault_cnt_ptr;
|
||||
u32 page_fault_cnt;
|
||||
bool mcu_halted;
|
||||
struct kbase_csf_fw_io fw_io;
|
||||
u64 compute_progress_timeout_cc;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "backend/gpu/mali_kbase_clk_rate_trace_mgr.h"
|
||||
#include <csf/ipa_control/mali_kbase_csf_ipa_control.h>
|
||||
#include <csf/mali_kbase_csf_registers.h>
|
||||
#include <csf/mali_kbase_csf_fw_io.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/firmware.h>
|
||||
|
|
@ -55,6 +56,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/version_compat_defs.h>
|
||||
|
||||
#include <mali_kbase_config_defaults.h>
|
||||
#define MALI_MAX_DEFAULT_FIRMWARE_NAME_LEN ((size_t)64)
|
||||
|
||||
#define DEFAULT_FW_NAME MALI_RELEASE_NAME".mali_csffw.bin"
|
||||
|
|
@ -68,6 +70,7 @@ static unsigned int csf_firmware_boot_timeout_ms;
|
|||
module_param(csf_firmware_boot_timeout_ms, uint, 0444);
|
||||
MODULE_PARM_DESC(csf_firmware_boot_timeout_ms, "Maximum time to wait for firmware to boot.");
|
||||
|
||||
static bool kbase_iter_trace_enable;
|
||||
|
||||
#ifdef CONFIG_MALI_BIFROST_DEBUG
|
||||
/* Makes Driver wait indefinitely for an acknowledgment for the different
|
||||
|
|
@ -97,6 +100,7 @@ MODULE_PARM_DESC(fw_debug, "Enables effective use of a debugger for debugging fi
|
|||
#define CSF_FIRMWARE_ENTRY_TYPE_TIMELINE_METADATA (4)
|
||||
#define CSF_FIRMWARE_ENTRY_TYPE_BUILD_INFO_METADATA (6)
|
||||
#define CSF_FIRMWARE_ENTRY_TYPE_FUNC_CALL_LIST (7)
|
||||
#define CSF_FIRMWARE_ENTRY_TYPE_PAGE_FAULT_CNT (8)
|
||||
#define CSF_FIRMWARE_ENTRY_TYPE_CORE_DUMP (9)
|
||||
|
||||
#define CSF_FIRMWARE_CACHE_MODE_NONE (0ul << 3)
|
||||
|
|
@ -115,7 +119,8 @@ MODULE_PARM_DESC(fw_debug, "Enables effective use of a debugger for debugging fi
|
|||
|
||||
#define CSF_GLB_REQ_CFG_MASK \
|
||||
(GLB_REQ_CFG_ALLOC_EN_MASK | GLB_REQ_CFG_PROGRESS_TIMER_MASK | \
|
||||
GLB_REQ_CFG_PWROFF_TIMER_MASK | GLB_REQ_IDLE_ENABLE_MASK)
|
||||
GLB_REQ_CFG_PWROFF_TIMER_MASK | GLB_REQ_IDLE_ENABLE_MASK | \
|
||||
GLB_REQ_CFG_EVICTION_TIMER_MASK | GLB_REQ_ITER_TRACE_ENABLE_MASK)
|
||||
|
||||
static inline u32 input_page_read(const u32 *const input, const u32 offset)
|
||||
{
|
||||
|
|
@ -179,6 +184,92 @@ struct firmware_timeline_metadata {
|
|||
size_t size;
|
||||
};
|
||||
|
||||
static void reinit_page_fault_cnt_firmware_memory(struct kbase_device *kbdev)
|
||||
{
|
||||
if (!kbdev->csf.page_fault_cnt_ptr)
|
||||
return;
|
||||
|
||||
/* Store the GPU address of shared memory location, where the page fault counter
|
||||
* value will be written, inside the FW data memory.
|
||||
*/
|
||||
kbase_csf_update_firmware_memory(
|
||||
kbdev, kbdev->csf.page_fault_cnt_ptr_address,
|
||||
(u32)((kbdev->csf.firmware_trace_buffers.mcu_rw.va_reg->start_pfn << PAGE_SHIFT) +
|
||||
PAGE_SIZE - sizeof(u32)));
|
||||
|
||||
*kbdev->csf.page_fault_cnt_ptr = kbdev->csf.page_fault_cnt = 0;
|
||||
}
|
||||
|
||||
static void init_page_fault_cnt_firmware_memory(struct kbase_device *kbdev)
|
||||
{
|
||||
if (!kbdev->csf.page_fault_cnt_ptr_address)
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(!kbdev->csf.firmware_trace_buffers.mcu_rw.va_reg))
|
||||
return;
|
||||
|
||||
/* Save the CPU address of shared memory location where the page fault counter
|
||||
* value will be written.
|
||||
* The shared memory location comes from the last 4 bytes of the page that
|
||||
* is allocated to maintain the extract offset value for different trace
|
||||
* buffers. Only the first 4 bytes of every cacheline is used for the extract offset
|
||||
* value.
|
||||
*/
|
||||
kbdev->csf.page_fault_cnt_ptr =
|
||||
(u32 *)((u8 *)kbdev->csf.firmware_trace_buffers.mcu_rw.cpu_addr + PAGE_SIZE -
|
||||
sizeof(u32));
|
||||
reinit_page_fault_cnt_firmware_memory(kbdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* set_iterator_trace_enable - Set the value for 'kbase_iter_trace_enable' global variable
|
||||
* according to the value of GLB_FEATURES.ITER_TRACE_SUPPORTED bit,
|
||||
* and the corresponding device tree entry.
|
||||
* @kbdev: Kernel base device pointer
|
||||
*/
|
||||
static void set_iterator_trace_enable(struct kbase_device *kbdev)
|
||||
{
|
||||
const struct kbase_csf_global_iface *iface = &kbdev->csf.global_iface;
|
||||
bool dev_support_iter_trace = iface->features & GLB_FEATURES_ITER_TRACE_SUPPORTED_MASK;
|
||||
const void *dt_iter_trace_param;
|
||||
unsigned int val;
|
||||
|
||||
if (!dev_support_iter_trace) {
|
||||
kbase_iter_trace_enable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* check device tree for iterator trace enable property and
|
||||
* fallback to "iter_trace_enable" if not found and try again
|
||||
*/
|
||||
dt_iter_trace_param = of_get_property(kbdev->dev->of_node, "iter-trace-enable", NULL);
|
||||
|
||||
if (!dt_iter_trace_param)
|
||||
dt_iter_trace_param =
|
||||
of_get_property(kbdev->dev->of_node, "iter_trace_enable", NULL);
|
||||
|
||||
val = (dt_iter_trace_param) ? be32_to_cpup(dt_iter_trace_param) : 0;
|
||||
dev_dbg(kbdev->dev, "Iterator trace enable device-tree config value: %u", val);
|
||||
|
||||
kbase_iter_trace_enable = val ? true : false;
|
||||
}
|
||||
|
||||
static void iterator_trace_reinit(struct kbase_device *kbdev)
|
||||
{
|
||||
if (kbase_iter_trace_enable) {
|
||||
kbase_csf_firmware_global_input_mask(&kbdev->csf.global_iface, GLB_REQ,
|
||||
GLB_REQ_ITER_TRACE_ENABLE_MASK,
|
||||
GLB_REQ_ITER_TRACE_ENABLE_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
static void iterator_trace_init(struct kbase_device *kbdev)
|
||||
{
|
||||
set_iterator_trace_enable(kbdev);
|
||||
iterator_trace_reinit(kbdev);
|
||||
}
|
||||
|
||||
/* The shared interface area, used for communicating with firmware, is managed
|
||||
* like a virtual memory zone. Reserve the virtual space from that zone
|
||||
* corresponding to shared interface entry parsed from the firmware image.
|
||||
|
|
@ -217,7 +308,7 @@ void kbase_csf_firmware_disable_mcu(struct kbase_device *kbdev)
|
|||
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(MCU_CONTROL), MCU_CONTROL_REQ_DISABLE);
|
||||
}
|
||||
|
||||
static void wait_for_firmware_stop(struct kbase_device *kbdev)
|
||||
void kbase_csf_firmware_disable_mcu_wait(struct kbase_device *kbdev)
|
||||
{
|
||||
u32 val;
|
||||
const u32 timeout_us =
|
||||
|
|
@ -232,17 +323,12 @@ static void wait_for_firmware_stop(struct kbase_device *kbdev)
|
|||
KBASE_TLSTREAM_TL_KBASE_CSFFW_FW_OFF(kbdev, kbase_backend_get_cycle_cnt(kbdev));
|
||||
}
|
||||
|
||||
void kbase_csf_firmware_disable_mcu_wait(struct kbase_device *kbdev)
|
||||
{
|
||||
wait_for_firmware_stop(kbdev);
|
||||
}
|
||||
|
||||
static void stop_csf_firmware(struct kbase_device *kbdev)
|
||||
void kbase_csf_stop_firmware_and_wait(struct kbase_device *kbdev)
|
||||
{
|
||||
/* Stop the MCU firmware */
|
||||
kbase_csf_firmware_disable_mcu(kbdev);
|
||||
|
||||
wait_for_firmware_stop(kbdev);
|
||||
kbase_csf_firmware_disable_mcu_wait(kbdev);
|
||||
}
|
||||
|
||||
static void wait_for_firmware_boot(struct kbase_device *kbdev)
|
||||
|
|
@ -261,7 +347,6 @@ static void wait_for_firmware_boot(struct kbase_device *kbdev)
|
|||
*/
|
||||
remaining = wait_event_timeout(kbdev->csf.event_wait, kbdev->csf.interrupt_received == true,
|
||||
wait_timeout);
|
||||
|
||||
if (!remaining)
|
||||
dev_err(kbdev->dev, "Timed out waiting for fw boot completion");
|
||||
|
||||
|
|
@ -485,6 +570,8 @@ static int reload_fw_image(struct kbase_device *kbdev)
|
|||
kbdev->csf.firmware_full_reload_needed = false;
|
||||
|
||||
kbase_csf_firmware_reload_trace_buffers_data(kbdev);
|
||||
reinit_page_fault_cnt_firmware_memory(kbdev);
|
||||
iterator_trace_reinit(kbdev);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1043,6 +1130,14 @@ static int load_firmware_entry(struct kbase_device *kbdev, const struct kbase_cs
|
|||
}
|
||||
kbase_csf_firmware_log_parse_logging_call_list_entry(kbdev, entry);
|
||||
return 0;
|
||||
case CSF_FIRMWARE_ENTRY_TYPE_PAGE_FAULT_CNT:
|
||||
/* Entry about the location of page fault counter */
|
||||
if (size < sizeof(*entry)) {
|
||||
dev_err(kbdev->dev, "Page fault counter entry too short (size=%u)", size);
|
||||
return -EINVAL;
|
||||
}
|
||||
kbdev->csf.page_fault_cnt_ptr_address = *entry;
|
||||
return 0;
|
||||
case CSF_FIRMWARE_ENTRY_TYPE_CORE_DUMP:
|
||||
/* Core Dump section */
|
||||
if (size < CORE_DUMP_ENTRY_START_ADDR_OFFSET + sizeof(*entry)) {
|
||||
|
|
@ -1657,12 +1752,13 @@ static inline void set_gpu_idle_timer_glb_req(struct kbase_device *const kbdev,
|
|||
global_iface, GLB_REQ, GLB_REQ_REQ_IDLE_DISABLE, GLB_REQ_IDLE_DISABLE_MASK);
|
||||
}
|
||||
|
||||
kbdev->csf.gpu_idle_timer_enabled = set;
|
||||
atomic_set(&kbdev->csf.scheduler.gpu_idle_timer_enabled, set);
|
||||
}
|
||||
|
||||
static void enable_gpu_idle_timer(struct kbase_device *const kbdev)
|
||||
{
|
||||
struct kbase_csf_global_iface *global_iface = &kbdev->csf.global_iface;
|
||||
bool const fw_soi_allowed = kbase_pm_fw_sleep_on_idle_allowed(kbdev);
|
||||
|
||||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
|
||||
|
|
@ -1670,14 +1766,114 @@ static void enable_gpu_idle_timer(struct kbase_device *const kbdev)
|
|||
kbdev->csf.gpu_idle_dur_count);
|
||||
|
||||
kbase_csf_firmware_global_input_mask(global_iface, GLB_IDLE_TIMER_CONFIG,
|
||||
kbdev->csf.gpu_idle_dur_count_no_modifier,
|
||||
kbdev->csf.gpu_idle_dur_count_no_modifier
|
||||
<< GLB_IDLE_TIMER_CONFIG_NO_MODIFIER_SHIFT,
|
||||
GLB_IDLE_TIMER_CONFIG_NO_MODIFIER_MASK);
|
||||
kbase_csf_firmware_global_input_mask(global_iface, GLB_IDLE_TIMER_CONFIG,
|
||||
fw_soi_allowed
|
||||
<< GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_SHIFT,
|
||||
GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_MASK);
|
||||
|
||||
set_gpu_idle_timer_glb_req(kbdev, true);
|
||||
atomic_set(&kbdev->csf.scheduler.fw_soi_enabled, fw_soi_allowed);
|
||||
dev_dbg(kbdev->dev, "Enabling GPU idle timer with count-value: 0x%.8x",
|
||||
kbdev->csf.gpu_idle_dur_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert_dur_to_suspend_count() - Convert CSG suspend timeout from ms to cycle count
|
||||
* @kbdev: Instance of a GPU platform device that implements a CSF interface
|
||||
* @dur_ms: Timeout value in ms
|
||||
* @no_modifier: Indicate whether bit-shift is applied, 0 when applied, 1 otherwise
|
||||
*
|
||||
* Convert CSG suspend timeout from ms to cycle count, then generate a register value
|
||||
* combining cycle count and timer source
|
||||
*
|
||||
* Return: Register value which will be stored into register GLB_EVICTION_TIMER.
|
||||
*/
|
||||
static u32 convert_dur_to_suspend_count(struct kbase_device *kbdev, const u64 dur_ms,
|
||||
u32 *no_modifier)
|
||||
{
|
||||
/* Get the cntfreq_el0 value, which drives the SYSTEM_TIMESTAMP */
|
||||
u64 freq = kbase_arch_timer_get_cntfrq(kbdev);
|
||||
u64 dur_val = dur_ms;
|
||||
u32 cnt_val_u32, reg_val_u32;
|
||||
const bool src_system_timestamp = freq > 0;
|
||||
const u8 SUSPEND_VAL_UNIT_SHIFT = 10;
|
||||
|
||||
if (!src_system_timestamp) {
|
||||
/* Get the cycle_counter source alternative */
|
||||
spin_lock(&kbdev->pm.clk_rtm.lock);
|
||||
if (kbdev->pm.clk_rtm.clks[0])
|
||||
freq = kbdev->pm.clk_rtm.clks[0]->clock_val;
|
||||
else
|
||||
dev_err(kbdev->dev, "No GPU clock, unexpected intregration issue!");
|
||||
spin_unlock(&kbdev->pm.clk_rtm.lock);
|
||||
|
||||
dev_info(kbdev->dev,
|
||||
"No timestamp frequency, use cycle counter for csg suspend timeout!");
|
||||
}
|
||||
|
||||
/* Formula for dur_val = (dur/1e3) * freq_HZ) */
|
||||
dur_val = dur_val * freq;
|
||||
dur_val = div_u64(dur_val, MSEC_PER_SEC);
|
||||
if (dur_val < S32_MAX) {
|
||||
*no_modifier = 1;
|
||||
} else {
|
||||
dur_val = dur_val >> SUSPEND_VAL_UNIT_SHIFT;
|
||||
*no_modifier = 0;
|
||||
}
|
||||
|
||||
/* Interface limits the value field to S32_MAX */
|
||||
cnt_val_u32 = (dur_val > S32_MAX) ? S32_MAX : (u32)dur_val;
|
||||
|
||||
reg_val_u32 = GLB_EVICTION_TIMER_TIMEOUT_SET(0, cnt_val_u32);
|
||||
/* add the source flag */
|
||||
reg_val_u32 = GLB_EVICTION_TIMER_TIMER_SOURCE_SET(
|
||||
reg_val_u32,
|
||||
(src_system_timestamp ? GLB_EVICTION_TIMER_TIMER_SOURCE_SYSTEM_TIMESTAMP :
|
||||
GLB_EVICTION_TIMER_TIMER_SOURCE_GPU_COUNTER));
|
||||
|
||||
return reg_val_u32;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_csg_suspend_timeout() - Update CSG suspend timeout setting on FW side
|
||||
*
|
||||
* @kbdev: Instance of a GPU platform device that implements a CSF interface
|
||||
*/
|
||||
static void set_csg_suspend_timeout(struct kbase_device *const kbdev)
|
||||
{
|
||||
u32 dur_ms, dur_val;
|
||||
u32 no_modifier = 0;
|
||||
struct kbase_csf_global_iface *global_iface = &kbdev->csf.global_iface;
|
||||
|
||||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
|
||||
dur_ms = kbdev->csf.csg_suspend_timeout_ms;
|
||||
if (unlikely(dur_ms < CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MIN +
|
||||
CSG_SUSPEND_TIMEOUT_HOST_ADDED_MS ||
|
||||
dur_ms > CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MAX +
|
||||
CSG_SUSPEND_TIMEOUT_HOST_ADDED_MS)) {
|
||||
dev_err(kbdev->dev, "Unexpected CSG suspend timeout: %ums, default to: %ums",
|
||||
dur_ms, CSG_SUSPEND_TIMEOUT_MS);
|
||||
kbdev->csf.csg_suspend_timeout_ms = CSG_SUSPEND_TIMEOUT_MS;
|
||||
dur_ms = CSG_SUSPEND_TIMEOUT_MS;
|
||||
}
|
||||
dur_ms = dur_ms - CSG_SUSPEND_TIMEOUT_HOST_ADDED_MS;
|
||||
|
||||
dur_val = convert_dur_to_suspend_count(kbdev, dur_ms, &no_modifier);
|
||||
|
||||
kbase_csf_firmware_global_input(global_iface, GLB_EVICTION_TIMER, dur_val);
|
||||
|
||||
kbase_csf_firmware_global_input_mask(global_iface, GLB_EVICTION_TIMER_CONFIG, no_modifier,
|
||||
GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_MASK);
|
||||
|
||||
set_global_request(global_iface, GLB_REQ_CFG_EVICTION_TIMER_MASK);
|
||||
|
||||
dev_dbg(kbdev->dev, "Updating CSG suspend timeout with count-value: 0x%.8x", dur_val);
|
||||
}
|
||||
|
||||
static bool global_debug_request_complete(struct kbase_device *const kbdev, u32 const req_mask)
|
||||
{
|
||||
struct kbase_csf_global_iface *global_iface = &kbdev->csf.global_iface;
|
||||
|
|
@ -1766,7 +1962,8 @@ static void global_init(struct kbase_device *const kbdev, u64 core_mask)
|
|||
GLB_ACK_IRQ_MASK_CFG_PROGRESS_TIMER_MASK | GLB_ACK_IRQ_MASK_PROTM_ENTER_MASK |
|
||||
GLB_ACK_IRQ_MASK_PROTM_EXIT_MASK | GLB_ACK_IRQ_MASK_FIRMWARE_CONFIG_UPDATE_MASK |
|
||||
GLB_ACK_IRQ_MASK_CFG_PWROFF_TIMER_MASK | GLB_ACK_IRQ_MASK_IDLE_EVENT_MASK |
|
||||
GLB_REQ_DEBUG_CSF_REQ_MASK | GLB_ACK_IRQ_MASK_IDLE_ENABLE_MASK;
|
||||
GLB_REQ_DEBUG_CSF_REQ_MASK | GLB_ACK_IRQ_MASK_IDLE_ENABLE_MASK |
|
||||
GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_MASK | GLB_ACK_IRQ_MASK_ITER_TRACE_ENABLE_MASK;
|
||||
|
||||
const struct kbase_csf_global_iface *const global_iface = &kbdev->csf.global_iface;
|
||||
unsigned long flags;
|
||||
|
|
@ -1781,11 +1978,10 @@ static void global_init(struct kbase_device *const kbdev, u64 core_mask)
|
|||
|
||||
set_timeout_global(global_iface, kbase_csf_timeout_get(kbdev));
|
||||
|
||||
/* The GPU idle timer is always enabled for simplicity. Checks will be
|
||||
* done before scheduling the GPU idle worker to see if it is
|
||||
* appropriate for the current power policy.
|
||||
/* The csg suspend timeout is always enabled so customer has the flexibility to update it
|
||||
* at any time.
|
||||
*/
|
||||
enable_gpu_idle_timer(kbdev);
|
||||
set_csg_suspend_timeout(kbdev);
|
||||
|
||||
/* Unmask the interrupts */
|
||||
kbase_csf_firmware_global_input(global_iface, GLB_ACK_IRQ_MASK, ack_irq_mask);
|
||||
|
|
@ -1963,6 +2159,7 @@ void kbase_csf_firmware_reload_completed(struct kbase_device *kbdev)
|
|||
|
||||
KBASE_KTRACE_ADD(kbdev, CSF_FIRMWARE_REBOOT, NULL, 0u);
|
||||
|
||||
|
||||
/* Tell MCU state machine to transit to next state */
|
||||
kbdev->csf.firmware_reloaded = true;
|
||||
kbase_pm_update_state(kbdev);
|
||||
|
|
@ -2068,23 +2265,34 @@ u32 kbase_csf_firmware_set_gpu_idle_hysteresis_time(struct kbase_device *kbdev,
|
|||
* gets serialized.
|
||||
*/
|
||||
kbase_csf_scheduler_lock(kbdev);
|
||||
while (atomic_read(&kbdev->csf.scheduler.pending_gpu_idle_work) > 0) {
|
||||
kbase_csf_scheduler_unlock(kbdev);
|
||||
kbase_csf_scheduler_wait_for_kthread_pending_work(
|
||||
kbdev, &kbdev->csf.scheduler.pending_gpu_idle_work);
|
||||
kbase_csf_scheduler_lock(kbdev);
|
||||
}
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags);
|
||||
|
||||
kbdev->csf.gpu_idle_hysteresis_ns = dur_ns;
|
||||
kbdev->csf.gpu_idle_dur_count = hysteresis_val;
|
||||
kbdev->csf.gpu_idle_dur_count_no_modifier = no_modifier;
|
||||
|
||||
if (kbdev->csf.gpu_idle_timer_enabled) {
|
||||
if (atomic_read(&kbdev->csf.scheduler.gpu_idle_timer_enabled)) {
|
||||
/* Timer is already enabled. Disable the timer as FW only reads
|
||||
* the new idle timer value when timer is re-enabled.
|
||||
*/
|
||||
kbase_csf_firmware_disable_gpu_idle_timer(kbdev);
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
/* Ensure that the request has taken effect */
|
||||
wait_for_global_request(kbdev, GLB_REQ_IDLE_DISABLE_MASK);
|
||||
if (wait_for_global_request(kbdev, GLB_REQ_IDLE_DISABLE_MASK))
|
||||
dev_err(kbdev->dev,
|
||||
"Failed to disable GLB_IDLE timer when setting a new idle hysteresis timeout");
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags);
|
||||
kbase_csf_firmware_enable_gpu_idle_timer(kbdev);
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
wait_for_global_request(kbdev, GLB_REQ_IDLE_ENABLE_MASK);
|
||||
if (wait_for_global_request(kbdev, GLB_REQ_IDLE_ENABLE_MASK))
|
||||
dev_err(kbdev->dev,
|
||||
"Failed to re-enable GLB_IDLE timer when setting a new idle hysteresis timeout");
|
||||
} else {
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
}
|
||||
|
|
@ -2190,78 +2398,6 @@ u32 kbase_csf_firmware_reset_mcu_core_pwroff_time(struct kbase_device *kbdev)
|
|||
return kbase_csf_firmware_set_mcu_core_pwroff_time(kbdev, DEFAULT_GLB_PWROFF_TIMEOUT_NS);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_csf_get_iterator_trace_enable - Parsing the iterator_trace enable firstly from
|
||||
* the module parameter, and then from device-tree.
|
||||
* @kbdev: Kernel base device pointer
|
||||
*
|
||||
* Return: true on enabled, otherwise false.
|
||||
*/
|
||||
static bool kbase_csf_get_iterator_trace_enable(struct kbase_device *kbdev)
|
||||
{
|
||||
const void *dt_iter_trace_param;
|
||||
unsigned int val;
|
||||
|
||||
|
||||
/* check device tree for iterator trace enable property and
|
||||
* fallback to "iter_trace_enable" if not found and try again
|
||||
*/
|
||||
dt_iter_trace_param = of_get_property(kbdev->dev->of_node, "iter-trace-enable", NULL);
|
||||
|
||||
if (!dt_iter_trace_param)
|
||||
dt_iter_trace_param =
|
||||
of_get_property(kbdev->dev->of_node, "iter_trace_enable", NULL);
|
||||
|
||||
val = (dt_iter_trace_param) ? be32_to_cpup(dt_iter_trace_param) : 0;
|
||||
dev_dbg(kbdev->dev, "Iterator trace enable device-tree config value: %u", val);
|
||||
|
||||
return (val != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_device_csf_iterator_trace_init - Send request to enable iterator
|
||||
* trace port.
|
||||
* @kbdev: Kernel base device pointer
|
||||
*
|
||||
* Return: 0 on success (or if enable request is not sent), or error
|
||||
* code -EINVAL on failure of GPU to acknowledge enable request.
|
||||
*/
|
||||
static int kbase_device_csf_iterator_trace_init(struct kbase_device *kbdev)
|
||||
{
|
||||
/* Enable the iterator trace port if supported by the GPU and is
|
||||
* configured to do so. The FW must advertise this feature in GLB_FEATURES.
|
||||
*/
|
||||
if (kbdev->pm.backend.gpu_powered) {
|
||||
const struct kbase_csf_global_iface *iface = &kbdev->csf.global_iface;
|
||||
bool dev_support_iter_trace = iface->features &
|
||||
GLB_FEATURES_ITER_TRACE_SUPPORTED_MASK;
|
||||
|
||||
dev_dbg(kbdev->dev, "Device supporting iterator trace: %s\n",
|
||||
dev_support_iter_trace ? "true" : "false");
|
||||
if (dev_support_iter_trace && kbase_csf_get_iterator_trace_enable(kbdev)) {
|
||||
long ack_timeout = kbase_csf_timeout_in_jiffies(
|
||||
kbase_get_timeout_ms(kbdev, CSF_FIRMWARE_TIMEOUT));
|
||||
|
||||
/* write enable request to global input */
|
||||
kbase_csf_firmware_global_input_mask(iface, GLB_REQ,
|
||||
GLB_REQ_ITER_TRACE_ENABLE_MASK,
|
||||
GLB_REQ_ITER_TRACE_ENABLE_MASK);
|
||||
/* Ring global doorbell */
|
||||
kbase_csf_ring_doorbell(kbdev, CSF_KERNEL_DOORBELL_NR);
|
||||
|
||||
ack_timeout = wait_event_timeout(
|
||||
kbdev->csf.event_wait,
|
||||
!((kbase_csf_firmware_global_input_read(iface, GLB_REQ) ^
|
||||
kbase_csf_firmware_global_output(iface, GLB_ACK)) &
|
||||
GLB_REQ_ITER_TRACE_ENABLE_MASK),
|
||||
ack_timeout);
|
||||
|
||||
return ack_timeout ? 0 : -EINVAL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kbase_csf_firmware_early_init(struct kbase_device *kbdev)
|
||||
{
|
||||
init_waitqueue_head(&kbdev->csf.event_wait);
|
||||
|
|
@ -2275,9 +2411,7 @@ int kbase_csf_firmware_early_init(struct kbase_device *kbdev)
|
|||
INIT_WORK(&kbdev->csf.firmware_reload_work, kbase_csf_firmware_reload_worker);
|
||||
INIT_WORK(&kbdev->csf.fw_error_work, firmware_error_worker);
|
||||
|
||||
kbdev->csf.glb_init_request_pending = true;
|
||||
|
||||
init_rwsem(&kbdev->csf.pmode_sync_sem);
|
||||
init_rwsem(&kbdev->csf.mmu_sync_sem);
|
||||
mutex_init(&kbdev->csf.reg_lock);
|
||||
kbase_csf_pending_gpuq_kick_queues_init(kbdev);
|
||||
|
||||
|
|
@ -2307,6 +2441,8 @@ int kbase_csf_firmware_late_init(struct kbase_device *kbdev)
|
|||
convert_dur_to_idle_count(kbdev, kbdev->csf.gpu_idle_hysteresis_ns, &no_modifier);
|
||||
kbdev->csf.gpu_idle_dur_count_no_modifier = no_modifier;
|
||||
|
||||
kbdev->csf.csg_suspend_timeout_ms = CSG_SUSPEND_TIMEOUT_MS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2495,6 +2631,8 @@ int kbase_csf_firmware_load_init(struct kbase_device *kbdev)
|
|||
goto err_out;
|
||||
}
|
||||
|
||||
init_page_fault_cnt_firmware_memory(kbdev);
|
||||
|
||||
ret = kbase_csf_firmware_cfg_fw_wa_init(kbdev);
|
||||
if (ret != 0) {
|
||||
dev_err(kbdev->dev, "Failed to initialize firmware workarounds");
|
||||
|
|
@ -2515,6 +2653,8 @@ int kbase_csf_firmware_load_init(struct kbase_device *kbdev)
|
|||
if (ret != 0)
|
||||
goto err_out;
|
||||
|
||||
iterator_trace_init(kbdev);
|
||||
|
||||
ret = kbase_csf_doorbell_mapping_init(kbdev);
|
||||
if (ret != 0)
|
||||
goto err_out;
|
||||
|
|
@ -2545,10 +2685,6 @@ int kbase_csf_firmware_load_init(struct kbase_device *kbdev)
|
|||
if (ret != 0)
|
||||
goto err_out;
|
||||
|
||||
ret = kbase_device_csf_iterator_trace_init(kbdev);
|
||||
if (ret != 0)
|
||||
goto err_out;
|
||||
|
||||
if (kbdev->csf.fw_core_dump.available)
|
||||
kbase_csf_firmware_core_dump_init(kbdev);
|
||||
|
||||
|
|
@ -2598,7 +2734,7 @@ void kbase_csf_firmware_unload_term(struct kbase_device *kbdev)
|
|||
kbdev->csf.firmware_inited = false;
|
||||
if (WARN_ON(kbdev->pm.backend.mcu_state != KBASE_MCU_OFF)) {
|
||||
kbdev->pm.backend.mcu_state = KBASE_MCU_OFF;
|
||||
stop_csf_firmware(kbdev);
|
||||
kbase_csf_stop_firmware_and_wait(kbdev);
|
||||
}
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
|
|
@ -2804,6 +2940,7 @@ void kbase_csf_firmware_disable_gpu_idle_timer(struct kbase_device *kbdev)
|
|||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
|
||||
set_gpu_idle_timer_glb_req(kbdev, false);
|
||||
atomic_set(&kbdev->csf.scheduler.fw_soi_enabled, false);
|
||||
dev_dbg(kbdev->dev, "Sending request to disable gpu idle timer");
|
||||
|
||||
kbase_csf_ring_doorbell(kbdev, CSF_KERNEL_DOORBELL_NR);
|
||||
|
|
@ -2947,7 +3084,6 @@ void kbase_csf_firmware_trigger_mcu_sleep(struct kbase_device *kbdev)
|
|||
KBASE_TLSTREAM_TL_KBASE_CSFFW_FW_REQUEST_SLEEP(kbdev, kbase_backend_get_cycle_cnt(kbdev));
|
||||
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags);
|
||||
set_gpu_idle_timer_glb_req(kbdev, false);
|
||||
set_global_request(global_iface, GLB_REQ_SLEEP_MASK);
|
||||
dev_dbg(kbdev->dev, "Sending sleep request to MCU");
|
||||
kbase_csf_ring_doorbell(kbdev, CSF_KERNEL_DOORBELL_NR);
|
||||
|
|
@ -2956,11 +3092,23 @@ void kbase_csf_firmware_trigger_mcu_sleep(struct kbase_device *kbdev)
|
|||
|
||||
bool kbase_csf_firmware_is_mcu_in_sleep(struct kbase_device *kbdev)
|
||||
{
|
||||
bool db_notif_disabled;
|
||||
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
|
||||
return (global_request_complete(kbdev, GLB_REQ_SLEEP_MASK) &&
|
||||
kbase_csf_firmware_mcu_halted(kbdev));
|
||||
db_notif_disabled = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(MCU_CONTROL)) &
|
||||
MCU_CNTRL_DOORBELL_DISABLE_MASK;
|
||||
|
||||
if (!db_notif_disabled || !kbase_csf_firmware_mcu_halted(kbdev))
|
||||
return false;
|
||||
|
||||
if (global_request_complete(kbdev, GLB_REQ_SLEEP_MASK))
|
||||
return true;
|
||||
|
||||
kbase_pm_enable_mcu_db_notification(kbdev);
|
||||
dev_dbg(kbdev->dev, "Enabled DB notification");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -3222,3 +3370,127 @@ void kbase_csf_firmware_mcu_shared_mapping_term(struct kbase_device *kbdev,
|
|||
vunmap(csf_mapping->cpu_addr);
|
||||
kfree(csf_mapping->phys);
|
||||
}
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
|
||||
void kbase_csf_firmware_soi_update(struct kbase_device *kbdev)
|
||||
{
|
||||
struct kbase_csf_scheduler *scheduler = &kbdev->csf.scheduler;
|
||||
unsigned long flags;
|
||||
|
||||
/* There are 3 possibilities:
|
||||
* - Sleep-on-Idle allowed
|
||||
* - Sleep-on-Idle not allowed, GLB_IDLE timer disabled
|
||||
* - Sleep-on-Idle not allowed, GLB_IDLE timer enabled
|
||||
*/
|
||||
if (kbase_pm_fw_sleep_on_idle_allowed(kbdev)) {
|
||||
if (likely(atomic_read(&kbdev->csf.scheduler.fw_soi_enabled)))
|
||||
return;
|
||||
} else {
|
||||
if (test_bit(KBASE_GPU_NON_IDLE_OFF_SLOT_GROUPS_AVAILABLE,
|
||||
&kbdev->pm.backend.gpu_sleep_allowed)) {
|
||||
if (likely(!atomic_read(&kbdev->csf.scheduler.gpu_idle_timer_enabled)))
|
||||
return;
|
||||
} else if (likely(atomic_read(&kbdev->csf.scheduler.gpu_idle_timer_enabled))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (kbase_reset_gpu_try_prevent(kbdev))
|
||||
return;
|
||||
|
||||
kbase_csf_scheduler_lock(kbdev);
|
||||
|
||||
if (atomic_read(&scheduler->pending_gpu_idle_work) > 0)
|
||||
goto out_unlock_scheduler_lock;
|
||||
|
||||
if ((scheduler->state == SCHED_SUSPENDED) || (scheduler->state == SCHED_SLEEPING))
|
||||
goto out_unlock_scheduler_lock;
|
||||
|
||||
if (kbdev->pm.backend.mcu_state != KBASE_MCU_ON)
|
||||
goto out_unlock_scheduler_lock;
|
||||
|
||||
/* Ensure that an existing DISABLE request is completed before
|
||||
* proceeding. They are made without waiting for them to complete such
|
||||
* as when enabling the MCU.
|
||||
*/
|
||||
if (wait_for_global_request(kbdev, GLB_REQ_IDLE_DISABLE_MASK)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Existing GLB_IDLE timer config change failed to complete in time (gpu_sleep_allowed:%lx)",
|
||||
kbdev->pm.backend.gpu_sleep_allowed);
|
||||
goto out_unlock_scheduler_lock;
|
||||
}
|
||||
|
||||
/* Disable the GLB IDLE timer if it's currently enabled */
|
||||
if (atomic_read(&kbdev->csf.scheduler.gpu_idle_timer_enabled)) {
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags);
|
||||
kbase_csf_firmware_disable_gpu_idle_timer(kbdev);
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
if (wait_for_global_request(kbdev, GLB_REQ_IDLE_DISABLE_MASK)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Failed to disable GLB_IDLE timer following FW Sleep-on-Idle config change (gpu_sleep_allowed:%lx)",
|
||||
kbdev->pm.backend.gpu_sleep_allowed);
|
||||
goto out_unlock_scheduler_lock;
|
||||
}
|
||||
}
|
||||
|
||||
/* The GLB IDLE timer and, consequently, FW Sleep-on-Idle could remain
|
||||
* disabled in certain cases. Otherwise, we shall re-enable GLB IDLE
|
||||
* timer with the new FW Sleep-on-Idle configuration.
|
||||
*/
|
||||
if (!test_bit(KBASE_GPU_NON_IDLE_OFF_SLOT_GROUPS_AVAILABLE,
|
||||
&kbdev->pm.backend.gpu_sleep_allowed)) {
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags);
|
||||
kbase_csf_firmware_enable_gpu_idle_timer(kbdev);
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
if (wait_for_global_request(kbdev, GLB_REQ_IDLE_ENABLE_MASK)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Failed to re-enable GLB_IDLE timer following FW Sleep-on-Idle config change (gpu_sleep_allowed:%lx)",
|
||||
kbdev->pm.backend.gpu_sleep_allowed);
|
||||
goto out_unlock_scheduler_lock;
|
||||
}
|
||||
}
|
||||
|
||||
if (atomic_read(&scheduler->fw_soi_enabled)) {
|
||||
dev_dbg(kbdev->dev, "FW Sleep-on-Idle was enabled");
|
||||
KBASE_KTRACE_ADD(kbdev, FIRMWARE_SLEEP_ON_IDLE_CHANGED, NULL, true);
|
||||
} else {
|
||||
dev_dbg(kbdev->dev, "FW Sleep-on-Idle was disabled");
|
||||
KBASE_KTRACE_ADD(kbdev, FIRMWARE_SLEEP_ON_IDLE_CHANGED, NULL, false);
|
||||
}
|
||||
|
||||
out_unlock_scheduler_lock:
|
||||
kbase_csf_scheduler_unlock(kbdev);
|
||||
kbase_reset_gpu_allow(kbdev);
|
||||
}
|
||||
|
||||
int kbase_csf_firmware_soi_disable_on_scheduler_suspend(struct kbase_device *kbdev)
|
||||
{
|
||||
struct kbase_csf_scheduler *scheduler = &kbdev->csf.scheduler;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&scheduler->lock);
|
||||
|
||||
if (WARN_ON_ONCE(scheduler->state != SCHED_INACTIVE))
|
||||
return 0;
|
||||
|
||||
if (!atomic_read(&kbdev->csf.scheduler.fw_soi_enabled))
|
||||
return 0;
|
||||
|
||||
kbase_csf_scheduler_spin_lock(kbdev, &flags);
|
||||
if (atomic_read(&scheduler->fw_soi_enabled)) {
|
||||
kbase_csf_firmware_disable_gpu_idle_timer(kbdev);
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
if (wait_for_global_request(kbdev, GLB_REQ_IDLE_DISABLE_MASK)) {
|
||||
dev_err(kbdev->dev, "Failed to disable Sleep-on-Idle config");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
KBASE_KTRACE_ADD(kbdev, FIRMWARE_SLEEP_ON_IDLE_CHANGED, NULL, false);
|
||||
} else {
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* KBASE_PM_RUNTIME */
|
||||
|
|
|
|||
|
|
@ -591,13 +591,20 @@ void kbase_csf_firmware_enable_mcu(struct kbase_device *kbdev);
|
|||
void kbase_csf_firmware_disable_mcu(struct kbase_device *kbdev);
|
||||
|
||||
/**
|
||||
* kbase_csf_firmware_disable_mcu_wait - Wait for the MCU to reach disabled
|
||||
* status.
|
||||
* kbase_csf_firmware_disable_mcu_wait - Wait for the MCU to reach disabled status.
|
||||
*
|
||||
* @kbdev: Instance of a GPU platform device that implements a CSF interface.
|
||||
*/
|
||||
void kbase_csf_firmware_disable_mcu_wait(struct kbase_device *kbdev);
|
||||
|
||||
/**
|
||||
* kbase_csf_stop_firmware_and_wait - Disable firmware and wait for the MCU to reach
|
||||
* disabled status.
|
||||
*
|
||||
* @kbdev: Instance of a GPU platform device that implements a CSF interface.
|
||||
*/
|
||||
void kbase_csf_stop_firmware_and_wait(struct kbase_device *kbdev);
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
/**
|
||||
* kbase_csf_firmware_trigger_mcu_sleep - Send the command to put MCU in sleep
|
||||
|
|
@ -927,4 +934,27 @@ int kbase_csf_trigger_firmware_config_update(struct kbase_device *kbdev);
|
|||
*/
|
||||
int kbase_csf_firmware_req_core_dump(struct kbase_device *const kbdev);
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
|
||||
/**
|
||||
* kbase_csf_firmware_soi_update - Update FW Sleep-on-Idle config
|
||||
*
|
||||
* @kbdev: Device pointer
|
||||
*
|
||||
* This function reconfigures the FW Sleep-on-Idle configuration if necessary.
|
||||
*/
|
||||
void kbase_csf_firmware_soi_update(struct kbase_device *kbdev);
|
||||
|
||||
/**
|
||||
* kbase_csf_firmware_soi_disable_on_scheduler_suspend - Disable FW Sleep-on-Idle config
|
||||
* on scheduler suspension
|
||||
*
|
||||
* @kbdev: Device pointer
|
||||
*
|
||||
* Return: 0 on success, otherwise failure
|
||||
*/
|
||||
int kbase_csf_firmware_soi_disable_on_scheduler_suspend(struct kbase_device *kbdev);
|
||||
|
||||
#endif /* KBASE_PM_RUNTIME */
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ static inline void set_gpu_idle_timer_glb_req(struct kbase_device *const kbdev,
|
|||
global_iface, GLB_REQ, GLB_REQ_REQ_IDLE_DISABLE, GLB_REQ_IDLE_DISABLE_MASK);
|
||||
}
|
||||
|
||||
kbdev->csf.gpu_idle_timer_enabled = set;
|
||||
atomic_set(&kbdev->csf.scheduler.gpu_idle_timer_enabled, set);
|
||||
}
|
||||
|
||||
static void enable_gpu_idle_timer(struct kbase_device *const kbdev)
|
||||
|
|
@ -788,12 +788,6 @@ static void global_init(struct kbase_device *const kbdev, u64 core_mask)
|
|||
|
||||
set_timeout_global(global_iface, kbase_csf_timeout_get(kbdev));
|
||||
|
||||
/* The GPU idle timer is always enabled for simplicity. Checks will be
|
||||
* done before scheduling the GPU idle worker to see if it is
|
||||
* appropriate for the current power policy.
|
||||
*/
|
||||
enable_gpu_idle_timer(kbdev);
|
||||
|
||||
/* Unmask the interrupts */
|
||||
kbase_csf_firmware_global_input(global_iface, GLB_ACK_IRQ_MASK, ack_irq_mask);
|
||||
|
||||
|
|
@ -901,6 +895,7 @@ void kbase_csf_firmware_trigger_reload(struct kbase_device *kbdev)
|
|||
kbdev->csf.firmware_reloaded = true;
|
||||
}
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_firmware_trigger_reload);
|
||||
|
||||
void kbase_csf_firmware_reload_completed(struct kbase_device *kbdev)
|
||||
{
|
||||
|
|
@ -909,6 +904,7 @@ void kbase_csf_firmware_reload_completed(struct kbase_device *kbdev)
|
|||
if (unlikely(!kbdev->csf.firmware_inited))
|
||||
return;
|
||||
|
||||
|
||||
/* Tell MCU state machine to transit to next state */
|
||||
kbdev->csf.firmware_reloaded = true;
|
||||
kbase_pm_update_state(kbdev);
|
||||
|
|
@ -1019,7 +1015,7 @@ u32 kbase_csf_firmware_set_gpu_idle_hysteresis_time(struct kbase_device *kbdev,
|
|||
kbdev->csf.gpu_idle_dur_count = hysteresis_val;
|
||||
kbdev->csf.gpu_idle_dur_count_no_modifier = no_modifier;
|
||||
|
||||
if (kbdev->csf.gpu_idle_timer_enabled) {
|
||||
if (atomic_read(&kbdev->csf.scheduler.gpu_idle_timer_enabled)) {
|
||||
/* Timer is already enabled. Disable the timer as FW only reads
|
||||
* the new idle timer value when timer is re-enabled.
|
||||
*/
|
||||
|
|
@ -1142,7 +1138,7 @@ int kbase_csf_firmware_early_init(struct kbase_device *kbdev)
|
|||
INIT_WORK(&kbdev->csf.firmware_reload_work, kbase_csf_firmware_reload_worker);
|
||||
INIT_WORK(&kbdev->csf.fw_error_work, firmware_error_worker);
|
||||
|
||||
init_rwsem(&kbdev->csf.pmode_sync_sem);
|
||||
init_rwsem(&kbdev->csf.mmu_sync_sem);
|
||||
mutex_init(&kbdev->csf.reg_lock);
|
||||
kbase_csf_pending_gpuq_kick_queues_init(kbdev);
|
||||
|
||||
|
|
@ -1210,6 +1206,7 @@ int kbase_csf_firmware_load_init(struct kbase_device *kbdev)
|
|||
|
||||
/* NO_MALI: Don't load the MMU tables or boot CSF firmware */
|
||||
|
||||
|
||||
ret = invent_capabilities(kbdev);
|
||||
if (ret != 0)
|
||||
goto error;
|
||||
|
|
@ -1540,6 +1537,12 @@ void kbase_csf_firmware_disable_mcu(struct kbase_device *kbdev)
|
|||
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(MCU_CONTROL), MCU_CONTROL_REQ_DISABLE);
|
||||
}
|
||||
|
||||
void kbase_csf_stop_firmware_and_wait(struct kbase_device *kbdev)
|
||||
{
|
||||
/* Stop the MCU firmware, no wait required on NO_MALI instance */
|
||||
kbase_csf_firmware_disable_mcu(kbdev);
|
||||
}
|
||||
|
||||
void kbase_csf_firmware_disable_mcu_wait(struct kbase_device *kbdev)
|
||||
{
|
||||
/* NO_MALI: Nothing to do here */
|
||||
|
|
@ -1662,3 +1665,16 @@ void kbase_csf_firmware_mcu_shared_mapping_term(struct kbase_device *kbdev,
|
|||
vunmap(csf_mapping->cpu_addr);
|
||||
kfree(csf_mapping->phys);
|
||||
}
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
|
||||
void kbase_csf_firmware_soi_update(struct kbase_device *kbdev)
|
||||
{
|
||||
}
|
||||
|
||||
int kbase_csf_firmware_soi_disable_on_scheduler_suspend(struct kbase_device *kbdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* KBASE_PM_RUNTIME */
|
||||
|
|
|
|||
251
drivers/gpu/arm/bifrost/csf/mali_kbase_csf_fw_io.c
Normal file
251
drivers/gpu/arm/bifrost/csf/mali_kbase_csf_fw_io.c
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mali_kbase.h"
|
||||
#include "mali_kbase_csf_fw_io.h"
|
||||
#include <mali_kbase_linux.h>
|
||||
|
||||
#include <linux/mutex.h>
|
||||
|
||||
static inline u32 input_page_read(const u32 *const input, const u32 offset)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
return input[offset / sizeof(u32)];
|
||||
}
|
||||
|
||||
static inline void input_page_write(u32 *const input, const u32 offset, const u32 value)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
input[offset / sizeof(u32)] = value;
|
||||
}
|
||||
|
||||
static inline void input_page_partial_write(u32 *const input, const u32 offset, u32 value, u32 mask)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
input[offset / sizeof(u32)] = (input_page_read(input, offset) & ~mask) | (value & mask);
|
||||
}
|
||||
|
||||
static inline u32 output_page_read(const u32 *const output, const u32 offset)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
return output[offset / sizeof(u32)];
|
||||
}
|
||||
|
||||
void kbase_csf_fw_io_init(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
spin_lock_init(&fw_io->lock);
|
||||
bitmap_zero(fw_io->status, KBASE_FW_IO_STATUS_NUM_BITS);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_init);
|
||||
|
||||
void kbase_csf_fw_io_term(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_term);
|
||||
|
||||
void kbase_csf_fw_io_global_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset, u32 value)
|
||||
{
|
||||
const struct kbase_device *const kbdev = iface->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "glob input w: reg %08x val %08x\n", offset, value);
|
||||
input_page_write(iface->input, offset, value);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_global_write);
|
||||
|
||||
void kbase_csf_fw_io_global_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset,
|
||||
u32 value, u32 mask)
|
||||
{
|
||||
const struct kbase_device *const kbdev = iface->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "glob input w: reg %08x val %08x mask %08x\n", offset, value, mask);
|
||||
input_page_partial_write(iface->input, offset, value, mask);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_global_write_mask);
|
||||
|
||||
u32 kbase_csf_fw_io_global_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = iface->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = input_page_read(iface->input, offset);
|
||||
dev_dbg(kbdev->dev, "glob input r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_global_input_read);
|
||||
|
||||
u32 kbase_csf_fw_io_global_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = iface->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = output_page_read(iface->output, offset);
|
||||
dev_dbg(kbdev->dev, "glob output r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void kbase_csf_fw_io_group_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info, u32 offset,
|
||||
u32 value)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "csg input w: reg %08x val %08x\n", offset, value);
|
||||
input_page_write(info->input, offset, value);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_group_write);
|
||||
|
||||
void kbase_csf_fw_io_group_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info,
|
||||
u32 offset, u32 value, u32 mask)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "csg input w: reg %08x val %08x mask %08x\n", offset, value, mask);
|
||||
input_page_partial_write(info->input, offset, value, mask);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_group_write_mask);
|
||||
|
||||
u32 kbase_csf_fw_io_group_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = input_page_read(info->input, offset);
|
||||
dev_dbg(kbdev->dev, "csg input r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_group_input_read);
|
||||
|
||||
u32 kbase_csf_fw_io_group_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = output_page_read(info->output, offset);
|
||||
dev_dbg(kbdev->dev, "csg output r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void kbase_csf_fw_io_stream_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset,
|
||||
u32 value)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "cs input w: reg %08x val %08x\n", offset, value);
|
||||
input_page_write(info->input, offset, value);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_stream_write);
|
||||
|
||||
void kbase_csf_fw_io_stream_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset,
|
||||
u32 value, u32 mask)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "cs input w: reg %08x val %08x mask %08x\n", offset, value, mask);
|
||||
input_page_partial_write(info->input, offset, value, mask);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_stream_write_mask);
|
||||
|
||||
u32 kbase_csf_fw_io_stream_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = input_page_read(info->input, offset);
|
||||
dev_dbg(kbdev->dev, "cs input r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_stream_input_read);
|
||||
|
||||
u32 kbase_csf_fw_io_stream_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = output_page_read(info->output, offset);
|
||||
dev_dbg(kbdev->dev, "cs output r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void kbase_csf_fw_io_set_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit)
|
||||
{
|
||||
set_bit(status_bit, fw_io->status);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_set_status);
|
||||
|
||||
void kbase_csf_fw_io_clear_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit)
|
||||
{
|
||||
clear_bit(status_bit, fw_io->status);
|
||||
}
|
||||
|
||||
bool kbase_csf_fw_io_test_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit)
|
||||
{
|
||||
return test_bit(status_bit, fw_io->status);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_test_status);
|
||||
362
drivers/gpu/arm/bifrost/csf/mali_kbase_csf_fw_io.h
Normal file
362
drivers/gpu/arm/bifrost/csf/mali_kbase_csf_fw_io.h
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _KBASE_CSF_FW_IO_H_
|
||||
#define _KBASE_CSF_FW_IO_H_
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
/** The wait completed because the GPU was lost. */
|
||||
#define KBASE_CSF_FW_IO_WAIT_GPU_LOST 1
|
||||
|
||||
/** The wait was aborted because of an unexpected event. */
|
||||
#define KBASE_CSF_FW_IO_WAIT_UNSUPPORTED 255
|
||||
|
||||
/**
|
||||
* enum kbase_csf_fw_io_status_bits - Status bits for firmware I/O interface.
|
||||
*
|
||||
* @KBASE_FW_IO_STATUS_GPU_SUSPENDED: The GPU is suspended.
|
||||
* @KBASE_FW_IO_STATUS_NUM_BITS: Number of bits used to encode the state.
|
||||
*/
|
||||
enum kbase_csf_fw_io_status_bits {
|
||||
KBASE_FW_IO_STATUS_GPU_SUSPENDED = 0,
|
||||
KBASE_FW_IO_STATUS_NUM_BITS,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct kbase_csf_fw_io - Manager of firmware input/output interface.
|
||||
*
|
||||
* @lock: Mutex to serialize access to the interface.
|
||||
* @status: Internal status of the MCU interface.
|
||||
*/
|
||||
struct kbase_csf_fw_io {
|
||||
spinlock_t lock;
|
||||
DECLARE_BITMAP(status, KBASE_FW_IO_STATUS_NUM_BITS);
|
||||
};
|
||||
|
||||
struct kbase_csf_global_iface;
|
||||
struct kbase_csf_cmd_stream_group_info;
|
||||
struct kbase_csf_cmd_stream_info;
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_init() - Initialize manager of firmware input/output interface.
|
||||
*
|
||||
* @fw_io: Firmware I/O interface to initialize.
|
||||
*/
|
||||
void kbase_csf_fw_io_init(struct kbase_csf_fw_io *fw_io);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_term() - Terminate manager of firmware input/output interface.
|
||||
*
|
||||
* @fw_io: Firmware I/O interface to terminate.
|
||||
*/
|
||||
void kbase_csf_fw_io_term(struct kbase_csf_fw_io *fw_io);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_open() - Start a transaction with the firmware input/output interface.
|
||||
*
|
||||
* @fw_io: Firmware I/O interface to open.
|
||||
*
|
||||
* Return: 0 on success, otherwise an error code reflecting the status of the
|
||||
* interface.
|
||||
*/
|
||||
static inline int kbase_csf_fw_io_open(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
if (test_bit(KBASE_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status))
|
||||
return -KBASE_CSF_FW_IO_WAIT_GPU_LOST;
|
||||
|
||||
spin_lock(&fw_io->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_open_force() - Force a transaction with the firmware input/output interface.
|
||||
*
|
||||
* @fw_io: Firmware I/O interface to open.
|
||||
*
|
||||
* This function forces the start of a transaction regardless of the status
|
||||
* of the interface.
|
||||
*/
|
||||
static inline void kbase_csf_fw_io_open_force(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
spin_lock(&fw_io->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_close() - End a transaction with the firmware input/output interface.
|
||||
*
|
||||
* @fw_io: Firmware I/O interface to close.
|
||||
*/
|
||||
static inline void kbase_csf_fw_io_close(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
spin_unlock(&fw_io->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_assert_opened() - Assert if a transaction with the firmware input/output
|
||||
* interface has started.
|
||||
*
|
||||
* @fw_io: Firmware I/O interface.
|
||||
*/
|
||||
static inline void kbase_csf_fw_io_assert_opened(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_global_write() - Write a word in the global input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @iface: CSF interface provided by the firmware.
|
||||
* @offset: Offset of the word to write, in bytes.
|
||||
* @value: Value to be written.
|
||||
*/
|
||||
void kbase_csf_fw_io_global_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset,
|
||||
u32 value);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_global_write_mask() - Write part of a word in the global input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @iface: CSF interface provided by the firmware.
|
||||
* @offset: Offset of the word to write, in bytes.
|
||||
* @value: Value to be written.
|
||||
* @mask: Bitmask with the bits to be modified set.
|
||||
*/
|
||||
void kbase_csf_fw_io_global_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset,
|
||||
u32 value, u32 mask);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_global_input_read() - Read a word in the global input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @iface: CSF interface provided by the firmware.
|
||||
* @offset: Offset of the word to be read, in bytes.
|
||||
*
|
||||
* Return: Value of the word read from the global input page.
|
||||
*/
|
||||
u32 kbase_csf_fw_io_global_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_global_read() - Read a word in the global output page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @iface: CSF interface provided by the firmware.
|
||||
* @offset: Offset of the word to be read, in bytes.
|
||||
*
|
||||
* Return: Value of the word read from the global output page.
|
||||
*/
|
||||
u32 kbase_csf_fw_io_global_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_group_write() - Write a word in a CSG's input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @info: CSG interface provided by the firmware.
|
||||
* @offset: Offset of the word to write, in bytes.
|
||||
* @value: Value to be written.
|
||||
*/
|
||||
void kbase_csf_fw_io_group_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info, u32 offset,
|
||||
u32 value);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_group_write_mask() - Write part of a word in a CSG's input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @info: CSG interface provided by the firmware.
|
||||
* @offset: Offset of the word to write, in bytes.
|
||||
* @value: Value to be written.
|
||||
* @mask: Bitmask with the bits to be modified set.
|
||||
*/
|
||||
void kbase_csf_fw_io_group_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info,
|
||||
u32 offset, u32 value, u32 mask);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_group_input_read() - Read a word in a CSG's input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @info: CSG interface provided by the firmware.
|
||||
* @offset: Offset of the word to be read, in bytes.
|
||||
*
|
||||
* Return: Value of the word read from a CSG's input page.
|
||||
*/
|
||||
u32 kbase_csf_fw_io_group_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info,
|
||||
u32 offset);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_group_read() - Read a word in a CSG's output page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @info: CSG interface provided by the firmware.
|
||||
* @offset: Offset of the word to be read, in bytes.
|
||||
*
|
||||
* Return: Value of the word read from the CSG's output page.
|
||||
*/
|
||||
u32 kbase_csf_fw_io_group_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info, u32 offset);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_stream_write() - Write a word in a CS's input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @info: CSI interface provided by the firmware.
|
||||
* @offset: Offset of the word to write, in bytes.
|
||||
* @value: Value to be written.
|
||||
*/
|
||||
void kbase_csf_fw_io_stream_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset,
|
||||
u32 value);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_stream_write_mask() - Write part of a word in a CS's input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @info: CSI interface provided by the firmware.
|
||||
* @offset: Offset of the word to write, in bytes.
|
||||
* @value: Value to be written.
|
||||
* @mask: Bitmask with the bits to be modified set.
|
||||
*/
|
||||
void kbase_csf_fw_io_stream_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset,
|
||||
u32 value, u32 mask);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_stream_input_read() - Read a word in a CS's input page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @info: CSI interface provided by the firmware.
|
||||
* @offset: Offset of the word to be read, in bytes.
|
||||
*
|
||||
* Return: Value of the word read from a CS's input page.
|
||||
*/
|
||||
u32 kbase_csf_fw_io_stream_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_stream_read() - Read a word in a CS's output page.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @info: CSI interface provided by the firmware.
|
||||
* @offset: Offset of the word to be read, in bytes.
|
||||
*
|
||||
* Return: Value of the word read from the CS's output page.
|
||||
*/
|
||||
u32 kbase_csf_fw_io_stream_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_set_status() - Set a FW I/O status bit.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @status_bit: Status bit to set.
|
||||
*/
|
||||
void kbase_csf_fw_io_set_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_clear_status() - Clear a FW I/O status bit.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @status_bit: Status bit to clear.
|
||||
*/
|
||||
void kbase_csf_fw_io_clear_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_test_status() - Test a FW I/O status bit.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @status_bit: Status bit to test.
|
||||
*
|
||||
* Return: Value of the tested status bit.
|
||||
*/
|
||||
bool kbase_csf_fw_io_test_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit);
|
||||
|
||||
/**
|
||||
* kbase_csf_fw_io_wait_event_timeout() - Wait until condition gets true, timeout
|
||||
* occurs or a FW I/O status bit is set. The rest of the functionalities is equal
|
||||
* to wait_event_timeout().
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
* @wq_head: The waitqueue to wait on.
|
||||
* @condition: C expression for the event to wait for
|
||||
* @timeout: Timeout, in jiffies
|
||||
*
|
||||
* Return: Remaining jiffies (at least 1) on success,
|
||||
* 0 on timeout,
|
||||
* negative KBASE_CSF_FW_IO_WAIT_* error codes otherwise.
|
||||
*/
|
||||
#define kbase_csf_fw_io_wait_event_timeout(fw_io, wq_head, condition, timeout) \
|
||||
({ \
|
||||
int __ret; \
|
||||
int __wait_remaining = wait_event_timeout( \
|
||||
wq_head, condition || kbasep_csf_fw_io_check_status(fw_io), timeout); \
|
||||
__ret = kbasep_csf_fw_io_handle_wait_result(fw_io, __wait_remaining); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
/**
|
||||
* kbasep_csf_fw_io_check_status() - Private function to check if any FW I/O status bit is set.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager.
|
||||
*
|
||||
* Return: True if any FW I/O status bit is set, false otherwise.
|
||||
*/
|
||||
static inline bool kbasep_csf_fw_io_check_status(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
return !bitmap_empty(fw_io->status, KBASE_FW_IO_STATUS_NUM_BITS);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbasep_csf_fw_io_handle_wait_result() - Private function to handle the wait_event_timeout()
|
||||
* result.
|
||||
*
|
||||
* @fw_io: Firmware I/O manager
|
||||
* @wait_remaining: Remaining jiffies returned by wait_event_timeout()
|
||||
*
|
||||
* Return: Remaining jiffies (at least 1) on success,
|
||||
* 0 on timeout,
|
||||
* negative KBASE_CSF_FW_IO_WAIT_* error codes otherwise.
|
||||
*/
|
||||
static inline int kbasep_csf_fw_io_handle_wait_result(struct kbase_csf_fw_io *fw_io,
|
||||
int wait_remaining)
|
||||
{
|
||||
/* Check for any FW IO status bit set */
|
||||
if (!bitmap_empty(fw_io->status, KBASE_FW_IO_STATUS_NUM_BITS))
|
||||
return (test_bit(KBASE_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status)) ?
|
||||
-KBASE_CSF_FW_IO_WAIT_GPU_LOST :
|
||||
-KBASE_CSF_FW_IO_WAIT_UNSUPPORTED;
|
||||
|
||||
return wait_remaining;
|
||||
}
|
||||
#endif
|
||||
294
drivers/gpu/arm/bifrost/csf/mali_kbase_csf_fw_io_no_mali.c
Normal file
294
drivers/gpu/arm/bifrost/csf/mali_kbase_csf_fw_io_no_mali.c
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mali_kbase.h"
|
||||
#include "mali_kbase_csf_fw_io.h"
|
||||
#include <mali_kbase_linux.h>
|
||||
|
||||
#include <linux/mutex.h>
|
||||
|
||||
static inline u32 input_page_read(const u32 *const input, const u32 offset)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
return input[offset / sizeof(u32)];
|
||||
}
|
||||
|
||||
static inline void input_page_write(u32 *const input, const u32 offset, const u32 value)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
input[offset / sizeof(u32)] = value;
|
||||
}
|
||||
|
||||
static inline void input_page_partial_write(u32 *const input, const u32 offset, u32 value, u32 mask)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
input[offset / sizeof(u32)] = (input_page_read(input, offset) & ~mask) | (value & mask);
|
||||
}
|
||||
|
||||
static inline u32 output_page_read(const u32 *const output, const u32 offset)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
return output[offset / sizeof(u32)];
|
||||
}
|
||||
|
||||
static inline void output_page_write(u32 *const output, const u32 offset, const u32 value)
|
||||
{
|
||||
WARN_ON(offset % sizeof(u32));
|
||||
|
||||
output[offset / sizeof(u32)] = value;
|
||||
}
|
||||
|
||||
void kbase_csf_fw_io_init(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
spin_lock_init(&fw_io->lock);
|
||||
bitmap_zero(fw_io->status, KBASE_FW_IO_STATUS_NUM_BITS);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_init);
|
||||
|
||||
void kbase_csf_fw_io_term(struct kbase_csf_fw_io *fw_io)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_term);
|
||||
|
||||
void kbase_csf_fw_io_global_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset, u32 value)
|
||||
{
|
||||
const struct kbase_device *const kbdev = iface->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "glob input w: reg %08x val %08x\n", offset, value);
|
||||
input_page_write(iface->input, offset, value);
|
||||
|
||||
if (offset == GLB_REQ) {
|
||||
/* NO_MALI: Immediately acknowledge requests - except for PRFCNT_ENABLE
|
||||
* and PRFCNT_SAMPLE. These will be processed along with the
|
||||
* corresponding performance counter registers when the global doorbell
|
||||
* is rung in order to emulate the performance counter sampling behavior
|
||||
* of the real firmware.
|
||||
*/
|
||||
const u32 ack = output_page_read(iface->output, GLB_ACK);
|
||||
const u32 req_mask = ~(GLB_REQ_PRFCNT_ENABLE_MASK | GLB_REQ_PRFCNT_SAMPLE_MASK);
|
||||
const u32 toggled = (value ^ ack) & req_mask;
|
||||
|
||||
output_page_write(iface->output, GLB_ACK, ack ^ toggled);
|
||||
}
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_global_write);
|
||||
|
||||
void kbase_csf_fw_io_global_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset,
|
||||
u32 value, u32 mask)
|
||||
{
|
||||
const struct kbase_device *const kbdev = iface->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "glob input w: reg %08x val %08x mask %08x\n", offset, value, mask);
|
||||
|
||||
/* NO_MALI: Go through existing function to capture writes */
|
||||
kbase_csf_fw_io_global_write(fw_io, iface, offset,
|
||||
(input_page_read(iface->input, offset) & ~mask) |
|
||||
(value & mask));
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_global_write_mask);
|
||||
|
||||
u32 kbase_csf_fw_io_global_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = iface->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = input_page_read(iface->input, offset);
|
||||
dev_dbg(kbdev->dev, "glob input r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_global_input_read);
|
||||
|
||||
u32 kbase_csf_fw_io_global_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_global_iface *iface, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = iface->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = output_page_read(iface->output, offset);
|
||||
dev_dbg(kbdev->dev, "glob output r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void kbase_csf_fw_io_group_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info, u32 offset,
|
||||
u32 value)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "csg input w: reg %08x val %08x\n", offset, value);
|
||||
input_page_write(info->input, offset, value);
|
||||
|
||||
if (offset == CSG_REQ) {
|
||||
/* NO_MALI: Immediately acknowledge requests */
|
||||
output_page_write(info->output, CSG_ACK, value);
|
||||
}
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_group_write);
|
||||
|
||||
void kbase_csf_fw_io_group_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info,
|
||||
u32 offset, u32 value, u32 mask)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "csg input w: reg %08x val %08x mask %08x\n", offset, value, mask);
|
||||
|
||||
/* NO_MALI: Go through existing function to capture writes */
|
||||
kbase_csf_fw_io_group_write(fw_io, info, offset,
|
||||
(input_page_read(info->input, offset) & ~mask) |
|
||||
(value & mask));
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_group_write_mask);
|
||||
|
||||
u32 kbase_csf_fw_io_group_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = input_page_read(info->input, offset);
|
||||
dev_dbg(kbdev->dev, "csg input r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_group_input_read);
|
||||
|
||||
u32 kbase_csf_fw_io_group_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_group_info *info, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = output_page_read(info->output, offset);
|
||||
dev_dbg(kbdev->dev, "csg output r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void kbase_csf_fw_io_stream_write(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset,
|
||||
u32 value)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "cs input w: reg %08x val %08x\n", offset, value);
|
||||
input_page_write(info->input, offset, value);
|
||||
|
||||
if (offset == CS_REQ) {
|
||||
/* NO_MALI: Immediately acknowledge requests */
|
||||
output_page_write(info->output, CS_ACK, value);
|
||||
}
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_stream_write);
|
||||
|
||||
void kbase_csf_fw_io_stream_write_mask(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset,
|
||||
u32 value, u32 mask)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
dev_dbg(kbdev->dev, "cs input w: reg %08x val %08x mask %08x\n", offset, value, mask);
|
||||
|
||||
/* NO_MALI: Go through existing function to capture writes */
|
||||
kbase_csf_fw_io_stream_write(fw_io, info, offset,
|
||||
(input_page_read(info->input, offset) & ~mask) |
|
||||
(value & mask));
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_stream_write_mask);
|
||||
|
||||
u32 kbase_csf_fw_io_stream_input_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = input_page_read(info->input, offset);
|
||||
dev_dbg(kbdev->dev, "cs input r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_stream_input_read);
|
||||
|
||||
u32 kbase_csf_fw_io_stream_read(struct kbase_csf_fw_io *fw_io,
|
||||
const struct kbase_csf_cmd_stream_info *info, u32 offset)
|
||||
{
|
||||
const struct kbase_device *const kbdev = info->kbdev;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&fw_io->lock);
|
||||
|
||||
val = output_page_read(info->output, offset);
|
||||
dev_dbg(kbdev->dev, "cs output r: reg %08x val %08x\n", offset, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void kbase_csf_fw_io_set_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit)
|
||||
{
|
||||
set_bit(status_bit, fw_io->status);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_set_status);
|
||||
|
||||
void kbase_csf_fw_io_clear_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit)
|
||||
{
|
||||
clear_bit(status_bit, fw_io->status);
|
||||
}
|
||||
|
||||
bool kbase_csf_fw_io_test_status(struct kbase_csf_fw_io *fw_io,
|
||||
enum kbase_csf_fw_io_status_bits status_bit)
|
||||
{
|
||||
return test_bit(status_bit, fw_io->status);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_test_status);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -180,8 +180,9 @@ void kbase_csf_heap_context_allocator_term(struct kbase_csf_heap_context_allocat
|
|||
u64 kbase_csf_heap_context_allocator_alloc(struct kbase_csf_heap_context_allocator *const ctx_alloc)
|
||||
{
|
||||
struct kbase_context *const kctx = ctx_alloc->kctx;
|
||||
u64 flags = BASE_MEM_PROT_GPU_RD | BASE_MEM_PROT_GPU_WR | BASE_MEM_PROT_CPU_WR |
|
||||
BASEP_MEM_NO_USER_FREE | BASE_MEM_PROT_CPU_RD;
|
||||
base_mem_alloc_flags flags = BASE_MEM_PROT_GPU_RD | BASE_MEM_PROT_GPU_WR |
|
||||
BASE_MEM_PROT_CPU_WR | BASEP_MEM_NO_USER_FREE |
|
||||
BASE_MEM_PROT_CPU_RD;
|
||||
u64 nr_pages = PFN_UP(MAX_TILER_HEAPS * ctx_alloc->heap_context_size_aligned);
|
||||
u64 heap_gpu_va = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ static int kbase_kcpu_jit_allocate_prepare(struct kbase_kcpu_command_queue *kcpu
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (copy_from_user(info, data, sizeof(*info) * count) != 0) {
|
||||
if (copy_from_user(info, data, size_mul(sizeof(*info), count)) != 0) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
|
@ -563,7 +563,7 @@ static int kbase_kcpu_jit_free_prepare(struct kbase_kcpu_command_queue *kcpu_que
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
if (copy_from_user(ids, data, sizeof(*ids) * count)) {
|
||||
if (copy_from_user(ids, data, size_mul(sizeof(*ids), count))) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
|
@ -852,7 +852,8 @@ static int kbase_kcpu_cqs_wait_prepare(struct kbase_kcpu_command_queue *queue,
|
|||
if (!objs)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(objs, u64_to_user_ptr(cqs_wait_info->objs), nr_objs * sizeof(*objs))) {
|
||||
if (copy_from_user(objs, u64_to_user_ptr(cqs_wait_info->objs),
|
||||
size_mul(nr_objs, sizeof(*objs)))) {
|
||||
kfree(objs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -957,7 +958,8 @@ static int kbase_kcpu_cqs_set_prepare(struct kbase_kcpu_command_queue *kcpu_queu
|
|||
if (!objs)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(objs, u64_to_user_ptr(cqs_set_info->objs), nr_objs * sizeof(*objs))) {
|
||||
if (copy_from_user(objs, u64_to_user_ptr(cqs_set_info->objs),
|
||||
size_mul(nr_objs, sizeof(*objs)))) {
|
||||
kfree(objs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -1115,7 +1117,7 @@ static int kbase_kcpu_cqs_wait_operation_prepare(
|
|||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(objs, u64_to_user_ptr(cqs_wait_operation_info->objs),
|
||||
nr_objs * sizeof(*objs))) {
|
||||
size_mul(nr_objs, sizeof(*objs)))) {
|
||||
kfree(objs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
@ -1280,7 +1282,7 @@ static int kbase_kcpu_cqs_set_operation_prepare(
|
|||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(objs, u64_to_user_ptr(cqs_set_operation_info->objs),
|
||||
nr_objs * sizeof(*objs))) {
|
||||
size_mul(nr_objs, sizeof(*objs)))) {
|
||||
kfree(objs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,6 +172,11 @@
|
|||
#define CSG_STATUS_EP_CURRENT 0x0010 /* () Endpoint allocation status register */
|
||||
#define CSG_STATUS_EP_REQ 0x0014 /* () Endpoint request status register */
|
||||
#define CSG_RESOURCE_DEP 0x001C /* () Current resource dependencies */
|
||||
/* TODO: GPUCORE-xxxx: Remove after spec alignment, use 0x1C as CSG_RESOURCE_DEP is deprecated*/
|
||||
/* CSG_OUTPUT_BLOCK register offsets */
|
||||
#ifndef CSG_PROGRESS_TIMER_STATE
|
||||
#define CSG_PROGRESS_TIMER_STATE 0x001C /* () Current resource status */
|
||||
#endif
|
||||
|
||||
/* GLB_CONTROL_BLOCK register offsets */
|
||||
#define GLB_VERSION 0x0000 /* () Global interface version */
|
||||
|
|
@ -1243,6 +1248,21 @@
|
|||
CSG_STATUS_EP_REQ_EXCLUSIVE_FRAGMENT_MASK))
|
||||
|
||||
|
||||
/* CSG_PROGRESS_TIMER_STATE register */
|
||||
#ifndef CSG_PROGRESS_TIMER_STATE_GET
|
||||
#define CSG_PROGRESS_TIMER_STATE_SHIFT 0
|
||||
#define CSG_PROGRESS_TIMER_STATE_MASK ((u32)0xFFFFFFFF << CSG_PROGRESS_TIMER_STATE_SHIFT)
|
||||
#define CSG_PROGRESS_TIMER_STATE_GET(reg_val) \
|
||||
(((reg_val)&CSG_PROGRESS_TIMER_STATE_MASK) >> CSG_PROGRESS_TIMER_STATE_SHIFT)
|
||||
#define CSG_PROGRESS_TIMER_STATE_SET(reg_val, value) \
|
||||
(((reg_val) & ~CSG_PROGRESS_TIMER_STATE_MASK) | \
|
||||
(((value) << CSG_PROGRESS_TIMER_STATE_SHIFT) & CSG_PROGRESS_TIMER_STATE_MASK))
|
||||
/* CSG_PROGRESS_TIMER_STATE values */
|
||||
#define CSG_PROGRESS_TIMER_STATE_COMPUTE 0x0
|
||||
#define CSG_PROGRESS_TIMER_STATE_FRAGMENT 0x1
|
||||
#define CSG_PROGRESS_TIMER_STATE_TILER 0x2
|
||||
#define CSG_PROGRESS_TIMER_STATE_NEURAL 0x3
|
||||
#endif
|
||||
/* End of CSG_OUTPUT_BLOCK register set definitions */
|
||||
|
||||
/* STREAM_CONTROL_BLOCK register set definitions */
|
||||
|
|
@ -1380,6 +1400,13 @@
|
|||
#define GLB_REQ_SLEEP_SET(reg_val, value) \
|
||||
(((reg_val) & ~GLB_REQ_SLEEP_MASK) | \
|
||||
(((value) << GLB_REQ_SLEEP_SHIFT) & GLB_REQ_SLEEP_MASK))
|
||||
#define GLB_REQ_CFG_EVICTION_TIMER_SHIFT 16
|
||||
#define GLB_REQ_CFG_EVICTION_TIMER_MASK (0x1 << GLB_REQ_CFG_EVICTION_TIMER_SHIFT)
|
||||
#define GLB_REQ_CFG_EVICTION_TIMER_GET(reg_val) \
|
||||
(((reg_val)&GLB_REQ_CFG_EVICTION_TIMER_MASK) >> GLB_REQ_CFG_EVICTION_TIMER_SHIFT)
|
||||
#define GLB_REQ_CFG_EVICTION_TIMER_SET(reg_val, value) \
|
||||
(((reg_val) & ~GLB_REQ_CFG_EVICTION_TIMER_MASK) | \
|
||||
(((value) << GLB_REQ_CFG_EVICTION_TIMER_SHIFT) & GLB_REQ_CFG_EVICTION_TIMER_MASK))
|
||||
#define GLB_REQ_INACTIVE_COMPUTE_SHIFT 20
|
||||
#define GLB_REQ_INACTIVE_COMPUTE_MASK (0x1 << GLB_REQ_INACTIVE_COMPUTE_SHIFT)
|
||||
#define GLB_REQ_INACTIVE_COMPUTE_GET(reg_val) \
|
||||
|
|
@ -1524,6 +1551,17 @@
|
|||
(((reg_val) & ~GLB_ACK_IRQ_MASK_FIRMWARE_CONFIG_UPDATE_MASK) | \
|
||||
(((value) << GLB_ACK_IRQ_MASK_FIRMWARE_CONFIG_UPDATE_SHIFT) & \
|
||||
GLB_ACK_IRQ_MASK_FIRMWARE_CONFIG_UPDATE_MASK))
|
||||
#define GLB_ACK_IRQ_MASK_ITER_TRACE_ENABLE_SHIFT 11
|
||||
#define GLB_ACK_IRQ_MASK_ITER_TRACE_ENABLE_MASK (0x1 << GLB_ACK_IRQ_MASK_ITER_TRACE_ENABLE_SHIFT)
|
||||
#define GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_SHIFT 16
|
||||
#define GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_MASK (0x1 << GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_SHIFT)
|
||||
#define GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_GET(reg_val) \
|
||||
(((reg_val)&GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_MASK) >> \
|
||||
GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_SHIFT)
|
||||
#define GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_SET(reg_val, value) \
|
||||
(((reg_val) & ~GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_MASK) | \
|
||||
(((value) << GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_SHIFT) & \
|
||||
GLB_ACK_IRQ_MASK_CFG_EVICTION_TIMER_MASK))
|
||||
#define GLB_ACK_IRQ_MASK_INACTIVE_COMPUTE_SHIFT 20
|
||||
#define GLB_ACK_IRQ_MASK_INACTIVE_COMPUTE_MASK (0x1 << GLB_ACK_IRQ_MASK_INACTIVE_COMPUTE_SHIFT)
|
||||
#define GLB_ACK_IRQ_MASK_INACTIVE_COMPUTE_GET(reg_val) \
|
||||
|
|
@ -1635,6 +1673,45 @@
|
|||
GLB_PWROFF_TIMER_CONFIG_NO_MODIFIER_MASK))
|
||||
#endif /* End of GLB_PWROFF_TIMER_CONFIG values */
|
||||
|
||||
/* GLB_EVICTION_TIMER register */
|
||||
#ifndef GLB_EVICTION_TIMER
|
||||
#define GLB_EVICTION_TIMER 0x0090
|
||||
#define GLB_EVICTION_TIMER_TIMEOUT_SHIFT (0)
|
||||
#define GLB_EVICTION_TIMER_TIMEOUT_MASK ((0x7FFFFFFF) << GLB_EVICTION_TIMER_TIMEOUT_SHIFT)
|
||||
#define GLB_EVICTION_TIMER_TIMEOUT_GET(reg_val) \
|
||||
(((reg_val)&GLB_EVICTION_TIMER_TIMEOUT_MASK) >> GLB_EVICTION_TIMER_TIMEOUT_SHIFT)
|
||||
#define GLB_EVICTION_TIMER_TIMEOUT_SET(reg_val, value) \
|
||||
(((reg_val) & ~GLB_EVICTION_TIMER_TIMEOUT_MASK) | \
|
||||
(((value) << GLB_EVICTION_TIMER_TIMEOUT_SHIFT) & GLB_EVICTION_TIMER_TIMEOUT_MASK))
|
||||
#define GLB_EVICTION_TIMER_TIMER_SOURCE_SHIFT (31)
|
||||
#define GLB_EVICTION_TIMER_TIMER_SOURCE_MASK ((0x1) << GLB_EVICTION_TIMER_TIMER_SOURCE_SHIFT)
|
||||
#define GLB_EVICTION_TIMER_TIMER_SOURCE_GET(reg_val) \
|
||||
(((reg_val)&GLB_EVICTION_TIMER_TIMER_SOURCE_MASK) >> GLB_EVICTION_TIMER_TIMER_SOURCE_SHIFT)
|
||||
#define GLB_EVICTION_TIMER_TIMER_SOURCE_SET(reg_val, value) \
|
||||
(((reg_val) & ~GLB_EVICTION_TIMER_TIMER_SOURCE_MASK) | \
|
||||
(((value) << GLB_EVICTION_TIMER_TIMER_SOURCE_SHIFT) & \
|
||||
GLB_EVICTION_TIMER_TIMER_SOURCE_MASK))
|
||||
/* GLB_EVICTION_TIMER_TIMER_SOURCE values */
|
||||
#define GLB_EVICTION_TIMER_TIMER_SOURCE_SYSTEM_TIMESTAMP 0x0U
|
||||
#define GLB_EVICTION_TIMER_TIMER_SOURCE_GPU_COUNTER 0x1U
|
||||
/* End of GLB_EVICTION_TIMER_TIMER_SOURCE values */
|
||||
#endif /* End of GLB_EVICTION_TIMER */
|
||||
|
||||
/* GLB_EVICTION_TIMER_CONFIG register */
|
||||
#ifndef GLB_EVICTION_TIMER_CONFIG
|
||||
#define GLB_EVICTION_TIMER_CONFIG 0x0094 /* () Configuration fields for GLB_EVICTION_TIMER */
|
||||
#define GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_SHIFT 0
|
||||
#define GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_MASK \
|
||||
(0x1 << GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_SHIFT)
|
||||
#define GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_GET(reg_val) \
|
||||
(((reg_val)&GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_MASK) >> \
|
||||
GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_SHIFT)
|
||||
#define GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_SET(reg_val, value) \
|
||||
(((reg_val) & ~GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_MASK) | \
|
||||
(((value) << GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_SHIFT) & \
|
||||
GLB_EVICTION_TIMER_CONFIG_NO_MODIFIER_MASK))
|
||||
#endif /* End of GLB_EVICTION_TIMER_CONFIG values */
|
||||
|
||||
/* GLB_ALLOC_EN register */
|
||||
#define GLB_ALLOC_EN_MASK_SHIFT 0
|
||||
#define GLB_ALLOC_EN_MASK_MASK (GPU_ULL(0xFFFFFFFFFFFFFFFF) << GLB_ALLOC_EN_MASK_SHIFT)
|
||||
|
|
@ -1717,6 +1794,15 @@
|
|||
(((reg_val) & ~GLB_IDLE_TIMER_CONFIG_NO_MODIFIER_MASK) | \
|
||||
(((value) << GLB_IDLE_TIMER_CONFIG_NO_MODIFIER_SHIFT) & \
|
||||
GLB_IDLE_TIMER_CONFIG_NO_MODIFIER_MASK))
|
||||
#define GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_SHIFT 9
|
||||
#define GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_MASK (0x1 << GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_SHIFT)
|
||||
#define GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_GET(reg_val) \
|
||||
(((reg_val)&GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_MASK) >> \
|
||||
GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_SHIFT)
|
||||
#define GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_SET(reg_val, value) \
|
||||
(((reg_val) & ~GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_MASK) | \
|
||||
(((value) << GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_SHIFT) & \
|
||||
GLB_IDLE_TIMER_CONFIG_SLEEP_ON_IDLE_MASK))
|
||||
#endif /* End of GLB_IDLE_TIMER_CONFIG values */
|
||||
|
||||
/* GLB_INSTR_FEATURES register */
|
||||
|
|
|
|||
|
|
@ -496,12 +496,10 @@ static void kbase_csf_reset_gpu_worker(struct work_struct *data)
|
|||
|
||||
bool kbase_prepare_to_reset_gpu(struct kbase_device *kbdev, unsigned int flags)
|
||||
{
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (kbase_pm_is_gpu_lost(kbdev)) {
|
||||
/* GPU access has been removed, reset will be done by Arbiter instead */
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags & RESET_FLAGS_HWC_UNRECOVERABLE_ERROR)
|
||||
kbase_hwcnt_backend_csf_on_unrecoverable_error(&kbdev->hwcnt_gpu_iface);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include <csf/mali_kbase_csf_trace_buffer.h>
|
||||
#endif /* CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD */
|
||||
|
||||
|
||||
/* Value to indicate that a queue group is not groups_to_schedule list */
|
||||
#define KBASEP_GROUP_PREPARED_SEQ_NUM_INVALID (U32_MAX)
|
||||
|
||||
|
|
@ -93,6 +94,11 @@ static bool queue_group_scheduled_locked(struct kbase_queue_group *group);
|
|||
|
||||
#define kctx_as_enabled(kctx) (!kbase_ctx_flag(kctx, KCTX_AS_DISABLED_ON_FAULT))
|
||||
|
||||
bool is_gpu_level_suspend_supported(struct kbase_device *const kbdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD)
|
||||
/**
|
||||
* gpu_metrics_ctx_init() - Take a reference on GPU metrics context if it exists,
|
||||
|
|
@ -1196,13 +1202,20 @@ static void scheduler_wakeup(struct kbase_device *kbdev, bool kick)
|
|||
scheduler_enable_tick_timer_nolock(kbdev);
|
||||
}
|
||||
|
||||
static void scheduler_suspend(struct kbase_device *kbdev)
|
||||
static int scheduler_suspend(struct kbase_device *kbdev)
|
||||
{
|
||||
struct kbase_csf_scheduler *const scheduler = &kbdev->csf.scheduler;
|
||||
|
||||
lockdep_assert_held(&scheduler->lock);
|
||||
|
||||
if (!WARN_ON(scheduler->state == SCHED_SUSPENDED)) {
|
||||
#if KBASE_PM_RUNTIME
|
||||
int ret;
|
||||
|
||||
ret = kbase_csf_firmware_soi_disable_on_scheduler_suspend(kbdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif /* KBASE_PM_RUNTIME */
|
||||
dev_dbg(kbdev->dev, "Suspending the Scheduler");
|
||||
scheduler_pm_idle(kbdev);
|
||||
scheduler->state = SCHED_SUSPENDED;
|
||||
|
|
@ -1211,6 +1224,8 @@ static void scheduler_suspend(struct kbase_device *kbdev)
|
|||
#endif
|
||||
KBASE_KTRACE_ADD(kbdev, SCHED_SUSPENDED, NULL, scheduler->state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1462,7 +1477,7 @@ static int sched_halt_stream(struct kbase_queue *queue)
|
|||
long remaining;
|
||||
int slot;
|
||||
int err = 0;
|
||||
const u32 group_schedule_timeout = kbase_get_timeout_ms(kbdev, CSF_CSG_SUSPEND_TIMEOUT);
|
||||
const u32 group_schedule_timeout = kbdev->csf.csg_suspend_timeout_ms;
|
||||
const u32 fw_timeout_ms = kbase_get_timeout_ms(kbdev, CSF_FIRMWARE_TIMEOUT);
|
||||
|
||||
if (WARN_ON(!group))
|
||||
|
|
@ -1942,7 +1957,6 @@ static enum kbase_csf_csg_slot_state update_csg_slot_status(struct kbase_device
|
|||
if ((state == CSG_ACK_STATE_START) || (state == CSG_ACK_STATE_RESUME)) {
|
||||
slot_state = CSG_SLOT_RUNNING;
|
||||
atomic_set(&csg_slot->state, slot_state);
|
||||
csg_slot->trigger_jiffies = jiffies;
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_SLOT_RUNNING, csg_slot->resident_group,
|
||||
state);
|
||||
dev_dbg(kbdev->dev, "Group %u running on slot %d\n",
|
||||
|
|
@ -1953,7 +1967,6 @@ static enum kbase_csf_csg_slot_state update_csg_slot_status(struct kbase_device
|
|||
if ((state == CSG_ACK_STATE_SUSPEND) || (state == CSG_ACK_STATE_TERMINATE)) {
|
||||
slot_state = CSG_SLOT_STOPPED;
|
||||
atomic_set(&csg_slot->state, slot_state);
|
||||
csg_slot->trigger_jiffies = jiffies;
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_SLOT_STOPPED, csg_slot->resident_group,
|
||||
state);
|
||||
dev_dbg(kbdev->dev, "Group %u stopped on slot %d\n",
|
||||
|
|
@ -2052,7 +2065,6 @@ static void halt_csg_slot(struct kbase_queue_group *group, bool suspend)
|
|||
kbase_csf_ring_csg_doorbell(kbdev, slot);
|
||||
spin_unlock_irqrestore(&kbdev->csf.scheduler.interrupt_lock, flags);
|
||||
atomic_set(&csg_slot[slot].state, CSG_SLOT_DOWN2STOP);
|
||||
csg_slot[slot].trigger_jiffies = jiffies;
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_SLOT_STOP_REQ, group, halt_cmd);
|
||||
|
||||
KBASE_TLSTREAM_TL_KBASE_DEVICE_HALTING_CSG(kbdev, kbdev->id, (u32)slot, suspend);
|
||||
|
|
@ -2367,11 +2379,6 @@ static void cancel_tock_work(struct kbase_csf_scheduler *const scheduler)
|
|||
atomic_set(&scheduler->pending_tock_work, false);
|
||||
}
|
||||
|
||||
static void cancel_gpu_idle_work(struct kbase_csf_scheduler *const scheduler)
|
||||
{
|
||||
atomic_set(&scheduler->pending_gpu_idle_work, false);
|
||||
}
|
||||
|
||||
static void remove_group_from_runnable(struct kbase_csf_scheduler *const scheduler,
|
||||
struct kbase_queue_group *group,
|
||||
enum kbase_csf_group_state run_state)
|
||||
|
|
@ -2776,7 +2783,6 @@ static bool cleanup_csg_slot(struct kbase_queue_group *group)
|
|||
spin_unlock_bh(&kbdev->csf.scheduler.gpu_metrics_lock);
|
||||
#endif
|
||||
|
||||
csg_slot->trigger_jiffies = jiffies;
|
||||
atomic_set(&csg_slot->state, CSG_SLOT_READY);
|
||||
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_SLOT_CLEANED, group, (u64)slot);
|
||||
|
|
@ -2990,7 +2996,6 @@ static void program_csg_slot(struct kbase_queue_group *group, s8 slot, u8 prio)
|
|||
|
||||
/* Update status before rings the door-bell, marking ready => run */
|
||||
atomic_set(&csg_slot->state, CSG_SLOT_READY2RUN);
|
||||
csg_slot->trigger_jiffies = jiffies;
|
||||
csg_slot->priority = prio;
|
||||
|
||||
/* Trace the programming of the CSG on the slot */
|
||||
|
|
@ -3556,8 +3561,7 @@ static void program_suspending_csg_slots(struct kbase_device *kbdev)
|
|||
|
||||
while (!bitmap_empty(slot_mask, MAX_SUPPORTED_CSGS)) {
|
||||
DECLARE_BITMAP(changed, MAX_SUPPORTED_CSGS);
|
||||
long remaining = kbase_csf_timeout_in_jiffies(
|
||||
kbase_get_timeout_ms(kbdev, CSF_CSG_SUSPEND_TIMEOUT));
|
||||
long remaining = kbase_csf_timeout_in_jiffies(kbdev->csf.csg_suspend_timeout_ms);
|
||||
|
||||
bitmap_copy(changed, slot_mask, MAX_SUPPORTED_CSGS);
|
||||
|
||||
|
|
@ -4101,7 +4105,7 @@ static void scheduler_group_check_protm_enter(struct kbase_device *const kbdev,
|
|||
* entry to protected mode happens with a memory region being locked and
|
||||
* the same region is then accessed by the GPU in protected mode.
|
||||
*/
|
||||
down_write(&kbdev->csf.pmode_sync_sem);
|
||||
down_write(&kbdev->csf.mmu_sync_sem);
|
||||
spin_lock_irqsave(&scheduler->interrupt_lock, flags);
|
||||
|
||||
/* Check if the previous transition to enter & exit the protected
|
||||
|
|
@ -4167,7 +4171,7 @@ static void scheduler_group_check_protm_enter(struct kbase_device *const kbdev,
|
|||
spin_unlock_irqrestore(&scheduler->interrupt_lock, flags);
|
||||
|
||||
err = kbase_csf_wait_protected_mode_enter(kbdev);
|
||||
up_write(&kbdev->csf.pmode_sync_sem);
|
||||
up_write(&kbdev->csf.mmu_sync_sem);
|
||||
|
||||
if (err)
|
||||
schedule_actions_trigger_df(
|
||||
|
|
@ -4182,7 +4186,7 @@ static void scheduler_group_check_protm_enter(struct kbase_device *const kbdev,
|
|||
}
|
||||
|
||||
spin_unlock_irqrestore(&scheduler->interrupt_lock, flags);
|
||||
up_write(&kbdev->csf.pmode_sync_sem);
|
||||
up_write(&kbdev->csf.mmu_sync_sem);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -4760,27 +4764,28 @@ static int suspend_active_groups_on_powerdown(struct kbase_device *kbdev, bool s
|
|||
{
|
||||
struct kbase_csf_scheduler *const scheduler = &kbdev->csf.scheduler;
|
||||
DECLARE_BITMAP(slot_mask, MAX_SUPPORTED_CSGS) = { 0 };
|
||||
int ret;
|
||||
|
||||
ret = suspend_active_queue_groups(kbdev, slot_mask, false);
|
||||
if (unlikely(suspend_active_queue_groups(kbdev, slot_mask, false))) {
|
||||
if (!is_gpu_level_suspend_supported(kbdev)) {
|
||||
const int csg_nr = ffs(slot_mask[0]) - 1;
|
||||
struct kbase_queue_group *group;
|
||||
enum dumpfault_error_type error_type = DF_CSG_SUSPEND_TIMEOUT;
|
||||
|
||||
if (unlikely(ret)) {
|
||||
const int csg_nr = ffs(slot_mask[0]) - 1;
|
||||
struct kbase_queue_group *group = scheduler->csg_slots[csg_nr].resident_group;
|
||||
enum dumpfault_error_type error_type = DF_CSG_SUSPEND_TIMEOUT;
|
||||
group = scheduler->csg_slots[csg_nr].resident_group;
|
||||
|
||||
/* The suspend of CSGs failed,
|
||||
* trigger the GPU reset to be in a deterministic state.
|
||||
*/
|
||||
dev_warn(
|
||||
kbdev->dev,
|
||||
"[%llu] Timeout (%d ms) waiting for CSG slots to suspend on power down, slot_mask: 0x%*pb\n",
|
||||
kbase_backend_get_cycle_cnt(kbdev),
|
||||
kbase_get_timeout_ms(kbdev, CSF_FIRMWARE_TIMEOUT),
|
||||
kbdev->csf.global_iface.group_num, slot_mask);
|
||||
if (kbase_csf_firmware_ping_wait(kbdev, FW_PING_AFTER_ERROR_TIMEOUT_MS))
|
||||
error_type = DF_PING_REQUEST_TIMEOUT;
|
||||
schedule_actions_trigger_df(kbdev, group->kctx, error_type);
|
||||
/* The suspend of CSGs failed,
|
||||
* trigger the GPU reset to be in a deterministic state.
|
||||
*/
|
||||
dev_warn(
|
||||
kbdev->dev,
|
||||
"[%llu] Timeout (%d ms) waiting for CSG slots to suspend on power down, slot_mask: 0x%*pb\n",
|
||||
kbase_backend_get_cycle_cnt(kbdev),
|
||||
kbase_get_timeout_ms(kbdev, CSF_FIRMWARE_TIMEOUT),
|
||||
kbdev->csf.global_iface.group_num, slot_mask);
|
||||
if (kbase_csf_firmware_ping_wait(kbdev, FW_PING_AFTER_ERROR_TIMEOUT_MS))
|
||||
error_type = DF_PING_REQUEST_TIMEOUT;
|
||||
schedule_actions_trigger_df(kbdev, group->kctx, error_type);
|
||||
}
|
||||
|
||||
if (kbase_prepare_to_reset_gpu(kbdev, RESET_FLAGS_NONE))
|
||||
kbase_reset_gpu(kbdev);
|
||||
|
|
@ -4788,6 +4793,8 @@ static int suspend_active_groups_on_powerdown(struct kbase_device *kbdev, bool s
|
|||
return -1;
|
||||
}
|
||||
|
||||
kbdev->csf.mcu_halted = false;
|
||||
|
||||
/* Check if the groups became active whilst the suspend was ongoing,
|
||||
* but only for the case where the system suspend is not in progress
|
||||
*/
|
||||
|
|
@ -4947,9 +4954,13 @@ static bool scheduler_suspend_on_idle(struct kbase_device *kbdev)
|
|||
}
|
||||
|
||||
dev_dbg(kbdev->dev, "Scheduler to be suspended on GPU becoming idle");
|
||||
scheduler_suspend(kbdev);
|
||||
cancel_tick_work(scheduler);
|
||||
return true;
|
||||
ret = scheduler_suspend(kbdev);
|
||||
if (!ret) {
|
||||
cancel_tick_work(scheduler);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gpu_idle_worker(struct kbase_device *kbdev)
|
||||
|
|
@ -5193,8 +5204,7 @@ static int wait_csg_slots_suspend(struct kbase_device *kbdev, unsigned long *slo
|
|||
bitmap_copy(slot_mask_local, slot_mask, MAX_SUPPORTED_CSGS);
|
||||
|
||||
while (!bitmap_empty(slot_mask_local, MAX_SUPPORTED_CSGS)) {
|
||||
long remaining = kbase_csf_timeout_in_jiffies(
|
||||
kbase_get_timeout_ms(kbdev, CSF_CSG_SUSPEND_TIMEOUT));
|
||||
long remaining = kbase_csf_timeout_in_jiffies(kbdev->csf.csg_suspend_timeout_ms);
|
||||
DECLARE_BITMAP(changed, MAX_SUPPORTED_CSGS);
|
||||
|
||||
bitmap_copy(changed, slot_mask_local, MAX_SUPPORTED_CSGS);
|
||||
|
|
@ -5343,20 +5353,6 @@ static void evict_lru_or_blocked_csg(struct kbase_device *kbdev)
|
|||
}
|
||||
}
|
||||
|
||||
static void scheduler_enable_gpu_idle_timer(struct kbase_device *kbdev)
|
||||
{
|
||||
struct kbase_csf_scheduler *scheduler = &kbdev->csf.scheduler;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&scheduler->lock);
|
||||
|
||||
if (!kbdev->csf.gpu_idle_timer_enabled) {
|
||||
spin_lock_irqsave(&scheduler->interrupt_lock, flags);
|
||||
kbase_csf_firmware_enable_gpu_idle_timer(kbdev);
|
||||
spin_unlock_irqrestore(&scheduler->interrupt_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void schedule_actions(struct kbase_device *kbdev, bool is_tick)
|
||||
{
|
||||
struct kbase_csf_scheduler *scheduler = &kbdev->csf.scheduler;
|
||||
|
|
@ -5399,7 +5395,6 @@ static void schedule_actions(struct kbase_device *kbdev, bool is_tick)
|
|||
* in particular, no alterations to on-slot CSGs.
|
||||
*/
|
||||
if (keep_lru_on_slots(kbdev)) {
|
||||
scheduler_enable_gpu_idle_timer(kbdev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -5472,7 +5467,6 @@ redo_local_tock:
|
|||
|
||||
wait_csg_slots_start(kbdev);
|
||||
wait_csg_slots_finish_prio_update(kbdev);
|
||||
scheduler_enable_gpu_idle_timer(kbdev);
|
||||
|
||||
if (new_protm_top_grp) {
|
||||
scheduler_group_check_protm_enter(kbdev, scheduler->top_grp);
|
||||
|
|
@ -5495,6 +5489,15 @@ redo_local_tock:
|
|||
}
|
||||
|
||||
evict_lru_or_blocked_csg(kbdev);
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
if (atomic_read(&scheduler->non_idle_offslot_grps))
|
||||
set_bit(KBASE_GPU_NON_IDLE_OFF_SLOT_GROUPS_AVAILABLE,
|
||||
&kbdev->pm.backend.gpu_sleep_allowed);
|
||||
else
|
||||
clear_bit(KBASE_GPU_NON_IDLE_OFF_SLOT_GROUPS_AVAILABLE,
|
||||
&kbdev->pm.backend.gpu_sleep_allowed);
|
||||
#endif /* KBASE_PM_RUNTIME */
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -5653,19 +5656,20 @@ static int suspend_active_queue_groups(struct kbase_device *kbdev, unsigned long
|
|||
{
|
||||
struct kbase_csf_scheduler *const scheduler = &kbdev->csf.scheduler;
|
||||
u32 num_groups = kbdev->csf.global_iface.group_num;
|
||||
struct kbase_queue_group *group;
|
||||
u32 slot_num;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&scheduler->lock);
|
||||
|
||||
for (slot_num = 0; slot_num < num_groups; slot_num++) {
|
||||
struct kbase_queue_group *group = scheduler->csg_slots[slot_num].resident_group;
|
||||
for (slot_num = 0; slot_num < num_groups; slot_num++) {
|
||||
group = scheduler->csg_slots[slot_num].resident_group;
|
||||
|
||||
if (group) {
|
||||
if (group) {
|
||||
suspend_queue_group(group);
|
||||
set_bit(slot_num, slot_mask);
|
||||
set_bit(slot_num, slot_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = wait_csg_slots_suspend(kbdev, slot_mask);
|
||||
return ret;
|
||||
|
|
@ -5819,7 +5823,10 @@ static void scheduler_inner_reset(struct kbase_device *kbdev)
|
|||
/* Cancel any potential queued delayed work(s) */
|
||||
cancel_tick_work(scheduler);
|
||||
cancel_tock_work(scheduler);
|
||||
cancel_gpu_idle_work(scheduler);
|
||||
/* gpu_idle_worker() might already be running at this point, which
|
||||
* could decrement the pending_gpu_idle_worker counter to below 0.
|
||||
* It'd be safer to let it run if one has already been scheduled.
|
||||
*/
|
||||
cancel_delayed_work_sync(&scheduler->ping_work);
|
||||
|
||||
mutex_lock(&scheduler->lock);
|
||||
|
|
@ -5837,10 +5844,22 @@ static void scheduler_inner_reset(struct kbase_device *kbdev)
|
|||
scheduler->top_kctx = NULL;
|
||||
scheduler->top_grp = NULL;
|
||||
|
||||
atomic_set(&scheduler->gpu_idle_timer_enabled, false);
|
||||
atomic_set(&scheduler->fw_soi_enabled, false);
|
||||
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, SCHEDULER_TOP_GRP, scheduler->top_grp,
|
||||
scheduler->num_active_address_spaces |
|
||||
(((u64)scheduler->total_runnable_grps) << 32));
|
||||
|
||||
#ifdef KBASE_PM_RUNTIME
|
||||
if (scheduler->state == SCHED_SLEEPING) {
|
||||
#if IS_ENABLED(CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD)
|
||||
hrtimer_cancel(&scheduler->gpu_metrics_timer);
|
||||
#endif
|
||||
scheduler->state = SCHED_SUSPENDED;
|
||||
KBASE_KTRACE_ADD(kbdev, SCHED_SUSPENDED, NULL, scheduler->state);
|
||||
}
|
||||
#endif
|
||||
mutex_unlock(&scheduler->lock);
|
||||
}
|
||||
|
||||
|
|
@ -6726,6 +6745,11 @@ static int kbase_csf_scheduler_kthread(void *data)
|
|||
while (atomic_read(&scheduler->pending_gpu_idle_work) > 0)
|
||||
gpu_idle_worker(kbdev);
|
||||
|
||||
/* Update GLB_IDLE timer/FW Sleep-on-Idle config (which might
|
||||
* have been disabled during FW boot et. al.).
|
||||
*/
|
||||
kbase_csf_firmware_soi_update(kbdev);
|
||||
|
||||
dev_dbg(kbdev->dev, "Waking up for event after a scheduling iteration.");
|
||||
wake_up_all(&kbdev->csf.event_wait);
|
||||
}
|
||||
|
|
@ -6786,6 +6810,9 @@ int kbase_csf_scheduler_init(struct kbase_device *kbdev)
|
|||
scheduler->gpu_metrics_timer.function = gpu_metrics_timer_callback;
|
||||
#endif /* CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD */
|
||||
|
||||
atomic_set(&scheduler->gpu_idle_timer_enabled, false);
|
||||
atomic_set(&scheduler->fw_soi_enabled, false);
|
||||
|
||||
return kbase_csf_mcu_shared_regs_data_init(kbdev);
|
||||
}
|
||||
|
||||
|
|
@ -6988,8 +7015,9 @@ int kbase_csf_scheduler_pm_suspend_no_lock(struct kbase_device *kbdev)
|
|||
goto exit;
|
||||
} else {
|
||||
dev_dbg(kbdev->dev, "Scheduler PM suspend");
|
||||
scheduler_suspend(kbdev);
|
||||
cancel_tick_work(scheduler);
|
||||
result = scheduler_suspend(kbdev);
|
||||
if (!result)
|
||||
cancel_tick_work(scheduler);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -693,4 +693,6 @@ void kbase_csf_scheduler_force_wakeup(struct kbase_device *kbdev);
|
|||
void kbase_csf_scheduler_force_sleep(struct kbase_device *kbdev);
|
||||
#endif
|
||||
|
||||
bool is_gpu_level_suspend_supported(struct kbase_device *const kbdev);
|
||||
|
||||
#endif /* _KBASE_CSF_SCHEDULER_H_ */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -260,8 +260,9 @@ static struct kbase_csf_tiler_heap_chunk *alloc_new_chunk(struct kbase_context *
|
|||
u64 chunk_size)
|
||||
{
|
||||
u64 nr_pages = PFN_UP(chunk_size);
|
||||
u64 flags = BASE_MEM_PROT_GPU_RD | BASE_MEM_PROT_GPU_WR | BASE_MEM_PROT_CPU_WR |
|
||||
BASEP_MEM_NO_USER_FREE | BASE_MEM_COHERENT_LOCAL | BASE_MEM_PROT_CPU_RD;
|
||||
base_mem_alloc_flags flags = BASE_MEM_PROT_GPU_RD | BASE_MEM_PROT_GPU_WR |
|
||||
BASE_MEM_PROT_CPU_WR | BASEP_MEM_NO_USER_FREE |
|
||||
BASE_MEM_COHERENT_LOCAL | BASE_MEM_PROT_CPU_RD;
|
||||
struct kbase_csf_tiler_heap_chunk *chunk = NULL;
|
||||
/* The chunk kernel mapping needs to be large enough to:
|
||||
* - initially zero the CHUNK_HDR_SIZE area
|
||||
|
|
@ -350,13 +351,14 @@ static struct kbase_csf_tiler_heap_chunk *alloc_new_chunk(struct kbase_context *
|
|||
}
|
||||
|
||||
remove_external_chunk_mappings(kctx, chunk);
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
|
||||
/* If page migration is enabled, we don't want to migrate tiler heap pages.
|
||||
* This does not change if the constituent pages are already marked as isolated.
|
||||
*/
|
||||
if (kbase_is_page_migration_enabled())
|
||||
kbase_set_phy_alloc_page_status(chunk->region->gpu_alloc, NOT_MOVABLE);
|
||||
kbase_set_phy_alloc_page_status(kctx, chunk->region->gpu_alloc, NOT_MOVABLE);
|
||||
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
|
||||
return chunk;
|
||||
|
||||
|
|
@ -640,7 +642,7 @@ static bool kbasep_is_buffer_descriptor_region_suitable(struct kbase_context *co
|
|||
|
||||
if (!(reg->flags & KBASE_REG_CPU_RD) || kbase_is_region_shrinkable(reg) ||
|
||||
(reg->flags & KBASE_REG_PF_GROW)) {
|
||||
dev_err(kctx->kbdev->dev, "Region has invalid flags: 0x%lX!\n", reg->flags);
|
||||
dev_err(kctx->kbdev->dev, "Region has invalid flags: 0x%llX!\n", reg->flags);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -737,7 +739,7 @@ int kbase_csf_tiler_heap_init(struct kbase_context *const kctx, u32 const chunk_
|
|||
KBASE_VMAP_FLAG_PERMANENT_MAP_ACCOUNTING);
|
||||
|
||||
if (kbase_is_page_migration_enabled())
|
||||
kbase_set_phy_alloc_page_status(buf_desc_reg->gpu_alloc, NOT_MOVABLE);
|
||||
kbase_set_phy_alloc_page_status(kctx, buf_desc_reg->gpu_alloc, NOT_MOVABLE);
|
||||
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -469,14 +469,15 @@ unsigned int kbase_csf_firmware_trace_buffer_read_data(struct firmware_trace_buf
|
|||
} else {
|
||||
unsigned int bytes_copied_head, bytes_copied_tail;
|
||||
|
||||
bytes_copied_tail = min_t(unsigned int, num_bytes, (buffer_size - extract_offset));
|
||||
bytes_copied_tail =
|
||||
min_t(unsigned int, num_bytes, size_sub(buffer_size, extract_offset));
|
||||
memcpy(data, &data_cpu_va[extract_offset], bytes_copied_tail);
|
||||
|
||||
bytes_copied_head =
|
||||
min_t(unsigned int, (num_bytes - bytes_copied_tail), insert_offset);
|
||||
memcpy(&data[bytes_copied_tail], data_cpu_va, bytes_copied_head);
|
||||
|
||||
bytes_copied = bytes_copied_head + bytes_copied_tail;
|
||||
bytes_copied = size_add(bytes_copied_head, bytes_copied_tail);
|
||||
extract_offset += bytes_copied;
|
||||
if (extract_offset >= buffer_size)
|
||||
extract_offset = bytes_copied_head;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2022-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2022-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -443,7 +443,7 @@ kbase_debug_coresight_csf_config_create(void *client_data,
|
|||
}
|
||||
|
||||
config = kzalloc(sizeof(struct kbase_debug_coresight_csf_config), GFP_KERNEL);
|
||||
if (WARN_ON(!client))
|
||||
if (WARN_ON(!config))
|
||||
return NULL;
|
||||
|
||||
config->client = client;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2020-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -212,6 +212,9 @@ KBASE_KTRACE_CODE_MAKE_CODE(SCHEDULER_EVICT_CTX_SLOTS_START),
|
|||
KBASE_KTRACE_CODE_MAKE_CODE(SCHED_BUSY), KBASE_KTRACE_CODE_MAKE_CODE(SCHED_INACTIVE),
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(SCHED_SUSPENDED), KBASE_KTRACE_CODE_MAKE_CODE(SCHED_SLEEPING),
|
||||
|
||||
/* info_val == true if FW Sleep-on-Idle is enabled, false otherwise */
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(FIRMWARE_SLEEP_ON_IDLE_CHANGED),
|
||||
|
||||
/* info_val = mcu state */
|
||||
#define KBASEP_MCU_STATE(n) KBASE_KTRACE_CODE_MAKE_CODE(PM_MCU_##n),
|
||||
#include "backend/gpu/mali_kbase_pm_mcu_states.h"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2020-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -69,6 +69,7 @@ DEFINE_MALI_ADD_EVENT(SCHED_BUSY);
|
|||
DEFINE_MALI_ADD_EVENT(SCHED_INACTIVE);
|
||||
DEFINE_MALI_ADD_EVENT(SCHED_SUSPENDED);
|
||||
DEFINE_MALI_ADD_EVENT(SCHED_SLEEPING);
|
||||
DEFINE_MALI_ADD_EVENT(FIRMWARE_SLEEP_ON_IDLE_CHANGED);
|
||||
#define KBASEP_MCU_STATE(n) DEFINE_MALI_ADD_EVENT(PM_MCU_##n);
|
||||
#include "backend/gpu/mali_kbase_pm_mcu_states.h"
|
||||
#undef KBASEP_MCU_STATE
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2011-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2011-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -149,13 +149,17 @@ KBASE_KTRACE_CODE_MAKE_CODE(CORE_CTX_DESTROY),
|
|||
KBASE_KTRACE_CODE_MAKE_CODE(SCHED_RETAIN_CTX_NOLOCK),
|
||||
/* info_val == kctx->refcount */
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(SCHED_RELEASE_CTX),
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
/*
|
||||
* Arbitration events
|
||||
*/
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_GPU_LOST), KBASE_KTRACE_CODE_MAKE_CODE(ARB_VM_STATE),
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_VM_STATE),
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_VM_EVT),
|
||||
#endif
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_GPU_GRANTED),
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_GPU_LOST),
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_GPU_STARTED),
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_GPU_STOP_REQUESTED),
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_GPU_STOPPED),
|
||||
KBASE_KTRACE_CODE_MAKE_CODE(ARB_GPU_REQUESTED),
|
||||
|
||||
#if MALI_USE_CSF
|
||||
#include "debug/backend/mali_kbase_debug_ktrace_codes_csf.h"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -95,13 +95,16 @@ DEFINE_MALI_ADD_EVENT(PM_RUNTIME_RESUME_CALLBACK);
|
|||
#undef KBASEP_L2_STATE
|
||||
DEFINE_MALI_ADD_EVENT(SCHED_RETAIN_CTX_NOLOCK);
|
||||
DEFINE_MALI_ADD_EVENT(SCHED_RELEASE_CTX);
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
|
||||
DEFINE_MALI_ADD_EVENT(ARB_GPU_LOST);
|
||||
DEFINE_MALI_ADD_EVENT(ARB_VM_STATE);
|
||||
DEFINE_MALI_ADD_EVENT(ARB_VM_EVT);
|
||||
DEFINE_MALI_ADD_EVENT(ARB_GPU_GRANTED);
|
||||
DEFINE_MALI_ADD_EVENT(ARB_GPU_LOST);
|
||||
DEFINE_MALI_ADD_EVENT(ARB_GPU_STARTED);
|
||||
DEFINE_MALI_ADD_EVENT(ARB_GPU_STOP_REQUESTED);
|
||||
DEFINE_MALI_ADD_EVENT(ARB_GPU_STOPPED);
|
||||
DEFINE_MALI_ADD_EVENT(ARB_GPU_REQUESTED);
|
||||
|
||||
#endif
|
||||
#if MALI_USE_CSF
|
||||
#include "backend/mali_kbase_debug_linux_ktrace_csf.h"
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -132,11 +132,15 @@ static int kbase_backend_late_init(struct kbase_device *kbdev)
|
|||
|
||||
fail_update_l2_features:
|
||||
kbase_backend_devfreq_term(kbdev);
|
||||
fail_devfreq_init:
|
||||
kbasep_pm_metrics_term(kbdev);
|
||||
fail_pm_metrics_init:
|
||||
kbase_ipa_control_term(kbdev);
|
||||
|
||||
fail_devfreq_init:
|
||||
{
|
||||
kbasep_pm_metrics_term(kbdev);
|
||||
}
|
||||
fail_pm_metrics_init:
|
||||
{
|
||||
kbase_ipa_control_term(kbdev);
|
||||
}
|
||||
#ifdef CONFIG_MALI_BIFROST_DEBUG
|
||||
#if IS_ENABLED(CONFIG_MALI_REAL_HW)
|
||||
fail_interrupt_test:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
bool kbase_is_gpu_removed(struct kbase_device *kbdev)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_MALI_ARBITER_SUPPORT))
|
||||
if (!kbase_has_arbiter(kbdev))
|
||||
return false;
|
||||
|
||||
|
||||
|
|
@ -88,6 +88,7 @@ static void kbase_gpu_fault_interrupt(struct kbase_device *kbdev)
|
|||
void kbase_gpu_interrupt(struct kbase_device *kbdev, u32 val)
|
||||
{
|
||||
u32 power_changed_mask = (POWER_CHANGED_ALL | MCU_STATUS_GPU_IRQ);
|
||||
struct kbase_csf_scheduler *scheduler = &kbdev->csf.scheduler;
|
||||
|
||||
|
||||
KBASE_KTRACE_ADD(kbdev, CORE_GPU_IRQ, NULL, val);
|
||||
|
|
@ -95,7 +96,6 @@ void kbase_gpu_interrupt(struct kbase_device *kbdev, u32 val)
|
|||
kbase_gpu_fault_interrupt(kbdev);
|
||||
|
||||
if (val & GPU_PROTECTED_FAULT) {
|
||||
struct kbase_csf_scheduler *scheduler = &kbdev->csf.scheduler;
|
||||
unsigned long flags;
|
||||
|
||||
dev_err_ratelimited(kbdev->dev, "GPU fault in protected mode");
|
||||
|
|
@ -149,10 +149,33 @@ void kbase_gpu_interrupt(struct kbase_device *kbdev, u32 val)
|
|||
unsigned long flags;
|
||||
|
||||
dev_dbg(kbdev->dev, "Doorbell mirror interrupt received");
|
||||
|
||||
/* Assume that the doorbell comes from userspace which
|
||||
* presents new works in order to invalidate a possible GPU
|
||||
* idle event.
|
||||
* If the doorbell was raised by KBase then the FW would handle
|
||||
* the pending doorbell then raise a 2nd GBL_IDLE IRQ which
|
||||
* would allow us to put the GPU to sleep.
|
||||
*/
|
||||
atomic_set(&scheduler->gpu_no_longer_idle, true);
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
kbase_pm_disable_db_mirror_interrupt(kbdev);
|
||||
kbdev->pm.backend.exit_gpu_sleep_mode = true;
|
||||
kbase_csf_scheduler_invoke_tick(kbdev);
|
||||
|
||||
if (likely(kbdev->pm.backend.mcu_state == KBASE_MCU_IN_SLEEP)) {
|
||||
kbdev->pm.backend.exit_gpu_sleep_mode = true;
|
||||
kbase_csf_scheduler_invoke_tick(kbdev);
|
||||
} else if (likely(test_bit(KBASE_GPU_SUPPORTS_FW_SLEEP_ON_IDLE,
|
||||
&kbdev->pm.backend.gpu_sleep_allowed)) &&
|
||||
(kbdev->pm.backend.mcu_state != KBASE_MCU_ON_PEND_SLEEP)) {
|
||||
/* The firmware is going to sleep on its own but new
|
||||
* doorbells were rung before we manage to handle
|
||||
* the GLB_IDLE IRQ in the bottom half. We shall enable
|
||||
* DB notification to allow the DB to be handled by FW.
|
||||
*/
|
||||
dev_dbg(kbdev->dev, "Re-enabling MCU immediately following DB_MIRROR IRQ");
|
||||
kbase_pm_enable_mcu_db_notification(kbdev);
|
||||
}
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -179,7 +202,7 @@ void kbase_gpu_interrupt(struct kbase_device *kbdev, u32 val)
|
|||
* cores.
|
||||
*/
|
||||
if (kbdev->pm.backend.l2_always_on ||
|
||||
kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TTRX_921))
|
||||
kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TTRX_921))
|
||||
kbase_pm_power_changed(kbdev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
bool kbase_is_gpu_removed(struct kbase_device *kbdev)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_MALI_ARBITER_SUPPORT))
|
||||
if (!kbase_has_arbiter(kbdev))
|
||||
return false;
|
||||
|
||||
return (KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(GPU_ID)) == 0);
|
||||
|
|
@ -103,7 +103,7 @@ void kbase_gpu_interrupt(struct kbase_device *kbdev, u32 val)
|
|||
* cores.
|
||||
*/
|
||||
if (kbdev->pm.backend.l2_always_on ||
|
||||
kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TTRX_921))
|
||||
kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TTRX_921))
|
||||
kbase_pm_power_changed(kbdev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,10 +32,6 @@
|
|||
#include <hwcnt/backend/mali_kbase_hwcnt_backend_jm_watchdog.h>
|
||||
#include <backend/gpu/mali_kbase_model_linux.h>
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
#include <arbiter/mali_kbase_arbiter_pm.h>
|
||||
#endif
|
||||
|
||||
#include <mali_kbase.h>
|
||||
#include <backend/gpu/mali_kbase_irq_internal.h>
|
||||
#include <backend/gpu/mali_kbase_jm_internal.h>
|
||||
|
|
|
|||
|
|
@ -51,10 +51,7 @@
|
|||
#include "backend/gpu/mali_kbase_irq_internal.h"
|
||||
#include "mali_kbase_regs_history_debugfs.h"
|
||||
#include "mali_kbase_pbha.h"
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
#include "arbiter/mali_kbase_arbiter_pm.h"
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS) && !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
|
||||
|
||||
|
|
@ -69,6 +66,22 @@ static DEFINE_MUTEX(kbase_dev_list_lock);
|
|||
static LIST_HEAD(kbase_dev_list);
|
||||
static unsigned int kbase_dev_nr;
|
||||
|
||||
static unsigned int mma_wa_id;
|
||||
|
||||
static int set_mma_wa_id(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
return kbase_param_set_uint_minmax(val, kp, 1, 15);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops mma_wa_id_ops = {
|
||||
.set = set_mma_wa_id,
|
||||
.get = param_get_uint,
|
||||
};
|
||||
|
||||
module_param_cb(mma_wa_id, &mma_wa_id_ops, &mma_wa_id, 0444);
|
||||
__MODULE_PARM_TYPE(mma_wa_id, "uint");
|
||||
MODULE_PARM_DESC(mma_wa_id, "PBHA ID for MMA workaround. Valid range is from 1 to 15.");
|
||||
|
||||
struct kbase_device *kbase_device_alloc(void)
|
||||
{
|
||||
return vzalloc(sizeof(struct kbase_device));
|
||||
|
|
@ -320,6 +333,10 @@ int kbase_device_misc_init(struct kbase_device *const kbdev)
|
|||
if (err)
|
||||
goto dma_set_mask_failed;
|
||||
|
||||
/* Set mma_wa_id if it has been passed in as a module parameter */
|
||||
if ((kbdev->gpu_props.gpu_id.arch_id >= GPU_ID_ARCH_MAKE(14, 8, 0)) && mma_wa_id != 0)
|
||||
kbdev->mma_wa_id = mma_wa_id;
|
||||
|
||||
err = kbase_pbha_read_dtb(kbdev);
|
||||
if (err)
|
||||
goto term_as;
|
||||
|
|
@ -597,17 +614,12 @@ int kbase_device_early_init(struct kbase_device *kbdev)
|
|||
/* We're done accessing the GPU registers for now. */
|
||||
kbase_pm_register_access_disable(kbdev);
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (kbdev->arb.arb_if) {
|
||||
if (kbase_has_arbiter(kbdev)) {
|
||||
if (kbdev->pm.arb_vm_state)
|
||||
err = kbase_arbiter_pm_install_interrupts(kbdev);
|
||||
} else {
|
||||
err = kbase_install_interrupts(kbdev);
|
||||
}
|
||||
#else
|
||||
err = kbase_install_interrupts(kbdev);
|
||||
#endif
|
||||
|
||||
if (err)
|
||||
goto gpuprops_term;
|
||||
|
||||
|
|
@ -633,15 +645,10 @@ ktrace_term:
|
|||
|
||||
void kbase_device_early_term(struct kbase_device *kbdev)
|
||||
{
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (kbdev->arb.arb_if)
|
||||
if (kbase_has_arbiter(kbdev))
|
||||
kbase_arbiter_pm_release_interrupts(kbdev);
|
||||
else
|
||||
kbase_release_interrupts(kbdev);
|
||||
#else
|
||||
kbase_release_interrupts(kbdev);
|
||||
#endif
|
||||
|
||||
kbase_gpuprops_term(kbdev);
|
||||
kbase_device_backend_term(kbdev);
|
||||
kbase_regmap_term(kbdev);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
#define KBASE_REGMAP_ACCESS_ALWAYS_POWERED (1U << 16)
|
||||
|
||||
static u32 always_powered_regs[] = {
|
||||
#if MALI_USE_CSF
|
||||
#else /* MALI_USE_CSF */
|
||||
|
||||
#if !MALI_USE_CSF
|
||||
PTM_AW_IRQ_CLEAR,
|
||||
PTM_AW_IRQ_INJECTION,
|
||||
PTM_AW_IRQ_MASK,
|
||||
|
|
@ -44,13 +44,19 @@ static u32 always_powered_regs[] = {
|
|||
PTM_AW_MESSAGE__PTM_OUTGOING_MESSAGE1,
|
||||
PTM_AW_MESSAGE__PTM_OUTGOING_MESSAGE_STATUS,
|
||||
PTM_ID,
|
||||
#endif /* MALI_USE_CSF */
|
||||
#endif /* !MALI_USE_CSF */
|
||||
};
|
||||
|
||||
static void kbasep_reg_setup_always_powered_registers(struct kbase_device *kbdev)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
|
||||
#if !MALI_USE_CSF
|
||||
if (kbdev->gpu_props.gpu_id.arch_id < GPU_ID_ARCH_MAKE(9, 14, 0))
|
||||
return;
|
||||
#endif /* MALI_USE_CSF */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(always_powered_regs); i++) {
|
||||
u32 reg_enum = always_powered_regs[i];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2023-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2023-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@
|
|||
*/
|
||||
#define AS_MEMATTR_ATTRIBUTE0_MEMORY_TYPE_SHARED 0x0
|
||||
|
||||
|
||||
/* CSF_CONFIG register */
|
||||
#define CSF_CONFIG_FORCE_COHERENCY_FEATURES_SHIFT 2
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -78,6 +78,18 @@ typedef int kbase_hwcnt_backend_init_fn(const struct kbase_hwcnt_backend_info *i
|
|||
*/
|
||||
typedef void kbase_hwcnt_backend_term_fn(struct kbase_hwcnt_backend *backend);
|
||||
|
||||
/**
|
||||
* typedef kbase_hwcnt_backend_acquire_fn - Enable counter collection.
|
||||
* @backend: Non-NULL pointer to backend interface.
|
||||
*/
|
||||
typedef void kbase_hwcnt_backend_acquire_fn(const struct kbase_hwcnt_backend *backend);
|
||||
|
||||
/**
|
||||
* typedef kbase_hwcnt_backend_release_fn - Disable counter collection.
|
||||
* @backend: Non-NULL pointer to backend interface.
|
||||
*/
|
||||
typedef void kbase_hwcnt_backend_release_fn(const struct kbase_hwcnt_backend *backend);
|
||||
|
||||
/**
|
||||
* typedef kbase_hwcnt_backend_timestamp_ns_fn - Get the current backend
|
||||
* timestamp.
|
||||
|
|
@ -206,6 +218,10 @@ typedef int kbase_hwcnt_backend_dump_get_fn(struct kbase_hwcnt_backend *backend,
|
|||
* metadata.
|
||||
* @init: Function ptr to initialise an instance of the backend.
|
||||
* @term: Function ptr to terminate an instance of the backend.
|
||||
* @acquire: Callback to indicate that counter collection has
|
||||
* been enabled.
|
||||
* @release: Callback to indicate that counter collection has
|
||||
* been disabled.
|
||||
* @timestamp_ns: Function ptr to get the current backend timestamp.
|
||||
* @dump_enable: Function ptr to enable dumping.
|
||||
* @dump_enable_nolock: Function ptr to enable dumping while the
|
||||
|
|
@ -222,6 +238,8 @@ struct kbase_hwcnt_backend_interface {
|
|||
kbase_hwcnt_backend_metadata_fn *metadata;
|
||||
kbase_hwcnt_backend_init_fn *init;
|
||||
kbase_hwcnt_backend_term_fn *term;
|
||||
kbase_hwcnt_backend_acquire_fn *acquire;
|
||||
kbase_hwcnt_backend_release_fn *release;
|
||||
kbase_hwcnt_backend_timestamp_ns_fn *timestamp_ns;
|
||||
kbase_hwcnt_backend_dump_enable_fn *dump_enable;
|
||||
kbase_hwcnt_backend_dump_enable_nolock_fn *dump_enable_nolock;
|
||||
|
|
|
|||
|
|
@ -1710,6 +1710,22 @@ static void kbasep_hwcnt_backend_csf_term(struct kbase_hwcnt_backend *backend)
|
|||
kbasep_hwcnt_backend_csf_destroy(backend_csf);
|
||||
}
|
||||
|
||||
static void kbasep_hwcnt_backend_csf_acquire(const struct kbase_hwcnt_backend *backend)
|
||||
{
|
||||
struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
|
||||
struct kbase_hwcnt_backend_csf_info *csf_info = backend_csf->info;
|
||||
|
||||
csf_info->csf_if->acquire(csf_info->csf_if->ctx);
|
||||
}
|
||||
|
||||
static void kbasep_hwcnt_backend_csf_release(const struct kbase_hwcnt_backend *backend)
|
||||
{
|
||||
struct kbase_hwcnt_backend_csf *backend_csf = (struct kbase_hwcnt_backend_csf *)backend;
|
||||
struct kbase_hwcnt_backend_csf_info *csf_info = backend_csf->info;
|
||||
|
||||
csf_info->csf_if->release(csf_info->csf_if->ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbasep_hwcnt_backend_csf_info_destroy() - Destroy a CSF backend info.
|
||||
* @info: Pointer to info to destroy.
|
||||
|
|
@ -2168,6 +2184,8 @@ int kbase_hwcnt_backend_csf_create(struct kbase_hwcnt_backend_csf_if *csf_if, u3
|
|||
iface->metadata = kbasep_hwcnt_backend_csf_metadata;
|
||||
iface->init = kbasep_hwcnt_backend_csf_init;
|
||||
iface->term = kbasep_hwcnt_backend_csf_term;
|
||||
iface->acquire = kbasep_hwcnt_backend_csf_acquire;
|
||||
iface->release = kbasep_hwcnt_backend_csf_release;
|
||||
iface->timestamp_ns = kbasep_hwcnt_backend_csf_timestamp_ns;
|
||||
iface->dump_enable = kbasep_hwcnt_backend_csf_dump_enable;
|
||||
iface->dump_enable_nolock = kbasep_hwcnt_backend_csf_dump_enable_nolock;
|
||||
|
|
|
|||
|
|
@ -114,6 +114,20 @@ typedef void (*kbase_hwcnt_backend_csf_if_lock_fn)(struct kbase_hwcnt_backend_cs
|
|||
typedef void (*kbase_hwcnt_backend_csf_if_unlock_fn)(struct kbase_hwcnt_backend_csf_if_ctx *ctx,
|
||||
unsigned long flags);
|
||||
|
||||
/**
|
||||
* typedef kbase_hwcnt_backend_csf_if_acquire_fn - Enable counter collection.
|
||||
*
|
||||
* @ctx: Non-NULL pointer to a CSF context.
|
||||
*/
|
||||
typedef void (*kbase_hwcnt_backend_csf_if_acquire_fn)(struct kbase_hwcnt_backend_csf_if_ctx *ctx);
|
||||
|
||||
/**
|
||||
* typedef kbase_hwcnt_backend_csf_if_release_fn - Disable counter collection.
|
||||
*
|
||||
* @ctx: Non-NULL pointer to a CSF context.
|
||||
*/
|
||||
typedef void (*kbase_hwcnt_backend_csf_if_release_fn)(struct kbase_hwcnt_backend_csf_if_ctx *ctx);
|
||||
|
||||
/**
|
||||
* typedef kbase_hwcnt_backend_csf_if_get_prfcnt_info_fn - Get performance
|
||||
* counter information.
|
||||
|
|
@ -272,6 +286,10 @@ typedef void (*kbase_hwcnt_backend_csf_if_get_gpu_cycle_count_fn)(
|
|||
* @assert_lock_held: Function ptr to assert backend spinlock is held.
|
||||
* @lock: Function ptr to acquire backend spinlock.
|
||||
* @unlock: Function ptr to release backend spinlock.
|
||||
* @acquire: Callback to indicate that counter collection has
|
||||
* been enabled.
|
||||
* @release: Callback to indicate that counter collection has
|
||||
* been disabled.
|
||||
* @get_prfcnt_info: Function ptr to get performance counter related
|
||||
* information.
|
||||
* @ring_buf_alloc: Function ptr to allocate ring buffer for CSF HWC.
|
||||
|
|
@ -292,6 +310,8 @@ struct kbase_hwcnt_backend_csf_if {
|
|||
kbase_hwcnt_backend_csf_if_assert_lock_held_fn assert_lock_held;
|
||||
kbase_hwcnt_backend_csf_if_lock_fn lock;
|
||||
kbase_hwcnt_backend_csf_if_unlock_fn unlock;
|
||||
kbase_hwcnt_backend_csf_if_acquire_fn acquire;
|
||||
kbase_hwcnt_backend_csf_if_release_fn release;
|
||||
kbase_hwcnt_backend_csf_if_get_prfcnt_info_fn get_prfcnt_info;
|
||||
kbase_hwcnt_backend_csf_if_ring_buf_alloc_fn ring_buf_alloc;
|
||||
kbase_hwcnt_backend_csf_if_ring_buf_sync_fn ring_buf_sync;
|
||||
|
|
|
|||
|
|
@ -131,6 +131,26 @@ static void kbasep_hwcnt_backend_csf_if_fw_unlock(struct kbase_hwcnt_backend_csf
|
|||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
}
|
||||
|
||||
static void kbasep_hwcnt_backend_csf_if_fw_acquire(struct kbase_hwcnt_backend_csf_if_ctx *ctx)
|
||||
{
|
||||
struct kbase_hwcnt_backend_csf_if_fw_ctx *fw_ctx =
|
||||
(struct kbase_hwcnt_backend_csf_if_fw_ctx *)ctx;
|
||||
|
||||
/* Mark performance counters collection as enabled */
|
||||
set_bit(KBASE_GPU_PERF_COUNTERS_COLLECTION_ENABLED,
|
||||
&fw_ctx->kbdev->pm.backend.gpu_sleep_allowed);
|
||||
}
|
||||
|
||||
static void kbasep_hwcnt_backend_csf_if_fw_release(struct kbase_hwcnt_backend_csf_if_ctx *ctx)
|
||||
{
|
||||
struct kbase_hwcnt_backend_csf_if_fw_ctx *fw_ctx =
|
||||
(struct kbase_hwcnt_backend_csf_if_fw_ctx *)ctx;
|
||||
|
||||
/* Mark performance counters collection as disabled */
|
||||
clear_bit(KBASE_GPU_PERF_COUNTERS_COLLECTION_ENABLED,
|
||||
&fw_ctx->kbdev->pm.backend.gpu_sleep_allowed);
|
||||
}
|
||||
|
||||
/**
|
||||
* kbasep_hwcnt_backend_csf_if_fw_on_freq_change() - On freq change callback
|
||||
*
|
||||
|
|
@ -813,6 +833,8 @@ int kbase_hwcnt_backend_csf_if_fw_create(struct kbase_device *kbdev,
|
|||
if_fw->assert_lock_held = kbasep_hwcnt_backend_csf_if_fw_assert_lock_held;
|
||||
if_fw->lock = kbasep_hwcnt_backend_csf_if_fw_lock;
|
||||
if_fw->unlock = kbasep_hwcnt_backend_csf_if_fw_unlock;
|
||||
if_fw->acquire = kbasep_hwcnt_backend_csf_if_fw_acquire;
|
||||
if_fw->release = kbasep_hwcnt_backend_csf_if_fw_release;
|
||||
if_fw->get_prfcnt_info = kbasep_hwcnt_backend_csf_if_fw_get_prfcnt_info;
|
||||
if_fw->ring_buf_alloc = kbasep_hwcnt_backend_csf_if_fw_ring_buf_alloc;
|
||||
if_fw->ring_buf_sync = kbasep_hwcnt_backend_csf_if_fw_ring_buf_sync;
|
||||
|
|
|
|||
|
|
@ -683,7 +683,7 @@ static int kbasep_hwcnt_backend_jm_dump_alloc(const struct kbase_hwcnt_backend_j
|
|||
struct kbase_context *kctx, u64 *gpu_dump_va)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
u64 flags;
|
||||
base_mem_alloc_flags flags;
|
||||
u64 nr_pages;
|
||||
|
||||
/* Calls to this function are inherently asynchronous, with respect to
|
||||
|
|
@ -851,6 +851,14 @@ static void kbasep_hwcnt_backend_jm_term(struct kbase_hwcnt_backend *backend)
|
|||
kbasep_hwcnt_backend_jm_destroy((struct kbase_hwcnt_backend_jm *)backend);
|
||||
}
|
||||
|
||||
static void kbasep_hwcnt_backend_jm_acquire(const struct kbase_hwcnt_backend *backend)
|
||||
{
|
||||
}
|
||||
|
||||
static void kbasep_hwcnt_backend_jm_release(const struct kbase_hwcnt_backend *backend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* kbasep_hwcnt_backend_jm_info_destroy() - Destroy a JM backend info.
|
||||
* @info: Pointer to info to destroy.
|
||||
|
|
@ -932,6 +940,8 @@ int kbase_hwcnt_backend_jm_create(struct kbase_device *kbdev,
|
|||
iface->metadata = kbasep_hwcnt_backend_jm_metadata;
|
||||
iface->init = kbasep_hwcnt_backend_jm_init;
|
||||
iface->term = kbasep_hwcnt_backend_jm_term;
|
||||
iface->acquire = kbasep_hwcnt_backend_jm_acquire;
|
||||
iface->release = kbasep_hwcnt_backend_jm_release;
|
||||
iface->timestamp_ns = kbasep_hwcnt_backend_jm_timestamp_ns;
|
||||
iface->dump_enable = kbasep_hwcnt_backend_jm_dump_enable;
|
||||
iface->dump_enable_nolock = kbasep_hwcnt_backend_jm_dump_enable_nolock;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2021-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2021-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -317,6 +317,14 @@ kbasep_hwcnt_backend_jm_watchdog_term_partial(struct kbase_hwcnt_backend_jm_watc
|
|||
kfree(wd_backend);
|
||||
}
|
||||
|
||||
static void kbasep_hwcnt_backend_jm_watchdog_acquire(const struct kbase_hwcnt_backend *backend)
|
||||
{
|
||||
}
|
||||
|
||||
static void kbasep_hwcnt_backend_jm_watchdog_release(const struct kbase_hwcnt_backend *backend)
|
||||
{
|
||||
}
|
||||
|
||||
/* Job manager watchdog backend, implementation of kbase_hwcnt_backend_term_fn
|
||||
* Calling term does *not* destroy the interface
|
||||
*/
|
||||
|
|
@ -807,6 +815,8 @@ int kbase_hwcnt_backend_jm_watchdog_create(struct kbase_hwcnt_backend_interface
|
|||
.metadata = kbasep_hwcnt_backend_jm_watchdog_metadata,
|
||||
.init = kbasep_hwcnt_backend_jm_watchdog_init,
|
||||
.term = kbasep_hwcnt_backend_jm_watchdog_term,
|
||||
.acquire = kbasep_hwcnt_backend_jm_watchdog_acquire,
|
||||
.release = kbasep_hwcnt_backend_jm_watchdog_release,
|
||||
.timestamp_ns = kbasep_hwcnt_backend_jm_watchdog_timestamp_ns,
|
||||
.dump_enable = kbasep_hwcnt_backend_jm_watchdog_dump_enable,
|
||||
.dump_enable_nolock = kbasep_hwcnt_backend_jm_watchdog_dump_enable_nolock,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -599,6 +599,9 @@ int kbase_hwcnt_accumulator_acquire(struct kbase_hwcnt_context *hctx,
|
|||
return errcode;
|
||||
}
|
||||
|
||||
/* Inform the backend that counter collection has been enabled. */
|
||||
hctx->iface->acquire(hctx->accum.backend);
|
||||
|
||||
spin_lock_irqsave(&hctx->state_lock, flags);
|
||||
|
||||
WARN_ON(hctx->disable_count == 0);
|
||||
|
|
@ -646,6 +649,9 @@ void kbase_hwcnt_accumulator_release(struct kbase_hwcnt_accumulator *accum)
|
|||
|
||||
mutex_unlock(&hctx->accum_lock);
|
||||
|
||||
/* Inform the backend that counter collection has been disabled. */
|
||||
hctx->iface->release(hctx->accum.backend);
|
||||
|
||||
kbasep_hwcnt_accumulator_term(hctx);
|
||||
|
||||
mutex_lock(&hctx->accum_lock);
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ enum kbase_hwcnt_physical_set {
|
|||
/**
|
||||
* struct kbase_hwcnt_gpu_info - Information about hwcnt blocks on the GPUs.
|
||||
* @l2_count: L2 cache count.
|
||||
* @sc_core_mask: Shader core mask. May be sparse.
|
||||
* @sc_core_mask: Shader core mask. May be sparse.
|
||||
* @clk_cnt: Number of clock domains available.
|
||||
* @csg_cnt: Number of CSGs available.
|
||||
* @prfcnt_values_per_block: Total entries (header + counters) of performance
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -19,65 +19,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hardware counter types.
|
||||
* Contains structures for describing the physical layout of hardware counter
|
||||
* dump buffers and enable maps within a system.
|
||||
*
|
||||
* Also contains helper functions for manipulation of these dump buffers and
|
||||
* enable maps.
|
||||
*
|
||||
* Through use of these structures and functions, hardware counters can be
|
||||
* enabled, copied, accumulated, and generally manipulated in a generic way,
|
||||
* regardless of the physical counter dump layout.
|
||||
*
|
||||
* Terminology:
|
||||
*
|
||||
* Hardware Counter System:
|
||||
* A collection of hardware counter blocks, making a full hardware counter
|
||||
* system.
|
||||
* Hardware Counter Block:
|
||||
* A block of hardware counters (e.g. shader block, tiler block).
|
||||
* Hardware Counter Block Instance:
|
||||
* An instance of a Hardware Counter Block (e.g. an MP4 GPU might have
|
||||
* 4 shader block instances).
|
||||
*
|
||||
* Block Header:
|
||||
* A header value inside a counter block. Headers don't count anything,
|
||||
* so it is only valid to copy or zero them. Headers are always the first
|
||||
* values in the block.
|
||||
* Block Counter:
|
||||
* A counter value inside a counter block. Counters can be zeroed, copied,
|
||||
* or accumulated. Counters are always immediately after the headers in the
|
||||
* block.
|
||||
* Block Value:
|
||||
* A catch-all term for block headers and block counters.
|
||||
*
|
||||
* Enable Map:
|
||||
* An array of u64 bitfields, where each bit either enables exactly one
|
||||
* block value, or is unused (padding). Note that this is derived from
|
||||
* the client configuration, and is not obtained from the hardware.
|
||||
* Dump Buffer:
|
||||
* An array of u64 values, where each u64 corresponds either to one block
|
||||
* value, or is unused (padding).
|
||||
* Block State Buffer:
|
||||
* An array of blk_stt_t values, where each blk_stt_t corresponds to one block
|
||||
* instance and is used to track the on/off power state transitions, as well has
|
||||
* hardware resource availability, and whether the block was operating
|
||||
* in normal or protected mode.
|
||||
* Availability Mask:
|
||||
* A bitfield, where each bit corresponds to whether a block instance is
|
||||
* physically available (e.g. an MP3 GPU may have a sparse core mask of
|
||||
* 0b1011, meaning it only has 3 cores but for hardware counter dumps has the
|
||||
* same dump buffer layout as an MP4 GPU with a core mask of 0b1111. In this
|
||||
* case, the availability mask might be 0b1011111 (the exact layout will
|
||||
* depend on the specific hardware architecture), with the 3 extra early bits
|
||||
* corresponding to other block instances in the hardware counter system).
|
||||
* Metadata:
|
||||
* Structure describing the physical layout of the enable map and dump buffers
|
||||
* for a specific hardware counter system.
|
||||
*/
|
||||
|
||||
#ifndef _KBASE_HWCNT_TYPES_H_
|
||||
#define _KBASE_HWCNT_TYPES_H_
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2017-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2017-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -115,7 +115,7 @@ static ssize_t param_string_set(struct file *file, const char __user *user_buf,
|
|||
goto end;
|
||||
}
|
||||
|
||||
buf_size = min(param->size - 1, count);
|
||||
buf_size = min(size_sub(param->size, 1), count);
|
||||
if (copy_from_user(param->addr.str, user_buf, buf_size)) {
|
||||
ret = -EFAULT;
|
||||
goto end;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -308,11 +308,11 @@ enum kbase_atom_gpu_rb_state {
|
|||
* powered down and GPU shall come out of fully
|
||||
* coherent mode before entering protected mode.
|
||||
* @KBASE_ATOM_ENTER_PROTECTED_SET_COHERENCY: Prepare coherency change;
|
||||
* for BASE_HW_ISSUE_TGOX_R1_1234 also request L2 power on
|
||||
* for KBASE_HW_ISSUE_TGOX_R1_1234 also request L2 power on
|
||||
* so that coherency register contains correct value when
|
||||
* GPU enters protected mode.
|
||||
* @KBASE_ATOM_ENTER_PROTECTED_FINISHED: End state; for
|
||||
* BASE_HW_ISSUE_TGOX_R1_1234 check
|
||||
* KBASE_HW_ISSUE_TGOX_R1_1234 check
|
||||
* that L2 is powered up and switch GPU to protected mode.
|
||||
*/
|
||||
enum kbase_atom_enter_protected_state {
|
||||
|
|
@ -500,10 +500,6 @@ enum kbase_atom_exit_protected_state {
|
|||
* is snapshot of the age_count counter in kbase
|
||||
* context.
|
||||
* @jobslot: Job slot to use when BASE_JD_REQ_JOB_SLOT is specified.
|
||||
* @renderpass_id:Renderpass identifier used to associate an atom that has
|
||||
* BASE_JD_REQ_START_RENDERPASS set in its core requirements
|
||||
* with an atom that has BASE_JD_REQ_END_RENDERPASS set.
|
||||
* @jc_fragment: Set of GPU fragment job chains
|
||||
*/
|
||||
struct kbase_jd_atom {
|
||||
struct work_struct work;
|
||||
|
|
@ -564,8 +560,6 @@ struct kbase_jd_atom {
|
|||
enum base_jd_event_code event_code;
|
||||
base_jd_core_req core_req;
|
||||
u8 jobslot;
|
||||
u8 renderpass_id;
|
||||
struct base_jd_fragment jc_fragment;
|
||||
|
||||
u32 ticks;
|
||||
int sched_priority;
|
||||
|
|
@ -676,71 +670,6 @@ static inline bool kbase_jd_atom_is_earlier(const struct kbase_jd_atom *katom_a,
|
|||
|
||||
#define KBASE_JD_DEP_QUEUE_SIZE 256
|
||||
|
||||
/**
|
||||
* enum kbase_jd_renderpass_state - State of a renderpass
|
||||
* @KBASE_JD_RP_COMPLETE: Unused or completed renderpass. Can only transition to
|
||||
* START.
|
||||
* @KBASE_JD_RP_START: Renderpass making a first attempt at tiling.
|
||||
* Can transition to PEND_OOM or COMPLETE.
|
||||
* @KBASE_JD_RP_PEND_OOM: Renderpass whose first attempt at tiling used too much
|
||||
* memory and has a soft-stop pending. Can transition to
|
||||
* OOM or COMPLETE.
|
||||
* @KBASE_JD_RP_OOM: Renderpass whose first attempt at tiling used too much
|
||||
* memory and therefore switched to incremental
|
||||
* rendering. The fragment job chain is forced to run.
|
||||
* Can only transition to RETRY.
|
||||
* @KBASE_JD_RP_RETRY: Renderpass making a second or subsequent attempt at
|
||||
* tiling. Can transition to RETRY_PEND_OOM or COMPLETE.
|
||||
* @KBASE_JD_RP_RETRY_PEND_OOM: Renderpass whose second or subsequent attempt at
|
||||
* tiling used too much memory again and has a
|
||||
* soft-stop pending. Can transition to RETRY_OOM
|
||||
* or COMPLETE.
|
||||
* @KBASE_JD_RP_RETRY_OOM: Renderpass whose second or subsequent attempt at
|
||||
* tiling used too much memory again. The fragment job
|
||||
* chain is forced to run. Can only transition to RETRY.
|
||||
*
|
||||
* A state machine is used to control incremental rendering.
|
||||
*/
|
||||
enum kbase_jd_renderpass_state {
|
||||
KBASE_JD_RP_COMPLETE, /* COMPLETE => START */
|
||||
KBASE_JD_RP_START, /* START => PEND_OOM or COMPLETE */
|
||||
KBASE_JD_RP_PEND_OOM, /* PEND_OOM => OOM or COMPLETE */
|
||||
KBASE_JD_RP_OOM, /* OOM => RETRY */
|
||||
KBASE_JD_RP_RETRY, /* RETRY => RETRY_PEND_OOM or COMPLETE */
|
||||
KBASE_JD_RP_RETRY_PEND_OOM, /* RETRY_PEND_OOM => RETRY_OOM or COMPLETE */
|
||||
KBASE_JD_RP_RETRY_OOM /* RETRY_OOM => RETRY */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct kbase_jd_renderpass - Data for a renderpass
|
||||
* @state: Current state of the renderpass. If KBASE_JD_RP_COMPLETE then
|
||||
* all other members are invalid.
|
||||
* Both the job dispatcher context and hwaccess_lock must be
|
||||
* locked to modify this so that it can be read with either
|
||||
* (or both) locked.
|
||||
* @start_katom: Address of the atom that is the start of a renderpass.
|
||||
* Both the job dispatcher context and hwaccess_lock must be
|
||||
* locked to modify this so that it can be read with either
|
||||
* (or both) locked.
|
||||
* @end_katom: Address of the atom that is the end of a renderpass, or NULL
|
||||
* if that atom hasn't been added to the job scheduler yet.
|
||||
* The job dispatcher context and hwaccess_lock must be
|
||||
* locked to modify this so that it can be read with either
|
||||
* (or both) locked.
|
||||
* @oom_reg_list: A list of region structures which triggered out-of-memory.
|
||||
* The hwaccess_lock must be locked to access this.
|
||||
*
|
||||
* Atoms tagged with BASE_JD_REQ_START_RENDERPASS or BASE_JD_REQ_END_RENDERPASS
|
||||
* are associated with an object of this type, which is created and maintained
|
||||
* by kbase to keep track of each renderpass.
|
||||
*/
|
||||
struct kbase_jd_renderpass {
|
||||
enum kbase_jd_renderpass_state state;
|
||||
struct kbase_jd_atom *start_katom;
|
||||
struct kbase_jd_atom *end_katom;
|
||||
struct list_head oom_reg_list;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct kbase_jd_context - per context object encapsulating all the
|
||||
* Job dispatcher related state.
|
||||
|
|
@ -751,9 +680,6 @@ struct kbase_jd_renderpass {
|
|||
* @atoms: Array of the objects representing atoms,
|
||||
* containing the complete state and attributes
|
||||
* of an atom.
|
||||
* @renderpasses: Array of renderpass state for incremental
|
||||
* rendering, indexed by user-specified renderpass
|
||||
* ID.
|
||||
* @job_nr: Tracks the number of atoms being processed by the
|
||||
* kbase. This includes atoms that are not tracked by
|
||||
* scheduler: 'not ready to run' & 'dependency-only'
|
||||
|
|
@ -803,7 +729,6 @@ struct kbase_jd_context {
|
|||
struct mutex lock;
|
||||
struct kbasep_js_kctx_info sched_info;
|
||||
struct kbase_jd_atom atoms[BASE_JD_ATOM_COUNT];
|
||||
struct kbase_jd_renderpass renderpasses[BASE_JD_RP_COUNT];
|
||||
struct workqueue_struct *job_done_wq;
|
||||
|
||||
wait_queue_head_t zero_jobs_wait;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2020-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -567,22 +567,6 @@ bool kbase_js_complete_atom_wq(struct kbase_context *kctx, struct kbase_jd_atom
|
|||
*/
|
||||
struct kbase_jd_atom *kbase_js_complete_atom(struct kbase_jd_atom *katom, ktime_t *end_timestamp);
|
||||
|
||||
/**
|
||||
* kbase_js_atom_blocked_on_x_dep - Decide whether to ignore a cross-slot
|
||||
* dependency
|
||||
* @katom: Pointer to an atom in the slot ringbuffer
|
||||
*
|
||||
* A cross-slot dependency is ignored if necessary to unblock incremental
|
||||
* rendering. If the atom at the start of a renderpass used too much memory
|
||||
* and was soft-stopped then the atom at the end of a renderpass is submitted
|
||||
* to hardware regardless of its dependency on the start-of-renderpass atom.
|
||||
* This can happen multiple times for the same pair of atoms.
|
||||
*
|
||||
* Return: true to block the atom or false to allow it to be submitted to
|
||||
* hardware.
|
||||
*/
|
||||
bool kbase_js_atom_blocked_on_x_dep(struct kbase_jd_atom *katom);
|
||||
|
||||
/**
|
||||
* kbase_js_sched - Submit atoms from all available contexts.
|
||||
*
|
||||
|
|
@ -809,8 +793,7 @@ static inline bool
|
|||
kbasep_js_has_atom_finished(const struct kbasep_js_atom_retained_state *katom_retained_state)
|
||||
{
|
||||
return (bool)(katom_retained_state->event_code != BASE_JD_EVENT_STOPPED &&
|
||||
katom_retained_state->event_code != BASE_JD_EVENT_REMOVED_FROM_NEXT &&
|
||||
katom_retained_state->event_code != BASE_JD_EVENT_END_RP_DONE);
|
||||
katom_retained_state->event_code != BASE_JD_EVENT_REMOVED_FROM_NEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,163 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
/* AUTOMATICALLY GENERATED FILE. If you want to amend the issues/features,
|
||||
* please update base/tools/hwconfig_generator/hwc_{issues,features}.py
|
||||
* For more information see base/tools/docs/hwconfig_generator.md
|
||||
*/
|
||||
|
||||
#ifndef _BASE_HWCONFIG_FEATURES_H_
|
||||
#define _BASE_HWCONFIG_FEATURES_H_
|
||||
|
||||
#include <linux/version_compat_defs.h>
|
||||
|
||||
enum base_hw_feature {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_TLS_HASHING,
|
||||
BASE_HW_FEATURE_THREAD_GROUP_SPLIT,
|
||||
BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_IDVS_GROUP_SIZE,
|
||||
BASE_HW_FEATURE_L2_CONFIG,
|
||||
BASE_HW_FEATURE_L2_SLICE_HASH,
|
||||
BASE_HW_FEATURE_GPU_SLEEP,
|
||||
BASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER,
|
||||
BASE_HW_FEATURE_CORE_FEATURES,
|
||||
BASE_HW_FEATURE_PBHA_HWU,
|
||||
BASE_HW_FEATURE_LARGE_PAGE_ALLOC,
|
||||
BASE_HW_FEATURE_THREAD_TLS_ALLOC,
|
||||
BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_generic[] = {
|
||||
BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tMIx[] = {
|
||||
BASE_HW_FEATURE_THREAD_GROUP_SPLIT, BASE_HW_FEATURE_FLUSH_REDUCTION, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tHEx[] = {
|
||||
BASE_HW_FEATURE_THREAD_GROUP_SPLIT, BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tSIx[] = {
|
||||
BASE_HW_FEATURE_THREAD_GROUP_SPLIT, BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tDVx[] = {
|
||||
BASE_HW_FEATURE_THREAD_GROUP_SPLIT, BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tNOx[] = {
|
||||
BASE_HW_FEATURE_THREAD_GROUP_SPLIT, BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE, BASE_HW_FEATURE_TLS_HASHING,
|
||||
BASE_HW_FEATURE_IDVS_GROUP_SIZE, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tGOx[] = {
|
||||
BASE_HW_FEATURE_THREAD_GROUP_SPLIT, BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE, BASE_HW_FEATURE_TLS_HASHING,
|
||||
BASE_HW_FEATURE_IDVS_GROUP_SIZE, BASE_HW_FEATURE_CORE_FEATURES,
|
||||
BASE_HW_FEATURE_THREAD_TLS_ALLOC, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tTRx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_IDVS_GROUP_SIZE, BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tNAx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_IDVS_GROUP_SIZE, BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tBEx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_IDVS_GROUP_SIZE,
|
||||
BASE_HW_FEATURE_L2_CONFIG,
|
||||
BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER,
|
||||
BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tBAx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_IDVS_GROUP_SIZE,
|
||||
BASE_HW_FEATURE_L2_CONFIG,
|
||||
BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER,
|
||||
BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tODx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_L2_CONFIG, BASE_HW_FEATURE_CLEAN_ONLY_SAFE, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tGRx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_L2_CONFIG, BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_CORE_FEATURES, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tVAx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_L2_CONFIG, BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_CORE_FEATURES, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tTUx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_L2_CONFIG, BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_L2_SLICE_HASH, BASE_HW_FEATURE_GPU_SLEEP,
|
||||
BASE_HW_FEATURE_CORE_FEATURES, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tTIx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_L2_CONFIG,
|
||||
BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_L2_SLICE_HASH,
|
||||
BASE_HW_FEATURE_GPU_SLEEP,
|
||||
BASE_HW_FEATURE_CORE_FEATURES,
|
||||
BASE_HW_FEATURE_PBHA_HWU,
|
||||
BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tKRx[] = {
|
||||
BASE_HW_FEATURE_FLUSH_REDUCTION, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
BASE_HW_FEATURE_L2_CONFIG, BASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
BASE_HW_FEATURE_L2_SLICE_HASH, BASE_HW_FEATURE_GPU_SLEEP,
|
||||
BASE_HW_FEATURE_CORE_FEATURES, BASE_HW_FEATURE_PBHA_HWU,
|
||||
BASE_HW_FEATURE_LARGE_PAGE_ALLOC, BASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
|
||||
#endif /* _BASE_HWCONFIG_FEATURES_H_ */
|
||||
|
|
@ -1,621 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
/* AUTOMATICALLY GENERATED FILE. If you want to amend the issues/features,
|
||||
* please update base/tools/hwconfig_generator/hwc_{issues,features}.py
|
||||
* For more information see base/tools/docs/hwconfig_generator.md
|
||||
*/
|
||||
|
||||
#ifndef _BASE_HWCONFIG_ISSUES_H_
|
||||
#define _BASE_HWCONFIG_ISSUES_H_
|
||||
|
||||
#include <linux/version_compat_defs.h>
|
||||
|
||||
enum base_hw_issue {
|
||||
BASE_HW_ISSUE_5736,
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_10682,
|
||||
BASE_HW_ISSUE_11054,
|
||||
BASE_HW_ISSUE_T76X_3953,
|
||||
BASE_HW_ISSUE_TMIX_7891,
|
||||
BASE_HW_ISSUE_TMIX_7940,
|
||||
BASE_HW_ISSUE_TMIX_8042,
|
||||
BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TMIX_8138,
|
||||
BASE_HW_ISSUE_TMIX_8206,
|
||||
BASE_HW_ISSUE_TMIX_8343,
|
||||
BASE_HW_ISSUE_TMIX_8463,
|
||||
BASE_HW_ISSUE_TMIX_8456,
|
||||
BASE_HW_ISSUE_TSIX_1116,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TMIX_8438,
|
||||
BASE_HW_ISSUE_TNOX_1194,
|
||||
BASE_HW_ISSUE_TGOX_R1_1234,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TSIX_1792,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_3076,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TTRX_3485,
|
||||
BASE_HW_ISSUE_GPU2019_3212,
|
||||
BASE_HW_ISSUE_TURSEHW_1997,
|
||||
BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_TURSEHW_2716,
|
||||
BASE_HW_ISSUE_GPU2019_3901,
|
||||
BASE_HW_ISSUE_GPU2021PRO_290,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_TITANHW_2679,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2922,
|
||||
BASE_HW_ISSUE_TITANHW_2952,
|
||||
BASE_HW_ISSUE_KRAKEHW_2151,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_KRAKEHW_2269,
|
||||
BASE_HW_ISSUE_TURSEHW_2934,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__attribute__((
|
||||
unused)) static const enum base_hw_issue base_hw_issues_generic[] = { BASE_HW_ISSUE_END };
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tMIx_r0p0_05dev0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_10682, BASE_HW_ISSUE_11054,
|
||||
BASE_HW_ISSUE_T76X_3953, BASE_HW_ISSUE_TMIX_7891, BASE_HW_ISSUE_TMIX_8042,
|
||||
BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TMIX_8138, BASE_HW_ISSUE_TMIX_8206,
|
||||
BASE_HW_ISSUE_TMIX_8343, BASE_HW_ISSUE_TMIX_8463, BASE_HW_ISSUE_TMIX_8456,
|
||||
BASE_HW_ISSUE_TMIX_8438, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tMIx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_10682, BASE_HW_ISSUE_11054,
|
||||
BASE_HW_ISSUE_TMIX_7891, BASE_HW_ISSUE_TMIX_7940, BASE_HW_ISSUE_TMIX_8042,
|
||||
BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TMIX_8138, BASE_HW_ISSUE_TMIX_8206,
|
||||
BASE_HW_ISSUE_TMIX_8343, BASE_HW_ISSUE_TMIX_8463, BASE_HW_ISSUE_TMIX_8456,
|
||||
BASE_HW_ISSUE_TMIX_8438, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tMIx_r0p1[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_10682, BASE_HW_ISSUE_11054,
|
||||
BASE_HW_ISSUE_TMIX_7891, BASE_HW_ISSUE_TMIX_7940, BASE_HW_ISSUE_TMIX_8042,
|
||||
BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TMIX_8138, BASE_HW_ISSUE_TMIX_8206,
|
||||
BASE_HW_ISSUE_TMIX_8343, BASE_HW_ISSUE_TMIX_8463, BASE_HW_ISSUE_TMIX_8456,
|
||||
BASE_HW_ISSUE_TMIX_8438, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tMIx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_7891,
|
||||
BASE_HW_ISSUE_TMIX_7940, BASE_HW_ISSUE_TMIX_8042, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TMIX_8138, BASE_HW_ISSUE_TMIX_8206, BASE_HW_ISSUE_TMIX_8343,
|
||||
BASE_HW_ISSUE_TMIX_8456, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tHEx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_10682, BASE_HW_ISSUE_11054,
|
||||
BASE_HW_ISSUE_TMIX_7891, BASE_HW_ISSUE_TMIX_8042, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tHEx_r0p1[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_10682, BASE_HW_ISSUE_11054,
|
||||
BASE_HW_ISSUE_TMIX_7891, BASE_HW_ISSUE_TMIX_8042, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tHEx_r0p2[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_10682, BASE_HW_ISSUE_11054,
|
||||
BASE_HW_ISSUE_TMIX_7891, BASE_HW_ISSUE_TMIX_8042, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tHEx_r0p3[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_10682, BASE_HW_ISSUE_TMIX_7891,
|
||||
BASE_HW_ISSUE_TMIX_8042, BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tHEx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_7891,
|
||||
BASE_HW_ISSUE_TMIX_8042, BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tSIx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_11054, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_1116, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TSIX_1792,
|
||||
BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tSIx_r0p1[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_11054, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_1116, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TSIX_1792,
|
||||
BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tSIx_r1p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_11054, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_1116, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tSIx_r1p1[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TSIX_1116,
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tSIx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_1116, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tDVx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TSIX_1116,
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tDVx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_1116, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tNOx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TSIX_1116,
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TNOX_1194, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tNOx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_1116, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tGOx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TSIX_1116,
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TNOX_1194, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tGOx_r1p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133, BASE_HW_ISSUE_TSIX_1116,
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TGOX_R1_1234, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_GPU2017_1336, BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tGOx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TMIX_8133,
|
||||
BASE_HW_ISSUE_TSIX_1116, BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTRx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_3076, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414, BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TTRX_3083, BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TTRX_3485,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTRx_r0p1[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_3076, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414, BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TTRX_3083, BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TTRX_3485,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTRx_r0p2[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_3076,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tTRx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_3414, BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470, BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tNAx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_3076, BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414, BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TTRX_3083, BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TTRX_3485,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tNAx_r0p1[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_3076,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_GPU2017_1336,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tNAx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_3414, BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470, BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBEx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083, BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TTRX_3485,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBEx_r0p1[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBEx_r1p0[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBEx_r1p1[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tBEx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_3414, BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470, BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_lBEx_r1p0[] = {
|
||||
BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921, BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083, BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TTRX_3485,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_lBEx_r1p1[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBAx_r0p0[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBAx_r0p1[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBAx_r0p2[] = {
|
||||
BASE_HW_ISSUE_9435,
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
BASE_HW_ISSUE_TTRX_921,
|
||||
BASE_HW_ISSUE_TTRX_3414,
|
||||
BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470,
|
||||
BASE_HW_ISSUE_TTRX_3464,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tBAx[] = {
|
||||
BASE_HW_ISSUE_5736, BASE_HW_ISSUE_9435, BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TTRX_3414, BASE_HW_ISSUE_TTRX_3083,
|
||||
BASE_HW_ISSUE_TTRX_3470, BASE_HW_ISSUE_TTRX_3464, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tODx_r0p0[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3212,
|
||||
BASE_HW_ISSUE_GPU2019_3878, BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tODx[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3212,
|
||||
BASE_HW_ISSUE_GPU2019_3878, BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tGRx_r0p0[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tGRx[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tVAx_r0p0[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tVAx_r0p1[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tVAx[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r0p0[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033,
|
||||
BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TURSEHW_1997,
|
||||
BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_TURSEHW_2716,
|
||||
BASE_HW_ISSUE_GPU2019_3901,
|
||||
BASE_HW_ISSUE_GPU2021PRO_290,
|
||||
BASE_HW_ISSUE_TITANHW_2710,
|
||||
BASE_HW_ISSUE_TITANHW_2679,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_TURSEHW_2934,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r0p1[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TURSEHW_1997,
|
||||
BASE_HW_ISSUE_GPU2019_3878, BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2019_3901,
|
||||
BASE_HW_ISSUE_GPU2021PRO_290, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2922, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_TURSEHW_2934, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tTUx[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_GPU2021PRO_290,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2922, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_TURSEHW_2934,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r1p0[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_GPU2021PRO_290,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2922, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_TURSEHW_2934,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r1p1[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_GPU2021PRO_290,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2922, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_TURSEHW_2934,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r1p2[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_GPU2021PRO_290,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2922, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_TURSEHW_2934,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r1p3[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_GPU2019_3878,
|
||||
BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2019_3901, BASE_HW_ISSUE_GPU2021PRO_290,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_TITANHW_2922, BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_TURSEHW_2934,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tTIx[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TURSEHW_2716,
|
||||
BASE_HW_ISSUE_GPU2021PRO_290, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2922, BASE_HW_ISSUE_TITANHW_2952,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_TURSEHW_2934, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTIx_r0p0[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TURSEHW_2716,
|
||||
BASE_HW_ISSUE_GPU2021PRO_290, BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2922, BASE_HW_ISSUE_TITANHW_2952,
|
||||
BASE_HW_ISSUE_TITANHW_2938, BASE_HW_ISSUE_TURSEHW_2934, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTIx_r0p1[] = {
|
||||
BASE_HW_ISSUE_TSIX_2033, BASE_HW_ISSUE_TTRX_1337,
|
||||
BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2021PRO_290,
|
||||
BASE_HW_ISSUE_TITANHW_2710, BASE_HW_ISSUE_TITANHW_2679,
|
||||
BASE_HW_ISSUE_GPU2022PRO_148, BASE_HW_ISSUE_TITANHW_2938,
|
||||
BASE_HW_ISSUE_TURSEHW_2934, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tKRx_r0p0[] = {
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_KRAKEHW_2151, BASE_HW_ISSUE_KRAKEHW_2269, BASE_HW_ISSUE_TITANHW_2922,
|
||||
BASE_HW_ISSUE_TURSEHW_2934, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tKRx_r0p1[] = {
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_KRAKEHW_2269, BASE_HW_ISSUE_TURSEHW_2934, BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tKRx[] = {
|
||||
BASE_HW_ISSUE_TTRX_1337, BASE_HW_ISSUE_TURSEHW_2716, BASE_HW_ISSUE_GPU2022PRO_148,
|
||||
BASE_HW_ISSUE_KRAKEHW_2151, BASE_HW_ISSUE_KRAKEHW_2269, BASE_HW_ISSUE_TURSEHW_2934,
|
||||
BASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
|
||||
#endif /* _BASE_HWCONFIG_ISSUES_H_ */
|
||||
Binary file not shown.
|
|
@ -345,21 +345,6 @@ void kbase_job_done(struct kbase_device *kbdev, u32 done);
|
|||
void kbase_job_slot_ctx_priority_check_locked(struct kbase_context *kctx,
|
||||
struct kbase_jd_atom *katom);
|
||||
|
||||
/**
|
||||
* kbase_job_slot_softstop_start_rp() - Soft-stop the atom at the start
|
||||
* of a renderpass.
|
||||
* @kctx: Pointer to a kernel base context.
|
||||
* @reg: Reference of a growable GPU memory region in the same context.
|
||||
* Takes ownership of the reference if successful.
|
||||
*
|
||||
* Used to switch to incremental rendering if we have nearly run out of
|
||||
* virtual address space in a growable memory region and the atom currently
|
||||
* executing on a job slot is the tiler job chain at the start of a renderpass.
|
||||
*
|
||||
* Return: 0 if successful, otherwise a negative error code.
|
||||
*/
|
||||
int kbase_job_slot_softstop_start_rp(struct kbase_context *kctx, struct kbase_va_region *reg);
|
||||
|
||||
/**
|
||||
* kbase_job_slot_softstop - Soft-stop the specified job slot
|
||||
*
|
||||
|
|
@ -496,9 +481,7 @@ void kbasep_as_do_poke(struct work_struct *work);
|
|||
* or a dmb was executed recently (to ensure the value is most up-to-date).
|
||||
* However, without a lock the value could change afterwards.
|
||||
*
|
||||
* Return:
|
||||
* * false if a suspend is not in progress
|
||||
* * !=false otherwise
|
||||
* Return: False if a suspend is not in progress, true otherwise,
|
||||
*/
|
||||
static inline bool kbase_pm_is_suspending(struct kbase_device *kbdev)
|
||||
{
|
||||
|
|
@ -521,21 +504,20 @@ static inline bool kbase_pm_is_resuming(struct kbase_device *kbdev)
|
|||
return kbdev->pm.resuming;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
/*
|
||||
* Check whether a gpu lost is in progress
|
||||
*
|
||||
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
||||
*
|
||||
* Indicates whether a gpu lost has been received and jobs are no longer
|
||||
* being scheduled
|
||||
* being scheduled.
|
||||
*
|
||||
* Return: false if gpu is lost
|
||||
* Return: != false otherwise
|
||||
* Return: false if GPU is already lost or if no Arbiter is present (as GPU will
|
||||
* always be present in this case), true otherwise.
|
||||
*/
|
||||
static inline bool kbase_pm_is_gpu_lost(struct kbase_device *kbdev)
|
||||
{
|
||||
return (atomic_read(&kbdev->pm.gpu_lost) == 0 ? false : true);
|
||||
return (kbdev->arb.arb_if && ((bool)atomic_read(&kbdev->pm.gpu_lost)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -556,7 +538,6 @@ static inline void kbase_pm_set_gpu_lost(struct kbase_device *kbdev, bool gpu_lo
|
|||
if (new_val != cur_val)
|
||||
KBASE_KTRACE_ADD(kbdev, ARB_GPU_LOST, NULL, (u64)new_val);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* kbase_pm_is_active - Determine whether the GPU is active
|
||||
|
|
|
|||
|
|
@ -33,13 +33,21 @@
|
|||
*
|
||||
* @MALI_KBASE_CAP_SYSTEM_MONITOR: System Monitor
|
||||
* @MALI_KBASE_CAP_JIT_PRESSURE_LIMIT: JIT Pressure limit
|
||||
* @MALI_KBASE_CAP_MEM_DONT_NEED: Not needed physical memory
|
||||
* @MALI_KBASE_CAP_MEM_GROW_ON_GPF: Memory grow on page fault
|
||||
* @MALI_KBASE_CAP_MEM_PROTECTED: Protected memory
|
||||
* @MALI_KBASE_CAP_MEM_IMPORT_SYNC_ON_MAP_UNMAP: CPU cache maintenance required when
|
||||
* imported GPU memory is mapped/unmapped
|
||||
* @MALI_KBASE_CAP_MEM_KERNEL_SYNC: Kernel side cache sync ops required
|
||||
* @MALI_KBASE_CAP_MEM_SAME_VA: Same VA on CPU and GPU
|
||||
* @MALI_KBASE_CAP_QUERY_MEM_DONT_NEED: BASE_MEM_DONT_NEED is queryable
|
||||
* @MALI_KBASE_CAP_QUERY_MEM_GROW_ON_GPF: BASE_MEM_GROW_ON_GPF is queryable
|
||||
* @MALI_KBASE_CAP_QUERY_MEM_PROTECTED: BASE_MEM_PROTECTED is queryable
|
||||
* @MALI_KBASE_CAP_QUERY_MEM_IMPORT_SYNC_ON_MAP_UNMAP: BASE_MEM_IMPORT_SYNC_ON_MAP_UNMAP is
|
||||
* queryable
|
||||
* @MALI_KBASE_CAP_QUERY_MEM_KERNEL_SYNC: BASE_MEM_KERNEL_SYNC is queryable
|
||||
* @MALI_KBASE_CAP_QUERY_MEM_SAME_VA: BASE_MEM_SAME_VA is queryable
|
||||
* @MALI_KBASE_CAP_REJECT_ALLOC_MEM_DONT_NEED: BASE_MEM_DONT_NEED is not allocatable
|
||||
* @MALI_KBASE_CAP_REJECT_ALLOC_MEM_PROTECTED_IN_UNPROTECTED_ALLOCS: BASE_MEM_PROTECTED is not
|
||||
* allocatable in functions other
|
||||
* than base_mem_protected
|
||||
* @MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_8: BASE_MEM_UNUSED_BIT_8 is not allocatable
|
||||
* @MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_19: BASE_MEM_UNUSED_BIT_19 is not allocatable
|
||||
* @MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_20: BASE_MEM_UNUSED_BIT_20 is not allocatable
|
||||
* @MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_27: BASE_MEM_UNUSED_BIT_27 is not allocatable
|
||||
* @MALI_KBASE_NUM_CAPS: Delimiter
|
||||
*
|
||||
* New enumerator must not be negative and smaller than @MALI_KBASE_NUM_CAPS.
|
||||
|
|
@ -47,12 +55,18 @@
|
|||
enum mali_kbase_cap {
|
||||
MALI_KBASE_CAP_SYSTEM_MONITOR = 0,
|
||||
MALI_KBASE_CAP_JIT_PRESSURE_LIMIT,
|
||||
MALI_KBASE_CAP_MEM_DONT_NEED,
|
||||
MALI_KBASE_CAP_MEM_GROW_ON_GPF,
|
||||
MALI_KBASE_CAP_MEM_PROTECTED,
|
||||
MALI_KBASE_CAP_MEM_IMPORT_SYNC_ON_MAP_UNMAP,
|
||||
MALI_KBASE_CAP_MEM_KERNEL_SYNC,
|
||||
MALI_KBASE_CAP_MEM_SAME_VA,
|
||||
MALI_KBASE_CAP_QUERY_MEM_DONT_NEED,
|
||||
MALI_KBASE_CAP_QUERY_MEM_GROW_ON_GPF,
|
||||
MALI_KBASE_CAP_QUERY_MEM_PROTECTED,
|
||||
MALI_KBASE_CAP_QUERY_MEM_IMPORT_SYNC_ON_MAP_UNMAP,
|
||||
MALI_KBASE_CAP_QUERY_MEM_KERNEL_SYNC,
|
||||
MALI_KBASE_CAP_QUERY_MEM_SAME_VA,
|
||||
MALI_KBASE_CAP_REJECT_ALLOC_MEM_DONT_NEED,
|
||||
MALI_KBASE_CAP_REJECT_ALLOC_MEM_PROTECTED_IN_UNPROTECTED_ALLOCS,
|
||||
MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_8,
|
||||
MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_19,
|
||||
MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_20,
|
||||
MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_27,
|
||||
MALI_KBASE_NUM_CAPS
|
||||
};
|
||||
|
||||
|
|
@ -68,34 +82,67 @@ static inline bool mali_kbase_supports_jit_pressure_limit(unsigned long api_vers
|
|||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_JIT_PRESSURE_LIMIT);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_mem_dont_need(unsigned long api_version)
|
||||
static inline bool mali_kbase_supports_query_mem_dont_need(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_MEM_DONT_NEED);
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_QUERY_MEM_DONT_NEED);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_mem_grow_on_gpf(unsigned long api_version)
|
||||
static inline bool mali_kbase_supports_query_mem_grow_on_gpf(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_MEM_GROW_ON_GPF);
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_QUERY_MEM_GROW_ON_GPF);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_mem_protected(unsigned long api_version)
|
||||
static inline bool mali_kbase_supports_query_mem_protected(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_MEM_PROTECTED);
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_QUERY_MEM_PROTECTED);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_mem_import_sync_on_map_unmap(unsigned long api_version)
|
||||
static inline bool mali_kbase_supports_query_mem_import_sync_on_map_unmap(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_MEM_IMPORT_SYNC_ON_MAP_UNMAP);
|
||||
return mali_kbase_supports_cap(api_version,
|
||||
MALI_KBASE_CAP_QUERY_MEM_IMPORT_SYNC_ON_MAP_UNMAP);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_mem_kernel_sync(unsigned long api_version)
|
||||
static inline bool mali_kbase_supports_query_mem_kernel_sync(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_MEM_KERNEL_SYNC);
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_QUERY_MEM_KERNEL_SYNC);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_mem_same_va(unsigned long api_version)
|
||||
static inline bool mali_kbase_supports_query_mem_same_va(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_MEM_SAME_VA);
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_QUERY_MEM_SAME_VA);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_reject_alloc_mem_dont_need(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_REJECT_ALLOC_MEM_DONT_NEED);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
mali_kbase_supports_reject_alloc_mem_protected_in_unprotected_allocs(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(
|
||||
api_version, MALI_KBASE_CAP_REJECT_ALLOC_MEM_PROTECTED_IN_UNPROTECTED_ALLOCS);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_reject_alloc_mem_unused_bit_8(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_8);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_reject_alloc_mem_unused_bit_19(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_19);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_reject_alloc_mem_unused_bit_20(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_20);
|
||||
}
|
||||
|
||||
static inline bool mali_kbase_supports_reject_alloc_mem_unused_bit_27(unsigned long api_version)
|
||||
{
|
||||
return mali_kbase_supports_cap(api_version, MALI_KBASE_CAP_REJECT_ALLOC_MEM_UNUSED_BIT_27);
|
||||
}
|
||||
|
||||
#endif /* __KBASE_CAPS_H_ */
|
||||
|
|
|
|||
|
|
@ -255,6 +255,42 @@ enum {
|
|||
*/
|
||||
#define DEFAULT_PROGRESS_TIMEOUT_CYCLES (2500000000ull)
|
||||
|
||||
/* MIN value of iterators' suspend timeout*/
|
||||
#define CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MIN (200)
|
||||
#if CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MIN <= 0
|
||||
#error "CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MIN should be larger than 0"
|
||||
#endif
|
||||
|
||||
/* MAX value of iterators' suspend timeout*/
|
||||
#define CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MAX (60000)
|
||||
#if CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MAX >= (0xFFFFFFFF)
|
||||
#error "CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MAX should be less than U32_MAX"
|
||||
#endif
|
||||
|
||||
/* Firmware iterators' suspend timeout, default 4000ms. Customer can update this by
|
||||
* using debugfs -- csg_suspend_timeout
|
||||
*/
|
||||
#if IS_ENABLED(CONFIG_MALI_REAL_HW) && !IS_ENABLED(CONFIG_MALI_IS_FPGA)
|
||||
#define CSG_SUSPEND_TIMEOUT_FIRMWARE_MS (4000)
|
||||
#else
|
||||
#define CSG_SUSPEND_TIMEOUT_FIRMWARE_MS (31000)
|
||||
#endif
|
||||
#if (CSG_SUSPEND_TIMEOUT_FIRMWARE_MS < CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MIN) || \
|
||||
(CSG_SUSPEND_TIMEOUT_FIRMWARE_MS > CSG_SUSPEND_TIMEOUT_FIRMWARE_MS_MAX)
|
||||
#error "CSG_SUSPEND_TIMEOUT_FIRMWARE_MS is out of range"
|
||||
#endif
|
||||
|
||||
/* Additional time in milliseconds added to the firmware iterators' suspend timeout,
|
||||
* default 100ms
|
||||
*/
|
||||
#define CSG_SUSPEND_TIMEOUT_HOST_ADDED_MS (100)
|
||||
|
||||
/* Host side CSG suspend timeout */
|
||||
#define CSG_SUSPEND_TIMEOUT_MS (CSG_SUSPEND_TIMEOUT_FIRMWARE_MS + CSG_SUSPEND_TIMEOUT_HOST_ADDED_MS)
|
||||
|
||||
/* MAX allowed timeout value(ms) on host side, should be less than ANR timeout */
|
||||
#define MAX_TIMEOUT_MS (4500)
|
||||
|
||||
#else /* MALI_USE_CSF */
|
||||
|
||||
/* A default timeout in clock cycles to be used when an invalid timeout
|
||||
|
|
@ -327,14 +363,6 @@ enum {
|
|||
*/
|
||||
#define DEFAULT_PROGRESS_TIMEOUT ((u64)5 * 500 * 1024 * 1024)
|
||||
|
||||
/* Default threshold at which to switch to incremental rendering
|
||||
*
|
||||
* Fraction of the maximum size of an allocation that grows on GPU page fault
|
||||
* that can be used up before the driver switches to incremental rendering,
|
||||
* in 256ths. 0 means disable incremental rendering.
|
||||
*/
|
||||
#define DEFAULT_IR_THRESHOLD (192)
|
||||
|
||||
/* Waiting time in clock cycles for the completion of a MMU operation.
|
||||
*
|
||||
* Ideally 1.6M GPU cycles required for the L2 cache (512KiB slice) flush.
|
||||
|
|
|
|||
|
|
@ -62,9 +62,7 @@
|
|||
#include "csf/mali_kbase_csf_cpu_queue.h"
|
||||
#include "csf/mali_kbase_csf_event.h"
|
||||
#endif
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
#include "arbiter/mali_kbase_arbiter_pm.h"
|
||||
#endif
|
||||
|
||||
#include "mali_kbase_cs_experimental.h"
|
||||
|
||||
|
|
@ -76,6 +74,7 @@
|
|||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
#include "mali_kbase_pbha_debugfs.h"
|
||||
#endif
|
||||
#include "mali_kbase_ioctl_helpers.h"
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
|
@ -153,21 +152,29 @@ static const struct mali_kbase_capability_def kbase_caps_table[MALI_KBASE_NUM_CA
|
|||
#if MALI_USE_CSF
|
||||
{ 1, 0 }, /* SYSTEM_MONITOR */
|
||||
{ 1, 0 }, /* JIT_PRESSURE_LIMIT */
|
||||
{ 1, 22 }, /* MEM_DONT_NEED */
|
||||
{ 1, 0 }, /* MEM_GROW_ON_GPF */
|
||||
{ 1, 0 }, /* MEM_PROTECTED */
|
||||
{ 1, 26 }, /* MEM_IMPORT_SYNC_ON_MAP_UNMAP */
|
||||
{ 1, 26 }, /* MEM_KERNEL_SYNC */
|
||||
{ 1, 28 } /* MEM_SAME_VA */
|
||||
{ 1, 22 }, /* QUERY_MEM_DONT_NEED */
|
||||
{ 1, 0 }, /* QUERY_MEM_GROW_ON_GPF */
|
||||
{ 1, 0 }, /* QUERY_MEM_PROTECTED */
|
||||
{ 1, 26 }, /* QUERY_MEM_IMPORT_SYNC_ON_MAP_UNMAP */
|
||||
{ 1, 26 }, /* QUERY_MEM_KERNEL_SYNC */
|
||||
{ 1, 28 }, /* QUERY_MEM_SAME_VA */
|
||||
{ 1, 31 }, /* REJECT_ALLOC_MEM_DONT_NEED */
|
||||
{ 1, 31 }, /* REJECT_ALLOC_MEM_PROTECTED_IN_UNPROTECTED_ALLOCS */
|
||||
{ 1, 31 }, /* REJECT_ALLOC_MEM_UNUSED_BIT_20 */
|
||||
{ 1, 31 } /* REJECT_ALLOC_MEM_UNUSED_BIT_27 */
|
||||
#else
|
||||
{ 11, 15 }, /* SYSTEM_MONITOR */
|
||||
{ 11, 25 }, /* JIT_PRESSURE_LIMIT */
|
||||
{ 11, 40 }, /* MEM_DONT_NEED */
|
||||
{ 11, 2 }, /* MEM_GROW_ON_GPF */
|
||||
{ 11, 2 }, /* MEM_PROTECTED */
|
||||
{ 11, 43 }, /* MEM_IMPORT_SYNC_ON_MAP_UNMAP */
|
||||
{ 11, 43 }, /* MEM_KERNEL_SYNC */
|
||||
{ 11, 44 } /* MEM_SAME_VA */
|
||||
{ 11, 40 }, /* QUERY_MEM_DONT_NEED */
|
||||
{ 11, 2 }, /* QUERY_MEM_GROW_ON_GPF */
|
||||
{ 11, 2 }, /* QUERY_MEM_PROTECTED */
|
||||
{ 11, 43 }, /* QUERY_MEM_IMPORT_SYNC_ON_MAP_UNMAP */
|
||||
{ 11, 43 }, /* QUERY_MEM_KERNEL_SYNC */
|
||||
{ 11, 44 }, /* QUERY_MEM_SAME_VA */
|
||||
{ 11, 46 }, /* REJECT_ALLOC_MEM_DONT_NEED */
|
||||
{ 11, 46 }, /* REJECT_ALLOC_MEM_PROTECTED_IN_UNPROTECTED_ALLOCS */
|
||||
{ 11, 46 }, /* REJECT_ALLOC_MEM_UNUSED_BIT_8 */
|
||||
{ 11, 46 } /* REJECT_ALLOC_MEM_UNUSED_BIT_19 */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -819,7 +826,7 @@ static int kbase_api_mem_alloc_ex(struct kbase_context *kctx,
|
|||
union kbase_ioctl_mem_alloc_ex *alloc_ex)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
u64 flags = alloc_ex->in.flags;
|
||||
base_mem_alloc_flags flags = alloc_ex->in.flags;
|
||||
u64 gpu_va;
|
||||
|
||||
/* Calls to this function are inherently asynchronous, with respect to
|
||||
|
|
@ -929,7 +936,7 @@ static int kbase_api_mem_alloc(struct kbase_context *kctx, union kbase_ioctl_mem
|
|||
static int kbase_api_mem_alloc(struct kbase_context *kctx, union kbase_ioctl_mem_alloc *alloc)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
u64 flags = alloc->in.flags;
|
||||
base_mem_alloc_flags flags = alloc->in.flags;
|
||||
u64 gpu_va;
|
||||
|
||||
/* Calls to this function are inherently asynchronous, with respect to
|
||||
|
|
@ -1055,16 +1062,6 @@ static int kbase_api_get_ddk_version(struct kbase_context *kctx,
|
|||
static int kbase_api_mem_jit_init(struct kbase_context *kctx,
|
||||
struct kbase_ioctl_mem_jit_init *jit_init)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(jit_init->padding); i++) {
|
||||
/* Ensure all padding bytes are 0 for potential future
|
||||
* extension
|
||||
*/
|
||||
if (jit_init->padding[i])
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return kbase_region_tracker_init_jit(kctx, jit_init->va_pages, jit_init->max_allocations,
|
||||
jit_init->trim_level, jit_init->group_id,
|
||||
jit_init->phys_pages);
|
||||
|
|
@ -1130,7 +1127,7 @@ static int kbase_api_mem_commit(struct kbase_context *kctx, struct kbase_ioctl_m
|
|||
static int kbase_api_mem_alias(struct kbase_context *kctx, union kbase_ioctl_mem_alias *alias)
|
||||
{
|
||||
struct base_mem_aliasing_info *ai;
|
||||
u64 flags;
|
||||
base_mem_alloc_flags flags;
|
||||
int err;
|
||||
|
||||
if (alias->in.nents == 0 || alias->in.nents > BASE_MEM_ALIAS_MAX_ENTS)
|
||||
|
|
@ -1141,7 +1138,7 @@ static int kbase_api_mem_alias(struct kbase_context *kctx, union kbase_ioctl_mem
|
|||
return -ENOMEM;
|
||||
|
||||
err = copy_from_user(ai, u64_to_user_ptr(alias->in.aliasing_info),
|
||||
sizeof(*ai) * alias->in.nents);
|
||||
size_mul(sizeof(*ai), alias->in.nents));
|
||||
if (err) {
|
||||
vfree(ai);
|
||||
return -EFAULT;
|
||||
|
|
@ -1169,7 +1166,7 @@ static int kbase_api_mem_alias(struct kbase_context *kctx, union kbase_ioctl_mem
|
|||
static int kbase_api_mem_import(struct kbase_context *kctx, union kbase_ioctl_mem_import *import)
|
||||
{
|
||||
int ret;
|
||||
u64 flags = import->in.flags;
|
||||
base_mem_alloc_flags flags = import->in.flags;
|
||||
|
||||
if (flags & BASEP_MEM_FLAGS_KERNEL_ONLY)
|
||||
return -ENOMEM;
|
||||
|
|
@ -1281,7 +1278,8 @@ static int kbase_api_sticky_resource_map(struct kbase_context *kctx,
|
|||
if (!map->count || map->count > BASE_EXT_RES_COUNT_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
ret = copy_from_user(gpu_addr, u64_to_user_ptr(map->address), sizeof(u64) * map->count);
|
||||
ret = copy_from_user(gpu_addr, u64_to_user_ptr(map->address),
|
||||
size_mul(sizeof(u64), map->count));
|
||||
|
||||
if (ret != 0)
|
||||
return -EFAULT;
|
||||
|
|
@ -1320,7 +1318,8 @@ static int kbase_api_sticky_resource_unmap(struct kbase_context *kctx,
|
|||
if (!unmap->count || unmap->count > BASE_EXT_RES_COUNT_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
ret = copy_from_user(gpu_addr, u64_to_user_ptr(unmap->address), sizeof(u64) * unmap->count);
|
||||
ret = copy_from_user(gpu_addr, u64_to_user_ptr(unmap->address),
|
||||
size_mul(sizeof(u64), unmap->count));
|
||||
|
||||
if (ret != 0)
|
||||
return -EFAULT;
|
||||
|
|
@ -1402,7 +1401,6 @@ static int kbasep_cs_queue_group_create_1_6(struct kbase_context *kctx,
|
|||
union kbase_ioctl_cs_queue_group_create_1_6 *create)
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
union kbase_ioctl_cs_queue_group_create
|
||||
new_create = { .in = {
|
||||
.tiler_mask = create->in.tiler_mask,
|
||||
|
|
@ -1415,13 +1413,7 @@ static int kbasep_cs_queue_group_create_1_6(struct kbase_context *kctx,
|
|||
.compute_max = create->in.compute_max,
|
||||
} };
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(create->in.padding); i++) {
|
||||
if (create->in.padding[i] != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = kbase_csf_queue_group_create(kctx, &new_create);
|
||||
|
||||
create->out.group_handle = new_create.out.group_handle;
|
||||
create->out.group_uid = new_create.out.group_uid;
|
||||
|
||||
|
|
@ -1432,7 +1424,6 @@ static int kbasep_cs_queue_group_create_1_18(struct kbase_context *kctx,
|
|||
union kbase_ioctl_cs_queue_group_create_1_18 *create)
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
union kbase_ioctl_cs_queue_group_create
|
||||
new_create = { .in = {
|
||||
.tiler_mask = create->in.tiler_mask,
|
||||
|
|
@ -1447,13 +1438,7 @@ static int kbasep_cs_queue_group_create_1_18(struct kbase_context *kctx,
|
|||
.dvs_buf = create->in.dvs_buf,
|
||||
} };
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(create->in.padding); i++) {
|
||||
if (create->in.padding[i] != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = kbase_csf_queue_group_create(kctx, &new_create);
|
||||
|
||||
create->out.group_handle = new_create.out.group_handle;
|
||||
create->out.group_uid = new_create.out.group_uid;
|
||||
|
||||
|
|
@ -1580,14 +1565,15 @@ static int kbase_ioctl_cs_get_glb_iface(struct kbase_context *kctx,
|
|||
¶m->out.prfcnt_size, ¶m->out.instr_features);
|
||||
|
||||
if (copy_to_user(user_groups, group_data,
|
||||
MIN(max_group_num, param->out.group_num) * sizeof(*group_data)))
|
||||
size_mul(MIN(max_group_num, param->out.group_num),
|
||||
sizeof(*group_data))))
|
||||
err = -EFAULT;
|
||||
}
|
||||
|
||||
if (!err)
|
||||
if (copy_to_user(user_streams, stream_data,
|
||||
MIN(max_total_stream_num, param->out.total_stream_num) *
|
||||
sizeof(*stream_data)))
|
||||
size_mul(MIN(max_total_stream_num, param->out.total_stream_num),
|
||||
sizeof(*stream_data))))
|
||||
err = -EFAULT;
|
||||
|
||||
kfree(group_data);
|
||||
|
|
@ -1611,10 +1597,6 @@ static int kbase_ioctl_read_user_page(struct kbase_context *kctx,
|
|||
if (unlikely(user_page->in.offset != LATEST_FLUSH))
|
||||
return -EINVAL;
|
||||
|
||||
/* Validating padding that must be zero */
|
||||
if (unlikely(user_page->in.padding != 0))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
if (!kbdev->pm.backend.gpu_powered)
|
||||
user_page->out.val_lo = POWER_DOWN_LATEST_FLUSH_VALUE;
|
||||
|
|
@ -1641,65 +1623,6 @@ kbasep_ioctl_context_priority_check(struct kbase_context *kctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define KBASE_HANDLE_IOCTL(cmd, function, arg) \
|
||||
do { \
|
||||
int ret; \
|
||||
BUILD_BUG_ON(_IOC_DIR(cmd) != _IOC_NONE); \
|
||||
dev_dbg(arg->kbdev->dev, "Enter ioctl %s\n", #function); \
|
||||
ret = function(arg); \
|
||||
dev_dbg(arg->kbdev->dev, "Return %d from ioctl %s\n", ret, #function); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
#define KBASE_HANDLE_IOCTL_IN(cmd, function, type, arg) \
|
||||
do { \
|
||||
type param; \
|
||||
int ret, err; \
|
||||
dev_dbg(arg->kbdev->dev, "Enter ioctl %s\n", #function); \
|
||||
BUILD_BUG_ON(_IOC_DIR(cmd) != _IOC_WRITE); \
|
||||
BUILD_BUG_ON(sizeof(param) != _IOC_SIZE(cmd)); \
|
||||
err = copy_from_user(¶m, uarg, sizeof(param)); \
|
||||
if (err) \
|
||||
return -EFAULT; \
|
||||
ret = function(arg, ¶m); \
|
||||
dev_dbg(arg->kbdev->dev, "Return %d from ioctl %s\n", ret, #function); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
#define KBASE_HANDLE_IOCTL_OUT(cmd, function, type, arg) \
|
||||
do { \
|
||||
type param; \
|
||||
int ret, err; \
|
||||
dev_dbg(arg->kbdev->dev, "Enter ioctl %s\n", #function); \
|
||||
BUILD_BUG_ON(_IOC_DIR(cmd) != _IOC_READ); \
|
||||
BUILD_BUG_ON(sizeof(param) != _IOC_SIZE(cmd)); \
|
||||
memset(¶m, 0, sizeof(param)); \
|
||||
ret = function(arg, ¶m); \
|
||||
err = copy_to_user(uarg, ¶m, sizeof(param)); \
|
||||
if (err) \
|
||||
return -EFAULT; \
|
||||
dev_dbg(arg->kbdev->dev, "Return %d from ioctl %s\n", ret, #function); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
#define KBASE_HANDLE_IOCTL_INOUT(cmd, function, type, arg) \
|
||||
do { \
|
||||
type param; \
|
||||
int ret, err; \
|
||||
dev_dbg(arg->kbdev->dev, "Enter ioctl %s\n", #function); \
|
||||
BUILD_BUG_ON(_IOC_DIR(cmd) != (_IOC_WRITE | _IOC_READ)); \
|
||||
BUILD_BUG_ON(sizeof(param) != _IOC_SIZE(cmd)); \
|
||||
err = copy_from_user(¶m, uarg, sizeof(param)); \
|
||||
if (err) \
|
||||
return -EFAULT; \
|
||||
ret = function(arg, ¶m); \
|
||||
err = copy_to_user(uarg, ¶m, sizeof(param)); \
|
||||
if (err) \
|
||||
return -EFAULT; \
|
||||
dev_dbg(arg->kbdev->dev, "Return %d from ioctl %s\n", ret, #function); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
static int kbasep_ioctl_set_limited_core_count(
|
||||
struct kbase_context *kctx,
|
||||
struct kbase_ioctl_set_limited_core_count *set_limited_core_count)
|
||||
|
|
@ -2418,30 +2341,41 @@ static int core_mask_parse(struct kbase_device *const kbdev, const char *const b
|
|||
static int core_mask_set(struct kbase_device *kbdev, struct kbase_core_mask *const new_mask)
|
||||
{
|
||||
u64 new_core_mask = new_mask->new_core_mask;
|
||||
u64 shader_present = kbdev->gpu_props.shader_present;
|
||||
u64 shader_present;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
lockdep_assert_held(&kbdev->pm.lock);
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
kbase_csf_scheduler_lock(kbdev);
|
||||
kbase_pm_lock(kbdev);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
shader_present = kbdev->gpu_props.shader_present;
|
||||
|
||||
if ((new_core_mask & shader_present) != new_core_mask) {
|
||||
dev_err(kbdev->dev,
|
||||
"Invalid core mask 0x%llX: Includes non-existent cores (present = 0x%llX)",
|
||||
"Invalid requested core mask 0x%llX: Includes non-existent cores (present = 0x%llX)",
|
||||
new_core_mask, shader_present);
|
||||
return -EINVAL;
|
||||
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
} else if (!(new_core_mask & shader_present & kbdev->pm.backend.ca_cores_enabled)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Invalid core mask 0x%llX: No intersection with currently available cores (present = 0x%llX, CA enabled = 0x%llX)",
|
||||
"Invalid requested core mask 0x%llX: No intersection with currently available cores (present = 0x%llX, CA enabled = 0x%llX)",
|
||||
new_core_mask, kbdev->gpu_props.shader_present,
|
||||
kbdev->pm.backend.ca_cores_enabled);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
if (kbdev->pm.debug_core_mask != new_core_mask)
|
||||
kbase_pm_set_debug_core_mask(kbdev, new_core_mask);
|
||||
|
||||
return 0;
|
||||
exit:
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
kbase_pm_unlock(kbdev);
|
||||
kbase_csf_scheduler_unlock(kbdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
struct kbase_core_mask {
|
||||
|
|
@ -2478,15 +2412,23 @@ static int core_mask_set(struct kbase_device *kbdev, struct kbase_core_mask *con
|
|||
{
|
||||
u64 shader_present = kbdev->gpu_props.shader_present;
|
||||
u64 group_core_mask = kbdev->gpu_props.coherency_info.group.core_mask;
|
||||
u64 *new_core_mask = &new_mask->new_core_mask[0];
|
||||
u64 *new_core_mask;
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
size_t i;
|
||||
|
||||
kbase_pm_lock(kbdev);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
new_core_mask = &new_mask->new_core_mask[0];
|
||||
|
||||
for (i = 0; i < BASE_JM_MAX_NR_SLOTS; ++i) {
|
||||
if ((new_core_mask[i] & shader_present) != new_core_mask[i]) {
|
||||
dev_err(kbdev->dev,
|
||||
"Invalid core mask 0x%llX for JS %zu: Includes non-existent cores (present = 0x%llX)",
|
||||
new_core_mask[i], i, shader_present);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
|
||||
} else if (!(new_core_mask[i] & shader_present &
|
||||
kbdev->pm.backend.ca_cores_enabled)) {
|
||||
|
|
@ -2494,17 +2436,20 @@ static int core_mask_set(struct kbase_device *kbdev, struct kbase_core_mask *con
|
|||
"Invalid core mask 0x%llX for JS %zu: No intersection with currently available cores (present = 0x%llX, CA enabled = 0x%llX)",
|
||||
new_core_mask[i], i, kbdev->gpu_props.shader_present,
|
||||
kbdev->pm.backend.ca_cores_enabled);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
} else if (!(new_core_mask[i] & group_core_mask)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Invalid core mask 0x%llX for JS %zu: No intersection with group 0 core mask 0x%llX",
|
||||
new_core_mask[i], i, group_core_mask);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
} else if (!(new_core_mask[i] & kbdev->gpu_props.curr_config.shader_present)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Invalid core mask 0x%llX for JS %zu: No intersection with current core mask 0x%llX",
|
||||
new_core_mask[i], i, kbdev->gpu_props.curr_config.shader_present);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2515,7 +2460,11 @@ static int core_mask_set(struct kbase_device *kbdev, struct kbase_core_mask *con
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
exit:
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
kbase_pm_unlock(kbdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -2539,7 +2488,6 @@ static ssize_t core_mask_store(struct device *dev, struct device_attribute *attr
|
|||
struct kbase_core_mask core_mask = {};
|
||||
|
||||
int err;
|
||||
unsigned long flags;
|
||||
|
||||
CSTD_UNUSED(attr);
|
||||
|
||||
|
|
@ -2552,14 +2500,8 @@ static ssize_t core_mask_store(struct device *dev, struct device_attribute *attr
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
mutex_lock(&kbdev->pm.lock);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
err = core_mask_set(kbdev, &core_mask);
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
mutex_unlock(&kbdev->pm.lock);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -4385,7 +4327,8 @@ void registers_unmap(struct kbase_device *kbdev)
|
|||
kbase_common_reg_unmap(kbdev);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MALI_ARBITER_SUPPORT) && defined(CONFIG_OF)
|
||||
#if defined(CONFIG_OF)
|
||||
|
||||
static bool kbase_is_pm_enabled(const struct device_node *gpu_node)
|
||||
{
|
||||
const struct device_node *power_model_node;
|
||||
|
|
@ -4424,13 +4367,13 @@ static bool kbase_is_full_coherency_enabled(const struct device_node *gpu_node)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
#endif /* defined(CONFIG_MALI_ARBITER_SUPPORT) && defined(CONFIG_OF) */
|
||||
#endif /* defined(CONFIG_OF) */
|
||||
|
||||
int kbase_device_backend_init(struct kbase_device *kbdev)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
#if defined(CONFIG_MALI_ARBITER_SUPPORT) && defined(CONFIG_OF)
|
||||
#if defined(CONFIG_OF)
|
||||
/*
|
||||
* Attempt to initialize arbitration.
|
||||
* If the platform is not suitable for arbitration, return -EPERM.
|
||||
|
|
@ -4439,13 +4382,13 @@ int kbase_device_backend_init(struct kbase_device *kbdev)
|
|||
*/
|
||||
if (kbase_is_pm_enabled(kbdev->dev->of_node)) {
|
||||
/* Arbitration AND power management invalid */
|
||||
dev_err(kbdev->dev, "Invalid combination of arbitration AND power management\n");
|
||||
dev_dbg(kbdev->dev, "Arbitration not supported with power management");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (kbase_is_full_coherency_enabled(kbdev->dev->of_node)) {
|
||||
/* Arbitration AND full coherency invalid */
|
||||
dev_err(kbdev->dev, "Invalid combination of arbitration AND full coherency\n");
|
||||
dev_dbg(kbdev->dev, "Arbitration not supported with full coherency");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
|
|
@ -4466,21 +4409,19 @@ int kbase_device_backend_init(struct kbase_device *kbdev)
|
|||
if (product_model != GPU_ID_PRODUCT_TGOX && product_model != GPU_ID_PRODUCT_TNOX &&
|
||||
product_model != GPU_ID_PRODUCT_TBAX) {
|
||||
kbase_arbiter_pm_early_term(kbdev);
|
||||
dev_err(kbdev->dev, "GPU platform not suitable for arbitration\n");
|
||||
dev_dbg(kbdev->dev, "GPU platform not suitable for arbitration");
|
||||
return -EPERM;
|
||||
}
|
||||
#endif /* !MALI_USE_CSF */
|
||||
dev_info(kbdev->dev, "Arbitration interface enabled\n");
|
||||
dev_info(kbdev->dev, "Arbitration interface enabled");
|
||||
}
|
||||
#endif /* defined(CONFIG_MALI_ARBITER_SUPPORT) && defined(CONFIG_OF) */
|
||||
#endif /* defined(CONFIG_OF) */
|
||||
return err;
|
||||
}
|
||||
|
||||
void kbase_device_backend_term(struct kbase_device *kbdev)
|
||||
{
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
kbase_arbiter_pm_early_term(kbdev);
|
||||
#endif
|
||||
}
|
||||
|
||||
int power_control_init(struct kbase_device *kbdev)
|
||||
|
|
@ -4898,7 +4839,7 @@ static struct dentry *init_debugfs(struct kbase_device *kbdev)
|
|||
if (IS_ERR_OR_NULL(dentry))
|
||||
return dentry;
|
||||
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE)) {
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE)) {
|
||||
dentry = debugfs_create_file("protected_debug_mode", 0444,
|
||||
kbdev->mali_debugfs_directory, kbdev,
|
||||
&fops_protected_debug_mode);
|
||||
|
|
@ -5785,11 +5726,11 @@ static int kbase_platform_device_probe(struct platform_device *pdev)
|
|||
#if (KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE)
|
||||
mutex_unlock(&kbase_probe_mutex);
|
||||
#endif
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
mutex_lock(&kbdev->pm.lock);
|
||||
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_INITIALIZED_EVT);
|
||||
mutex_unlock(&kbdev->pm.lock);
|
||||
#endif
|
||||
if (kbase_has_arbiter(kbdev)) {
|
||||
mutex_lock(&kbdev->pm.lock);
|
||||
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_INITIALIZED_EVT);
|
||||
mutex_unlock(&kbdev->pm.lock);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -30,9 +30,6 @@
|
|||
*/
|
||||
static inline void mali_kbase_print_cs_experimental(void)
|
||||
{
|
||||
#if MALI_INCREMENTAL_RENDERING_JM
|
||||
pr_info("mali_kbase: INCREMENTAL_RENDERING_JM (experimental) enabled");
|
||||
#endif /* MALI_INCREMENTAL_RENDERING_JM */
|
||||
}
|
||||
|
||||
#endif /* _KBASE_CS_EXPERIMENTAL_H_ */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2022-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2022-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -58,7 +58,7 @@ static void debug_zone_mem_allocs_show(struct kbase_reg_zone *zone, struct seq_f
|
|||
for (p = rb_first(rbtree); p; p = rb_next(p)) {
|
||||
reg = rb_entry(p, struct kbase_va_region, rblink);
|
||||
if (!(reg->flags & KBASE_REG_FREE)) {
|
||||
seq_printf(sfile, "%16llx, %16zx, %16zx, %8lx, %s\n",
|
||||
seq_printf(sfile, "%16llx, %16zx, %16zx, %8llx, %s\n",
|
||||
reg->start_pfn << PAGE_SHIFT, reg->nr_pages << PAGE_SHIFT,
|
||||
kbase_reg_current_backed_size(reg) << PAGE_SHIFT, reg->flags,
|
||||
type_names[reg->gpu_alloc->type]);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@
|
|||
#define _KBASE_DEFS_H_
|
||||
|
||||
#include <mali_kbase_config.h>
|
||||
#include <mali_base_hwconfig_features.h>
|
||||
#include <mali_base_hwconfig_issues.h>
|
||||
#include <mali_kbase_hwconfig_features.h>
|
||||
#include <mali_kbase_hwconfig_issues.h>
|
||||
#include <mali_kbase_mem_lowlevel.h>
|
||||
#include <mmu/mali_kbase_mmu_hw.h>
|
||||
#include <backend/gpu/mali_kbase_instr_defs.h>
|
||||
|
|
@ -52,10 +52,6 @@
|
|||
#include <linux/version_compat_defs.h>
|
||||
|
||||
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
#include <linux/debugfs.h>
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
#ifdef CONFIG_MALI_BIFROST_DEVFREQ
|
||||
#include <linux/devfreq.h>
|
||||
#endif /* CONFIG_MALI_BIFROST_DEVFREQ */
|
||||
|
|
@ -64,9 +60,7 @@
|
|||
#include <linux/devfreq_cooling.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
#include <arbiter/mali_kbase_arbiter_defs.h>
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
|
||||
#include <linux/memory_group_manager.h>
|
||||
#include <soc/rockchip/rockchip_opp_select.h>
|
||||
|
|
@ -78,6 +72,7 @@
|
|||
#include <linux/file.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
/** Number of milliseconds before we time out on a GPU soft/hard reset */
|
||||
|
|
@ -297,24 +292,33 @@ struct kbase_fault {
|
|||
#define MAX_PAGES_FOR_FREE_PGDS ((size_t)9)
|
||||
|
||||
/* Maximum number of pointers to free PGDs */
|
||||
#define MAX_FREE_PGDS ((PAGE_SIZE / sizeof(struct page *)) * MAX_PAGES_FOR_FREE_PGDS)
|
||||
#define MAX_FREE_PGDS ((PAGE_SIZE / sizeof(phys_addr_t)) * MAX_PAGES_FOR_FREE_PGDS)
|
||||
|
||||
/**
|
||||
* struct kbase_mmu_table - object representing a set of GPU page tables
|
||||
* @mmu_lock: Lock to serialize the accesses made to multi level GPU
|
||||
* page tables
|
||||
* @pgd: Physical address of the page allocated for the top
|
||||
* level page table of the context, this is used for
|
||||
* MMU HW programming as the address translation will
|
||||
* start from the top level page table.
|
||||
* @group_id: A memory group ID to be passed to a platform-specific
|
||||
* memory group manager.
|
||||
* Valid range is 0..(MEMORY_GROUP_MANAGER_NR_GROUPS-1).
|
||||
* @kctx: If this set of MMU tables belongs to a context then
|
||||
* this is a back-reference to the context, otherwise
|
||||
* it is NULL.
|
||||
* @scratch_mem: Scratch memory used for MMU operations, which are
|
||||
* serialized by the @mmu_lock.
|
||||
* @mmu_lock: Lock to serialize the accesses made to multi level GPU
|
||||
* page tables
|
||||
* @pgd: Physical address of the page allocated for the top
|
||||
* level page table of the context, this is used for
|
||||
* MMU HW programming as the address translation will
|
||||
* start from the top level page table.
|
||||
* @group_id: A memory group ID to be passed to a platform-specific
|
||||
* memory group manager.
|
||||
* Valid range is 0..(MEMORY_GROUP_MANAGER_NR_GROUPS-1).
|
||||
* @kctx: If this set of MMU tables belongs to a context then
|
||||
* this is a back-reference to the context, otherwise
|
||||
* it is NULL.
|
||||
* @scratch_mem: Scratch memory used for MMU operations, which are
|
||||
* serialized by the @mmu_lock.
|
||||
* @pgd_pages_list: List head to link all 16K/64K pages allocated for the PGDs of mmut.
|
||||
* These pages will be used to allocate 4KB PGD pages for
|
||||
* the GPU page table.
|
||||
* Linked with &kbase_page_metadata.data.pt_mapped.pgd_link.
|
||||
* @last_allocated_pgd_page: Pointer to PGD page from where the last sub page
|
||||
* was allocated for mmut.
|
||||
* @last_freed_pgd_page: Pointer to PGD page to which the last freed 4K sub page
|
||||
* was returned for mmut.
|
||||
* @num_free_pgd_sub_pages: The total number of free 4K PGD pages in the mmut.
|
||||
*/
|
||||
struct kbase_mmu_table {
|
||||
struct mutex mmu_lock;
|
||||
|
|
@ -332,7 +336,7 @@ struct kbase_mmu_table {
|
|||
* @levels: Array of PGD pages, large enough to copy one PGD
|
||||
* for each level of the MMU table.
|
||||
*/
|
||||
u64 levels[MIDGARD_MMU_BOTTOMLEVEL][PAGE_SIZE / sizeof(u64)];
|
||||
u64 levels[MIDGARD_MMU_BOTTOMLEVEL][GPU_PAGE_SIZE / sizeof(u64)];
|
||||
} teardown_pages;
|
||||
/**
|
||||
* @free_pgds: Scratch memory used for insertion, update and teardown
|
||||
|
|
@ -341,11 +345,18 @@ struct kbase_mmu_table {
|
|||
*/
|
||||
struct {
|
||||
/** @pgds: Array of pointers to PGDs to free. */
|
||||
struct page *pgds[MAX_FREE_PGDS];
|
||||
phys_addr_t pgds[MAX_FREE_PGDS];
|
||||
/** @head_index: Index of first free element in the PGDs array. */
|
||||
size_t head_index;
|
||||
} free_pgds;
|
||||
} scratch_mem;
|
||||
|
||||
#if GPU_PAGES_PER_CPU_PAGE > 1
|
||||
struct list_head pgd_pages_list;
|
||||
struct page *last_allocated_pgd_page;
|
||||
struct page *last_freed_pgd_page;
|
||||
u32 num_free_pgd_sub_pages;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if MALI_USE_CSF
|
||||
|
|
@ -371,14 +382,9 @@ static inline int kbase_as_has_page_fault(struct kbase_as *as, struct kbase_faul
|
|||
*
|
||||
* @used_pages: Tracks usage of OS shared memory. Updated when OS memory is
|
||||
* allocated/freed.
|
||||
* @ir_threshold: Fraction of the maximum size of an allocation that grows
|
||||
* on GPU page fault that can be used before the driver
|
||||
* switches to incremental rendering, in 1/256ths.
|
||||
* 0 means disabled.
|
||||
*/
|
||||
struct kbasep_mem_device {
|
||||
atomic_t used_pages;
|
||||
atomic_t ir_threshold;
|
||||
};
|
||||
|
||||
struct kbase_clk_rate_listener;
|
||||
|
|
@ -483,9 +489,7 @@ struct kbase_pm_device_data {
|
|||
#if MALI_USE_CSF
|
||||
bool runtime_active;
|
||||
#endif
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
atomic_t gpu_lost;
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
wait_queue_head_t zero_active_count_wait;
|
||||
wait_queue_head_t resume_wait;
|
||||
|
||||
|
|
@ -501,10 +505,8 @@ struct kbase_pm_device_data {
|
|||
void (*callback_power_runtime_term)(struct kbase_device *kbdev);
|
||||
u32 dvfs_period;
|
||||
struct kbase_pm_backend_data backend;
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
struct kbase_arbiter_vm_state *arb_vm_state;
|
||||
atomic_t gpu_users_waiting;
|
||||
#endif /* CONFIG_MALI_ARBITER_SUPPORT */
|
||||
struct kbase_clk_rate_trace_manager clk_rtm;
|
||||
};
|
||||
|
||||
|
|
@ -947,7 +949,7 @@ struct kbase_mem_migrate {
|
|||
* @ipa.last_sample_time: Records the time when counters, used for dynamic
|
||||
* energy estimation, were last sampled.
|
||||
* @previous_frequency: Previous frequency of GPU clock used for
|
||||
* BASE_HW_ISSUE_GPU2017_1336 workaround, This clock is
|
||||
* KBASE_HW_ISSUE_GPU2017_1336 workaround, This clock is
|
||||
* restored when L2 is powered on.
|
||||
* @job_fault_debug: Flag to control the dumping of debug data for job faults,
|
||||
* set when the 'job_fault' debugfs file is opened.
|
||||
|
|
@ -1069,7 +1071,8 @@ struct kbase_mem_migrate {
|
|||
* KCPU queue. These structures may outlive kbase module
|
||||
* itself. Therefore, in such a case, a warning should be
|
||||
* be produced.
|
||||
* @va_region_slab: kmem_cache (slab) for allocated kbase_va_region structures.
|
||||
* @va_region_slab: kmem_cache (slab) for allocated @kbase_va_region structures.
|
||||
* @page_metadata_slab: kmem_cache (slab) for allocated @kbase_page_metadata structures.
|
||||
* @fence_signal_timeout_enabled: Global flag for whether fence signal timeout tracking
|
||||
* is enabled.
|
||||
* @pcm_prioritized_process_nb: Notifier block for the Priority Control Manager
|
||||
|
|
@ -1134,8 +1137,8 @@ struct kbase_device {
|
|||
|
||||
struct kbase_gpu_props gpu_props;
|
||||
|
||||
unsigned long hw_issues_mask[(BASE_HW_ISSUE_END + BITS_PER_LONG - 1) / BITS_PER_LONG];
|
||||
unsigned long hw_features_mask[(BASE_HW_FEATURE_END + BITS_PER_LONG - 1) / BITS_PER_LONG];
|
||||
unsigned long hw_issues_mask[(KBASE_HW_ISSUE_END + BITS_PER_LONG - 1) / BITS_PER_LONG];
|
||||
unsigned long hw_features_mask[(KBASE_HW_FEATURE_END + BITS_PER_LONG - 1) / BITS_PER_LONG];
|
||||
|
||||
struct {
|
||||
atomic_t count;
|
||||
|
|
@ -1151,6 +1154,12 @@ struct kbase_device {
|
|||
*/
|
||||
u8 pbha_propagate_bits;
|
||||
|
||||
/**
|
||||
* @mma_wa_id: The PBHA ID to use for the PBHA OVERRIDE based workaround for MMA violation.
|
||||
*
|
||||
*/
|
||||
u32 mma_wa_id;
|
||||
|
||||
#if MALI_USE_CSF
|
||||
struct kbase_hwcnt_backend_csf_if hwcnt_backend_csf_if_fw;
|
||||
#else
|
||||
|
|
@ -1242,7 +1251,6 @@ struct kbase_device {
|
|||
atomic_t job_fault_debug;
|
||||
#endif /* !MALI_USE_CSF */
|
||||
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
struct dentry *mali_debugfs_directory;
|
||||
struct dentry *debugfs_ctx_directory;
|
||||
struct dentry *debugfs_instr_directory;
|
||||
|
|
@ -1264,7 +1272,6 @@ struct kbase_device {
|
|||
u32 reg_offset;
|
||||
} regs_dump_debugfs_data;
|
||||
#endif /* !MALI_CUSTOMER_RELEASE */
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
atomic_t ctx_num;
|
||||
|
||||
|
|
@ -1355,9 +1362,7 @@ struct kbase_device {
|
|||
} dummy_job_wa;
|
||||
bool dummy_job_wa_loaded;
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
struct kbase_arbiter_device arb;
|
||||
#endif
|
||||
/* Priority Control Manager device */
|
||||
struct priority_control_manager_device *pcm_dev;
|
||||
|
||||
|
|
@ -1382,6 +1387,9 @@ struct kbase_device {
|
|||
atomic_t live_fence_metadata;
|
||||
#endif
|
||||
struct kmem_cache *va_region_slab;
|
||||
#if GPU_PAGES_PER_CPU_PAGE > 1
|
||||
struct kmem_cache *page_metadata_slab;
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD)
|
||||
/**
|
||||
|
|
@ -2131,6 +2139,18 @@ static inline u64 kbase_get_lock_region_min_size_log2(struct kbase_gpu_props con
|
|||
return 15; /* 32 kB */
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_has_arbiter - Check whether GPU has an arbiter.
|
||||
*
|
||||
* @kbdev: KBase device.
|
||||
*
|
||||
* Return: True if there is an arbiter, False otherwise.
|
||||
*/
|
||||
static inline bool kbase_has_arbiter(struct kbase_device *kbdev)
|
||||
{
|
||||
return (bool)kbdev->arb.arb_if;
|
||||
}
|
||||
|
||||
/* Conversion helpers for setting up high resolution timers */
|
||||
#define HR_TIMER_DELAY_MSEC(x) (ns_to_ktime(((u64)(x)) * 1000000U))
|
||||
#define HR_TIMER_DELAY_NSEC(x) (ns_to_ktime(x))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -218,7 +218,7 @@ static bool wa_blob_load_needed(struct kbase_device *kbdev)
|
|||
if (of_machine_is_compatible("arm,juno"))
|
||||
return false;
|
||||
|
||||
if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_TTRX_3485))
|
||||
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TTRX_3485))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -311,7 +311,7 @@ int kbase_dummy_job_wa_load(struct kbase_device *kbdev)
|
|||
while (blob_offset) {
|
||||
const struct wa_blob *blob;
|
||||
size_t nr_pages;
|
||||
u64 flags;
|
||||
base_mem_alloc_flags flags;
|
||||
u64 gpu_va;
|
||||
struct kbase_va_region *va_region;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2023-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -39,9 +39,6 @@ static inline void validate_tracepoint_data(struct kbase_gpu_metrics_ctx *gpu_me
|
|||
u64 start_time, u64 end_time, u64 total_active)
|
||||
{
|
||||
#if 0
|
||||
WARN(total_active > NSEC_PER_SEC, "total_active %llu > 1 second for aid %u active_cnt %u",
|
||||
total_active, gpu_metrics_ctx->aid, gpu_metrics_ctx->active_cnt);
|
||||
|
||||
WARN(start_time >= end_time, "start_time %llu >= end_time %llu for aid %u active_cnt %u",
|
||||
start_time, end_time, gpu_metrics_ctx->aid, gpu_metrics_ctx->active_cnt);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2011-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2011-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -437,7 +437,7 @@ int kbase_gpuprops_update_l2_features(struct kbase_device *kbdev)
|
|||
{
|
||||
int err = 0;
|
||||
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_L2_CONFIG)) {
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_L2_CONFIG)) {
|
||||
struct kbasep_gpuprops_regdump *regdump = &PRIV_DATA_REGDUMP(kbdev);
|
||||
|
||||
/* Check for L2 cache size & hash overrides */
|
||||
|
|
@ -699,7 +699,7 @@ static void kbase_populate_user_data(struct kbase_device *kbdev, struct gpu_prop
|
|||
data->thread_props.max_thread_group_split = THREAD_MTGS_DEFAULT;
|
||||
}
|
||||
|
||||
if (!kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_THREAD_GROUP_SPLIT))
|
||||
if (!kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_THREAD_GROUP_SPLIT))
|
||||
data->thread_props.max_thread_group_split = 0;
|
||||
|
||||
/* Raw Register Values */
|
||||
|
|
|
|||
|
|
@ -178,6 +178,10 @@ int kbase_gpu_gwt_dump(struct kbase_context *kctx, union kbase_ioctl_cinstr_gwt_
|
|||
__user void *user_addr = (__user void *)(uintptr_t)gwt_dump->in.addr_buffer;
|
||||
__user void *user_sizes = (__user void *)(uintptr_t)gwt_dump->in.size_buffer;
|
||||
|
||||
/* We don't have any valid user space buffer to copy the write modified addresses. */
|
||||
if (!gwt_dump->in.len || !gwt_dump->in.addr_buffer || !gwt_dump->in.size_buffer)
|
||||
return -EINVAL;
|
||||
|
||||
kbase_gpu_vm_lock(kctx);
|
||||
|
||||
if (!kctx->gwt_enabled) {
|
||||
|
|
@ -186,14 +190,6 @@ int kbase_gpu_gwt_dump(struct kbase_context *kctx, union kbase_ioctl_cinstr_gwt_
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
if (!gwt_dump->in.len || !gwt_dump->in.addr_buffer || !gwt_dump->in.size_buffer) {
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
/* We don't have any valid user space buffer to copy the
|
||||
* write modified addresses.
|
||||
*/
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (list_empty(&kctx->gwt_snapshot_list) && !list_empty(&kctx->gwt_current_list)) {
|
||||
list_replace_init(&kctx->gwt_current_list, &kctx->gwt_snapshot_list);
|
||||
|
||||
|
|
@ -227,14 +223,14 @@ int kbase_gpu_gwt_dump(struct kbase_context *kctx, union kbase_ioctl_cinstr_gwt_
|
|||
|
||||
if (count) {
|
||||
err = copy_to_user((user_addr + (ubuf_count * sizeof(u64))),
|
||||
(void *)addr_buffer, count * sizeof(u64));
|
||||
(void *)addr_buffer, size_mul(count, sizeof(u64)));
|
||||
if (err) {
|
||||
dev_err(kctx->kbdev->dev, "Copy to user failure\n");
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
return err;
|
||||
}
|
||||
err = copy_to_user((user_sizes + (ubuf_count * sizeof(u64))),
|
||||
(void *)num_page_buffer, count * sizeof(u64));
|
||||
(void *)num_page_buffer, size_mul(count, sizeof(u64)));
|
||||
if (err) {
|
||||
dev_err(kctx->kbdev->dev, "Copy to user failure\n");
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
* Run-time work-arounds helpers
|
||||
*/
|
||||
|
||||
#include <mali_base_hwconfig_features.h>
|
||||
#include <mali_base_hwconfig_issues.h>
|
||||
#include <mali_kbase_hwconfig_features.h>
|
||||
#include <mali_kbase_hwconfig_issues.h>
|
||||
#include <hw_access/mali_kbase_hw_access_regmap.h>
|
||||
#include "mali_kbase.h"
|
||||
#include "mali_kbase_hw.h"
|
||||
|
|
@ -92,7 +92,7 @@ void kbase_hw_set_features_mask(struct kbase_device *kbdev)
|
|||
break;
|
||||
}
|
||||
|
||||
for (; *features != BASE_HW_FEATURE_END; features++)
|
||||
for (; *features != KBASE_HW_FEATURE_END; features++)
|
||||
set_bit(*features, &kbdev->hw_features_mask[0]);
|
||||
|
||||
#if defined(CONFIG_MALI_VECTOR_DUMP)
|
||||
|
|
@ -103,8 +103,8 @@ void kbase_hw_set_features_mask(struct kbase_device *kbdev)
|
|||
* in the implementation of flush reduction optimization due to
|
||||
* unclear or ambiguous ARCH spec.
|
||||
*/
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_CLEAN_ONLY_SAFE))
|
||||
clear_bit(BASE_HW_FEATURE_FLUSH_REDUCTION, &kbdev->hw_features_mask[0]);
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE))
|
||||
clear_bit(KBASE_HW_FEATURE_FLUSH_REDUCTION, &kbdev->hw_features_mask[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ void kbase_hw_set_features_mask(struct kbase_device *kbdev)
|
|||
* @kbdev: Device pointer
|
||||
*
|
||||
* Return: pointer to an array of hardware issues, terminated by
|
||||
* BASE_HW_ISSUE_END.
|
||||
* KBASE_HW_ISSUE_END.
|
||||
*
|
||||
* In debugging versions of the driver, unknown versions of a known GPU will
|
||||
* be treated as the most recent known version not later than the actual
|
||||
|
|
@ -424,7 +424,7 @@ int kbase_hw_set_issues_mask(struct kbase_device *kbdev)
|
|||
gpu_id->product_major, gpu_id->arch_major, gpu_id->arch_minor, gpu_id->arch_rev,
|
||||
gpu_id->version_major, gpu_id->version_minor, gpu_id->version_status);
|
||||
|
||||
for (; *issues != BASE_HW_ISSUE_END; issues++)
|
||||
for (; *issues != KBASE_HW_ISSUE_END; issues++)
|
||||
set_bit(*issues, &kbdev->hw_issues_mask[0]);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2012-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2012-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -23,8 +23,8 @@
|
|||
* DOC: Run-time work-arounds helpers
|
||||
*/
|
||||
|
||||
#ifndef _KBASE_HW_H_
|
||||
#define _KBASE_HW_H_
|
||||
#ifndef _MALI_KBASE_HW_H_
|
||||
#define _MALI_KBASE_HW_H_
|
||||
|
||||
#include "mali_kbase_defs.h"
|
||||
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
* @kbdev: Device pointer
|
||||
*/
|
||||
#define kbase_hw_has_l2_slice_hash_feature(kbdev) \
|
||||
test_bit(BASE_HW_FEATURE_L2_SLICE_HASH, &(kbdev)->hw_features_mask[0])
|
||||
test_bit(KBASE_HW_FEATURE_L2_SLICE_HASH, &(kbdev)->hw_features_mask[0])
|
||||
|
||||
/**
|
||||
* kbase_hw_set_issues_mask - Set the hardware issues mask based on the GPU ID
|
||||
|
|
@ -73,4 +73,4 @@ int kbase_hw_set_issues_mask(struct kbase_device *kbdev);
|
|||
*/
|
||||
void kbase_hw_set_features_mask(struct kbase_device *kbdev);
|
||||
|
||||
#endif /* _KBASE_HW_H_ */
|
||||
#endif /* _MALI_KBASE_HW_H_ */
|
||||
|
|
|
|||
158
drivers/gpu/arm/bifrost/mali_kbase_hwconfig_features.h
Normal file
158
drivers/gpu/arm/bifrost/mali_kbase_hwconfig_features.h
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _KBASE_HWCONFIG_FEATURES_H_
|
||||
#define _KBASE_HWCONFIG_FEATURES_H_
|
||||
|
||||
#include <linux/version_compat_defs.h>
|
||||
|
||||
enum base_hw_feature {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_TLS_HASHING,
|
||||
KBASE_HW_FEATURE_THREAD_GROUP_SPLIT,
|
||||
KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_IDVS_GROUP_SIZE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG,
|
||||
KBASE_HW_FEATURE_L2_SLICE_HASH,
|
||||
KBASE_HW_FEATURE_GPU_SLEEP,
|
||||
KBASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER,
|
||||
KBASE_HW_FEATURE_CORE_FEATURES,
|
||||
KBASE_HW_FEATURE_PBHA_HWU,
|
||||
KBASE_HW_FEATURE_LARGE_PAGE_ALLOC,
|
||||
KBASE_HW_FEATURE_THREAD_TLS_ALLOC,
|
||||
KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_generic[] = {
|
||||
KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tMIx[] = {
|
||||
KBASE_HW_FEATURE_THREAD_GROUP_SPLIT, KBASE_HW_FEATURE_FLUSH_REDUCTION, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tHEx[] = {
|
||||
KBASE_HW_FEATURE_THREAD_GROUP_SPLIT, KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tSIx[] = {
|
||||
KBASE_HW_FEATURE_THREAD_GROUP_SPLIT, KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tDVx[] = {
|
||||
KBASE_HW_FEATURE_THREAD_GROUP_SPLIT, KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tNOx[] = {
|
||||
KBASE_HW_FEATURE_THREAD_GROUP_SPLIT, KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE, KBASE_HW_FEATURE_TLS_HASHING,
|
||||
KBASE_HW_FEATURE_IDVS_GROUP_SIZE, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tGOx[] = {
|
||||
KBASE_HW_FEATURE_THREAD_GROUP_SPLIT, KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE, KBASE_HW_FEATURE_TLS_HASHING,
|
||||
KBASE_HW_FEATURE_IDVS_GROUP_SIZE, KBASE_HW_FEATURE_CORE_FEATURES,
|
||||
KBASE_HW_FEATURE_THREAD_TLS_ALLOC, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tTRx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION, KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_IDVS_GROUP_SIZE, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tNAx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION, KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_IDVS_GROUP_SIZE, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tBEx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_IDVS_GROUP_SIZE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG,
|
||||
KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER,
|
||||
KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tBAx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_IDVS_GROUP_SIZE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG,
|
||||
KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_FLUSH_INV_SHADER_OTHER,
|
||||
KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tODx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION, KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tGRx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION, KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_CORE_FEATURES, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tVAx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION, KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_CORE_FEATURES, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tTUx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION, KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_L2_SLICE_HASH, KBASE_HW_FEATURE_GPU_SLEEP,
|
||||
KBASE_HW_FEATURE_CORE_FEATURES, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tTIx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION,
|
||||
KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG,
|
||||
KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_L2_SLICE_HASH,
|
||||
KBASE_HW_FEATURE_GPU_SLEEP,
|
||||
KBASE_HW_FEATURE_CORE_FEATURES,
|
||||
KBASE_HW_FEATURE_PBHA_HWU,
|
||||
KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_feature base_hw_features_tKRx[] = {
|
||||
KBASE_HW_FEATURE_FLUSH_REDUCTION, KBASE_HW_FEATURE_PROTECTED_DEBUG_MODE,
|
||||
KBASE_HW_FEATURE_L2_CONFIG, KBASE_HW_FEATURE_CLEAN_ONLY_SAFE,
|
||||
KBASE_HW_FEATURE_L2_SLICE_HASH, KBASE_HW_FEATURE_GPU_SLEEP,
|
||||
KBASE_HW_FEATURE_CORE_FEATURES, KBASE_HW_FEATURE_PBHA_HWU,
|
||||
KBASE_HW_FEATURE_LARGE_PAGE_ALLOC, KBASE_HW_FEATURE_END
|
||||
};
|
||||
|
||||
|
||||
#endif /* _KBASE_HWCONFIG_FEATURES_H_ */
|
||||
609
drivers/gpu/arm/bifrost/mali_kbase_hwconfig_issues.h
Normal file
609
drivers/gpu/arm/bifrost/mali_kbase_hwconfig_issues.h
Normal file
|
|
@ -0,0 +1,609 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _KBASE_HWCONFIG_ISSUES_H_
|
||||
#define _KBASE_HWCONFIG_ISSUES_H_
|
||||
|
||||
#include <linux/version_compat_defs.h>
|
||||
|
||||
enum base_hw_issue {
|
||||
KBASE_HW_ISSUE_5736,
|
||||
KBASE_HW_ISSUE_9435,
|
||||
KBASE_HW_ISSUE_10682,
|
||||
KBASE_HW_ISSUE_11054,
|
||||
KBASE_HW_ISSUE_T76X_3953,
|
||||
KBASE_HW_ISSUE_TMIX_7891,
|
||||
KBASE_HW_ISSUE_TMIX_7940,
|
||||
KBASE_HW_ISSUE_TMIX_8042,
|
||||
KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TMIX_8138,
|
||||
KBASE_HW_ISSUE_TMIX_8206,
|
||||
KBASE_HW_ISSUE_TMIX_8343,
|
||||
KBASE_HW_ISSUE_TMIX_8463,
|
||||
KBASE_HW_ISSUE_TMIX_8456,
|
||||
KBASE_HW_ISSUE_TSIX_1116,
|
||||
KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TMIX_8438,
|
||||
KBASE_HW_ISSUE_TNOX_1194,
|
||||
KBASE_HW_ISSUE_TGOX_R1_1234,
|
||||
KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_TSIX_1792,
|
||||
KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_3076,
|
||||
KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TTRX_3083,
|
||||
KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TTRX_3485,
|
||||
KBASE_HW_ISSUE_GPU2019_3212,
|
||||
KBASE_HW_ISSUE_TURSEHW_1997,
|
||||
KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_TURSEHW_2716,
|
||||
KBASE_HW_ISSUE_GPU2019_3901,
|
||||
KBASE_HW_ISSUE_GPU2021PRO_290,
|
||||
KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_TITANHW_2679,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2922,
|
||||
KBASE_HW_ISSUE_TITANHW_2952,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2151,
|
||||
KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2269,
|
||||
KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_generic[] = { KBASE_HW_ISSUE_END };
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tMIx_r0p0_05dev0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_10682, KBASE_HW_ISSUE_11054,
|
||||
KBASE_HW_ISSUE_T76X_3953, KBASE_HW_ISSUE_TMIX_7891, KBASE_HW_ISSUE_TMIX_8042,
|
||||
KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TMIX_8138, KBASE_HW_ISSUE_TMIX_8206,
|
||||
KBASE_HW_ISSUE_TMIX_8343, KBASE_HW_ISSUE_TMIX_8463, KBASE_HW_ISSUE_TMIX_8456,
|
||||
KBASE_HW_ISSUE_TMIX_8438, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tMIx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_10682, KBASE_HW_ISSUE_11054,
|
||||
KBASE_HW_ISSUE_TMIX_7891, KBASE_HW_ISSUE_TMIX_7940, KBASE_HW_ISSUE_TMIX_8042,
|
||||
KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TMIX_8138, KBASE_HW_ISSUE_TMIX_8206,
|
||||
KBASE_HW_ISSUE_TMIX_8343, KBASE_HW_ISSUE_TMIX_8463, KBASE_HW_ISSUE_TMIX_8456,
|
||||
KBASE_HW_ISSUE_TMIX_8438, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tMIx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_10682, KBASE_HW_ISSUE_11054,
|
||||
KBASE_HW_ISSUE_TMIX_7891, KBASE_HW_ISSUE_TMIX_7940, KBASE_HW_ISSUE_TMIX_8042,
|
||||
KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TMIX_8138, KBASE_HW_ISSUE_TMIX_8206,
|
||||
KBASE_HW_ISSUE_TMIX_8343, KBASE_HW_ISSUE_TMIX_8463, KBASE_HW_ISSUE_TMIX_8456,
|
||||
KBASE_HW_ISSUE_TMIX_8438, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tMIx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_7891,
|
||||
KBASE_HW_ISSUE_TMIX_7940, KBASE_HW_ISSUE_TMIX_8042, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TMIX_8138, KBASE_HW_ISSUE_TMIX_8206, KBASE_HW_ISSUE_TMIX_8343,
|
||||
KBASE_HW_ISSUE_TMIX_8456, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tHEx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_10682, KBASE_HW_ISSUE_11054,
|
||||
KBASE_HW_ISSUE_TMIX_7891, KBASE_HW_ISSUE_TMIX_8042, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tHEx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_10682, KBASE_HW_ISSUE_11054,
|
||||
KBASE_HW_ISSUE_TMIX_7891, KBASE_HW_ISSUE_TMIX_8042, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tHEx_r0p2[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_10682, KBASE_HW_ISSUE_11054,
|
||||
KBASE_HW_ISSUE_TMIX_7891, KBASE_HW_ISSUE_TMIX_8042, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tHEx_r0p3[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_10682, KBASE_HW_ISSUE_TMIX_7891,
|
||||
KBASE_HW_ISSUE_TMIX_8042, KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tHEx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_7891,
|
||||
KBASE_HW_ISSUE_TMIX_8042, KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tSIx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_11054, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_1116, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TSIX_1792,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tSIx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_11054, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_1116, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TSIX_1792,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tSIx_r1p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_11054, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_1116, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tSIx_r1p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TSIX_1116,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tSIx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_1116, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tDVx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TSIX_1116,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tDVx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_1116, KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tNOx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_1116, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TNOX_1194, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tNOx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435,
|
||||
KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TSIX_1116,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tGOx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_1116, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TNOX_1194, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tGOx_r1p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TMIX_8133,
|
||||
KBASE_HW_ISSUE_TSIX_1116, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TGOX_R1_1234, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_GPU2017_1336, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tGOx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435,
|
||||
KBASE_HW_ISSUE_TMIX_8133, KBASE_HW_ISSUE_TSIX_1116,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTRx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_3076, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_TTRX_3414, KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TTRX_3485,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTRx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_3076, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_TTRX_3414, KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TTRX_3485,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTRx_r0p2[] = {
|
||||
KBASE_HW_ISSUE_9435,
|
||||
KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_3076,
|
||||
KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TTRX_3083,
|
||||
KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tTRx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_3414, KBASE_HW_ISSUE_TTRX_3083,
|
||||
KBASE_HW_ISSUE_TTRX_3470, KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tNAx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_3076, KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_TTRX_3414, KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TTRX_3485,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tNAx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_9435,
|
||||
KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_3076,
|
||||
KBASE_HW_ISSUE_TTRX_921,
|
||||
KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_GPU2017_1336,
|
||||
KBASE_HW_ISSUE_TTRX_3083,
|
||||
KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tNAx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_3414, KBASE_HW_ISSUE_TTRX_3083,
|
||||
KBASE_HW_ISSUE_TTRX_3470, KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBEx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TTRX_3485,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBEx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBEx_r1p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBEx_r1p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tBEx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_TTRX_3414, KBASE_HW_ISSUE_TTRX_3083,
|
||||
KBASE_HW_ISSUE_TTRX_3470, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_lBEx_r1p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TTRX_3485,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_lBEx_r1p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBAx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBAx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tBAx_r0p2[] = {
|
||||
KBASE_HW_ISSUE_9435, KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TTRX_2968_TTRX_3162,
|
||||
KBASE_HW_ISSUE_TTRX_921, KBASE_HW_ISSUE_TTRX_3414,
|
||||
KBASE_HW_ISSUE_TTRX_3083, KBASE_HW_ISSUE_TTRX_3470,
|
||||
KBASE_HW_ISSUE_TTRX_3464, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tBAx[] = {
|
||||
KBASE_HW_ISSUE_5736, KBASE_HW_ISSUE_9435,
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_TTRX_3414, KBASE_HW_ISSUE_TTRX_3083,
|
||||
KBASE_HW_ISSUE_TTRX_3470, KBASE_HW_ISSUE_TTRX_3464,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tODx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_GPU2019_3212, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tODx[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_GPU2019_3212, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tGRx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tGRx[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tVAx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tVAx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tVAx[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TURSEHW_1997,
|
||||
KBASE_HW_ISSUE_GPU2019_3878, KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2019_3901,
|
||||
KBASE_HW_ISSUE_GPU2021PRO_290, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_TITANHW_2679,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TURSEHW_1997,
|
||||
KBASE_HW_ISSUE_GPU2019_3878, KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2019_3901,
|
||||
KBASE_HW_ISSUE_GPU2021PRO_290, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_TITANHW_2679,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2922, KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_TURSEHW_2934, KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tTUx[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_GPU2021PRO_290,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_TITANHW_2679, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2922, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r1p0[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_GPU2021PRO_290,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_TITANHW_2679, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2922, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r1p1[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_GPU2021PRO_290,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_TITANHW_2679, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2922, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r1p2[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_GPU2021PRO_290,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_TITANHW_2679, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2922, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTUx_r1p3[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_GPU2019_3878,
|
||||
KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2019_3901, KBASE_HW_ISSUE_GPU2021PRO_290,
|
||||
KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_TITANHW_2679, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2922, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tTIx[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_TURSEHW_2716,
|
||||
KBASE_HW_ISSUE_GPU2021PRO_290,
|
||||
KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_TITANHW_2679,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2922,
|
||||
KBASE_HW_ISSUE_TITANHW_2952,
|
||||
KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTIx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033,
|
||||
KBASE_HW_ISSUE_TTRX_1337,
|
||||
KBASE_HW_ISSUE_TURSEHW_2716,
|
||||
KBASE_HW_ISSUE_GPU2021PRO_290,
|
||||
KBASE_HW_ISSUE_TITANHW_2710,
|
||||
KBASE_HW_ISSUE_TITANHW_2679,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_TITANHW_2922,
|
||||
KBASE_HW_ISSUE_TITANHW_2952,
|
||||
KBASE_HW_ISSUE_TITANHW_2938,
|
||||
KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tTIx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_TSIX_2033, KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TURSEHW_2716,
|
||||
KBASE_HW_ISSUE_GPU2021PRO_290, KBASE_HW_ISSUE_TITANHW_2710, KBASE_HW_ISSUE_TITANHW_2679,
|
||||
KBASE_HW_ISSUE_GPU2022PRO_148, KBASE_HW_ISSUE_TITANHW_2938, KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tKRx_r0p0[] = {
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2151, KBASE_HW_ISSUE_KRAKEHW_2269, KBASE_HW_ISSUE_TITANHW_2922,
|
||||
KBASE_HW_ISSUE_TURSEHW_2934, KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_tKRx_r0p1[] = {
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2269, KBASE_HW_ISSUE_TURSEHW_2934, KBASE_HW_ISSUE_KRAKEHW_2321,
|
||||
KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
__maybe_unused static const enum base_hw_issue base_hw_issues_model_tKRx[] = {
|
||||
KBASE_HW_ISSUE_TTRX_1337, KBASE_HW_ISSUE_TURSEHW_2716, KBASE_HW_ISSUE_GPU2022PRO_148,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2151, KBASE_HW_ISSUE_KRAKEHW_2269, KBASE_HW_ISSUE_TURSEHW_2934,
|
||||
KBASE_HW_ISSUE_KRAKEHW_2321, KBASE_HW_ISSUE_END
|
||||
};
|
||||
|
||||
|
||||
#endif /* _KBASE_HWCONFIG_ISSUES_H_ */
|
||||
542
drivers/gpu/arm/bifrost/mali_kbase_ioctl_helpers.h
Normal file
542
drivers/gpu/arm/bifrost/mali_kbase_ioctl_helpers.h
Normal file
|
|
@ -0,0 +1,542 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _KBASE_IOCTL_HELPERS_H_
|
||||
#define _KBASE_IOCTL_HELPERS_H_
|
||||
|
||||
#include <uapi/gpu/arm/bifrost/mali_kbase_ioctl.h>
|
||||
|
||||
/* Macro for IOCTLs that don't have IOCTL struct */
|
||||
#define KBASE_HANDLE_IOCTL(cmd, function, arg) \
|
||||
do { \
|
||||
int ret; \
|
||||
BUILD_BUG_ON(_IOC_DIR(cmd) != _IOC_NONE); \
|
||||
dev_dbg(arg->kbdev->dev, "Enter ioctl %s\n", #function); \
|
||||
ret = function(arg); \
|
||||
dev_dbg(arg->kbdev->dev, "Return %d from ioctl %s\n", ret, #function); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
/* Macro for IOCTLs that have input IOCTL struct */
|
||||
#define KBASE_HANDLE_IOCTL_IN(cmd, function, type, arg) \
|
||||
do { \
|
||||
type param; \
|
||||
int ret, err; \
|
||||
dev_dbg(arg->kbdev->dev, "Enter ioctl %s\n", #function); \
|
||||
BUILD_BUG_ON(_IOC_DIR(cmd) != _IOC_WRITE); \
|
||||
BUILD_BUG_ON(sizeof(param) != _IOC_SIZE(cmd)); \
|
||||
err = copy_from_user(¶m, uarg, sizeof(param)); \
|
||||
if (unlikely(err)) \
|
||||
return -EFAULT; \
|
||||
err = check_padding_##cmd(¶m); \
|
||||
if (unlikely(err)) \
|
||||
return -EINVAL; \
|
||||
ret = function(arg, ¶m); \
|
||||
dev_dbg(arg->kbdev->dev, "Return %d from ioctl %s\n", ret, #function); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
/* Macro for IOCTLs that have output IOCTL struct */
|
||||
#define KBASE_HANDLE_IOCTL_OUT(cmd, function, type, arg) \
|
||||
do { \
|
||||
type param; \
|
||||
int ret, err; \
|
||||
dev_dbg(arg->kbdev->dev, "Enter ioctl %s\n", #function); \
|
||||
BUILD_BUG_ON(_IOC_DIR(cmd) != _IOC_READ); \
|
||||
BUILD_BUG_ON(sizeof(param) != _IOC_SIZE(cmd)); \
|
||||
memset(¶m, 0, sizeof(param)); \
|
||||
ret = function(arg, ¶m); \
|
||||
err = copy_to_user(uarg, ¶m, sizeof(param)); \
|
||||
if (unlikely(err)) \
|
||||
return -EFAULT; \
|
||||
dev_dbg(arg->kbdev->dev, "Return %d from ioctl %s\n", ret, #function); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
/* Macro for IOCTLs that have input and output IOCTL struct */
|
||||
#define KBASE_HANDLE_IOCTL_INOUT(cmd, function, type, arg) \
|
||||
do { \
|
||||
type param; \
|
||||
int ret, err; \
|
||||
dev_dbg(arg->kbdev->dev, "Enter ioctl %s\n", #function); \
|
||||
BUILD_BUG_ON(_IOC_DIR(cmd) != (_IOC_WRITE | _IOC_READ)); \
|
||||
BUILD_BUG_ON(sizeof(param) != _IOC_SIZE(cmd)); \
|
||||
err = copy_from_user(¶m, uarg, sizeof(param)); \
|
||||
if (unlikely(err)) \
|
||||
return -EFAULT; \
|
||||
err = check_padding_##cmd(¶m); \
|
||||
if (unlikely(err)) \
|
||||
return -EINVAL; \
|
||||
ret = function(arg, ¶m); \
|
||||
err = copy_to_user(uarg, ¶m, sizeof(param)); \
|
||||
if (unlikely(err)) \
|
||||
return -EFAULT; \
|
||||
dev_dbg(arg->kbdev->dev, "Return %d from ioctl %s\n", ret, #function); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
/* Inline functions to check padding bytes in the input IOCTL struct.
|
||||
* Return 0 if all padding bytes are zero, non-zero otherwise.
|
||||
*/
|
||||
static inline int check_padding_KBASE_IOCTL_VERSION_CHECK(struct kbase_ioctl_version_check *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_VERSION_CHECK_RESERVED(struct kbase_ioctl_version_check *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_SET_FLAGS(struct kbase_ioctl_set_flags *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_GET_GPUPROPS(struct kbase_ioctl_get_gpuprops *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_ALLOC(union kbase_ioctl_mem_alloc *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_QUERY(union kbase_ioctl_mem_query *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_FREE(struct kbase_ioctl_mem_free *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_HWCNT_READER_SETUP(struct kbase_ioctl_hwcnt_reader_setup *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_HWCNT_SET(struct kbase_ioctl_hwcnt_values *p)
|
||||
{
|
||||
return p->padding;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_GET_DDK_VERSION(struct kbase_ioctl_get_ddk_version *p)
|
||||
{
|
||||
return p->padding;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_JIT_INIT(struct kbase_ioctl_mem_jit_init *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->padding); i++) {
|
||||
if (p->padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_SYNC(struct kbase_ioctl_mem_sync *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* Checking p->padding is deferred till the support window for backward-compatibility ends.
|
||||
* GPUCORE-42000 will add the checking.
|
||||
*
|
||||
* To avoid the situation with old version of base which might not set padding bytes as 0,
|
||||
* padding bytes are set as zero here on behalf on user space.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(p->padding); i++)
|
||||
p->padding[i] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_MEM_FIND_CPU_OFFSET(union kbase_ioctl_mem_find_cpu_offset *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_TLSTREAM_ACQUIRE(struct kbase_ioctl_tlstream_acquire *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_COMMIT(struct kbase_ioctl_mem_commit *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_ALIAS(union kbase_ioctl_mem_alias *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_IMPORT(union kbase_ioctl_mem_import *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_FLAGS_CHANGE(struct kbase_ioctl_mem_flags_change *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_STREAM_CREATE(struct kbase_ioctl_stream_create *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_FENCE_VALIDATE(struct kbase_ioctl_fence_validate *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_PROFILE_ADD(struct kbase_ioctl_mem_profile_add *p)
|
||||
{
|
||||
return p->padding;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_STICKY_RESOURCE_MAP(struct kbase_ioctl_sticky_resource_map *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_STICKY_RESOURCE_UNMAP(struct kbase_ioctl_sticky_resource_unmap *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_FIND_GPU_START_AND_OFFSET(
|
||||
union kbase_ioctl_mem_find_gpu_start_and_offset *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_CINSTR_GWT_DUMP(union kbase_ioctl_cinstr_gwt_dump *p)
|
||||
{
|
||||
/*
|
||||
* Checking p->padding is deferred till the support window for backward-compatibility ends.
|
||||
* GPUCORE-42000 will add the checking.
|
||||
*
|
||||
* To avoid the situation with old version of base which might not set padding bytes as 0,
|
||||
* padding bytes are set as zero here on behalf on user space.
|
||||
*/
|
||||
p->in.padding = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_EXEC_INIT(struct kbase_ioctl_mem_exec_init *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_GET_CPU_GPU_TIMEINFO(union kbase_ioctl_get_cpu_gpu_timeinfo *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->in.paddings); i++) {
|
||||
if (p->in.paddings[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CONTEXT_PRIORITY_CHECK(struct kbase_ioctl_context_priority_check *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_SET_LIMITED_CORE_COUNT(struct kbase_ioctl_set_limited_core_count *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_KINSTR_PRFCNT_ENUM_INFO(struct kbase_ioctl_kinstr_prfcnt_enum_info *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_KINSTR_PRFCNT_SETUP(union kbase_ioctl_kinstr_prfcnt_setup *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if MALI_UNIT_TEST
|
||||
#endif /* MALI_UNIT_TEST */
|
||||
|
||||
#if MALI_USE_CSF
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_QUEUE_REGISTER(struct kbase_ioctl_cs_queue_register *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->padding); i++) {
|
||||
if (p->padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_CS_QUEUE_KICK(struct kbase_ioctl_cs_queue_kick *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_CS_QUEUE_BIND(union kbase_ioctl_cs_queue_bind *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* Checking p->padding is deferred till the support window for backward-compatibility ends.
|
||||
* GPUCORE-42000 will add the checking.
|
||||
*
|
||||
* To avoid the situation with old version of base which might not set padding bytes as 0,
|
||||
* padding bytes are set as zero here on behalf on user space.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(p->in.padding); i++)
|
||||
p->in.padding[i] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_QUEUE_REGISTER_EX(struct kbase_ioctl_cs_queue_register_ex *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->padding); i++) {
|
||||
if (p->padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->ex_padding); i++) {
|
||||
if (p->ex_padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_QUEUE_TERMINATE(struct kbase_ioctl_cs_queue_terminate *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_QUEUE_GROUP_CREATE_1_6(union kbase_ioctl_cs_queue_group_create_1_6 *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->in.padding); i++) {
|
||||
if (p->in.padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_CS_QUEUE_GROUP_CREATE_1_18(
|
||||
union kbase_ioctl_cs_queue_group_create_1_18 *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->in.padding); i++) {
|
||||
if (p->in.padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_QUEUE_GROUP_CREATE(union kbase_ioctl_cs_queue_group_create *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->in.padding); i++) {
|
||||
if (p->in.padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_QUEUE_GROUP_TERMINATE(struct kbase_ioctl_cs_queue_group_term *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->padding); i++) {
|
||||
if (p->padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_KCPU_QUEUE_DELETE(struct kbase_ioctl_kcpu_queue_delete *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* Checking p->padding is deferred till the support window for backward-compatibility ends.
|
||||
* GPUCORE-42000 will add the checking.
|
||||
*
|
||||
* To avoid the situation with old version of base which might not set padding bytes as 0,
|
||||
* padding bytes are set as zero here on behalf on user space.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(p->padding); i++)
|
||||
p->padding[i] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_KCPU_QUEUE_ENQUEUE(struct kbase_ioctl_kcpu_queue_enqueue *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* Checking p->padding is deferred till the support window for backward-compatibility ends.
|
||||
* GPUCORE-42000 will add the checking.
|
||||
*
|
||||
* To avoid the situation with old version of base which might not set padding bytes as 0,
|
||||
* padding bytes are set as zero here on behalf on user space.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(p->padding); i++)
|
||||
p->padding[i] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_TILER_HEAP_INIT(union kbase_ioctl_cs_tiler_heap_init *p)
|
||||
{
|
||||
return p->in.padding;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_TILER_HEAP_INIT_1_13(union kbase_ioctl_cs_tiler_heap_init_1_13 *p)
|
||||
{
|
||||
return p->in.padding;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_TILER_HEAP_TERM(struct kbase_ioctl_cs_tiler_heap_term *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_CS_GET_GLB_IFACE(union kbase_ioctl_cs_get_glb_iface *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_CS_CPU_QUEUE_DUMP(struct kbase_ioctl_cs_cpu_queue_info *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_MEM_ALLOC_EX(union kbase_ioctl_mem_alloc_ex *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->in.extra); i++) {
|
||||
if (p->in.extra[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_READ_USER_PAGE(union kbase_ioctl_read_user_page *p)
|
||||
{
|
||||
return p->in.padding;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_QUEUE_GROUP_CLEAR_FAULTS(struct kbase_ioctl_queue_group_clear_faults *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* Checking p->padding is deferred till the support window for backward-compatibility ends.
|
||||
* GPUCORE-42000 will add the checking.
|
||||
*
|
||||
* To avoid the situation with old version of base which might not set padding bytes as 0,
|
||||
* padding bytes are set as zero here on behalf on user space.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(p->padding); i++)
|
||||
p->padding[i] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* MALI_USE_CSF */
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_JOB_SUBMIT(struct kbase_ioctl_job_submit *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
check_padding_KBASE_IOCTL_SOFT_EVENT_UPDATE(struct kbase_ioctl_soft_event_update *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int check_padding_KBASE_IOCTL_KINSTR_JM_FD(union kbase_kinstr_jm_fd *p)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p->in.padding); i++) {
|
||||
if (p->in.padding[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !MALI_USE_CSF */
|
||||
|
||||
#endif /* _KBASE_IOCTL_HELPERS_H_ */
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2010-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -39,9 +39,6 @@
|
|||
#include <mali_kbase_hwaccess_jm.h>
|
||||
#include <tl/mali_kbase_tracepoints.h>
|
||||
#include <mali_linux_trace.h>
|
||||
|
||||
#include <mali_kbase_cs_experimental.h>
|
||||
|
||||
#include <mali_kbase_caps.h>
|
||||
|
||||
/* Return whether katom will run on the GPU or not. Currently only soft jobs and
|
||||
|
|
@ -209,7 +206,7 @@ static int kbase_jd_pre_external_resources(struct kbase_jd_atom *katom,
|
|||
}
|
||||
|
||||
if (copy_from_user(input_extres, get_compat_pointer(katom->kctx, user_atom->extres_list),
|
||||
sizeof(*input_extres) * katom->nr_extres) != 0) {
|
||||
size_mul(sizeof(*input_extres), katom->nr_extres)) != 0) {
|
||||
err = -EINVAL;
|
||||
goto failed_input_copy;
|
||||
}
|
||||
|
|
@ -697,7 +694,6 @@ static void jd_trace_atom_submit(struct kbase_context *const kctx,
|
|||
|
||||
static bool jd_submit_atom(struct kbase_context *const kctx,
|
||||
const struct base_jd_atom *const user_atom,
|
||||
const struct base_jd_fragment *const user_jc_incr,
|
||||
struct kbase_jd_atom *const katom)
|
||||
{
|
||||
struct kbase_device *kbdev = kctx->kbdev;
|
||||
|
|
@ -755,8 +751,6 @@ static bool jd_submit_atom(struct kbase_context *const kctx,
|
|||
}
|
||||
#endif /* MALI_JIT_PRESSURE_LIMIT_BASE */
|
||||
|
||||
katom->renderpass_id = user_atom->renderpass_id;
|
||||
|
||||
/* Implicitly sets katom->protected_state.enter as well. */
|
||||
katom->protected_state.exit = KBASE_ATOM_EXIT_PROTECTED_CHECK;
|
||||
|
||||
|
|
@ -875,20 +869,7 @@ static bool jd_submit_atom(struct kbase_context *const kctx,
|
|||
/* Create a new atom. */
|
||||
jd_trace_atom_submit(kctx, katom, &katom->sched_priority);
|
||||
|
||||
#if !MALI_INCREMENTAL_RENDERING_JM
|
||||
/* Reject atoms for incremental rendering if not supported */
|
||||
if (katom->core_req & (BASE_JD_REQ_START_RENDERPASS | BASE_JD_REQ_END_RENDERPASS)) {
|
||||
dev_err(kctx->kbdev->dev, "Rejecting atom with unsupported core_req 0x%x\n",
|
||||
katom->core_req);
|
||||
katom->event_code = BASE_JD_EVENT_JOB_INVALID;
|
||||
return kbase_jd_done_nolock(katom, true);
|
||||
}
|
||||
#endif /* !MALI_INCREMENTAL_RENDERING_JM */
|
||||
|
||||
if (katom->core_req & BASE_JD_REQ_END_RENDERPASS) {
|
||||
WARN_ON(katom->jc != 0);
|
||||
katom->jc_fragment = *user_jc_incr;
|
||||
} else if (!katom->jc && (katom->core_req & BASE_JD_REQ_ATOM_TYPE) != BASE_JD_REQ_DEP) {
|
||||
if (!katom->jc && (katom->core_req & BASE_JD_REQ_ATOM_TYPE) != BASE_JD_REQ_DEP) {
|
||||
/* Reject atoms with job chain = NULL, as these cause issues
|
||||
* with soft-stop
|
||||
*/
|
||||
|
|
@ -1018,8 +999,7 @@ int kbase_jd_submit(struct kbase_context *kctx, void __user *user_addr, u32 nr_a
|
|||
struct kbase_device *kbdev;
|
||||
u32 latest_flush;
|
||||
|
||||
bool jd_atom_is_v2 = (stride == sizeof(struct base_jd_atom_v2) ||
|
||||
stride == offsetof(struct base_jd_atom_v2, renderpass_id));
|
||||
bool jd_atom_is_v2 = (stride == sizeof(struct base_jd_atom_v2));
|
||||
|
||||
CSTD_UNUSED(uk6_atom);
|
||||
|
||||
|
|
@ -1035,10 +1015,7 @@ int kbase_jd_submit(struct kbase_context *kctx, void __user *user_addr, u32 nr_a
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stride != offsetof(struct base_jd_atom_v2, renderpass_id) &&
|
||||
stride != sizeof(struct base_jd_atom_v2) &&
|
||||
stride != offsetof(struct base_jd_atom, renderpass_id) &&
|
||||
stride != sizeof(struct base_jd_atom)) {
|
||||
if (stride != sizeof(struct base_jd_atom_v2) && stride != sizeof(struct base_jd_atom)) {
|
||||
dev_err(kbdev->dev,
|
||||
"Stride %u passed to job_submit isn't supported by the kernel\n", stride);
|
||||
return -EINVAL;
|
||||
|
|
@ -1057,7 +1034,6 @@ int kbase_jd_submit(struct kbase_context *kctx, void __user *user_addr, u32 nr_a
|
|||
struct base_jd_atom user_atom = {
|
||||
.seq_nr = 0,
|
||||
};
|
||||
struct base_jd_fragment user_jc_incr;
|
||||
struct kbase_jd_atom *katom;
|
||||
|
||||
if (unlikely(jd_atom_is_v2)) {
|
||||
|
|
@ -1082,44 +1058,6 @@ int kbase_jd_submit(struct kbase_context *kctx, void __user *user_addr, u32 nr_a
|
|||
}
|
||||
}
|
||||
|
||||
if (stride == offsetof(struct base_jd_atom_v2, renderpass_id)) {
|
||||
dev_dbg(kbdev->dev, "No renderpass ID: use 0\n");
|
||||
user_atom.renderpass_id = 0;
|
||||
} else {
|
||||
/* Ensure all padding bytes are 0 for potential future
|
||||
* extension
|
||||
*/
|
||||
size_t j;
|
||||
|
||||
dev_dbg(kbdev->dev, "Renderpass ID is %d\n", user_atom.renderpass_id);
|
||||
for (j = 0; j < sizeof(user_atom.padding); j++) {
|
||||
if (user_atom.padding[j]) {
|
||||
dev_err(kbdev->dev, "Bad padding byte %zu: %d\n", j,
|
||||
user_atom.padding[j]);
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
/* In this case 'jc' is the CPU address of a struct
|
||||
* instead of a GPU address of a job chain.
|
||||
*/
|
||||
if (user_atom.core_req & BASE_JD_REQ_END_RENDERPASS) {
|
||||
if (copy_from_user(&user_jc_incr, u64_to_user_ptr(user_atom.jc),
|
||||
sizeof(user_jc_incr))) {
|
||||
dev_err(kbdev->dev,
|
||||
"Invalid jc address 0x%llx passed to job_submit\n",
|
||||
user_atom.jc);
|
||||
err = -EFAULT;
|
||||
break;
|
||||
}
|
||||
dev_dbg(kbdev->dev, "Copied IR jobchain addresses\n");
|
||||
user_atom.jc = 0;
|
||||
}
|
||||
|
||||
user_addr = (void __user *)((uintptr_t)user_addr + stride);
|
||||
|
||||
mutex_lock(&jctx->lock);
|
||||
|
|
@ -1172,8 +1110,7 @@ int kbase_jd_submit(struct kbase_context *kctx, void __user *user_addr, u32 nr_a
|
|||
mutex_lock(&jctx->lock);
|
||||
}
|
||||
KBASE_TLSTREAM_TL_JD_SUBMIT_ATOM_START(kbdev, katom);
|
||||
need_to_try_schedule_context |=
|
||||
jd_submit_atom(kctx, &user_atom, &user_jc_incr, katom);
|
||||
need_to_try_schedule_context |= jd_submit_atom(kctx, &user_atom, katom);
|
||||
KBASE_TLSTREAM_TL_JD_SUBMIT_ATOM_END(kbdev, katom);
|
||||
/* Register a completed job as a disjoint event when the GPU is in a disjoint state
|
||||
* (ie. being reset).
|
||||
|
|
@ -1579,9 +1516,6 @@ int kbase_jd_init(struct kbase_context *kctx)
|
|||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < BASE_JD_RP_COUNT; i++)
|
||||
kctx->jctx.renderpasses[i].state = KBASE_JD_RP_COMPLETE;
|
||||
|
||||
mutex_init(&kctx->jctx.lock);
|
||||
|
||||
init_waitqueue_head(&kctx->jctx.zero_jobs_wait);
|
||||
|
|
|
|||
|
|
@ -333,19 +333,6 @@ static void jsctx_queue_foreach_prio(struct kbase_context *kctx, unsigned int js
|
|||
|
||||
rb_erase(node, &queue->runnable_tree);
|
||||
callback(kctx->kbdev, entry);
|
||||
|
||||
/* Runnable end-of-renderpass atoms can also be in the linked
|
||||
* list of atoms blocked on cross-slot dependencies. Remove them
|
||||
* to avoid calling the callback twice.
|
||||
*/
|
||||
if (entry->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST) {
|
||||
WARN_ON(!(entry->core_req & BASE_JD_REQ_END_RENDERPASS));
|
||||
dev_dbg(kctx->kbdev->dev, "Del runnable atom %pK from X_DEP list\n",
|
||||
(void *)entry);
|
||||
|
||||
list_del(&entry->queue);
|
||||
entry->atom_flags &= ~KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
while (!list_empty(&queue->x_dep_head)) {
|
||||
|
|
@ -1230,7 +1217,7 @@ static bool kbase_js_ctx_pullable(struct kbase_context *kctx, unsigned int js, b
|
|||
dev_dbg(kbdev->dev, "JS: Atom %pK is blocked in js_ctx_pullable\n", (void *)katom);
|
||||
return false; /* next atom blocked */
|
||||
}
|
||||
if (kbase_js_atom_blocked_on_x_dep(katom)) {
|
||||
if (katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED) {
|
||||
if (katom->x_pre_dep->gpu_rb_state == KBASE_ATOM_GPU_RB_NOT_IN_SLOT_RB ||
|
||||
katom->x_pre_dep->will_fail_event_code) {
|
||||
dev_dbg(kbdev->dev,
|
||||
|
|
@ -1371,9 +1358,6 @@ static bool kbase_js_dep_validate(struct kbase_context *kctx, struct kbase_jd_at
|
|||
(dep_atom->status != KBASE_JD_ATOM_STATE_UNUSED)) {
|
||||
katom->atom_flags |= KBASE_KATOM_FLAG_X_DEP_BLOCKED;
|
||||
|
||||
dev_dbg(kbdev->dev, "Set X_DEP flag on atom %pK\n",
|
||||
(void *)katom);
|
||||
|
||||
katom->x_pre_dep = dep_atom;
|
||||
dep_atom->x_post_dep = katom;
|
||||
if (kbase_jd_katom_dep_type(&katom->dep[i]) ==
|
||||
|
|
@ -1447,110 +1431,12 @@ void kbase_js_update_ctx_priority(struct kbase_context *kctx)
|
|||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_js_update_ctx_priority);
|
||||
|
||||
/**
|
||||
* js_add_start_rp() - Add an atom that starts a renderpass to the job scheduler
|
||||
* @start_katom: Pointer to the atom to be added.
|
||||
* Return: 0 if successful or a negative value on failure.
|
||||
*/
|
||||
static int js_add_start_rp(struct kbase_jd_atom *const start_katom)
|
||||
{
|
||||
struct kbase_context *const kctx = start_katom->kctx;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&kctx->jctx.lock);
|
||||
|
||||
if (WARN_ON(!(start_katom->core_req & BASE_JD_REQ_START_RENDERPASS)))
|
||||
return -EINVAL;
|
||||
|
||||
if (start_katom->core_req & BASE_JD_REQ_END_RENDERPASS)
|
||||
return -EINVAL;
|
||||
|
||||
compiletime_assert((1ull << (sizeof(start_katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[start_katom->renderpass_id];
|
||||
|
||||
if (rp->state != KBASE_JD_RP_COMPLETE)
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "JS add start atom %pK of RP %d\n", (void *)start_katom,
|
||||
start_katom->renderpass_id);
|
||||
|
||||
/* The following members are read when updating the job slot
|
||||
* ringbuffer/fifo therefore they require additional locking.
|
||||
*/
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
rp->state = KBASE_JD_RP_START;
|
||||
rp->start_katom = start_katom;
|
||||
rp->end_katom = NULL;
|
||||
INIT_LIST_HEAD(&rp->oom_reg_list);
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* js_add_end_rp() - Add an atom that ends a renderpass to the job scheduler
|
||||
* @end_katom: Pointer to the atom to be added.
|
||||
* Return: 0 if successful or a negative value on failure.
|
||||
*/
|
||||
static int js_add_end_rp(struct kbase_jd_atom *const end_katom)
|
||||
{
|
||||
struct kbase_context *const kctx = end_katom->kctx;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
|
||||
lockdep_assert_held(&kctx->jctx.lock);
|
||||
|
||||
if (WARN_ON(!(end_katom->core_req & BASE_JD_REQ_END_RENDERPASS)))
|
||||
return -EINVAL;
|
||||
|
||||
if (end_katom->core_req & BASE_JD_REQ_START_RENDERPASS)
|
||||
return -EINVAL;
|
||||
|
||||
compiletime_assert((1ull << (sizeof(end_katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[end_katom->renderpass_id];
|
||||
|
||||
dev_dbg(kbdev->dev, "JS add end atom %pK in state %d of RP %d\n", (void *)end_katom,
|
||||
(int)rp->state, end_katom->renderpass_id);
|
||||
|
||||
if (rp->state == KBASE_JD_RP_COMPLETE)
|
||||
return -EINVAL;
|
||||
|
||||
if (rp->end_katom == NULL) {
|
||||
/* We can't be in a retry state until the fragment job chain
|
||||
* has completed.
|
||||
*/
|
||||
unsigned long flags;
|
||||
|
||||
WARN_ON(rp->state == KBASE_JD_RP_RETRY);
|
||||
WARN_ON(rp->state == KBASE_JD_RP_RETRY_PEND_OOM);
|
||||
WARN_ON(rp->state == KBASE_JD_RP_RETRY_OOM);
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
rp->end_katom = end_katom;
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
} else
|
||||
WARN_ON(rp->end_katom != end_katom);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool kbasep_js_add_job(struct kbase_context *kctx, struct kbase_jd_atom *atom)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct kbasep_js_kctx_info *js_kctx_info;
|
||||
struct kbase_device *kbdev;
|
||||
struct kbasep_js_device_data *js_devdata;
|
||||
int err = 0;
|
||||
|
||||
bool enqueue_required = false;
|
||||
bool timer_sync = false;
|
||||
|
|
@ -1566,17 +1452,6 @@ bool kbasep_js_add_job(struct kbase_context *kctx, struct kbase_jd_atom *atom)
|
|||
mutex_lock(&js_devdata->queue_mutex);
|
||||
mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
|
||||
|
||||
if (atom->core_req & BASE_JD_REQ_START_RENDERPASS)
|
||||
err = js_add_start_rp(atom);
|
||||
else if (atom->core_req & BASE_JD_REQ_END_RENDERPASS)
|
||||
err = js_add_end_rp(atom);
|
||||
|
||||
if (err < 0) {
|
||||
atom->event_code = BASE_JD_EVENT_JOB_INVALID;
|
||||
atom->status = KBASE_JD_ATOM_STATE_COMPLETED;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin Runpool transaction
|
||||
*/
|
||||
|
|
@ -1860,10 +1735,7 @@ kbasep_js_runpool_release_ctx_internal(struct kbase_device *kbdev, struct kbase_
|
|||
kbasep_js_ctx_attr_ctx_release_atom(kbdev, kctx, katom_retained_state);
|
||||
|
||||
if (new_ref_count == 2 && kbase_ctx_flag(kctx, KCTX_PRIVILEGED) &&
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
!kbase_pm_is_gpu_lost(kbdev) &&
|
||||
#endif
|
||||
!kbase_pm_is_suspending(kbdev)) {
|
||||
!kbase_pm_is_gpu_lost(kbdev) && !kbase_pm_is_suspending(kbdev)) {
|
||||
/* Context is kept scheduled into an address space even when
|
||||
* there are no jobs, in this case we have to handle the
|
||||
* situation where all jobs have been evicted from the GPU and
|
||||
|
|
@ -1880,10 +1752,7 @@ kbasep_js_runpool_release_ctx_internal(struct kbase_device *kbdev, struct kbase_
|
|||
* which was previously acquired by kbasep_js_schedule_ctx().
|
||||
*/
|
||||
if (new_ref_count == 1 && (!kbasep_js_is_submit_allowed(js_devdata, kctx) ||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
kbase_pm_is_gpu_lost(kbdev) ||
|
||||
#endif
|
||||
kbase_pm_is_suspending(kbdev))) {
|
||||
kbase_pm_is_gpu_lost(kbdev) || kbase_pm_is_suspending(kbdev))) {
|
||||
int num_slots = kbdev->gpu_props.num_job_slots;
|
||||
unsigned int slot;
|
||||
|
||||
|
|
@ -2189,11 +2058,7 @@ static bool kbasep_js_schedule_ctx(struct kbase_device *kbdev, struct kbase_cont
|
|||
* of it being called strictly after the suspend flag is set, and will
|
||||
* wait for this lock to drop)
|
||||
*/
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (kbase_pm_is_suspending(kbdev) || kbase_pm_is_gpu_lost(kbdev)) {
|
||||
#else
|
||||
if (kbase_pm_is_suspending(kbdev)) {
|
||||
#endif
|
||||
/* Cause it to leave at some later point */
|
||||
bool retained;
|
||||
CSTD_UNUSED(retained);
|
||||
|
|
@ -2267,7 +2132,6 @@ void kbasep_js_schedule_privileged_ctx(struct kbase_device *kbdev, struct kbase_
|
|||
js_devdata = &kbdev->js_data;
|
||||
js_kctx_info = &kctx->jctx.sched_info;
|
||||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
/* This should only happen in response to a system call
|
||||
* from a user-space thread.
|
||||
* In a non-arbitrated environment this can never happen
|
||||
|
|
@ -2279,18 +2143,10 @@ void kbasep_js_schedule_privileged_ctx(struct kbase_device *kbdev, struct kbase_
|
|||
* the wait event for KCTX_SCHEDULED, since no context
|
||||
* can be scheduled until we have the GPU again.
|
||||
*/
|
||||
if (kbdev->arb.arb_if == NULL)
|
||||
if (!kbase_has_arbiter(kbdev)) {
|
||||
if (WARN_ON(kbase_pm_is_suspending(kbdev)))
|
||||
return;
|
||||
#else
|
||||
/* This should only happen in response to a system call
|
||||
* from a user-space thread.
|
||||
* In a non-arbitrated environment this can never happen
|
||||
* whilst suspending.
|
||||
*/
|
||||
if (WARN_ON(kbase_pm_is_suspending(kbdev)))
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
mutex_lock(&js_devdata->queue_mutex);
|
||||
mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
|
||||
|
|
@ -2416,63 +2272,63 @@ void kbasep_js_resume(struct kbase_device *kbdev)
|
|||
struct kbase_context *kctx, *n;
|
||||
unsigned long flags;
|
||||
|
||||
#ifndef CONFIG_MALI_ARBITER_SUPPORT
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
if (kbase_has_arbiter(kbdev)) {
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
list_for_each_entry_safe(kctx, n,
|
||||
&kbdev->js_data.ctx_list_unpullable[js][prio],
|
||||
jctx.sched_info.ctx.ctx_list_entry[js]) {
|
||||
struct kbasep_js_kctx_info *js_kctx_info;
|
||||
list_for_each_entry_safe(
|
||||
kctx, n, &kbdev->js_data.ctx_list_unpullable[js][prio],
|
||||
jctx.sched_info.ctx.ctx_list_entry[js]) {
|
||||
struct kbasep_js_kctx_info *js_kctx_info;
|
||||
bool timer_sync = false;
|
||||
|
||||
/* Drop lock so we can take kctx mutexes */
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
js_kctx_info = &kctx->jctx.sched_info;
|
||||
|
||||
mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
|
||||
mutex_lock(&js_devdata->runpool_mutex);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
|
||||
kbase_js_ctx_pullable(kctx, js, false))
|
||||
timer_sync = kbase_js_ctx_list_add_pullable_nolock(
|
||||
kbdev, kctx, js);
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
if (timer_sync)
|
||||
kbase_backend_ctx_count_changed(kbdev);
|
||||
|
||||
mutex_unlock(&js_devdata->runpool_mutex);
|
||||
mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
|
||||
|
||||
/* Take lock before accessing list again */
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
} else {
|
||||
bool timer_sync = false;
|
||||
|
||||
/* Drop lock so we can take kctx mutexes */
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
js_kctx_info = &kctx->jctx.sched_info;
|
||||
|
||||
mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
|
||||
mutex_lock(&js_devdata->runpool_mutex);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
|
||||
kbase_js_ctx_pullable(kctx, js, false))
|
||||
timer_sync = kbase_js_ctx_list_add_pullable_nolock(
|
||||
kbdev, kctx, js);
|
||||
list_for_each_entry_safe(
|
||||
kctx, n, &kbdev->js_data.ctx_list_unpullable[js][prio],
|
||||
jctx.sched_info.ctx.ctx_list_entry[js]) {
|
||||
if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
|
||||
kbase_js_ctx_pullable(kctx, js, false))
|
||||
timer_sync |= kbase_js_ctx_list_add_pullable_nolock(
|
||||
kbdev, kctx, js);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
if (timer_sync)
|
||||
if (timer_sync) {
|
||||
mutex_lock(&js_devdata->runpool_mutex);
|
||||
kbase_backend_ctx_count_changed(kbdev);
|
||||
|
||||
mutex_unlock(&js_devdata->runpool_mutex);
|
||||
mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
|
||||
|
||||
/* Take lock before accessing list again */
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
mutex_unlock(&js_devdata->runpool_mutex);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
#else
|
||||
bool timer_sync = false;
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
list_for_each_entry_safe(kctx, n,
|
||||
&kbdev->js_data.ctx_list_unpullable[js][prio],
|
||||
jctx.sched_info.ctx.ctx_list_entry[js]) {
|
||||
if (!kbase_ctx_flag(kctx, KCTX_SCHEDULED) &&
|
||||
kbase_js_ctx_pullable(kctx, js, false))
|
||||
timer_sync |= kbase_js_ctx_list_add_pullable_nolock(
|
||||
kbdev, kctx, js);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
if (timer_sync) {
|
||||
mutex_lock(&js_devdata->runpool_mutex);
|
||||
kbase_backend_ctx_count_changed(kbdev);
|
||||
mutex_unlock(&js_devdata->runpool_mutex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mutex_unlock(&js_devdata->queue_mutex);
|
||||
|
|
@ -2515,7 +2371,7 @@ static unsigned int kbase_js_get_slot(struct kbase_device *kbdev, struct kbase_j
|
|||
|
||||
bool kbase_js_dep_resolved_submit(struct kbase_context *kctx, struct kbase_jd_atom *katom)
|
||||
{
|
||||
bool enqueue_required, add_required = true;
|
||||
bool enqueue_required;
|
||||
|
||||
katom->slot_nr = kbase_js_get_slot(kctx->kbdev, katom);
|
||||
|
||||
|
|
@ -2525,10 +2381,7 @@ bool kbase_js_dep_resolved_submit(struct kbase_context *kctx, struct kbase_jd_at
|
|||
/* If slot will transition from unpullable to pullable then add to
|
||||
* pullable list
|
||||
*/
|
||||
if (jsctx_rb_none_to_pull(kctx, katom->slot_nr))
|
||||
enqueue_required = true;
|
||||
else
|
||||
enqueue_required = false;
|
||||
enqueue_required = jsctx_rb_none_to_pull(kctx, katom->slot_nr);
|
||||
|
||||
if ((katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED) ||
|
||||
(katom->pre_dep &&
|
||||
|
|
@ -2541,15 +2394,9 @@ bool kbase_js_dep_resolved_submit(struct kbase_context *kctx, struct kbase_jd_at
|
|||
|
||||
list_add_tail(&katom->queue, &queue->x_dep_head);
|
||||
katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
|
||||
if (kbase_js_atom_blocked_on_x_dep(katom)) {
|
||||
enqueue_required = false;
|
||||
add_required = false;
|
||||
}
|
||||
enqueue_required = false;
|
||||
} else {
|
||||
dev_dbg(kctx->kbdev->dev, "Atom %pK not added to X_DEP list\n", (void *)katom);
|
||||
}
|
||||
|
||||
if (add_required) {
|
||||
/* Check if there are lower priority jobs to soft stop */
|
||||
kbase_job_slot_ctx_priority_check_locked(kctx, katom);
|
||||
|
||||
|
|
@ -2575,30 +2422,22 @@ bool kbase_js_dep_resolved_submit(struct kbase_context *kctx, struct kbase_jd_at
|
|||
*/
|
||||
static void kbase_js_move_to_tree(struct kbase_jd_atom *katom)
|
||||
{
|
||||
struct kbase_context *const kctx = katom->kctx;
|
||||
|
||||
lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
|
||||
lockdep_assert_held(&katom->kctx->kbdev->hwaccess_lock);
|
||||
|
||||
while (katom) {
|
||||
WARN_ON(!(katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST));
|
||||
|
||||
if (!kbase_js_atom_blocked_on_x_dep(katom)) {
|
||||
dev_dbg(kctx->kbdev->dev,
|
||||
if (!(katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED)) {
|
||||
dev_dbg(katom->kctx->kbdev->dev,
|
||||
"Del atom %pK from X_DEP list in js_move_to_tree\n", (void *)katom);
|
||||
|
||||
list_del(&katom->queue);
|
||||
katom->atom_flags &= ~KBASE_KATOM_FLAG_JSCTX_IN_X_DEP_LIST;
|
||||
/* For incremental rendering, an end-of-renderpass atom
|
||||
* may have had its dependency on start-of-renderpass
|
||||
* ignored and may therefore already be in the tree.
|
||||
*/
|
||||
if (!(katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE)) {
|
||||
jsctx_tree_add(kctx, katom);
|
||||
katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_TREE;
|
||||
}
|
||||
jsctx_tree_add(katom->kctx, katom);
|
||||
katom->atom_flags |= KBASE_KATOM_FLAG_JSCTX_IN_TREE;
|
||||
} else {
|
||||
dev_dbg(kctx->kbdev->dev, "Atom %pK blocked on x-dep in js_move_to_tree\n",
|
||||
(void *)katom);
|
||||
dev_dbg(katom->kctx->kbdev->dev,
|
||||
"Atom %pK blocked on x-dep in js_move_to_tree\n", (void *)katom);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2671,11 +2510,7 @@ struct kbase_jd_atom *kbase_js_pull(struct kbase_context *kctx, unsigned int js)
|
|||
dev_dbg(kbdev->dev, "JS: No submit allowed for kctx %pK\n", (void *)kctx);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
if (kbase_pm_is_suspending(kbdev) || kbase_pm_is_gpu_lost(kbdev))
|
||||
#else
|
||||
if (kbase_pm_is_suspending(kbdev))
|
||||
#endif
|
||||
return NULL;
|
||||
|
||||
katom = jsctx_rb_peek(kctx, js);
|
||||
|
|
@ -2705,7 +2540,7 @@ struct kbase_jd_atom *kbase_js_pull(struct kbase_context *kctx, unsigned int js)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (kbase_js_atom_blocked_on_x_dep(katom)) {
|
||||
if (katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED) {
|
||||
if (katom->x_pre_dep->gpu_rb_state == KBASE_ATOM_GPU_RB_NOT_IN_SLOT_RB ||
|
||||
katom->x_pre_dep->will_fail_event_code) {
|
||||
dev_dbg(kbdev->dev,
|
||||
|
|
@ -2745,190 +2580,6 @@ struct kbase_jd_atom *kbase_js_pull(struct kbase_context *kctx, unsigned int js)
|
|||
return katom;
|
||||
}
|
||||
|
||||
/**
|
||||
* js_return_of_start_rp() - Handle soft-stop of an atom that starts a
|
||||
* renderpass
|
||||
* @start_katom: Pointer to the start-of-renderpass atom that was soft-stopped
|
||||
*
|
||||
* This function is called to switch to incremental rendering if the tiler job
|
||||
* chain at the start of a renderpass has used too much memory. It prevents the
|
||||
* tiler job being pulled for execution in the job scheduler again until the
|
||||
* next phase of incremental rendering is complete.
|
||||
*
|
||||
* If the end-of-renderpass atom is already in the job scheduler (because a
|
||||
* previous attempt at tiling used too much memory during the same renderpass)
|
||||
* then it is unblocked; otherwise, it is run by handing it to the scheduler.
|
||||
*/
|
||||
static void js_return_of_start_rp(struct kbase_jd_atom *const start_katom)
|
||||
{
|
||||
struct kbase_context *const kctx = start_katom->kctx;
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
struct kbase_jd_atom *end_katom;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&kctx->jctx.lock);
|
||||
|
||||
if (WARN_ON(!(start_katom->core_req & BASE_JD_REQ_START_RENDERPASS)))
|
||||
return;
|
||||
|
||||
compiletime_assert((1ull << (sizeof(start_katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[start_katom->renderpass_id];
|
||||
|
||||
if (WARN_ON(rp->start_katom != start_katom))
|
||||
return;
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "JS return start atom %pK in state %d of RP %d\n",
|
||||
(void *)start_katom, (int)rp->state, start_katom->renderpass_id);
|
||||
|
||||
if (WARN_ON(rp->state == KBASE_JD_RP_COMPLETE))
|
||||
return;
|
||||
|
||||
/* The tiler job might have been soft-stopped for some reason other
|
||||
* than running out of memory.
|
||||
*/
|
||||
if (rp->state == KBASE_JD_RP_START || rp->state == KBASE_JD_RP_RETRY) {
|
||||
dev_dbg(kctx->kbdev->dev, "JS return isn't OOM in state %d of RP %d\n",
|
||||
(int)rp->state, start_katom->renderpass_id);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "JS return confirm OOM in state %d of RP %d\n", (int)rp->state,
|
||||
start_katom->renderpass_id);
|
||||
|
||||
if (WARN_ON(rp->state != KBASE_JD_RP_PEND_OOM && rp->state != KBASE_JD_RP_RETRY_PEND_OOM))
|
||||
return;
|
||||
|
||||
/* Prevent the tiler job being pulled for execution in the
|
||||
* job scheduler again.
|
||||
*/
|
||||
dev_dbg(kbdev->dev, "Blocking start atom %pK\n", (void *)start_katom);
|
||||
atomic_inc(&start_katom->blocked);
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
rp->state = (rp->state == KBASE_JD_RP_PEND_OOM) ? KBASE_JD_RP_OOM : KBASE_JD_RP_RETRY_OOM;
|
||||
|
||||
/* Was the fragment job chain submitted to kbase yet? */
|
||||
end_katom = rp->end_katom;
|
||||
if (end_katom) {
|
||||
dev_dbg(kctx->kbdev->dev, "JS return add end atom %pK\n", (void *)end_katom);
|
||||
|
||||
if (rp->state == KBASE_JD_RP_RETRY_OOM) {
|
||||
/* Allow the end of the renderpass to be pulled for
|
||||
* execution again to continue incremental rendering.
|
||||
*/
|
||||
dev_dbg(kbdev->dev, "Unblocking end atom %pK\n", (void *)end_katom);
|
||||
atomic_dec(&end_katom->blocked);
|
||||
WARN_ON(!(end_katom->atom_flags & KBASE_KATOM_FLAG_JSCTX_IN_TREE));
|
||||
WARN_ON(end_katom->status != KBASE_JD_ATOM_STATE_IN_JS);
|
||||
|
||||
kbase_js_ctx_list_add_pullable_nolock(kbdev, kctx, end_katom->slot_nr);
|
||||
|
||||
/* Expect the fragment job chain to be scheduled without
|
||||
* further action because this function is called when
|
||||
* returning an atom to the job scheduler ringbuffer.
|
||||
*/
|
||||
end_katom = NULL;
|
||||
} else {
|
||||
WARN_ON(end_katom->status != KBASE_JD_ATOM_STATE_QUEUED &&
|
||||
end_katom->status != KBASE_JD_ATOM_STATE_IN_JS);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
if (end_katom)
|
||||
kbase_jd_dep_clear_locked(end_katom);
|
||||
}
|
||||
|
||||
/**
|
||||
* js_return_of_end_rp() - Handle completion of an atom that ends a renderpass
|
||||
* @end_katom: Pointer to the end-of-renderpass atom that was completed
|
||||
*
|
||||
* This function is called to continue incremental rendering if the tiler job
|
||||
* chain at the start of a renderpass used too much memory. It resets the
|
||||
* mechanism for detecting excessive memory usage then allows the soft-stopped
|
||||
* tiler job chain to be pulled for execution again.
|
||||
*
|
||||
* The start-of-renderpass atom must already been submitted to kbase.
|
||||
*/
|
||||
static void js_return_of_end_rp(struct kbase_jd_atom *const end_katom)
|
||||
{
|
||||
struct kbase_context *const kctx = end_katom->kctx;
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
struct kbase_jd_atom *start_katom;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&kctx->jctx.lock);
|
||||
|
||||
if (WARN_ON(!(end_katom->core_req & BASE_JD_REQ_END_RENDERPASS)))
|
||||
return;
|
||||
|
||||
compiletime_assert((1ull << (sizeof(end_katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[end_katom->renderpass_id];
|
||||
|
||||
if (WARN_ON(rp->end_katom != end_katom))
|
||||
return;
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "JS return end atom %pK in state %d of RP %d\n",
|
||||
(void *)end_katom, (int)rp->state, end_katom->renderpass_id);
|
||||
|
||||
if (WARN_ON(rp->state != KBASE_JD_RP_OOM && rp->state != KBASE_JD_RP_RETRY_OOM))
|
||||
return;
|
||||
|
||||
/* Reduce the number of mapped pages in the memory regions that
|
||||
* triggered out-of-memory last time so that we can detect excessive
|
||||
* memory usage again.
|
||||
*/
|
||||
kbase_gpu_vm_lock(kctx);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
while (!list_empty(&rp->oom_reg_list)) {
|
||||
struct kbase_va_region *reg =
|
||||
list_first_entry(&rp->oom_reg_list, struct kbase_va_region, link);
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
dev_dbg(kbdev->dev, "Reset backing to %zu pages for region %pK\n",
|
||||
reg->threshold_pages, (void *)reg);
|
||||
|
||||
if (!WARN_ON(reg->flags & KBASE_REG_VA_FREED))
|
||||
kbase_mem_shrink(kctx, reg, reg->threshold_pages);
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
dev_dbg(kbdev->dev, "Deleting region %pK from list\n", (void *)reg);
|
||||
list_del_init(®->link);
|
||||
kbase_va_region_alloc_put(kctx, reg);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
rp->state = KBASE_JD_RP_RETRY;
|
||||
dev_dbg(kbdev->dev, "Changed state to %d for retry\n", rp->state);
|
||||
|
||||
/* Allow the start of the renderpass to be pulled for execution again
|
||||
* to begin/continue incremental rendering.
|
||||
*/
|
||||
start_katom = rp->start_katom;
|
||||
if (!WARN_ON(!start_katom)) {
|
||||
dev_dbg(kbdev->dev, "Unblocking start atom %pK\n", (void *)start_katom);
|
||||
atomic_dec(&start_katom->blocked);
|
||||
(void)kbase_js_ctx_list_add_pullable_head_nolock(kbdev, kctx, start_katom->slot_nr);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
}
|
||||
|
||||
static void js_return_worker(struct work_struct *data)
|
||||
{
|
||||
struct kbase_jd_atom *katom = container_of(data, struct kbase_jd_atom, work);
|
||||
|
|
@ -2949,9 +2600,7 @@ static void js_return_worker(struct work_struct *data)
|
|||
katom->event_code);
|
||||
|
||||
KBASE_KTRACE_ADD_JM(kbdev, JS_RETURN_WORKER, kctx, katom, katom->jc, 0);
|
||||
|
||||
if (katom->event_code != BASE_JD_EVENT_END_RP_DONE)
|
||||
KBASE_TLSTREAM_TL_EVENT_ATOM_SOFTSTOP_EX(kbdev, katom);
|
||||
KBASE_TLSTREAM_TL_EVENT_ATOM_SOFTSTOP_EX(kbdev, katom);
|
||||
|
||||
kbase_backend_complete_wq(kbdev, katom);
|
||||
|
||||
|
|
@ -2960,8 +2609,7 @@ static void js_return_worker(struct work_struct *data)
|
|||
mutex_lock(&js_devdata->queue_mutex);
|
||||
mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
|
||||
|
||||
if (katom->event_code != BASE_JD_EVENT_END_RP_DONE)
|
||||
atomic_dec(&katom->blocked);
|
||||
atomic_dec(&katom->blocked);
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
|
|
@ -3026,16 +2674,6 @@ static void js_return_worker(struct work_struct *data)
|
|||
mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
|
||||
mutex_unlock(&js_devdata->queue_mutex);
|
||||
|
||||
if (katom->core_req & BASE_JD_REQ_START_RENDERPASS) {
|
||||
mutex_lock(&kctx->jctx.lock);
|
||||
js_return_of_start_rp(katom);
|
||||
mutex_unlock(&kctx->jctx.lock);
|
||||
} else if (katom->event_code == BASE_JD_EVENT_END_RP_DONE) {
|
||||
mutex_lock(&kctx->jctx.lock);
|
||||
js_return_of_end_rp(katom);
|
||||
mutex_unlock(&kctx->jctx.lock);
|
||||
}
|
||||
|
||||
dev_dbg(kbdev->dev, "JS: retained state %s finished",
|
||||
kbasep_js_has_atom_finished(&retained_state) ? "has" : "hasn't");
|
||||
|
||||
|
|
@ -3071,144 +2709,6 @@ void kbase_js_unpull(struct kbase_context *kctx, struct kbase_jd_atom *katom)
|
|||
queue_work(kctx->jctx.job_done_wq, &katom->work);
|
||||
}
|
||||
|
||||
/**
|
||||
* js_complete_start_rp() - Handle completion of atom that starts a renderpass
|
||||
* @kctx: Context pointer
|
||||
* @start_katom: Pointer to the atom that completed
|
||||
*
|
||||
* Put any references to virtual memory regions that might have been added by
|
||||
* kbase_job_slot_softstop_start_rp() because the tiler job chain completed
|
||||
* despite any pending soft-stop request.
|
||||
*
|
||||
* If the atom that just completed was soft-stopped during a previous attempt to
|
||||
* run it then there should be a blocked end-of-renderpass atom waiting for it,
|
||||
* which we must unblock to process the output of the tiler job chain.
|
||||
*
|
||||
* Return: true if caller should call kbase_backend_ctx_count_changed()
|
||||
*/
|
||||
static bool js_complete_start_rp(struct kbase_context *kctx,
|
||||
struct kbase_jd_atom *const start_katom)
|
||||
{
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
bool timer_sync = false;
|
||||
|
||||
lockdep_assert_held(&kctx->jctx.lock);
|
||||
|
||||
if (WARN_ON(!(start_katom->core_req & BASE_JD_REQ_START_RENDERPASS)))
|
||||
return false;
|
||||
|
||||
compiletime_assert((1ull << (sizeof(start_katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[start_katom->renderpass_id];
|
||||
|
||||
if (WARN_ON(rp->start_katom != start_katom))
|
||||
return false;
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "Start atom %pK is done in state %d of RP %d\n",
|
||||
(void *)start_katom, (int)rp->state, start_katom->renderpass_id);
|
||||
|
||||
if (WARN_ON(rp->state == KBASE_JD_RP_COMPLETE))
|
||||
return false;
|
||||
|
||||
if (rp->state == KBASE_JD_RP_PEND_OOM || rp->state == KBASE_JD_RP_RETRY_PEND_OOM) {
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(kctx->kbdev->dev, "Start atom %pK completed before soft-stop\n",
|
||||
(void *)start_katom);
|
||||
|
||||
kbase_gpu_vm_lock(kctx);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
while (!list_empty(&rp->oom_reg_list)) {
|
||||
struct kbase_va_region *reg =
|
||||
list_first_entry(&rp->oom_reg_list, struct kbase_va_region, link);
|
||||
|
||||
WARN_ON(reg->flags & KBASE_REG_VA_FREED);
|
||||
dev_dbg(kctx->kbdev->dev, "Deleting region %pK from list\n", (void *)reg);
|
||||
list_del_init(®->link);
|
||||
kbase_va_region_alloc_put(kctx, reg);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
} else {
|
||||
dev_dbg(kctx->kbdev->dev, "Start atom %pK did not exceed memory threshold\n",
|
||||
(void *)start_katom);
|
||||
|
||||
WARN_ON(rp->state != KBASE_JD_RP_START && rp->state != KBASE_JD_RP_RETRY);
|
||||
}
|
||||
|
||||
if (rp->state == KBASE_JD_RP_RETRY || rp->state == KBASE_JD_RP_RETRY_PEND_OOM) {
|
||||
struct kbase_jd_atom *const end_katom = rp->end_katom;
|
||||
|
||||
if (!WARN_ON(!end_katom)) {
|
||||
unsigned long flags;
|
||||
|
||||
/* Allow the end of the renderpass to be pulled for
|
||||
* execution again to continue incremental rendering.
|
||||
*/
|
||||
dev_dbg(kbdev->dev, "Unblocking end atom %pK!\n", (void *)end_katom);
|
||||
atomic_dec(&end_katom->blocked);
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
timer_sync = kbase_js_ctx_list_add_pullable_nolock(kbdev, kctx,
|
||||
end_katom->slot_nr);
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
return timer_sync;
|
||||
}
|
||||
|
||||
/**
|
||||
* js_complete_end_rp() - Handle final completion of atom that ends a renderpass
|
||||
* @kctx: Context pointer
|
||||
* @end_katom: Pointer to the atom that completed for the last time
|
||||
*
|
||||
* This function must only be called if the renderpass actually completed
|
||||
* without the tiler job chain at the start using too much memory; otherwise
|
||||
* completion of the end-of-renderpass atom is handled similarly to a soft-stop.
|
||||
*/
|
||||
static void js_complete_end_rp(struct kbase_context *kctx, struct kbase_jd_atom *const end_katom)
|
||||
{
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
unsigned long flags;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
|
||||
lockdep_assert_held(&kctx->jctx.lock);
|
||||
|
||||
if (WARN_ON(!(end_katom->core_req & BASE_JD_REQ_END_RENDERPASS)))
|
||||
return;
|
||||
|
||||
compiletime_assert((1ull << (sizeof(end_katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[end_katom->renderpass_id];
|
||||
|
||||
if (WARN_ON(rp->end_katom != end_katom))
|
||||
return;
|
||||
|
||||
dev_dbg(kbdev->dev, "End atom %pK is done in state %d of RP %d\n", (void *)end_katom,
|
||||
(int)rp->state, end_katom->renderpass_id);
|
||||
|
||||
if (WARN_ON(rp->state == KBASE_JD_RP_COMPLETE) || WARN_ON(rp->state == KBASE_JD_RP_OOM) ||
|
||||
WARN_ON(rp->state == KBASE_JD_RP_RETRY_OOM))
|
||||
return;
|
||||
|
||||
/* Rendering completed without running out of memory.
|
||||
*/
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
WARN_ON(!list_empty(&rp->oom_reg_list));
|
||||
rp->state = KBASE_JD_RP_COMPLETE;
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
dev_dbg(kbdev->dev, "Renderpass %d is complete\n", end_katom->renderpass_id);
|
||||
}
|
||||
|
||||
bool kbase_js_complete_atom_wq(struct kbase_context *kctx, struct kbase_jd_atom *katom)
|
||||
{
|
||||
struct kbasep_js_kctx_info *js_kctx_info;
|
||||
|
|
@ -3225,13 +2725,6 @@ bool kbase_js_complete_atom_wq(struct kbase_context *kctx, struct kbase_jd_atom
|
|||
|
||||
dev_dbg(kbdev->dev, "%s for atom %pK (s:%u)\n", __func__, (void *)katom, atom_slot);
|
||||
|
||||
/* Update the incremental rendering state machine.
|
||||
*/
|
||||
if (katom->core_req & BASE_JD_REQ_START_RENDERPASS)
|
||||
timer_sync |= js_complete_start_rp(kctx, katom);
|
||||
else if (katom->core_req & BASE_JD_REQ_END_RENDERPASS)
|
||||
js_complete_end_rp(kctx, katom);
|
||||
|
||||
js_kctx_info = &kctx->jctx.sched_info;
|
||||
js_devdata = &kbdev->js_data;
|
||||
|
||||
|
|
@ -3320,61 +2813,6 @@ bool kbase_js_complete_atom_wq(struct kbase_context *kctx, struct kbase_jd_atom
|
|||
return context_idle;
|
||||
}
|
||||
|
||||
/**
|
||||
* js_end_rp_is_complete() - Check whether an atom that ends a renderpass has
|
||||
* completed for the last time.
|
||||
*
|
||||
* @end_katom: Pointer to the atom that completed on the hardware.
|
||||
*
|
||||
* An atom that ends a renderpass may be run on the hardware several times
|
||||
* before notifying userspace or allowing dependent atoms to be executed.
|
||||
*
|
||||
* This function is used to decide whether or not to allow end-of-renderpass
|
||||
* atom completion. It only returns false if the atom at the start of the
|
||||
* renderpass was soft-stopped because it used too much memory during the most
|
||||
* recent attempt at tiling.
|
||||
*
|
||||
* Return: True if the atom completed for the last time.
|
||||
*/
|
||||
static bool js_end_rp_is_complete(struct kbase_jd_atom *const end_katom)
|
||||
{
|
||||
struct kbase_context *const kctx = end_katom->kctx;
|
||||
struct kbase_device *const kbdev = kctx->kbdev;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
|
||||
lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
|
||||
|
||||
if (WARN_ON(!(end_katom->core_req & BASE_JD_REQ_END_RENDERPASS)))
|
||||
return true;
|
||||
|
||||
compiletime_assert((1ull << (sizeof(end_katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[end_katom->renderpass_id];
|
||||
|
||||
if (WARN_ON(rp->end_katom != end_katom))
|
||||
return true;
|
||||
|
||||
dev_dbg(kbdev->dev, "JS complete end atom %pK in state %d of RP %d\n", (void *)end_katom,
|
||||
(int)rp->state, end_katom->renderpass_id);
|
||||
|
||||
if (WARN_ON(rp->state == KBASE_JD_RP_COMPLETE))
|
||||
return true;
|
||||
|
||||
/* Failure of end-of-renderpass atoms must not return to the
|
||||
* start of the renderpass.
|
||||
*/
|
||||
if (end_katom->event_code != BASE_JD_EVENT_DONE)
|
||||
return true;
|
||||
|
||||
if (rp->state != KBASE_JD_RP_OOM && rp->state != KBASE_JD_RP_RETRY_OOM)
|
||||
return true;
|
||||
|
||||
dev_dbg(kbdev->dev, "Suppressing end atom completion\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct kbase_jd_atom *kbase_js_complete_atom(struct kbase_jd_atom *katom, ktime_t *end_timestamp)
|
||||
{
|
||||
struct kbase_device *kbdev;
|
||||
|
|
@ -3387,12 +2825,6 @@ struct kbase_jd_atom *kbase_js_complete_atom(struct kbase_jd_atom *katom, ktime_
|
|||
|
||||
lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
|
||||
|
||||
if ((katom->core_req & BASE_JD_REQ_END_RENDERPASS) && !js_end_rp_is_complete(katom)) {
|
||||
katom->event_code = BASE_JD_EVENT_END_RP_DONE;
|
||||
kbase_js_unpull(kctx, katom);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (katom->will_fail_event_code)
|
||||
katom->event_code = katom->will_fail_event_code;
|
||||
|
||||
|
|
@ -3442,70 +2874,6 @@ struct kbase_jd_atom *kbase_js_complete_atom(struct kbase_jd_atom *katom, ktime_
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* kbase_js_atom_blocked_on_x_dep - Decide whether to ignore a cross-slot
|
||||
* dependency
|
||||
* @katom: Pointer to an atom in the slot ringbuffer
|
||||
*
|
||||
* A cross-slot dependency is ignored if necessary to unblock incremental
|
||||
* rendering. If the atom at the start of a renderpass used too much memory
|
||||
* and was soft-stopped then the atom at the end of a renderpass is submitted
|
||||
* to hardware regardless of its dependency on the start-of-renderpass atom.
|
||||
* This can happen multiple times for the same pair of atoms.
|
||||
*
|
||||
* Return: true to block the atom or false to allow it to be submitted to
|
||||
* hardware
|
||||
*/
|
||||
bool kbase_js_atom_blocked_on_x_dep(struct kbase_jd_atom *const katom)
|
||||
{
|
||||
struct kbase_context *const kctx = katom->kctx;
|
||||
struct kbase_device *kbdev = kctx->kbdev;
|
||||
struct kbase_jd_renderpass *rp;
|
||||
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
if (!(katom->atom_flags & KBASE_KATOM_FLAG_X_DEP_BLOCKED)) {
|
||||
dev_dbg(kbdev->dev, "Atom %pK is not blocked on a cross-slot dependency",
|
||||
(void *)katom);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(katom->core_req & BASE_JD_REQ_END_RENDERPASS)) {
|
||||
dev_dbg(kbdev->dev, "Atom %pK is blocked on a cross-slot dependency",
|
||||
(void *)katom);
|
||||
return true;
|
||||
}
|
||||
|
||||
compiletime_assert((1ull << (sizeof(katom->renderpass_id) * 8)) <=
|
||||
ARRAY_SIZE(kctx->jctx.renderpasses),
|
||||
"Should check invalid access to renderpasses");
|
||||
|
||||
rp = &kctx->jctx.renderpasses[katom->renderpass_id];
|
||||
/* We can read a subset of renderpass state without holding
|
||||
* higher-level locks (but not end_katom, for example).
|
||||
*/
|
||||
|
||||
WARN_ON(rp->state == KBASE_JD_RP_COMPLETE);
|
||||
|
||||
dev_dbg(kbdev->dev, "End atom has cross-slot dep in state %d\n", (int)rp->state);
|
||||
|
||||
if (rp->state != KBASE_JD_RP_OOM && rp->state != KBASE_JD_RP_RETRY_OOM)
|
||||
return true;
|
||||
|
||||
/* Tiler ran out of memory so allow the fragment job chain to run
|
||||
* if it only depends on the tiler job chain.
|
||||
*/
|
||||
if (katom->x_pre_dep != rp->start_katom) {
|
||||
dev_dbg(kbdev->dev, "Dependency is on %pK not start atom %pK\n",
|
||||
(void *)katom->x_pre_dep, (void *)rp->start_katom);
|
||||
return true;
|
||||
}
|
||||
|
||||
dev_dbg(kbdev->dev, "Ignoring cross-slot dep on atom %pK\n", (void *)katom->x_pre_dep);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void kbase_js_sched(struct kbase_device *kbdev, unsigned int js_mask)
|
||||
{
|
||||
struct kbasep_js_device_data *js_devdata;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -516,7 +516,8 @@ static ssize_t reader_changes_copy_to_user(struct reader_changes *const changes,
|
|||
do {
|
||||
changes_tail = changes->tail;
|
||||
changes_count = reader_changes_count_locked(changes);
|
||||
read_size = min(changes_count * entry_size, buffer_size & ~(entry_size - 1));
|
||||
read_size =
|
||||
min(size_mul(changes_count, entry_size), buffer_size & ~(entry_size - 1));
|
||||
|
||||
if (!read_size)
|
||||
break;
|
||||
|
|
@ -743,7 +744,6 @@ int kbase_kinstr_jm_get_fd(struct kbase_kinstr_jm *const ctx, union kbase_kinstr
|
|||
size_t const change_size = sizeof(struct kbase_kinstr_jm_atom_state_change);
|
||||
int status;
|
||||
int fd;
|
||||
size_t i;
|
||||
|
||||
if (!ctx || !jm_fd_arg)
|
||||
return -EINVAL;
|
||||
|
|
@ -753,10 +753,6 @@ int kbase_kinstr_jm_get_fd(struct kbase_kinstr_jm *const ctx, union kbase_kinstr
|
|||
if (!is_power_of_2(in->count))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < sizeof(in->padding); ++i)
|
||||
if (in->padding[i])
|
||||
return -EINVAL;
|
||||
|
||||
status = reader_init(&reader, ctx, in->count);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <mali_kbase_config.h>
|
||||
#include <mali_kbase.h>
|
||||
#include <mali_kbase_reg_track.h>
|
||||
#include <mali_kbase_caps.h>
|
||||
#include <hw_access/mali_kbase_hw_access_regmap.h>
|
||||
#include <mali_kbase_cache_policy.h>
|
||||
#include <mali_kbase_hw.h>
|
||||
|
|
@ -42,7 +43,6 @@
|
|||
#include <mali_kbase_native_mgm.h>
|
||||
#include <mali_kbase_mem_pool_group.h>
|
||||
#include <mmu/mali_kbase_mmu.h>
|
||||
#include <mali_kbase_config_defaults.h>
|
||||
#include <mali_kbase_trace_gpu_mem.h>
|
||||
#include <linux/version_compat_defs.h>
|
||||
|
||||
|
|
@ -52,6 +52,11 @@ static DEFINE_STATIC_KEY_FALSE(large_pages_static_key);
|
|||
#define VA_REGION_SLAB_NAME_PREFIX "va-region-slab-"
|
||||
#define VA_REGION_SLAB_NAME_SIZE (DEVNAME_SIZE + sizeof(VA_REGION_SLAB_NAME_PREFIX) + 1)
|
||||
|
||||
#if GPU_PAGES_PER_CPU_PAGE > 1
|
||||
#define PAGE_METADATA_SLAB_NAME_PREFIX "page-metadata-slab-"
|
||||
#define PAGE_METADATA_SLAB_NAME_SIZE (DEVNAME_SIZE + sizeof(PAGE_METADATA_SLAB_NAME_PREFIX) + 1)
|
||||
#endif
|
||||
|
||||
#if MALI_JIT_PRESSURE_LIMIT_BASE
|
||||
|
||||
/*
|
||||
|
|
@ -152,7 +157,7 @@ static void kbasep_mem_page_size_init(struct kbase_device *kbdev)
|
|||
|
||||
switch (large_page_conf) {
|
||||
case LARGE_PAGE_AUTO: {
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_LARGE_PAGE_ALLOC))
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_LARGE_PAGE_ALLOC))
|
||||
static_branch_inc(&large_pages_static_key);
|
||||
dev_info(kbdev->dev, "Large page allocation set to %s after hardware feature check",
|
||||
static_branch_unlikely(&large_pages_static_key) ? "true" : "false");
|
||||
|
|
@ -160,7 +165,7 @@ static void kbasep_mem_page_size_init(struct kbase_device *kbdev)
|
|||
}
|
||||
case LARGE_PAGE_ON: {
|
||||
static_branch_inc(&large_pages_static_key);
|
||||
if (!kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_LARGE_PAGE_ALLOC))
|
||||
if (!kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_LARGE_PAGE_ALLOC))
|
||||
dev_warn(kbdev->dev,
|
||||
"Enabling large page allocations on unsupporting GPU!");
|
||||
else
|
||||
|
|
@ -196,16 +201,16 @@ KBASE_EXPORT_TEST_API(kbase_is_large_pages_enabled);
|
|||
int kbase_mem_init(struct kbase_device *kbdev)
|
||||
{
|
||||
int err = 0;
|
||||
struct kbasep_mem_device *memdev;
|
||||
char va_region_slab_name[VA_REGION_SLAB_NAME_SIZE];
|
||||
#if GPU_PAGES_PER_CPU_PAGE > 1
|
||||
char page_metadata_slab_name[PAGE_METADATA_SLAB_NAME_SIZE];
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
struct device_node *mgm_node = NULL;
|
||||
#endif
|
||||
|
||||
KBASE_DEBUG_ASSERT(kbdev);
|
||||
|
||||
memdev = &kbdev->memdev;
|
||||
|
||||
kbasep_mem_page_size_init(kbdev);
|
||||
|
||||
scnprintf(va_region_slab_name, VA_REGION_SLAB_NAME_SIZE, VA_REGION_SLAB_NAME_PREFIX "%s",
|
||||
|
|
@ -219,6 +224,17 @@ int kbase_mem_init(struct kbase_device *kbdev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#if GPU_PAGES_PER_CPU_PAGE > 1
|
||||
scnprintf(page_metadata_slab_name, PAGE_METADATA_SLAB_NAME_SIZE,
|
||||
PAGE_METADATA_SLAB_NAME_PREFIX "%s", kbdev->devname);
|
||||
kbdev->page_metadata_slab = kmem_cache_create(
|
||||
page_metadata_slab_name, sizeof(struct kbase_page_metadata), 0, 0, NULL);
|
||||
if (kbdev->page_metadata_slab == NULL) {
|
||||
dev_err(kbdev->dev, "Failed to create page_metadata_slab");
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
kbase_mem_migrate_init(kbdev);
|
||||
kbase_mem_pool_group_config_set_max_size(&kbdev->mem_pool_defaults,
|
||||
KBASE_MEM_POOL_MAX_SIZE_KCTX);
|
||||
|
|
@ -228,12 +244,6 @@ int kbase_mem_init(struct kbase_device *kbdev)
|
|||
kbdev->dma_buf_root = RB_ROOT;
|
||||
mutex_init(&kbdev->dma_buf_lock);
|
||||
|
||||
#ifdef IR_THRESHOLD
|
||||
atomic_set(&memdev->ir_threshold, IR_THRESHOLD);
|
||||
#else
|
||||
atomic_set(&memdev->ir_threshold, DEFAULT_IR_THRESHOLD);
|
||||
#endif
|
||||
|
||||
kbdev->mgm_dev = &kbase_native_mgm_dev;
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
|
|
@ -299,6 +309,10 @@ void kbase_mem_term(struct kbase_device *kbdev)
|
|||
|
||||
kbase_mem_migrate_term(kbdev);
|
||||
|
||||
#if GPU_PAGES_PER_CPU_PAGE > 1
|
||||
kmem_cache_destroy(kbdev->page_metadata_slab);
|
||||
kbdev->page_metadata_slab = NULL;
|
||||
#endif
|
||||
kmem_cache_destroy(kbdev->va_region_slab);
|
||||
kbdev->va_region_slab = NULL;
|
||||
|
||||
|
|
@ -1221,6 +1235,7 @@ int kbase_alloc_phy_pages_helper(struct kbase_mem_phy_alloc *alloc, size_t nr_pa
|
|||
* to satisfy the memory allocation request.
|
||||
*/
|
||||
size_t nr_pages_to_account = 0;
|
||||
size_t nr_pages_from_partials = 0;
|
||||
|
||||
if (WARN_ON(alloc->type != KBASE_MEM_TYPE_NATIVE) ||
|
||||
WARN_ON(alloc->imported.native.kctx == NULL) ||
|
||||
|
|
@ -1279,6 +1294,7 @@ int kbase_alloc_phy_pages_helper(struct kbase_mem_phy_alloc *alloc, size_t nr_pa
|
|||
*tp++ = as_tagged_tag(page_to_phys(sa->page + pidx),
|
||||
FROM_PARTIAL);
|
||||
nr_left--;
|
||||
nr_pages_from_partials++;
|
||||
|
||||
if (bitmap_full(sa->sub_pages,
|
||||
NUM_PAGES_IN_2MB_LARGE_PAGE)) {
|
||||
|
|
@ -1386,6 +1402,13 @@ alloc_failed:
|
|||
|
||||
alloc->nents += nr_pages_to_free;
|
||||
kbase_free_phy_pages_helper(alloc, nr_pages_to_free);
|
||||
|
||||
/* Notice that the sub-pages from "partials" are not subtracted
|
||||
* from the counter by the free pages helper, because they just go
|
||||
* back to the "partials" they belong to, therefore they must be
|
||||
* subtracted from the counter here.
|
||||
*/
|
||||
nr_left += nr_pages_from_partials;
|
||||
}
|
||||
|
||||
/* Undo the preliminary memory accounting that was done early on
|
||||
|
|
@ -1994,11 +2017,13 @@ out_term:
|
|||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_alloc_phy_pages);
|
||||
|
||||
void kbase_set_phy_alloc_page_status(struct kbase_mem_phy_alloc *alloc,
|
||||
void kbase_set_phy_alloc_page_status(struct kbase_context *kctx, struct kbase_mem_phy_alloc *alloc,
|
||||
enum kbase_page_status status)
|
||||
{
|
||||
u32 i = 0;
|
||||
|
||||
lockdep_assert_held(&kctx->reg_lock);
|
||||
|
||||
for (; i < alloc->nents; i++) {
|
||||
struct tagged_addr phys = alloc->pages[i];
|
||||
struct kbase_page_metadata *page_md = kbase_page_private(as_page(phys));
|
||||
|
|
@ -2018,7 +2043,7 @@ void kbase_set_phy_alloc_page_status(struct kbase_mem_phy_alloc *alloc,
|
|||
}
|
||||
}
|
||||
|
||||
bool kbase_check_alloc_flags(unsigned long flags)
|
||||
bool kbase_check_alloc_flags(struct kbase_context *kctx, unsigned long flags)
|
||||
{
|
||||
/* Only known input flags should be set. */
|
||||
if (flags & ~BASE_MEM_FLAGS_INPUT_MASK)
|
||||
|
|
@ -2094,6 +2119,36 @@ bool kbase_check_alloc_flags(unsigned long flags)
|
|||
return false;
|
||||
#endif
|
||||
|
||||
/* Cannot be set only allocation, only with base_mem_set */
|
||||
if ((flags & BASE_MEM_DONT_NEED) &&
|
||||
(mali_kbase_supports_reject_alloc_mem_dont_need(kctx->api_version)))
|
||||
return false;
|
||||
|
||||
/* Cannot directly allocate protected memory, it is imported instead */
|
||||
if ((flags & BASE_MEM_PROTECTED) &&
|
||||
(mali_kbase_supports_reject_alloc_mem_protected_in_unprotected_allocs(
|
||||
kctx->api_version)))
|
||||
return false;
|
||||
|
||||
/* No unused bits are valid for allocations */
|
||||
#if MALI_USE_CSF
|
||||
if ((flags & BASE_MEM_UNUSED_BIT_20) &&
|
||||
(mali_kbase_supports_reject_alloc_mem_unused_bit_20(kctx->api_version)))
|
||||
return false;
|
||||
|
||||
if ((flags & BASE_MEM_UNUSED_BIT_27) &&
|
||||
(mali_kbase_supports_reject_alloc_mem_unused_bit_27(kctx->api_version)))
|
||||
return false;
|
||||
#else /* MALI_USE_CSF */
|
||||
if ((flags & BASE_MEM_UNUSED_BIT_8) &&
|
||||
(mali_kbase_supports_reject_alloc_mem_unused_bit_8(kctx->api_version)))
|
||||
return false;
|
||||
|
||||
if ((flags & BASE_MEM_UNUSED_BIT_19) &&
|
||||
(mali_kbase_supports_reject_alloc_mem_unused_bit_19(kctx->api_version)))
|
||||
return false;
|
||||
#endif /* MALI_USE_CSF */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2258,7 +2313,7 @@ KBASE_EXPORT_TEST_API(kbase_gpu_vm_lock);
|
|||
void kbase_gpu_vm_lock_with_pmode_sync(struct kbase_context *kctx)
|
||||
{
|
||||
#if MALI_USE_CSF
|
||||
down_read(&kctx->kbdev->csf.pmode_sync_sem);
|
||||
down_read(&kctx->kbdev->csf.mmu_sync_sem);
|
||||
#endif
|
||||
kbase_gpu_vm_lock(kctx);
|
||||
}
|
||||
|
|
@ -2274,7 +2329,7 @@ void kbase_gpu_vm_unlock_with_pmode_sync(struct kbase_context *kctx)
|
|||
{
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
#if MALI_USE_CSF
|
||||
up_read(&kctx->kbdev->csf.pmode_sync_sem);
|
||||
up_read(&kctx->kbdev->csf.mmu_sync_sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -3230,15 +3285,17 @@ struct kbase_va_region *kbase_jit_allocate(struct kbase_context *kctx,
|
|||
if (kbase_is_page_migration_enabled()) {
|
||||
kbase_gpu_vm_lock(kctx);
|
||||
mutex_lock(&kctx->jit_evict_lock);
|
||||
kbase_set_phy_alloc_page_status(reg->gpu_alloc, ALLOCATED_MAPPED);
|
||||
kbase_set_phy_alloc_page_status(kctx, reg->gpu_alloc,
|
||||
ALLOCATED_MAPPED);
|
||||
mutex_unlock(&kctx->jit_evict_lock);
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No suitable JIT allocation was found so create a new one */
|
||||
u64 flags = BASE_MEM_PROT_CPU_RD | BASE_MEM_PROT_GPU_RD | BASE_MEM_PROT_GPU_WR |
|
||||
BASE_MEM_GROW_ON_GPF | BASE_MEM_COHERENT_LOCAL | BASEP_MEM_NO_USER_FREE;
|
||||
base_mem_alloc_flags flags = BASE_MEM_PROT_CPU_RD | BASE_MEM_PROT_GPU_RD |
|
||||
BASE_MEM_PROT_GPU_WR | BASE_MEM_GROW_ON_GPF |
|
||||
BASE_MEM_COHERENT_LOCAL | BASEP_MEM_NO_USER_FREE;
|
||||
u64 gpu_addr;
|
||||
|
||||
#if !MALI_USE_CSF
|
||||
|
|
@ -3335,6 +3392,7 @@ end:
|
|||
|
||||
return reg;
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_jit_allocate);
|
||||
|
||||
void kbase_jit_free(struct kbase_context *kctx, struct kbase_va_region *reg)
|
||||
{
|
||||
|
|
@ -3376,13 +3434,30 @@ void kbase_jit_free(struct kbase_context *kctx, struct kbase_va_region *reg)
|
|||
|
||||
trace_jit_stats(kctx, reg->jit_bin_id, UINT_MAX);
|
||||
|
||||
kbase_gpu_vm_lock_with_pmode_sync(kctx);
|
||||
if (unlikely(atomic_read(®->cpu_alloc->kernel_mappings))) {
|
||||
WARN_ON(atomic64_read(®->no_user_free_count) > 1);
|
||||
kbase_va_region_no_user_free_dec(reg);
|
||||
mutex_lock(&kctx->jit_evict_lock);
|
||||
list_del(®->jit_node);
|
||||
mutex_unlock(&kctx->jit_evict_lock);
|
||||
kbase_mem_free_region(kctx, reg);
|
||||
kbase_gpu_vm_unlock_with_pmode_sync(kctx);
|
||||
return;
|
||||
}
|
||||
kbase_mem_evictable_mark_reclaim(reg->gpu_alloc);
|
||||
|
||||
kbase_gpu_vm_lock(kctx);
|
||||
reg->flags |= KBASE_REG_DONT_NEED;
|
||||
reg->flags &= ~KBASE_REG_ACTIVE_JIT_ALLOC;
|
||||
kbase_mem_shrink_cpu_mapping(kctx, reg, 0, reg->gpu_alloc->nents);
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
|
||||
/* Inactive JIT regions should be freed by the shrinker and not impacted
|
||||
* by page migration. Once freed, they will enter into the page migration
|
||||
* state machine via the mempools.
|
||||
*/
|
||||
if (kbase_is_page_migration_enabled())
|
||||
kbase_set_phy_alloc_page_status(kctx, reg->gpu_alloc, NOT_MOVABLE);
|
||||
|
||||
kbase_gpu_vm_unlock_with_pmode_sync(kctx);
|
||||
|
||||
/*
|
||||
* Add the allocation to the eviction list and the jit pool, after this
|
||||
|
|
@ -3397,14 +3472,9 @@ void kbase_jit_free(struct kbase_context *kctx, struct kbase_va_region *reg)
|
|||
|
||||
list_move(®->jit_node, &kctx->jit_pool_head);
|
||||
|
||||
/* Inactive JIT regions should be freed by the shrinker and not impacted
|
||||
* by page migration. Once freed, they will enter into the page migration
|
||||
* state machine via the mempools.
|
||||
*/
|
||||
if (kbase_is_page_migration_enabled())
|
||||
kbase_set_phy_alloc_page_status(reg->gpu_alloc, NOT_MOVABLE);
|
||||
mutex_unlock(&kctx->jit_evict_lock);
|
||||
}
|
||||
KBASE_EXPORT_TEST_API(kbase_jit_free);
|
||||
|
||||
void kbase_jit_backing_lost(struct kbase_va_region *reg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ static inline void kbase_process_page_usage_inc(struct kbase_context *kctx, int
|
|||
|
||||
/* Index of chosen MEMATTR for this region (0..7) */
|
||||
#define KBASE_REG_MEMATTR_MASK (7ul << 16)
|
||||
#define KBASE_REG_MEMATTR_INDEX(x) (((x)&7) << 16)
|
||||
#define KBASE_REG_MEMATTR_VALUE(x) (((x)&KBASE_REG_MEMATTR_MASK) >> 16)
|
||||
#define KBASE_REG_MEMATTR_INDEX(x) (((x) & 7) << 16)
|
||||
#define KBASE_REG_MEMATTR_VALUE(x) (((x) & KBASE_REG_MEMATTR_MASK) >> 16)
|
||||
|
||||
/* AS<n>_MEMATTR values from MMU_MEMATTR_STAGE1: */
|
||||
/* Use GPU implementation-defined caching policy. */
|
||||
|
|
@ -482,6 +482,26 @@ struct kbase_page_metadata {
|
|||
struct kbase_mmu_table *mmut;
|
||||
/* GPU virtual page frame number info is in GPU_PAGE_SIZE units */
|
||||
u64 pgd_vpfn_level;
|
||||
#if GPU_PAGES_PER_CPU_PAGE > 1
|
||||
/**
|
||||
* @pgd_link: Link to the &kbase_mmu_table.pgd_pages_list
|
||||
*/
|
||||
struct list_head pgd_link;
|
||||
/**
|
||||
* @pgd_page: Back pointer to the PGD page that the metadata is
|
||||
* associated with
|
||||
*/
|
||||
struct page *pgd_page;
|
||||
/**
|
||||
* @allocated_sub_pages: Bitmap representing the allocation status
|
||||
* of sub pages in the @pgd_page
|
||||
*/
|
||||
DECLARE_BITMAP(allocated_sub_pages, GPU_PAGES_PER_CPU_PAGE);
|
||||
/**
|
||||
* @num_allocated_sub_pages: The number of allocated sub pages in @pgd_page
|
||||
*/
|
||||
s8 num_allocated_sub_pages;
|
||||
#endif
|
||||
} pt_mapped;
|
||||
struct {
|
||||
struct kbase_device *kbdev;
|
||||
|
|
@ -510,6 +530,7 @@ enum kbase_jit_report_flags { KBASE_JIT_REPORT_ON_ALLOC_OR_FREE = (1u << 0) };
|
|||
/**
|
||||
* kbase_set_phy_alloc_page_status - Set the page migration status of the underlying
|
||||
* physical allocation.
|
||||
* @kctx: Pointer to Kbase context.
|
||||
* @alloc: the physical allocation containing the pages whose metadata is going
|
||||
* to be modified
|
||||
* @status: the status the pages should end up in
|
||||
|
|
@ -518,7 +539,7 @@ enum kbase_jit_report_flags { KBASE_JIT_REPORT_ON_ALLOC_OR_FREE = (1u << 0) };
|
|||
* proper states are set. Instead, it is only used when we change the allocation
|
||||
* to NOT_MOVABLE or from NOT_MOVABLE to ALLOCATED_MAPPED
|
||||
*/
|
||||
void kbase_set_phy_alloc_page_status(struct kbase_mem_phy_alloc *alloc,
|
||||
void kbase_set_phy_alloc_page_status(struct kbase_context *kctx, struct kbase_mem_phy_alloc *alloc,
|
||||
enum kbase_page_status status);
|
||||
|
||||
static inline void kbase_mem_phy_alloc_gpu_mapped(struct kbase_mem_phy_alloc *alloc)
|
||||
|
|
@ -620,9 +641,6 @@ static inline struct kbase_mem_phy_alloc *kbase_mem_phy_alloc_put(struct kbase_m
|
|||
* @nr_pages: The size of the region in pages.
|
||||
* @initial_commit: Initial commit, for aligning the start address and
|
||||
* correctly growing KBASE_REG_TILER_ALIGN_TOP regions.
|
||||
* @threshold_pages: If non-zero and the amount of memory committed to a region
|
||||
* that can grow on page fault exceeds this number of pages
|
||||
* then the driver switches to incremental rendering.
|
||||
* @flags: Flags
|
||||
* @extension: Number of pages allocated on page fault.
|
||||
* @cpu_alloc: The physical memory we mmap to the CPU when mapping this region.
|
||||
|
|
@ -659,8 +677,7 @@ struct kbase_va_region {
|
|||
void *user_data;
|
||||
size_t nr_pages;
|
||||
size_t initial_commit;
|
||||
size_t threshold_pages;
|
||||
unsigned long flags;
|
||||
base_mem_alloc_flags flags;
|
||||
size_t extension;
|
||||
struct kbase_mem_phy_alloc *cpu_alloc;
|
||||
struct kbase_mem_phy_alloc *gpu_alloc;
|
||||
|
|
@ -914,10 +931,12 @@ static inline struct kbase_mem_phy_alloc *kbase_alloc_create(struct kbase_contex
|
|||
atomic_set(&alloc->gpu_mappings, 0);
|
||||
atomic_set(&alloc->kernel_mappings, 0);
|
||||
alloc->nents = 0;
|
||||
alloc->pages = (void *)(alloc + 1);
|
||||
/* fill pages with invalid address value */
|
||||
for (i = 0; i < nr_pages; i++)
|
||||
alloc->pages[i] = as_tagged(KBASE_INVALID_PHYSICAL_ADDRESS);
|
||||
if (type != KBASE_MEM_TYPE_ALIAS) {
|
||||
alloc->pages = (void *)(alloc + 1);
|
||||
/* fill pages with invalid address value */
|
||||
for (i = 0; i < nr_pages; i++)
|
||||
alloc->pages[i] = as_tagged(KBASE_INVALID_PHYSICAL_ADDRESS);
|
||||
}
|
||||
INIT_LIST_HEAD(&alloc->mappings);
|
||||
alloc->type = type;
|
||||
alloc->group_id = group_id;
|
||||
|
|
@ -1307,7 +1326,7 @@ struct page *kbase_mem_alloc_page(struct kbase_mem_pool *pool, const bool alloc_
|
|||
*/
|
||||
void kbase_mem_pool_free_page(struct kbase_mem_pool *pool, struct page *p);
|
||||
|
||||
bool kbase_check_alloc_flags(unsigned long flags);
|
||||
bool kbase_check_alloc_flags(struct kbase_context *kctx, unsigned long flags);
|
||||
bool kbase_check_import_flags(unsigned long flags);
|
||||
|
||||
static inline bool kbase_import_size_is_valid(struct kbase_device *kbdev, u64 va_pages)
|
||||
|
|
@ -1799,8 +1818,8 @@ static inline dma_addr_t kbase_dma_addr_from_tagged(struct tagged_addr tagged_pa
|
|||
phys_addr_t pa = as_phys_addr_t(tagged_pa);
|
||||
struct page *page = pfn_to_page(PFN_DOWN(pa));
|
||||
dma_addr_t dma_addr = (is_huge(tagged_pa) || is_partial(tagged_pa)) ?
|
||||
kbase_dma_addr_as_priv(page) :
|
||||
kbase_dma_addr(page);
|
||||
kbase_dma_addr_as_priv(page) :
|
||||
kbase_dma_addr(page);
|
||||
|
||||
return dma_addr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,8 +83,6 @@
|
|||
#define KBASE_MEM_ION_SYNC_WORKAROUND
|
||||
#endif
|
||||
|
||||
#define IR_THRESHOLD_STEPS (256u)
|
||||
|
||||
/*
|
||||
* fully_backed_gpf_memory - enable full physical backing of all grow-on-GPU-page-fault
|
||||
* allocations in the kernel.
|
||||
|
|
@ -295,7 +293,7 @@ void kbase_phy_alloc_mapping_put(struct kbase_context *kctx, struct kbase_vmap_s
|
|||
}
|
||||
|
||||
struct kbase_va_region *kbase_mem_alloc(struct kbase_context *kctx, u64 va_pages, u64 commit_pages,
|
||||
u64 extension, u64 *flags, u64 *gpu_va,
|
||||
u64 extension, base_mem_alloc_flags *flags, u64 *gpu_va,
|
||||
enum kbase_caller_mmu_sync_info mmu_sync_info)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
|
|
@ -320,9 +318,8 @@ struct kbase_va_region *kbase_mem_alloc(struct kbase_context *kctx, u64 va_pages
|
|||
else
|
||||
dev_dbg(dev, "Keeping requested GPU VA of 0x%llx\n", (unsigned long long)*gpu_va);
|
||||
|
||||
if (!kbase_check_alloc_flags(*flags)) {
|
||||
dev_warn(dev, "%s called with bad flags (%llx)", __func__,
|
||||
(unsigned long long)*flags);
|
||||
if (!kbase_check_alloc_flags(kctx, *flags)) {
|
||||
dev_warn(dev, "%s called with bad flags (%llx)", __func__, *flags);
|
||||
goto bad_flags;
|
||||
}
|
||||
|
||||
|
|
@ -335,6 +332,12 @@ struct kbase_va_region *kbase_mem_alloc(struct kbase_context *kctx, u64 va_pages
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Ensure GPU cached if CPU cached */
|
||||
if ((*flags & BASE_MEM_CACHED_CPU) != 0) {
|
||||
dev_warn_once(dev, "Clearing BASE_MEM_UNCACHED_GPU flag to avoid MMA violation\n");
|
||||
*flags &= ~BASE_MEM_UNCACHED_GPU;
|
||||
}
|
||||
|
||||
if ((*flags & BASE_MEM_UNCACHED_GPU) != 0 &&
|
||||
(*flags & BASE_MEM_COHERENT_SYSTEM_REQUIRED) != 0) {
|
||||
/* Remove COHERENT_SYSTEM_REQUIRED flag if uncached GPU mapping is requested */
|
||||
|
|
@ -406,17 +409,8 @@ struct kbase_va_region *kbase_mem_alloc(struct kbase_context *kctx, u64 va_pages
|
|||
*flags &= ~BASE_MEM_CACHED_CPU;
|
||||
|
||||
if (*flags & BASE_MEM_GROW_ON_GPF) {
|
||||
unsigned int const ir_threshold =
|
||||
(unsigned int)atomic_read(&kctx->kbdev->memdev.ir_threshold);
|
||||
|
||||
reg->threshold_pages =
|
||||
((va_pages * ir_threshold) + (IR_THRESHOLD_STEPS / 2)) / IR_THRESHOLD_STEPS;
|
||||
} else
|
||||
reg->threshold_pages = 0;
|
||||
|
||||
if (*flags & BASE_MEM_GROW_ON_GPF) {
|
||||
/* kbase_check_alloc_sizes() already checks extension is valid for
|
||||
* assigning to reg->extension
|
||||
/* kbase_check_alloc_sizes() already checks extension is valid for assigning to
|
||||
* reg->extension.
|
||||
*/
|
||||
reg->extension = extension;
|
||||
#if !MALI_USE_CSF
|
||||
|
|
@ -597,11 +591,11 @@ int kbase_mem_query(struct kbase_context *kctx, u64 gpu_addr, u64 query, u64 *co
|
|||
*out |= BASE_MEM_COHERENT_SYSTEM;
|
||||
if (KBASE_REG_SHARE_IN & reg->flags)
|
||||
*out |= BASE_MEM_COHERENT_LOCAL;
|
||||
if (mali_kbase_supports_mem_dont_need(kctx->api_version)) {
|
||||
if (mali_kbase_supports_query_mem_dont_need(kctx->api_version)) {
|
||||
if (KBASE_REG_DONT_NEED & reg->flags)
|
||||
*out |= BASE_MEM_DONT_NEED;
|
||||
}
|
||||
if (mali_kbase_supports_mem_grow_on_gpf(kctx->api_version)) {
|
||||
if (mali_kbase_supports_query_mem_grow_on_gpf(kctx->api_version)) {
|
||||
/* Prior to this version, this was known about by
|
||||
* user-side but we did not return them. Returning
|
||||
* it caused certain clients that were not expecting
|
||||
|
|
@ -611,7 +605,7 @@ int kbase_mem_query(struct kbase_context *kctx, u64 gpu_addr, u64 query, u64 *co
|
|||
if (KBASE_REG_PF_GROW & reg->flags)
|
||||
*out |= BASE_MEM_GROW_ON_GPF;
|
||||
}
|
||||
if (mali_kbase_supports_mem_protected(kctx->api_version)) {
|
||||
if (mali_kbase_supports_query_mem_protected(kctx->api_version)) {
|
||||
/* Prior to this version, this was known about by
|
||||
* user-side but we did not return them. Returning
|
||||
* it caused certain clients that were not expecting
|
||||
|
|
@ -640,17 +634,17 @@ int kbase_mem_query(struct kbase_context *kctx, u64 gpu_addr, u64 query, u64 *co
|
|||
#endif /* MALI_USE_CSF */
|
||||
if (KBASE_REG_GPU_VA_SAME_4GB_PAGE & reg->flags)
|
||||
*out |= BASE_MEM_GPU_VA_SAME_4GB_PAGE;
|
||||
if (mali_kbase_supports_mem_import_sync_on_map_unmap(kctx->api_version)) {
|
||||
if (mali_kbase_supports_query_mem_import_sync_on_map_unmap(kctx->api_version)) {
|
||||
if (reg->gpu_alloc->type == KBASE_MEM_TYPE_IMPORTED_UMM) {
|
||||
if (reg->gpu_alloc->imported.umm.need_sync)
|
||||
*out |= BASE_MEM_IMPORT_SYNC_ON_MAP_UNMAP;
|
||||
}
|
||||
}
|
||||
if (mali_kbase_supports_mem_kernel_sync(kctx->api_version)) {
|
||||
if (mali_kbase_supports_query_mem_kernel_sync(kctx->api_version)) {
|
||||
if (unlikely(reg->cpu_alloc != reg->gpu_alloc))
|
||||
*out |= BASE_MEM_KERNEL_SYNC;
|
||||
}
|
||||
if (mali_kbase_supports_mem_same_va(kctx->api_version)) {
|
||||
if (mali_kbase_supports_query_mem_same_va(kctx->api_version)) {
|
||||
if (kbase_bits_to_zone(reg->flags) == SAME_VA_ZONE) {
|
||||
/* Imported memory is an edge case, where declaring it SAME_VA
|
||||
* would be ambiguous.
|
||||
|
|
@ -746,7 +740,7 @@ static unsigned long kbase_mem_evictable_reclaim_scan_objects(struct shrinker *s
|
|||
kctx = KBASE_GET_KBASE_DATA_FROM_SHRINKER(s, struct kbase_context, reclaim);
|
||||
|
||||
#if MALI_USE_CSF
|
||||
if (!down_read_trylock(&kctx->kbdev->csf.pmode_sync_sem)) {
|
||||
if (!down_read_trylock(&kctx->kbdev->csf.mmu_sync_sem)) {
|
||||
dev_warn(kctx->kbdev->dev,
|
||||
"Can't shrink GPU memory when P.Mode entrance is in progress");
|
||||
return 0;
|
||||
|
|
@ -791,7 +785,7 @@ static unsigned long kbase_mem_evictable_reclaim_scan_objects(struct shrinker *s
|
|||
|
||||
mutex_unlock(&kctx->jit_evict_lock);
|
||||
#if MALI_USE_CSF
|
||||
up_read(&kctx->kbdev->csf.pmode_sync_sem);
|
||||
up_read(&kctx->kbdev->csf.mmu_sync_sem);
|
||||
#endif
|
||||
return freed;
|
||||
}
|
||||
|
|
@ -886,7 +880,7 @@ void kbase_mem_evictable_make(struct kbase_mem_phy_alloc *gpu_alloc)
|
|||
/* Indicate to page migration that the memory can be reclaimed by the shrinker.
|
||||
*/
|
||||
if (kbase_is_page_migration_enabled())
|
||||
kbase_set_phy_alloc_page_status(gpu_alloc, NOT_MOVABLE);
|
||||
kbase_set_phy_alloc_page_status(kctx, gpu_alloc, NOT_MOVABLE);
|
||||
|
||||
mutex_unlock(&kctx->jit_evict_lock);
|
||||
kbase_mem_evictable_mark_reclaim(gpu_alloc);
|
||||
|
|
@ -944,7 +938,7 @@ bool kbase_mem_evictable_unmake(struct kbase_mem_phy_alloc *gpu_alloc)
|
|||
* from.
|
||||
*/
|
||||
if (kbase_is_page_migration_enabled())
|
||||
kbase_set_phy_alloc_page_status(gpu_alloc, ALLOCATED_MAPPED);
|
||||
kbase_set_phy_alloc_page_status(kctx, gpu_alloc, ALLOCATED_MAPPED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -962,7 +956,8 @@ bool kbase_mem_evictable_unmake(struct kbase_mem_phy_alloc *gpu_alloc)
|
|||
*
|
||||
* Return: 0 on success, error code otherwise.
|
||||
*/
|
||||
static int kbase_mem_flags_change_imported_umm(struct kbase_context *kctx, unsigned int flags,
|
||||
static int kbase_mem_flags_change_imported_umm(struct kbase_context *kctx,
|
||||
base_mem_alloc_flags flags,
|
||||
struct kbase_va_region *reg)
|
||||
{
|
||||
unsigned int real_flags = 0;
|
||||
|
|
@ -1045,7 +1040,7 @@ static int kbase_mem_flags_change_imported_umm(struct kbase_context *kctx, unsig
|
|||
*
|
||||
* Return: 0 on success, error code otherwise.
|
||||
*/
|
||||
static int kbase_mem_flags_change_native(struct kbase_context *kctx, unsigned int flags,
|
||||
static int kbase_mem_flags_change_native(struct kbase_context *kctx, base_mem_alloc_flags flags,
|
||||
struct kbase_va_region *reg)
|
||||
{
|
||||
bool kbase_reg_dont_need_flag = (KBASE_REG_DONT_NEED & reg->flags);
|
||||
|
|
@ -1077,8 +1072,8 @@ static int kbase_mem_flags_change_native(struct kbase_context *kctx, unsigned in
|
|||
return ret;
|
||||
}
|
||||
|
||||
int kbase_mem_flags_change(struct kbase_context *kctx, u64 gpu_addr, unsigned int flags,
|
||||
unsigned int mask)
|
||||
int kbase_mem_flags_change(struct kbase_context *kctx, u64 gpu_addr, base_mem_alloc_flags flags,
|
||||
base_mem_alloc_flags mask)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
int ret = -EINVAL;
|
||||
|
|
@ -1468,7 +1463,7 @@ static int get_umm_memory_group_id(struct kbase_context *kctx, struct dma_buf *d
|
|||
* object that wraps the dma-buf.
|
||||
*/
|
||||
static struct kbase_va_region *kbase_mem_from_umm(struct kbase_context *kctx, int fd, u64 *va_pages,
|
||||
u64 *flags, u32 padding)
|
||||
base_mem_alloc_flags *flags, u32 padding)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
struct dma_buf *dma_buf;
|
||||
|
|
@ -1614,7 +1609,8 @@ u32 kbase_get_cache_line_alignment(struct kbase_device *kbdev)
|
|||
|
||||
static struct kbase_va_region *kbase_mem_from_user_buffer(struct kbase_context *kctx,
|
||||
unsigned long address, unsigned long size,
|
||||
u64 *va_pages, u64 *flags)
|
||||
u64 *va_pages,
|
||||
base_mem_alloc_flags *flags)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
enum kbase_memory_zone zone = CUSTOM_VA_ZONE;
|
||||
|
|
@ -1746,7 +1742,7 @@ bad_size:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
u64 kbase_mem_alias(struct kbase_context *kctx, u64 *flags, u64 stride, u64 nents,
|
||||
u64 kbase_mem_alias(struct kbase_context *kctx, base_mem_alloc_flags *flags, u64 stride, u64 nents,
|
||||
struct base_mem_aliasing_info *ai, u64 *num_pages)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
|
|
@ -1968,7 +1964,8 @@ bad_flags:
|
|||
}
|
||||
|
||||
int kbase_mem_import(struct kbase_context *kctx, enum base_mem_import_type type,
|
||||
void __user *phandle, u32 padding, u64 *gpu_va, u64 *va_pages, u64 *flags)
|
||||
void __user *phandle, u32 padding, u64 *gpu_va, u64 *va_pages,
|
||||
base_mem_alloc_flags *flags)
|
||||
{
|
||||
struct kbase_va_region *reg;
|
||||
|
||||
|
|
@ -3107,7 +3104,7 @@ static int kbase_vmap_phy_pages(struct kbase_context *kctx, struct kbase_va_regi
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (reg->flags & KBASE_REG_DONT_NEED)
|
||||
if (kbase_is_region_shrinkable(reg))
|
||||
return -EINVAL;
|
||||
|
||||
prot = PAGE_KERNEL;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2010-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -51,7 +51,7 @@ struct kbase_hwc_dma_mapping {
|
|||
* Return: 0 on success or error code
|
||||
*/
|
||||
struct kbase_va_region *kbase_mem_alloc(struct kbase_context *kctx, u64 va_pages, u64 commit_pages,
|
||||
u64 extension, u64 *flags, u64 *gpu_va,
|
||||
u64 extension, base_mem_alloc_flags *flags, u64 *gpu_va,
|
||||
enum kbase_caller_mmu_sync_info mmu_sync_info);
|
||||
|
||||
/**
|
||||
|
|
@ -84,7 +84,8 @@ int kbase_mem_query(struct kbase_context *kctx, u64 gpu_addr, u64 query, u64 *co
|
|||
* Return: 0 on success or error code
|
||||
*/
|
||||
int kbase_mem_import(struct kbase_context *kctx, enum base_mem_import_type type,
|
||||
void __user *phandle, u32 padding, u64 *gpu_va, u64 *va_pages, u64 *flags);
|
||||
void __user *phandle, u32 padding, u64 *gpu_va, u64 *va_pages,
|
||||
base_mem_alloc_flags *flags);
|
||||
|
||||
/**
|
||||
* kbase_mem_alias - Create a new allocation for GPU, aliasing one or more
|
||||
|
|
@ -99,7 +100,7 @@ int kbase_mem_import(struct kbase_context *kctx, enum base_mem_import_type type,
|
|||
*
|
||||
* Return: 0 on failure or otherwise the GPU VA for the alias
|
||||
*/
|
||||
u64 kbase_mem_alias(struct kbase_context *kctx, u64 *flags, u64 stride, u64 nents,
|
||||
u64 kbase_mem_alias(struct kbase_context *kctx, base_mem_alloc_flags *flags, u64 stride, u64 nents,
|
||||
struct base_mem_aliasing_info *ai, u64 *num_pages);
|
||||
|
||||
/**
|
||||
|
|
@ -112,8 +113,8 @@ u64 kbase_mem_alias(struct kbase_context *kctx, u64 *flags, u64 stride, u64 nent
|
|||
*
|
||||
* Return: 0 on success or error code
|
||||
*/
|
||||
int kbase_mem_flags_change(struct kbase_context *kctx, u64 gpu_addr, unsigned int flags,
|
||||
unsigned int mask);
|
||||
int kbase_mem_flags_change(struct kbase_context *kctx, u64 gpu_addr, base_mem_alloc_flags flags,
|
||||
base_mem_alloc_flags mask);
|
||||
|
||||
/**
|
||||
* kbase_mem_commit - Change the physical backing size of a region
|
||||
|
|
|
|||
|
|
@ -68,6 +68,12 @@ bool kbase_alloc_page_metadata(struct kbase_device *kbdev, struct page *p, dma_a
|
|||
if (!IS_ENABLED(CONFIG_PAGE_MIGRATION_SUPPORT))
|
||||
return false;
|
||||
|
||||
/* Composite large-page is excluded from migration, trigger a warn if a development
|
||||
* wrongly leads to it.
|
||||
*/
|
||||
if (is_huge_head(as_tagged(page_to_phys(p))) || is_partial(as_tagged(page_to_phys(p))))
|
||||
dev_WARN(kbdev->dev, "%s: migration-metadata attempted on large-page.", __func__);
|
||||
|
||||
page_md = kzalloc(sizeof(struct kbase_page_metadata), GFP_KERNEL);
|
||||
if (!page_md)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -122,12 +122,16 @@ static vm_fault_t kbase_native_mgm_vmf_insert_pfn_prot(struct memory_group_manag
|
|||
}
|
||||
|
||||
static u64 kbase_native_mgm_update_gpu_pte(struct memory_group_manager_device *mgm_dev,
|
||||
unsigned int group_id, int mmu_level, u64 pte)
|
||||
unsigned int group_id, unsigned int pbha_id,
|
||||
unsigned int pte_flags, int mmu_level, u64 pte)
|
||||
{
|
||||
if (WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
|
||||
return pte;
|
||||
|
||||
pte |= ((u64)group_id << PTE_PBHA_SHIFT) & PTE_PBHA_MASK;
|
||||
if ((pte_flags & BIT(MMA_VIOLATION)) && pbha_id) {
|
||||
pr_warn_once("MMA violation! Applying PBHA override workaround to PTE\n");
|
||||
pte |= ((u64)pbha_id << PTE_PBHA_SHIFT) & PTE_PBHA_MASK;
|
||||
}
|
||||
|
||||
/* Address could be translated into a different bus address here */
|
||||
pte |= ((u64)1 << PTE_RES_BIT_MULTI_AS_SHIFT);
|
||||
|
|
@ -150,14 +154,24 @@ static u64 kbase_native_mgm_pte_to_original_pte(struct memory_group_manager_devi
|
|||
return pte;
|
||||
}
|
||||
|
||||
static bool kbase_native_mgm_get_import_memory_cached_access_permitted(
|
||||
struct memory_group_manager_device *mgm_dev,
|
||||
struct memory_group_manager_import_data *import_data)
|
||||
{
|
||||
CSTD_UNUSED(mgm_dev);
|
||||
CSTD_UNUSED(import_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct memory_group_manager_device kbase_native_mgm_dev = {
|
||||
.ops = {
|
||||
.mgm_alloc_page = kbase_native_mgm_alloc,
|
||||
.mgm_free_page = kbase_native_mgm_free,
|
||||
.mgm_get_import_memory_id = NULL,
|
||||
.mgm_vmf_insert_pfn_prot = kbase_native_mgm_vmf_insert_pfn_prot,
|
||||
.mgm_update_gpu_pte = kbase_native_mgm_update_gpu_pte,
|
||||
.mgm_pte_to_original_pte = kbase_native_mgm_pte_to_original_pte,
|
||||
},
|
||||
.ops = { .mgm_alloc_page = kbase_native_mgm_alloc,
|
||||
.mgm_free_page = kbase_native_mgm_free,
|
||||
.mgm_get_import_memory_id = NULL,
|
||||
.mgm_vmf_insert_pfn_prot = kbase_native_mgm_vmf_insert_pfn_prot,
|
||||
.mgm_update_gpu_pte = kbase_native_mgm_update_gpu_pte,
|
||||
.mgm_pte_to_original_pte = kbase_native_mgm_pte_to_original_pte,
|
||||
.mgm_get_import_memory_cached_access_permitted =
|
||||
kbase_native_mgm_get_import_memory_cached_access_permitted },
|
||||
.data = NULL
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2021-2023 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2021-2024 ARM Limited. All rights reserved.
|
||||
*
|
||||
* This program is free software and is provided to you under the terms of the
|
||||
* GNU General Public License version 2 as published by the Free Software
|
||||
|
|
@ -220,6 +220,24 @@ void kbase_pbha_write_settings(struct kbase_device *kbdev)
|
|||
for (i = 0; i < GPU_SYSC_ALLOC_COUNT; ++i)
|
||||
kbase_reg_write32(kbdev, GPU_SYSC_ALLOC_OFFSET(i), kbdev->sysc_alloc[i]);
|
||||
}
|
||||
|
||||
if (kbdev->mma_wa_id) {
|
||||
/* PBHA OVERRIDE register index (0-3) */
|
||||
uint reg_index = kbdev->mma_wa_id >> 2;
|
||||
/* PBHA index within a PBHA OVERRIDE register (0-3) */
|
||||
uint pbha_index = kbdev->mma_wa_id & 0x3;
|
||||
/* 4 bits of read attributes + 4 bits of write attributes for each PBHA */
|
||||
uint pbha_shift = pbha_index * 8;
|
||||
/* Noncacheable read = noncacheable write = b0001*/
|
||||
uint pbha_override_rw_noncacheable = 0x01 | 0x10;
|
||||
|
||||
u32 pbha_override_val =
|
||||
kbase_reg_read32(kbdev, GPU_SYSC_PBHA_OVERRIDE_OFFSET(reg_index));
|
||||
pbha_override_val &= ~((u32)0xFF << pbha_shift);
|
||||
pbha_override_val |= ((u32)pbha_override_rw_noncacheable << pbha_shift);
|
||||
kbase_reg_write32(kbdev, GPU_SYSC_PBHA_OVERRIDE_OFFSET(reg_index),
|
||||
pbha_override_val);
|
||||
}
|
||||
#else
|
||||
CSTD_UNUSED(kbdev);
|
||||
#endif /* MALI_USE_CSF */
|
||||
|
|
@ -280,7 +298,7 @@ static int kbase_pbha_read_propagate_bits_property(struct kbase_device *kbdev,
|
|||
u8 bits = 0;
|
||||
int err;
|
||||
|
||||
if (!kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_PBHA_HWU))
|
||||
if (!kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_PBHA_HWU))
|
||||
return 0;
|
||||
|
||||
err = of_property_read_u8(pbha_node, "propagate-bits", &bits);
|
||||
|
|
@ -310,6 +328,43 @@ static int kbase_pbha_read_propagate_bits_property(struct kbase_device *kbdev,
|
|||
kbdev->pbha_propagate_bits = bits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kbase_pbha_read_mma_wa_id_property(struct kbase_device *kbdev,
|
||||
const struct device_node *pbha_node)
|
||||
{
|
||||
u32 mma_wa_id = 0;
|
||||
int err;
|
||||
|
||||
/* Skip if kbdev->mma_wa_id has already been set via the module parameter */
|
||||
if ((kbdev->gpu_props.gpu_id.arch_id < GPU_ID_ARCH_MAKE(14, 8, 0)) || kbdev->mma_wa_id != 0)
|
||||
return 0;
|
||||
|
||||
err = of_property_read_u32(pbha_node, "mma-wa-id", &mma_wa_id);
|
||||
|
||||
/* Property does not exist. This is not a mandatory property, ignore this error */
|
||||
if (err == -EINVAL)
|
||||
return 0;
|
||||
|
||||
if (err == -ENODATA) {
|
||||
dev_err(kbdev->dev, "DTB property mma-wa-id has no value\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (err == -EOVERFLOW) {
|
||||
dev_err(kbdev->dev, "DTB value for mma-wa-id is out of range\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (mma_wa_id == 0 || mma_wa_id > 15) {
|
||||
dev_err(kbdev->dev,
|
||||
"Invalid DTB value for mma-wa-id: %u. Valid range is between 1 and 15.\n",
|
||||
mma_wa_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kbdev->mma_wa_id = mma_wa_id;
|
||||
return 0;
|
||||
}
|
||||
#endif /* MALI_USE_CSF */
|
||||
|
||||
int kbase_pbha_read_dtb(struct kbase_device *kbdev)
|
||||
|
|
@ -331,6 +386,12 @@ int kbase_pbha_read_dtb(struct kbase_device *kbdev)
|
|||
return err;
|
||||
|
||||
err = kbase_pbha_read_propagate_bits_property(kbdev, pbha_node);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = kbase_pbha_read_mma_wa_id_property(kbdev, pbha_node);
|
||||
|
||||
return err;
|
||||
#else
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ void kbase_pbha_debugfs_init(struct kbase_device *kbdev)
|
|||
debugfs_create_file("int_id_overrides", mode, debugfs_pbha_dir, kbdev,
|
||||
&pbha_int_id_overrides_fops);
|
||||
#if MALI_USE_CSF
|
||||
if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_PBHA_HWU))
|
||||
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_PBHA_HWU))
|
||||
debugfs_create_file("propagate_bits", mode, debugfs_pbha_dir, kbdev,
|
||||
&pbha_propagate_bits_fops);
|
||||
#endif /* MALI_USE_CSF */
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue