Revert "MALI: rockchip: upgrade bifrost DDK to g21p0-01eac0, from g18p0-01eac0"

This reverts commit a94d0b968a.
This commit is contained in:
Joshua Riek
2024-07-13 21:49:23 -04:00
committed by Ricardo Pardini
parent d674985810
commit 48afe9af03
383 changed files with 28460 additions and 36213 deletions

View File

@@ -1,6 +1,6 @@
/*
*
* (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2020 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
@@ -68,16 +68,6 @@ Description:
is supported or is powered down after suspending command
stream groups.
What: /sys/class/misc/mali%u/device/idle_hysteresis_time_ns
Description:
This attribute is available only with mali platform
device-driver that supports a CSF GPU. This attribute is
used to configure the timeout value in nanoseconds for the
GPU idle handling. If GPU has been idle for this timeout
period, then it is put to sleep for GPUs where sleep feature
is supported or is powered down after suspending command
stream groups.
What: /sys/class/misc/mali%u/device/js_ctx_scheduling_mode
Description:
This attribute is available only with platform device that
@@ -242,23 +232,6 @@ Description:
If we set the value to zero then MCU-controlled shader/tiler
power management will be disabled.
What: /sys/class/misc/mali%u/device/mcu_shader_pwroff_timeout_ns
Description:
This attribute is available only with mali platform
device-driver that supports a CSF GPU. The duration value unit
is in nanoseconds and is used for configuring MCU shader Core power-off
timer. The configured MCU shader Core power-off timer will only have
effect when the host driver has delegated the shader cores
power management to MCU. The supplied value will be
recorded internally without any change. But the actual field
value will be subject to core power-off timer source frequency
scaling and maximum value limiting. The default source will be
SYSTEM_TIMESTAMP counter. But in case the platform is not able
to supply it, the GPU CYCLE_COUNTER source will be used as an
alternative.
If we set the value to zero then MCU-controlled shader/tiler
power management will be disabled.
What: /sys/class/misc/mali%u/device/csg_scheduling_period
Description:

View File

@@ -1,6 +1,6 @@
/*
*
* (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2022 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
@@ -71,10 +71,6 @@ Description:
[11:10] = 1, Generate TS request approx every 128 cycles
[22:16] = 1, Trace bus ID
What: /sys/bus/coresight/devices/mali-source-ela/reset_regs
Description:
Attribute used to reset registers to zero.
What: /sys/bus/coresight/devices/mali-source-ela/enable_source
Description:
Attribute used to enable Coresight Source ELA.
@@ -83,121 +79,35 @@ What: /sys/bus/coresight/devices/mali-source-ela/is_enabled
Description:
Attribute used to check if Coresight Source ELA is enabled.
What: /sys/bus/coresight/devices/mali-source-ela/regs/TIMECTRL
What: /sys/bus/coresight/devices/mali-source-ela/select
Description:
Coresight Source ELA TIMECTRL register set/get.
Coresight Source ELA select trace mode:
[0], NONE
[1], JCN
[2], CEU_EXEC
[3], CEU_CMDS
[4], MCU_AHBP
[5], HOST_AXI
[6], NR_TRACEMODE
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/TSSR
What: /sys/bus/coresight/devices/mali-source-ela/sigmask0
Description:
Coresight Source ELA TSR register set/get.
Coresight Source ELA SIGMASK0 register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/ATBCTRL
What: /sys/bus/coresight/devices/mali-source-ela/sigmask4
Description:
Coresight Source ELA ATBCTRL register set/get.
Coresight Source ELA SIGMASK4 register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/PTACTION
What: /sys/bus/coresight/devices/mali-source-ela/sigcomp0
Description:
Coresight Source ELA PTACTION register set/get.
Coresight Source ELA SIGCOMP0 register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/AUXCTRL
What: /sys/bus/coresight/devices/mali-source-ela/sigcomp4
Description:
Coresight Source ELA AUXCTRL register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/CNTSEL
Description:
Coresight Source ELA CNTSEL register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/SIGSELn
Description:
Coresight Source ELA SIGSELn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/TRIGCTRLn
Description:
Coresight Source ELA TRIGCTRLn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/NEXTSTATEn
Description:
Coresight Source ELA NEXTSTATEn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/ACTIONn
Description:
Coresight Source ELA ACTIONn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/ALTNEXTSTATEn
Description:
Coresight Source ELA ALTNEXTSTATEn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/ALTACTIONn
Description:
Coresight Source ELA ALTACTIONn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/COMPCTRLn
Description:
Coresight Source ELA COMPCTRLn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/ALTCOMPCTRLn
Description:
Coresight Source ELA ALTCOMPCTRLn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/COUNTCOMPn
Description:
Coresight Source ELA COUNTCOMPn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/TWBSELn
Description:
Coresight Source ELA TWBSELn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/EXTMASKn
Description:
Coresight Source ELA EXTMASKn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/EXTCOMPn
Description:
Coresight Source ELA EXTCOMPn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/QUALMASKn
Description:
Coresight Source ELA QUALMASKn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/QUALCOMPn
Coresight Source ELA QUALCOMPn register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/SIGMASKn_0-7
Description:
Coresight Source ELA SIGMASKn_0-7 register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/SIGCOMPn_0-7
Description:
Coresight Source ELA SIGCOMPn_0-7 register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/SIGSELn_0-7
Description:
Coresight Source ELA SIGSELn_0-7 register set/get.
Refer to specification for more details.
What: /sys/bus/coresight/devices/mali-source-ela/regs/SIGMASKn_0-7
Description:
Coresight Source ELA SIGMASKn_0-7 register set/get.
Coresight Source ELA SIGCOMP4 register set/get.
Refer to specification for more details.

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# (C) COPYRIGHT 2022-2023 ARM Limited. All rights reserved.
# (C) COPYRIGHT 2022 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
@@ -109,65 +109,3 @@ surpass the arg value.
===============================================================================================================================
queue:KCPU-0-1 exec:S cmd:CQS_WAIT_OPERATION obj:0x0000007fbf6f2ff8 live_value:0x0000000000000000 | op:gt arg_value: 0x00000000
===============================================================================================================================
CSF Sync State Dump For Fence Signal Timeouts
---------------------------------------------
Summary
-------
A timer has been added to the KCPU queues which is checked to ensure
the queues have not "timed out" between the enqueuing of a fence signal command
and it's eventual execution. If this timeout happens then the CSF sync state
of all KCPU queues of the offending context is dumped. This feature is enabled
by default, but can be disabled/enabled later.
Explanation
------------
This new timer is created and destroyed alongside the creation and destruction
of each KCPU queue. It is started when a fence signal is enqueued, and cancelled
when the fence signal command has been processed. The timer times out after
10 seconds (at 100 MHz) if the execution of that fence signal event was never
processed. If this timeout occurs then the timer callback function identifies
the KCPU queue which the timer belongs to and invokes the CSF synchronisation
state dump mechanism, writing the sync state for the context of the queue
causing the timeout is dump to dmesg.
Fence Timeouts Controls
-----------------------
Disable/Enable Feature
----------------------
This feature is enabled by default, but can be disabled/ re-enabled via DebugFS
controls. The 'fence_signal_timeout_enable' debugfs entry is a global flag
which is written to, to turn this feature on and off.
Example:
--------
when writing to fence_signal_timeout_enable entry:
echo 1 > /sys/kernel/debug/mali0/fence_signal_timeout_enable -> feature is enabled.
echo 0 > /sys/kernel/debug/mali0/fence_signal_timeout_enable -> feature is disabled.
It is also possible to read from this file to check if the feature is currently
enabled or not checking the return value of fence_signal_timeout_enable.
Example:
--------
when reading from fence_signal_timeout_enable entry, if:
cat /sys/kernel/debug/mali0/fence_signal_timeout_enable returns 1 -> feature is enabled.
cat /sys/kernel/debug/mali0/fence_signal_timeout_enable returns 0 -> feature is disabled.
Update Timer Duration
---------------------
The timeout duration can be accessed through the 'fence_signal_timeout_ms'
debugfs entry. This can be read from to retrieve the current time in
milliseconds.
Example:
--------
cat /sys/kernel/debug/mali0/fence_signal_timeout_ms
The 'fence_signal_timeout_ms' debugfs entry can also be written to, to update
the time in milliseconds.
Example:
--------
echo 10000 > /sys/kernel/debug/mali0/fence_signal_timeout_ms

View File

@@ -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-2022 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
@@ -44,22 +44,22 @@ Documentation/devicetree/bindings/regulator/regulator.txt for details.
- mem-supply : Phandle to memory regulator for the Mali device. This is optional.
- operating-points-v2 : Refer to Documentation/devicetree/bindings/power/mali-opp.txt
for details.
- quirks-gpu : Used to write to the JM_CONFIG or CSF_CONFIG register.
- quirks_gpu : Used to write to the JM_CONFIG or CSF_CONFIG register.
Should be used with care. Options passed here are used to override
certain default behavior. Note: This will override 'idvs-group-size'
field in devicetree and module param 'corestack_driver_control',
therefore if 'quirks-gpu' is used then 'idvs-group-size' and
'corestack_driver_control' value should be incorporated into 'quirks-gpu'.
- quirks-sc : Used to write to the SHADER_CONFIG register.
therefore if 'quirks_gpu' is used then 'idvs-group-size' and
'corestack_driver_control' value should be incorporated into 'quirks_gpu'.
- quirks_sc : Used to write to the SHADER_CONFIG register.
Should be used with care. Options passed here are used to override
certain default behavior.
- quirks-tiler : Used to write to the TILER_CONFIG register.
- quirks_tiler : Used to write to the TILER_CONFIG register.
Should be used with care. Options passed here are used to
disable or override certain default behavior.
- quirks-mmu : Used to write to the L2_CONFIG register.
- quirks_mmu : Used to write to the L2_CONFIG register.
Should be used with care. Options passed here are used to
disable or override certain default behavior.
- power-model : Sets the power model parameters. Defined power models include:
- power_model : Sets the power model parameters. Defined power models include:
"mali-simple-power-model", "mali-g51-power-model", "mali-g52-power-model",
"mali-g52_r1-power-model", "mali-g71-power-model", "mali-g72-power-model",
"mali-g76-power-model", "mali-g77-power-model", "mali-tnax-power-model",
@@ -96,7 +96,7 @@ for details.
are used at different points so care should be taken to configure
both power models in the device tree (specifically dynamic-coefficient,
static-coefficient and scale) to best match the platform.
- power-policy : Sets the GPU power policy at probe time. Available options are
- power_policy : Sets the GPU power policy at probe time. Available options are
"coarse_demand" and "always_on". If not set, then "coarse_demand" is used.
- system-coherency : Sets the coherency protocol to be used for coherent
accesses made from the GPU.
@@ -116,19 +116,17 @@ for details.
- l2-hash-values : Override L2 hash function using provided hash values, on GPUs that supports it.
It is mutually exclusive with 'l2-hash'. Only one or the other must be
used in a supported GPU.
- arbiter-if : Phandle to the arbif platform device, used to provide KBASE with an interface
- arbiter_if : Phandle to the arbif platform device, used to provide KBASE with an interface
to the Arbiter. This is required when using arbitration; setting to a non-NULL
value will enable arbitration.
If arbitration is in use, then there should be no external GPU control.
When arbiter-if is in use then the following must not be:
- power-model (no IPA allowed with arbitration)
When arbiter_if is in use then the following must not be:
- power_model (no IPA allowed with arbitration)
- #cooling-cells
- operating-points-v2 (no dvfs in kbase with arbitration)
- system-coherency with a value of 1 (no full coherency with arbitration)
- int-id-override: list of <ID Setting[7:0]> tuples defining the IDs needed to be
- int_id_override: list of <ID Setting[7:0]> tuples defining the IDs needed to be
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.
Example for a Mali GPU with 1 clock and 1 regulator:
@@ -236,8 +234,8 @@ Example for a Mali GPU supporting PBHA configuration via DTB (default):
gpu@0xfc010000 {
...
pbha {
int-id-override = <2 0x32>, <9 0x05>, <16 0x32>;
propagate-bits = /bits/ 4 <0x03>;
int_id_override = <2 0x32>, <9 0x05>, <16 0x32>;
propagate_bits = <0x03>;
};
...
};

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
# (C) COPYRIGHT 2022 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
@@ -87,6 +87,27 @@ Required properties
- compatible: Has to be "arm,coresight-mali-source-ela"
- gpu : phandle to a Mali GPU definition
- signal-groups: Signal groups indexed from 0 to 5.
Used to configure the signal channels.
- sgN: Types of signals attached to one channel.
It can be more than one type in the case of
JCN request/response.
Types:
- "jcn-request": Can share the channel with "jcn-response"
- "jcn-response": Can share the channel with "jcn-request"
- "ceu-execution": Cannot share the channel with other types
- "ceu-commands": Cannot share the channel with other types
- "mcu-ahbp": Cannot share the channel with other types
- "host-axi": Cannot share the channel with other types
If the HW implementation shares a common channel
for JCN response and request (total of 4 channels),
Refer to:
- "Example: Shared JCN request/response channel"
Otherwise (total of 5 channels), refer to:
- "Example: Split JCN request/response channel"
- port:
- endpoint:
- remote-endpoint: phandle to a Coresight sink port
@@ -95,12 +116,19 @@ Example: Split JCN request/response channel
--------------------------------------------
This examples applies to implementations with a total of 5 signal groups,
where JCN request and response are assigned to independent or shared
channels depending on the GPU model.
where JCN request and response are assigned to independent channels.
mali-source-ela {
compatible = "arm,coresight-mali-source-ela";
gpu = <&gpu>;
signal-groups {
sg0 = "jcn-request";
sg1 = "jcn-response";
sg2 = "ceu-execution";
sg3 = "ceu-commands";
sg4 = "mcu-ahbp";
sg5 = "host-axi";
};
port {
mali_source_ela_out_port0: endpoint {
remote-endpoint = <&mali_sink_in_port2>;
@@ -108,9 +136,25 @@ mali-source-ela {
};
};
SysFS Configuration
Example: Shared JCN request/response channel
--------------------------------------------
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.
This examples applies to implementations with a total of 4 signal groups,
where JCN request and response are assigned to the same channel.
mali-source-ela {
compatible = "arm,coresight-mali-source-ela";
gpu = <&gpu>;
signal-groups {
sg0 = "jcn-request", "jcn-response";
sg1 = "ceu-execution";
sg2 = "ceu-commands";
sg3 = "mcu-ahbp";
sg4 = "host-axi";
};
port {
mali_source_ela_out_port0: endpoint {
remote-endpoint = <&mali_sink_in_port1>;
};
};
};

View File

@@ -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-2022 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
@@ -21,7 +21,6 @@
#
# ccflags
#
src:=$(if $(patsubst /%,,$(src)),$(srctree)/$(src),$(src))
ccflags-y += -I$(src)/../../../include
subdir-ccflags-y += $(ccflags-y)

View File

@@ -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-2022 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

View File

@@ -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-2022 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,53 +23,49 @@
#
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
KDIR ?= $(KERNEL_SRC)
M ?= $(shell pwd)
ifeq ($(KDIR),)
$(error Must specify KDIR to point to the kernel to target))
endif
CONFIGS :=
vars :=
#
# Default configuration values
#
CONFIG_MALI_BASE_MODULES ?= n
ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
#
# Default configuration values
#
CONFIG_MALI_BASE_MODULES ?= n
ifeq ($(CONFIG_MALI_BASE_MODULES),y)
CONFIG_MALI_CSF_SUPPORT ?= n
ifneq ($(CONFIG_DMA_SHARED_BUFFER),n)
CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER ?= y
else
# Prevent misuse when CONFIG_DMA_SHARED_BUFFER=n
CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER = n
endif
CONFIG_MALI_MEMORY_GROUP_MANAGER ?= y
ifneq ($(CONFIG_MALI_CSF_SUPPORT), n)
CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR ?= y
endif
ifeq ($(CONFIG_MALI_BASE_MODULES),y)
CONFIG_MALI_CSF_SUPPORT ?= n
ifneq ($(CONFIG_DMA_SHARED_BUFFER),n)
CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER ?= y
else
# Prevent misuse when CONFIG_MALI_BASE_MODULES=n
# Prevent misuse when CONFIG_DMA_SHARED_BUFFER=n
CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER = n
CONFIG_MALI_MEMORY_GROUP_MANAGER = n
CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR = n
endif
CONFIGS += \
CONFIG_MALI_BASE_MODULES \
CONFIG_MALI_CSF_SUPPORT \
CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER \
CONFIG_MALI_MEMORY_GROUP_MANAGER \
CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR \
CONFIG_MALI_MEMORY_GROUP_MANAGER ?= y
ifneq ($(CONFIG_MALI_CSF_SUPPORT), n)
CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR ?= y
endif
else
# Prevent misuse when CONFIG_MALI_BASE_MODULES=n
CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER = n
CONFIG_MALI_MEMORY_GROUP_MANAGER = n
CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR = n
endif
CONFIGS := \
CONFIG_MALI_BASE_MODULES \
CONFIG_MALI_CSF_SUPPORT \
CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER \
CONFIG_MALI_MEMORY_GROUP_MANAGER \
CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR \
#
# MAKE_ARGS to pass the custom CONFIGs on out-of-tree build
#
@@ -92,65 +88,65 @@ EXTRA_CFLAGS := $(foreach config,$(CONFIGS), \
$(if $(filter y m,$(value $(value config))), \
-D$(value config)=1))
CFLAGS_MODULE += -Wall -Werror
KBUILD_CFLAGS += -Wall -Werror
ifeq ($(CONFIG_GCOV_KERNEL), y)
CFLAGS_MODULE += $(call cc-option, -ftest-coverage)
CFLAGS_MODULE += $(call cc-option, -fprofile-arcs)
KBUILD_CFLAGS += $(call cc-option, -ftest-coverage)
KBUILD_CFLAGS += $(call cc-option, -fprofile-arcs)
EXTRA_CFLAGS += -DGCOV_PROFILE=1
endif
ifeq ($(CONFIG_MALI_KCOV),y)
CFLAGS_MODULE += $(call cc-option, -fsanitize-coverage=trace-cmp)
KBUILD_CFLAGS += $(call cc-option, -fsanitize-coverage=trace-cmp)
EXTRA_CFLAGS += -DKCOV=1
EXTRA_CFLAGS += -DKCOV_ENABLE_COMPARISONS=1
endif
# The following were added to align with W=1 in scripts/Makefile.extrawarn
# from the Linux source tree (v5.18.14)
CFLAGS_MODULE += -Wextra -Wunused -Wno-unused-parameter
CFLAGS_MODULE += -Wmissing-declarations
CFLAGS_MODULE += -Wmissing-format-attribute
CFLAGS_MODULE += -Wmissing-prototypes
CFLAGS_MODULE += -Wold-style-definition
KBUILD_CFLAGS += -Wextra -Wunused -Wno-unused-parameter
KBUILD_CFLAGS += -Wmissing-declarations
KBUILD_CFLAGS += -Wmissing-format-attribute
KBUILD_CFLAGS += -Wmissing-prototypes
KBUILD_CFLAGS += -Wold-style-definition
# The -Wmissing-include-dirs cannot be enabled as the path to some of the
# included directories change depending on whether it is an in-tree or
# out-of-tree build.
CFLAGS_MODULE += $(call cc-option, -Wunused-but-set-variable)
CFLAGS_MODULE += $(call cc-option, -Wunused-const-variable)
CFLAGS_MODULE += $(call cc-option, -Wpacked-not-aligned)
CFLAGS_MODULE += $(call cc-option, -Wstringop-truncation)
KBUILD_CFLAGS += $(call cc-option, -Wunused-but-set-variable)
KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable)
KBUILD_CFLAGS += $(call cc-option, -Wpacked-not-aligned)
KBUILD_CFLAGS += $(call cc-option, -Wstringop-truncation)
# The following turn off the warnings enabled by -Wextra
CFLAGS_MODULE += -Wno-sign-compare
CFLAGS_MODULE += -Wno-shift-negative-value
KBUILD_CFLAGS += -Wno-sign-compare
KBUILD_CFLAGS += -Wno-shift-negative-value
# This flag is needed to avoid build errors on older kernels
CFLAGS_MODULE += $(call cc-option, -Wno-cast-function-type)
KBUILD_CFLAGS += $(call cc-option, -Wno-cast-function-type)
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1
# The following were added to align with W=2 in scripts/Makefile.extrawarn
# from the Linux source tree (v5.18.14)
CFLAGS_MODULE += -Wdisabled-optimization
KBUILD_CFLAGS += -Wdisabled-optimization
# The -Wshadow flag cannot be enabled unless upstream kernels are
# patched to fix redefinitions of certain built-in functions and
# global variables.
CFLAGS_MODULE += $(call cc-option, -Wlogical-op)
CFLAGS_MODULE += -Wmissing-field-initializers
KBUILD_CFLAGS += $(call cc-option, -Wlogical-op)
KBUILD_CFLAGS += -Wmissing-field-initializers
# -Wtype-limits must be disabled due to build failures on kernel 5.x
CFLAGS_MODULE += -Wno-type-limits
CFLAGS_MODULE += $(call cc-option, -Wmaybe-uninitialized)
CFLAGS_MODULE += $(call cc-option, -Wunused-macros)
KBUILD_CFLAGS += -Wno-type-limit
KBUILD_CFLAGS += $(call cc-option, -Wmaybe-uninitialized)
KBUILD_CFLAGS += $(call cc-option, -Wunused-macros)
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2
# This warning is disabled to avoid build failures in some kernel versions
CFLAGS_MODULE += -Wno-ignored-qualifiers
KBUILD_CFLAGS += -Wno-ignored-qualifiers
all:
$(MAKE) -C $(KDIR) M=$(M) $(MAKE_ARGS) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" modules
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" modules
modules_install:
$(MAKE) -C $(KDIR) M=$(M) $(MAKE_ARGS) modules_install
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) modules_install
clean:
$(MAKE) -C $(KDIR) M=$(M) $(MAKE_ARGS) clean
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) clean

View File

@@ -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-2022 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
@@ -31,10 +31,6 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/dma-mapping.h>
#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE
#include <linux/dma-resv.h>
#endif
#include <linux/version_compat_defs.h>
#define DMA_BUF_TE_VER_MAJOR 1
#define DMA_BUF_TE_VER_MINOR 0
@@ -51,10 +47,6 @@
#define NO_SG_CHAIN
#endif
#ifndef CSTD_UNUSED
#define CSTD_UNUSED(x) ((void)(x))
#endif
struct dma_buf_te_alloc {
/* the real alloc */
size_t nr_pages;
@@ -73,9 +65,6 @@ struct dma_buf_te_alloc {
bool contiguous;
dma_addr_t contig_dma_addr;
void *contig_cpu_addr;
/* @lock: Used internally to serialize list manipulation, attach/detach etc. */
struct mutex lock;
};
struct dma_buf_te_attachment {
@@ -86,13 +75,12 @@ struct dma_buf_te_attachment {
static struct miscdevice te_device;
#if (KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE)
static int dma_buf_te_attach(struct dma_buf *buf, struct device *dev,
struct dma_buf_attachment *attachment)
static int dma_buf_te_attach(struct dma_buf *buf, struct device *dev, struct dma_buf_attachment *attachment)
#else
static int dma_buf_te_attach(struct dma_buf *buf, struct dma_buf_attachment *attachment)
#endif
{
struct dma_buf_te_alloc *alloc;
struct dma_buf_te_alloc *alloc;
alloc = buf->priv;
@@ -103,9 +91,8 @@ static int dma_buf_te_attach(struct dma_buf *buf, struct dma_buf_attachment *att
if (!attachment->priv)
return -ENOMEM;
mutex_lock(&alloc->lock);
/* dma_buf is externally locked during call */
alloc->nr_attached_devices++;
mutex_unlock(&alloc->lock);
return 0;
}
@@ -120,23 +107,20 @@ static void dma_buf_te_detach(struct dma_buf *buf, struct dma_buf_attachment *at
struct dma_buf_te_alloc *alloc = buf->priv;
struct dma_buf_te_attachment *pa = attachment->priv;
mutex_lock(&alloc->lock);
/* dma_buf is externally locked during call */
WARN(pa->attachment_mapped,
"WARNING: dma-buf-test-exporter detected detach with open device mappings");
WARN(pa->attachment_mapped, "WARNING: dma-buf-test-exporter detected detach with open device mappings");
alloc->nr_attached_devices--;
mutex_unlock(&alloc->lock);
kfree(pa);
}
static struct sg_table *dma_buf_te_map(struct dma_buf_attachment *attachment,
enum dma_data_direction direction)
static struct sg_table *dma_buf_te_map(struct dma_buf_attachment *attachment, enum dma_data_direction direction)
{
struct sg_table *sg;
struct scatterlist *iter;
struct dma_buf_te_alloc *alloc;
struct dma_buf_te_alloc *alloc;
struct dma_buf_te_attachment *pa = attachment->priv;
size_t i;
int ret;
@@ -146,7 +130,8 @@ static struct sg_table *dma_buf_te_map(struct dma_buf_attachment *attachment,
if (alloc->fail_map)
return ERR_PTR(-ENOMEM);
if (WARN(pa->attachment_mapped, "WARNING: Attempted to map already mapped attachment."))
if (WARN(pa->attachment_mapped,
"WARNING: Attempted to map already mapped attachment."))
return ERR_PTR(-EBUSY);
#ifdef NO_SG_CHAIN
@@ -160,22 +145,21 @@ static struct sg_table *dma_buf_te_map(struct dma_buf_attachment *attachment,
return ERR_PTR(-ENOMEM);
/* from here we access the allocation object, so lock the dmabuf pointing to it */
mutex_lock(&alloc->lock);
mutex_lock(&attachment->dmabuf->lock);
if (alloc->contiguous)
ret = sg_alloc_table(sg, 1, GFP_KERNEL);
else
ret = sg_alloc_table(sg, alloc->nr_pages, GFP_KERNEL);
if (ret) {
mutex_unlock(&alloc->lock);
mutex_unlock(&attachment->dmabuf->lock);
kfree(sg);
return ERR_PTR(ret);
}
if (alloc->contiguous) {
sg_dma_len(sg->sgl) = alloc->nr_pages * PAGE_SIZE;
sg_set_page(sg->sgl, pfn_to_page(PFN_DOWN(alloc->contig_dma_addr)),
alloc->nr_pages * PAGE_SIZE, 0);
sg_set_page(sg->sgl, pfn_to_page(PFN_DOWN(alloc->contig_dma_addr)), alloc->nr_pages * PAGE_SIZE, 0);
sg_dma_address(sg->sgl) = alloc->contig_dma_addr;
} else {
for_each_sg(sg->sgl, iter, alloc->nr_pages, i)
@@ -183,7 +167,7 @@ static struct sg_table *dma_buf_te_map(struct dma_buf_attachment *attachment,
}
if (!dma_map_sg(attachment->dev, sg->sgl, sg->nents, direction)) {
mutex_unlock(&alloc->lock);
mutex_unlock(&attachment->dmabuf->lock);
sg_free_table(sg);
kfree(sg);
return ERR_PTR(-ENOMEM);
@@ -192,26 +176,26 @@ static struct sg_table *dma_buf_te_map(struct dma_buf_attachment *attachment,
alloc->nr_device_mappings++;
pa->attachment_mapped = true;
pa->sg = sg;
mutex_unlock(&alloc->lock);
mutex_unlock(&attachment->dmabuf->lock);
return sg;
}
static void dma_buf_te_unmap(struct dma_buf_attachment *attachment, struct sg_table *sg,
enum dma_data_direction direction)
static void dma_buf_te_unmap(struct dma_buf_attachment *attachment,
struct sg_table *sg, enum dma_data_direction direction)
{
struct dma_buf_te_alloc *alloc;
struct dma_buf_te_attachment *pa = attachment->priv;
alloc = attachment->dmabuf->priv;
mutex_lock(&alloc->lock);
mutex_lock(&attachment->dmabuf->lock);
WARN(!pa->attachment_mapped, "WARNING: Unmatched unmap of attachment.");
alloc->nr_device_mappings--;
pa->attachment_mapped = false;
pa->sg = NULL;
mutex_unlock(&alloc->lock);
mutex_unlock(&attachment->dmabuf->lock);
dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, direction);
sg_free_table(sg);
@@ -225,12 +209,13 @@ static void dma_buf_te_release(struct dma_buf *buf)
alloc = buf->priv;
/* no need for locking */
mutex_destroy(&alloc->lock);
if (alloc->contiguous) {
dma_free_attrs(te_device.this_device, alloc->nr_pages * PAGE_SIZE,
alloc->contig_cpu_addr, alloc->contig_dma_addr,
DMA_ATTR_WRITE_COMBINE);
dma_free_attrs(te_device.this_device,
alloc->nr_pages * PAGE_SIZE,
alloc->contig_cpu_addr,
alloc->contig_dma_addr,
DMA_ATTR_WRITE_COMBINE);
} else {
for (i = 0; i < alloc->nr_pages; i++)
__free_page(alloc->pages[i]);
@@ -243,62 +228,46 @@ static void dma_buf_te_release(struct dma_buf *buf)
kfree(alloc);
}
static int dma_buf_te_sync(struct dma_buf *dmabuf, enum dma_data_direction direction,
bool start_cpu_access)
static int dma_buf_te_sync(struct dma_buf *dmabuf,
enum dma_data_direction direction,
bool start_cpu_access)
{
struct dma_buf_attachment *attachment;
struct dma_buf_te_alloc *alloc = dmabuf->priv;
/* Use the kernel lock to prevent the concurrent update of dmabuf->attachments */
#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE
dma_resv_lock(dmabuf->resv, NULL);
#else
mutex_lock(&dmabuf->lock);
#endif
/* Use the internal lock to block the concurrent attach/detach calls */
mutex_lock(&alloc->lock);
list_for_each_entry(attachment, &dmabuf->attachments, node) {
struct dma_buf_te_attachment *pa = attachment->priv;
struct sg_table *sg = pa->sg;
if (!sg) {
dev_dbg(te_device.this_device, "no mapping for device %s\n",
dev_name(attachment->dev));
dev_dbg(te_device.this_device, "no mapping for device %s\n", dev_name(attachment->dev));
continue;
}
if (start_cpu_access) {
dev_dbg(te_device.this_device, "sync cpu with device %s\n",
dev_name(attachment->dev));
dev_dbg(te_device.this_device, "sync cpu with device %s\n", dev_name(attachment->dev));
dma_sync_sg_for_cpu(attachment->dev, sg->sgl, sg->nents, direction);
} else {
dev_dbg(te_device.this_device, "sync device %s with cpu\n",
dev_name(attachment->dev));
dev_dbg(te_device.this_device, "sync device %s with cpu\n", dev_name(attachment->dev));
dma_sync_sg_for_device(attachment->dev, sg->sgl, sg->nents, direction);
}
}
mutex_unlock(&alloc->lock);
#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE
dma_resv_unlock(dmabuf->resv);
#else
mutex_unlock(&dmabuf->lock);
#endif
return 0;
}
static int dma_buf_te_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction)
static int dma_buf_te_begin_cpu_access(struct dma_buf *dmabuf,
enum dma_data_direction direction)
{
return dma_buf_te_sync(dmabuf, direction, true);
}
static int dma_buf_te_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction)
static int dma_buf_te_end_cpu_access(struct dma_buf *dmabuf,
enum dma_data_direction direction)
{
return dma_buf_te_sync(dmabuf, direction, false);
}
@@ -311,9 +280,9 @@ static void dma_buf_te_mmap_open(struct vm_area_struct *vma)
dma_buf = vma->vm_private_data;
alloc = dma_buf->priv;
mutex_lock(&alloc->lock);
mutex_lock(&dma_buf->lock);
alloc->nr_cpu_mappings++;
mutex_unlock(&alloc->lock);
mutex_unlock(&dma_buf->lock);
}
static void dma_buf_te_mmap_close(struct vm_area_struct *vma)
@@ -324,10 +293,10 @@ static void dma_buf_te_mmap_close(struct vm_area_struct *vma)
dma_buf = vma->vm_private_data;
alloc = dma_buf->priv;
mutex_lock(&alloc->lock);
BUG_ON(alloc->nr_cpu_mappings <= 0);
mutex_lock(&dma_buf->lock);
alloc->nr_cpu_mappings--;
mutex_unlock(&alloc->lock);
mutex_unlock(&dma_buf->lock);
}
#if KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE
@@ -362,9 +331,11 @@ static vm_fault_t dma_buf_te_mmap_fault(struct vm_fault *vmf)
return 0;
}
static const struct vm_operations_struct dma_buf_te_vm_ops = { .open = dma_buf_te_mmap_open,
.close = dma_buf_te_mmap_close,
.fault = dma_buf_te_mmap_fault };
static const struct vm_operations_struct dma_buf_te_vm_ops = {
.open = dma_buf_te_mmap_open,
.close = dma_buf_te_mmap_close,
.fault = dma_buf_te_mmap_fault
};
static int dma_buf_te_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
{
@@ -375,7 +346,7 @@ static int dma_buf_te_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
if (alloc->fail_mmap)
return -ENOMEM;
vm_flags_set(vma, VM_IO | VM_DONTEXPAND | VM_DONTDUMP);
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_ops = &dma_buf_te_vm_ops;
vma->vm_private_data = dmabuf;
@@ -403,9 +374,10 @@ static void *dma_buf_te_kmap(struct dma_buf *buf, unsigned long page_num)
if (page_num >= alloc->nr_pages)
return NULL;
return kbase_kmap(alloc->pages[page_num]);
return kmap(alloc->pages[page_num]);
}
static void dma_buf_te_kunmap(struct dma_buf *buf, unsigned long page_num, void *addr)
static void dma_buf_te_kunmap(struct dma_buf *buf,
unsigned long page_num, void *addr)
{
struct dma_buf_te_alloc *alloc;
@@ -413,7 +385,7 @@ static void dma_buf_te_kunmap(struct dma_buf *buf, unsigned long page_num, void
if (page_num >= alloc->nr_pages)
return;
kbase_kunmap(alloc->pages[page_num], addr);
kunmap(alloc->pages[page_num]);
}
static struct dma_buf_ops dma_buf_te_ops = {
@@ -495,9 +467,8 @@ static int do_dma_buf_te_ioctl_alloc(struct dma_buf_te_ioctl_alloc __user *buf,
#endif /* NO_SG_CHAIN */
if (alloc_req.size > max_nr_pages) {
dev_err(te_device.this_device,
"%s: buffer size of %llu pages exceeded the mapping limit of %zu pages",
__func__, alloc_req.size, max_nr_pages);
dev_err(te_device.this_device, "%s: buffer size of %llu pages exceeded the mapping limit of %zu pages",
__func__, alloc_req.size, max_nr_pages);
goto invalid_size;
}
@@ -517,21 +488,23 @@ static int do_dma_buf_te_ioctl_alloc(struct dma_buf_te_ioctl_alloc __user *buf,
#endif
if (!alloc->pages) {
dev_err(te_device.this_device, "%s: couldn't alloc %zu page structures", __func__,
alloc->nr_pages);
dev_err(te_device.this_device,
"%s: couldn't alloc %zu page structures",
__func__, alloc->nr_pages);
goto free_alloc_object;
}
if (contiguous) {
dma_addr_t dma_aux;
alloc->contig_cpu_addr = dma_alloc_attrs(
te_device.this_device, alloc->nr_pages * PAGE_SIZE, &alloc->contig_dma_addr,
GFP_KERNEL | __GFP_ZERO, DMA_ATTR_WRITE_COMBINE);
alloc->contig_cpu_addr = dma_alloc_attrs(te_device.this_device,
alloc->nr_pages * PAGE_SIZE,
&alloc->contig_dma_addr,
GFP_KERNEL | __GFP_ZERO,
DMA_ATTR_WRITE_COMBINE);
if (!alloc->contig_cpu_addr) {
dev_err(te_device.this_device,
"%s: couldn't alloc contiguous buffer %zu pages", __func__,
alloc->nr_pages);
dev_err(te_device.this_device, "%s: couldn't alloc contiguous buffer %zu pages",
__func__, alloc->nr_pages);
goto free_page_struct;
}
dma_aux = alloc->contig_dma_addr;
@@ -549,8 +522,6 @@ static int do_dma_buf_te_ioctl_alloc(struct dma_buf_te_ioctl_alloc __user *buf,
}
}
mutex_init(&alloc->lock);
/* alloc ready, let's export it */
{
struct dma_buf_export_info export_info = {
@@ -584,12 +555,13 @@ no_fd:
dma_buf_put(dma_buf);
no_export:
/* i still valid */
mutex_destroy(&alloc->lock);
no_page:
if (contiguous) {
dma_free_attrs(te_device.this_device, alloc->nr_pages * PAGE_SIZE,
alloc->contig_cpu_addr, alloc->contig_dma_addr,
DMA_ATTR_WRITE_COMBINE);
dma_free_attrs(te_device.this_device,
alloc->nr_pages * PAGE_SIZE,
alloc->contig_cpu_addr,
alloc->contig_dma_addr,
DMA_ATTR_WRITE_COMBINE);
} else {
while (i-- > 0)
__free_page(alloc->pages[i]);
@@ -630,11 +602,11 @@ static int do_dma_buf_te_ioctl_status(struct dma_buf_te_ioctl_status __user *arg
alloc = dmabuf->priv;
/* lock while reading status to take a snapshot */
mutex_lock(&alloc->lock);
mutex_lock(&dmabuf->lock);
status.attached_devices = alloc->nr_attached_devices;
status.device_mappings = alloc->nr_device_mappings;
status.cpu_mappings = alloc->nr_cpu_mappings;
mutex_unlock(&alloc->lock);
mutex_unlock(&dmabuf->lock);
if (copy_to_user(arg, &status, sizeof(status)))
goto err_have_dmabuf;
@@ -668,11 +640,11 @@ static int do_dma_buf_te_ioctl_set_failing(struct dma_buf_te_ioctl_set_failing _
/* ours, set the fail modes */
alloc = dmabuf->priv;
/* lock to set the fail modes atomically */
mutex_lock(&alloc->lock);
mutex_lock(&dmabuf->lock);
alloc->fail_attach = f.fail_attach;
alloc->fail_map = f.fail_map;
alloc->fail_mmap = f.fail_mmap;
mutex_unlock(&alloc->lock);
alloc->fail_map = f.fail_map;
alloc->fail_mmap = f.fail_mmap;
mutex_unlock(&dmabuf->lock);
/* success */
res = 0;
@@ -737,6 +709,7 @@ no_import:
static int do_dma_buf_te_ioctl_fill(struct dma_buf_te_ioctl_fill __user *arg)
{
struct dma_buf *dmabuf;
struct dma_buf_te_ioctl_fill f;
int ret;
@@ -756,21 +729,17 @@ static int do_dma_buf_te_ioctl_fill(struct dma_buf_te_ioctl_fill __user *arg)
static long dma_buf_te_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
CSTD_UNUSED(file);
switch (cmd) {
case DMA_BUF_TE_VERSION:
return do_dma_buf_te_ioctl_version((struct dma_buf_te_ioctl_version __user *)arg);
case DMA_BUF_TE_ALLOC:
return do_dma_buf_te_ioctl_alloc((struct dma_buf_te_ioctl_alloc __user *)arg,
false);
return do_dma_buf_te_ioctl_alloc((struct dma_buf_te_ioctl_alloc __user *)arg, false);
case DMA_BUF_TE_ALLOC_CONT:
return do_dma_buf_te_ioctl_alloc((struct dma_buf_te_ioctl_alloc __user *)arg, true);
case DMA_BUF_TE_QUERY:
return do_dma_buf_te_ioctl_status((struct dma_buf_te_ioctl_status __user *)arg);
case DMA_BUF_TE_SET_FAILING:
return do_dma_buf_te_ioctl_set_failing(
(struct dma_buf_te_ioctl_set_failing __user *)arg);
return do_dma_buf_te_ioctl_set_failing((struct dma_buf_te_ioctl_set_failing __user *)arg);
case DMA_BUF_TE_FILL:
return do_dma_buf_te_ioctl_fill((struct dma_buf_te_ioctl_fill __user *)arg);
default:
@@ -801,6 +770,7 @@ static int __init dma_buf_te_init(void)
dev_info(te_device.this_device, "dma_buf_te ready\n");
return 0;
}
static void __exit dma_buf_te_exit(void)

View File

@@ -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-2022 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
@@ -32,13 +32,15 @@
#include <linux/mm.h>
#include <linux/memory_group_manager.h>
#ifndef CSTD_UNUSED
#define CSTD_UNUSED(x) ((void)(x))
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
#undef DEFINE_SIMPLE_ATTRIBUTE
#define DEFINE_SIMPLE_ATTRIBUTE DEFINE_DEBUGFS_ATTRIBUTE
#define debugfs_create_file debugfs_create_file_unsafe
#endif
#if (KERNEL_VERSION(4, 20, 0) > LINUX_VERSION_CODE)
static inline vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr,
unsigned long pfn, pgprot_t pgprot)
static inline vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma,
unsigned long addr, unsigned long pfn, pgprot_t pgprot)
{
int err = vm_insert_pfn_prot(vma, addr, pfn, pgprot);
@@ -70,10 +72,10 @@ static inline vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigne
* debugfs. Display is organized per group with small and large sized pages.
*/
struct mgm_group {
atomic_t size;
atomic_t lp_size;
atomic_t insert_pfn;
atomic_t update_gpu_pte;
size_t size;
size_t lp_size;
size_t insert_pfn;
size_t update_gpu_pte;
};
/**
@@ -100,7 +102,7 @@ static int mgm_size_get(void *data, u64 *val)
{
struct mgm_group *group = data;
*val = atomic_read(&group->size);
*val = group->size;
return 0;
}
@@ -108,21 +110,27 @@ static int mgm_size_get(void *data, u64 *val)
static int mgm_lp_size_get(void *data, u64 *val)
{
struct mgm_group *group = data;
*val = atomic_read(&group->lp_size);
*val = group->lp_size;
return 0;
}
static int mgm_insert_pfn_get(void *data, u64 *val)
{
struct mgm_group *group = data;
*val = atomic_read(&group->insert_pfn);
*val = group->insert_pfn;
return 0;
}
static int mgm_update_gpu_pte_get(void *data, u64 *val)
{
struct mgm_group *group = data;
*val = atomic_read(&group->update_gpu_pte);
*val = group->update_gpu_pte;
return 0;
}
@@ -146,7 +154,8 @@ static int mgm_initialize_debugfs(struct mgm_groups *mgm_data)
/*
* Create root directory of memory-group-manager
*/
mgm_data->mgm_debugfs_root = debugfs_create_dir("physical-memory-group-manager", NULL);
mgm_data->mgm_debugfs_root =
debugfs_create_dir("physical-memory-group-manager", NULL);
if (IS_ERR_OR_NULL(mgm_data->mgm_debugfs_root)) {
dev_err(mgm_data->dev, "fail to create debugfs root directory\n");
return -ENODEV;
@@ -156,37 +165,43 @@ static int mgm_initialize_debugfs(struct mgm_groups *mgm_data)
* Create debugfs files per group
*/
for (i = 0; i < MEMORY_GROUP_MANAGER_NR_GROUPS; i++) {
scnprintf(debugfs_group_name, MGM_DEBUGFS_GROUP_NAME_MAX, "group_%d", i);
g = debugfs_create_dir(debugfs_group_name, mgm_data->mgm_debugfs_root);
scnprintf(debugfs_group_name, MGM_DEBUGFS_GROUP_NAME_MAX,
"group_%d", i);
g = debugfs_create_dir(debugfs_group_name,
mgm_data->mgm_debugfs_root);
if (IS_ERR_OR_NULL(g)) {
dev_err(mgm_data->dev, "fail to create group[%d]\n", i);
goto remove_debugfs;
}
e = debugfs_create_file("size", 0444, g, &mgm_data->groups[i], &fops_mgm_size);
e = debugfs_create_file("size", 0444, g, &mgm_data->groups[i],
&fops_mgm_size);
if (IS_ERR_OR_NULL(e)) {
dev_err(mgm_data->dev, "fail to create size[%d]\n", i);
goto remove_debugfs;
}
e = debugfs_create_file("lp_size", 0444, g, &mgm_data->groups[i],
&fops_mgm_lp_size);
e = debugfs_create_file("lp_size", 0444, g,
&mgm_data->groups[i], &fops_mgm_lp_size);
if (IS_ERR_OR_NULL(e)) {
dev_err(mgm_data->dev, "fail to create lp_size[%d]\n", i);
dev_err(mgm_data->dev,
"fail to create lp_size[%d]\n", i);
goto remove_debugfs;
}
e = debugfs_create_file("insert_pfn", 0444, g, &mgm_data->groups[i],
&fops_mgm_insert_pfn);
e = debugfs_create_file("insert_pfn", 0444, g,
&mgm_data->groups[i], &fops_mgm_insert_pfn);
if (IS_ERR_OR_NULL(e)) {
dev_err(mgm_data->dev, "fail to create insert_pfn[%d]\n", i);
dev_err(mgm_data->dev,
"fail to create insert_pfn[%d]\n", i);
goto remove_debugfs;
}
e = debugfs_create_file("update_gpu_pte", 0444, g, &mgm_data->groups[i],
&fops_mgm_update_gpu_pte);
e = debugfs_create_file("update_gpu_pte", 0444, g,
&mgm_data->groups[i], &fops_mgm_update_gpu_pte);
if (IS_ERR_OR_NULL(e)) {
dev_err(mgm_data->dev, "fail to create update_gpu_pte[%d]\n", i);
dev_err(mgm_data->dev,
"fail to create update_gpu_pte[%d]\n", i);
goto remove_debugfs;
}
}
@@ -221,30 +236,31 @@ static void update_size(struct memory_group_manager_device *mgm_dev, unsigned in
switch (order) {
case ORDER_SMALL_PAGE:
if (alloc)
atomic_inc(&data->groups[group_id].size);
data->groups[group_id].size++;
else {
WARN_ON(atomic_read(&data->groups[group_id].size) == 0);
atomic_dec(&data->groups[group_id].size);
WARN_ON(data->groups[group_id].size == 0);
data->groups[group_id].size--;
}
break;
break;
case ORDER_LARGE_PAGE:
if (alloc)
atomic_inc(&data->groups[group_id].lp_size);
data->groups[group_id].lp_size++;
else {
WARN_ON(atomic_read(&data->groups[group_id].lp_size) == 0);
atomic_dec(&data->groups[group_id].lp_size);
WARN_ON(data->groups[group_id].lp_size == 0);
data->groups[group_id].lp_size--;
}
break;
break;
default:
dev_err(data->dev, "Unknown order(%d)\n", order);
break;
break;
}
}
static struct page *example_mgm_alloc_page(struct memory_group_manager_device *mgm_dev,
int group_id, gfp_t gfp_mask, unsigned int order)
static struct page *example_mgm_alloc_page(
struct memory_group_manager_device *mgm_dev, int group_id,
gfp_t gfp_mask, unsigned int order)
{
struct mgm_groups *const data = mgm_dev->data;
struct page *p;
@@ -252,7 +268,8 @@ static struct page *example_mgm_alloc_page(struct memory_group_manager_device *m
dev_dbg(data->dev, "%s(mgm_dev=%pK, group_id=%d gfp_mask=0x%x order=%u\n", __func__,
(void *)mgm_dev, group_id, gfp_mask, order);
if (WARN_ON(group_id < 0) || WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
if (WARN_ON(group_id < 0) ||
WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
return NULL;
p = alloc_pages(gfp_mask, order);
@@ -268,15 +285,17 @@ static struct page *example_mgm_alloc_page(struct memory_group_manager_device *m
return p;
}
static void example_mgm_free_page(struct memory_group_manager_device *mgm_dev, int group_id,
struct page *page, unsigned int order)
static void example_mgm_free_page(
struct memory_group_manager_device *mgm_dev, int group_id,
struct page *page, unsigned int order)
{
struct mgm_groups *const data = mgm_dev->data;
dev_dbg(data->dev, "%s(mgm_dev=%pK, group_id=%d page=%pK order=%u\n", __func__,
(void *)mgm_dev, group_id, (void *)page, order);
if (WARN_ON(group_id < 0) || WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
if (WARN_ON(group_id < 0) ||
WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
return;
__free_pages(page, order);
@@ -284,8 +303,9 @@ static void example_mgm_free_page(struct memory_group_manager_device *mgm_dev, i
update_size(mgm_dev, group_id, order, false);
}
static int example_mgm_get_import_memory_id(struct memory_group_manager_device *mgm_dev,
struct memory_group_manager_import_data *import_data)
static int example_mgm_get_import_memory_id(
struct memory_group_manager_device *mgm_dev,
struct memory_group_manager_import_data *import_data)
{
struct mgm_groups *const data = mgm_dev->data;
@@ -295,21 +315,24 @@ static int example_mgm_get_import_memory_id(struct memory_group_manager_device *
if (!WARN_ON(!import_data)) {
WARN_ON(!import_data->u.dma_buf);
WARN_ON(import_data->type != MEMORY_GROUP_MANAGER_IMPORT_TYPE_DMA_BUF);
WARN_ON(import_data->type !=
MEMORY_GROUP_MANAGER_IMPORT_TYPE_DMA_BUF);
}
return IMPORTED_MEMORY_ID;
}
static u64 example_mgm_update_gpu_pte(struct memory_group_manager_device *const mgm_dev,
int const group_id, int const mmu_level, u64 pte)
static u64 example_mgm_update_gpu_pte(
struct memory_group_manager_device *const mgm_dev, int const group_id,
int const mmu_level, u64 pte)
{
struct mgm_groups *const data = mgm_dev->data;
dev_dbg(data->dev, "%s(mgm_dev=%pK, group_id=%d, mmu_level=%d, pte=0x%llx)\n", __func__,
(void *)mgm_dev, group_id, mmu_level, pte);
if (WARN_ON(group_id < 0) || WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
if (WARN_ON(group_id < 0) ||
WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
return pte;
pte |= ((u64)group_id << PTE_PBHA_SHIFT) & PTE_PBHA_MASK;
@@ -317,7 +340,7 @@ static u64 example_mgm_update_gpu_pte(struct memory_group_manager_device *const
/* Address could be translated into a different bus address here */
pte |= ((u64)1 << PTE_RES_BIT_MULTI_AS_SHIFT);
atomic_inc(&data->groups[group_id].update_gpu_pte);
data->groups[group_id].update_gpu_pte++;
return pte;
}
@@ -325,10 +348,6 @@ static u64 example_mgm_update_gpu_pte(struct memory_group_manager_device *const
static u64 example_mgm_pte_to_original_pte(struct memory_group_manager_device *const mgm_dev,
int const group_id, int const mmu_level, u64 pte)
{
CSTD_UNUSED(mgm_dev);
CSTD_UNUSED(group_id);
CSTD_UNUSED(mmu_level);
/* Undo the group ID modification */
pte &= ~PTE_PBHA_MASK;
/* Undo the bit set */
@@ -337,11 +356,10 @@ static u64 example_mgm_pte_to_original_pte(struct memory_group_manager_device *c
return pte;
}
static vm_fault_t example_mgm_vmf_insert_pfn_prot(struct memory_group_manager_device *const mgm_dev,
int const group_id,
struct vm_area_struct *const vma,
unsigned long const addr, unsigned long const pfn,
pgprot_t const prot)
static vm_fault_t example_mgm_vmf_insert_pfn_prot(
struct memory_group_manager_device *const mgm_dev, int const group_id,
struct vm_area_struct *const vma, unsigned long const addr,
unsigned long const pfn, pgprot_t const prot)
{
struct mgm_groups *const data = mgm_dev->data;
vm_fault_t fault;
@@ -351,13 +369,14 @@ static vm_fault_t example_mgm_vmf_insert_pfn_prot(struct memory_group_manager_de
__func__, (void *)mgm_dev, group_id, (void *)vma, addr, pfn,
(unsigned long long)pgprot_val(prot));
if (WARN_ON(group_id < 0) || WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
if (WARN_ON(group_id < 0) ||
WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
return VM_FAULT_SIGBUS;
fault = vmf_insert_pfn_prot(vma, addr, pfn, prot);
if (fault == VM_FAULT_NOPAGE)
atomic_inc(&data->groups[group_id].insert_pfn);
data->groups[group_id].insert_pfn++;
else
dev_err(data->dev, "vmf_insert_pfn_prot failed\n");
@@ -369,10 +388,10 @@ static int mgm_initialize_data(struct mgm_groups *mgm_data)
int i;
for (i = 0; i < MEMORY_GROUP_MANAGER_NR_GROUPS; i++) {
atomic_set(&mgm_data->groups[i].size, 0);
atomic_set(&mgm_data->groups[i].lp_size, 0);
atomic_set(&mgm_data->groups[i].insert_pfn, 0);
atomic_set(&mgm_data->groups[i].update_gpu_pte, 0);
mgm_data->groups[i].size = 0;
mgm_data->groups[i].lp_size = 0;
mgm_data->groups[i].insert_pfn = 0;
mgm_data->groups[i].update_gpu_pte = 0;
}
return mgm_initialize_debugfs(mgm_data);
@@ -383,12 +402,14 @@ static void mgm_term_data(struct mgm_groups *data)
int i;
for (i = 0; i < MEMORY_GROUP_MANAGER_NR_GROUPS; i++) {
if (atomic_read(&data->groups[i].size) != 0)
dev_warn(data->dev, "%d 0-order pages in group(%d) leaked\n",
atomic_read(&data->groups[i].size), i);
if (atomic_read(&data->groups[i].lp_size) != 0)
dev_warn(data->dev, "%d 9 order pages in group(%d) leaked\n",
atomic_read(&data->groups[i].lp_size), i);
if (data->groups[i].size != 0)
dev_warn(data->dev,
"%zu 0-order pages in group(%d) leaked\n",
data->groups[i].size, i);
if (data->groups[i].lp_size != 0)
dev_warn(data->dev,
"%zu 9 order pages in group(%d) leaked\n",
data->groups[i].lp_size, i);
}
mgm_term_debugfs(data);
@@ -406,7 +427,8 @@ static int memory_group_manager_probe(struct platform_device *pdev)
mgm_dev->owner = THIS_MODULE;
mgm_dev->ops.mgm_alloc_page = example_mgm_alloc_page;
mgm_dev->ops.mgm_free_page = example_mgm_free_page;
mgm_dev->ops.mgm_get_import_memory_id = example_mgm_get_import_memory_id;
mgm_dev->ops.mgm_get_import_memory_id =
example_mgm_get_import_memory_id;
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;
@@ -434,7 +456,8 @@ static int memory_group_manager_probe(struct platform_device *pdev)
static int memory_group_manager_remove(struct platform_device *pdev)
{
struct memory_group_manager_device *mgm_dev = platform_get_drvdata(pdev);
struct memory_group_manager_device *mgm_dev =
platform_get_drvdata(pdev);
struct mgm_groups *mgm_data = mgm_dev->data;
mgm_term_data(mgm_data);
@@ -453,20 +476,20 @@ static const struct of_device_id memory_group_manager_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, memory_group_manager_dt_ids);
static struct platform_driver
memory_group_manager_driver = { .probe = memory_group_manager_probe,
.remove = memory_group_manager_remove,
.driver = {
.name = "physical-memory-group-manager",
.of_match_table =
of_match_ptr(memory_group_manager_dt_ids),
/*
static struct platform_driver memory_group_manager_driver = {
.probe = memory_group_manager_probe,
.remove = memory_group_manager_remove,
.driver = {
.name = "physical-memory-group-manager",
.of_match_table = of_match_ptr(memory_group_manager_dt_ids),
/*
* Prevent the mgm_dev from being unbound and freed, as other's
* may have pointers to it and would get confused, or crash, if
* it suddenly disappear.
*/
.suppress_bind_attrs = true,
} };
.suppress_bind_attrs = true,
}
};
module_platform_driver(memory_group_manager_driver);

View File

@@ -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-2021 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
@@ -45,7 +45,7 @@
* @dev: Device pointer
* @allocated_pages_bitfield_arr: Status of all the physical memory pages within the
* protected memory region, one bit per page
* @rmem_base: Base physical address of the reserved memory region
* @rmem_base: Base address of the reserved memory region
* @rmem_size: Size of the reserved memory region, in pages
* @num_free_pages: Number of free pages in the memory region
* @rmem_lock: Lock to serialize the allocation and freeing of
@@ -68,9 +68,9 @@ struct simple_pma_device {
* PAGES_PER_BITFIELD_ELEM, adds an extra page for the remainder.
* @num_pages: number of pages
*/
#define ALLOC_PAGES_BITFIELD_ARR_SIZE(num_pages) \
((PAGES_PER_BITFIELD_ELEM * (0 != (num_pages % PAGES_PER_BITFIELD_ELEM)) + num_pages) / \
PAGES_PER_BITFIELD_ELEM)
#define ALLOC_PAGES_BITFIELD_ARR_SIZE(num_pages) \
((PAGES_PER_BITFIELD_ELEM * (0 != (num_pages % PAGES_PER_BITFIELD_ELEM)) + \
num_pages) / PAGES_PER_BITFIELD_ELEM)
/**
* small_granularity_alloc() - Allocate 1-32 power-of-two pages.
@@ -90,7 +90,8 @@ struct simple_pma_device {
* It can be thought of as the 'small-granularity' allocator.
*/
static void small_granularity_alloc(struct simple_pma_device *const epma_dev,
size_t alloc_bitfield_idx, size_t start_bit, size_t order,
size_t alloc_bitfield_idx, size_t start_bit,
size_t order,
struct protected_memory_allocation *pma)
{
size_t i;
@@ -98,26 +99,28 @@ static void small_granularity_alloc(struct simple_pma_device *const epma_dev,
u64 *bitfield;
size_t alloc_pages_bitfield_size;
if (WARN_ON(!epma_dev) || WARN_ON(!pma))
if (WARN_ON(!epma_dev) ||
WARN_ON(!pma))
return;
WARN(epma_dev->rmem_size == 0, "%s: rmem_size is 0", __func__);
alloc_pages_bitfield_size = ALLOC_PAGES_BITFIELD_ARR_SIZE(epma_dev->rmem_size);
WARN(alloc_bitfield_idx >= alloc_pages_bitfield_size, "%s: idx>bf_size: %zu %zu", __func__,
WARN(alloc_bitfield_idx >= alloc_pages_bitfield_size,
"%s: idx>bf_size: %zu %zu", __func__,
alloc_bitfield_idx, alloc_pages_bitfield_size);
WARN((start_bit + (1ULL << order)) > PAGES_PER_BITFIELD_ELEM,
"%s: start=%zu order=%zu ppbe=%zu", __func__, start_bit, order,
PAGES_PER_BITFIELD_ELEM);
WARN((start_bit + (1 << order)) > PAGES_PER_BITFIELD_ELEM,
"%s: start=%zu order=%zu ppbe=%zu",
__func__, start_bit, order, PAGES_PER_BITFIELD_ELEM);
bitfield = &epma_dev->allocated_pages_bitfield_arr[alloc_bitfield_idx];
for (i = 0; i < (1ULL << order); i++) {
for (i = 0; i < (1 << order); i++) {
/* Check the pages represented by this bit are actually free */
WARN(*bitfield & (1ULL << (start_bit + i)),
"in %s: page not free: %zu %zu %.16llx %zu\n", __func__, i, order, *bitfield,
alloc_pages_bitfield_size);
"in %s: page not free: %zu %zu %.16llx %zu\n",
__func__, i, order, *bitfield, alloc_pages_bitfield_size);
/* Mark the pages as now allocated */
*bitfield |= (1ULL << (start_bit + i));
@@ -149,7 +152,8 @@ static void small_granularity_alloc(struct simple_pma_device *const epma_dev,
* as the 'large-granularity' allocator.
*/
static void large_granularity_alloc(struct simple_pma_device *const epma_dev,
size_t start_alloc_bitfield_idx, size_t order,
size_t start_alloc_bitfield_idx,
size_t order,
struct protected_memory_allocation *pma)
{
size_t i;
@@ -157,7 +161,8 @@ static void large_granularity_alloc(struct simple_pma_device *const epma_dev,
size_t num_bitfield_elements_needed = num_pages_to_alloc / PAGES_PER_BITFIELD_ELEM;
size_t start_page_idx = start_alloc_bitfield_idx * PAGES_PER_BITFIELD_ELEM;
if (WARN_ON(!epma_dev) || WARN_ON(!pma))
if (WARN_ON(!epma_dev) ||
WARN_ON(!pma))
return;
/*
@@ -165,30 +170,29 @@ static void large_granularity_alloc(struct simple_pma_device *const epma_dev,
* between the start element and the end of the bitfield array
* to fulfill the request?
*/
WARN((start_alloc_bitfield_idx + order) >=
ALLOC_PAGES_BITFIELD_ARR_SIZE(epma_dev->rmem_size),
"%s: start=%zu order=%zu ms=%zu", __func__, start_alloc_bitfield_idx, order,
epma_dev->rmem_size);
WARN((start_alloc_bitfield_idx + order) >= ALLOC_PAGES_BITFIELD_ARR_SIZE(epma_dev->rmem_size),
"%s: start=%zu order=%zu ms=%zu",
__func__, start_alloc_bitfield_idx, order, epma_dev->rmem_size);
for (i = 0; i < num_bitfield_elements_needed; i++) {
u64 *bitfield =
&epma_dev->allocated_pages_bitfield_arr[start_alloc_bitfield_idx + i];
u64 *bitfield = &epma_dev->allocated_pages_bitfield_arr[start_alloc_bitfield_idx + i];
/* We expect all pages that relate to this bitfield element to be free */
WARN((*bitfield != 0), "in %s: pages not free: i=%zu o=%zu bf=%.16llx\n", __func__,
i, order, *bitfield);
WARN((*bitfield != 0),
"in %s: pages not free: i=%zu o=%zu bf=%.16llx\n",
__func__, i, order, *bitfield);
/* Mark all the pages for this element as not free */
*bitfield = ~0ULL;
}
/* Fill-in the allocation struct for the caller */
pma->pa = epma_dev->rmem_base + (start_page_idx << PAGE_SHIFT);
pma->pa = epma_dev->rmem_base + (start_page_idx << PAGE_SHIFT);
pma->order = order;
}
static struct protected_memory_allocation *
simple_pma_alloc_page(struct protected_memory_allocator_device *pma_dev, unsigned int order)
static struct protected_memory_allocation *simple_pma_alloc_page(
struct protected_memory_allocator_device *pma_dev, unsigned int order)
{
struct simple_pma_device *const epma_dev =
container_of(pma_dev, struct simple_pma_device, pma_dev);
@@ -200,7 +204,8 @@ simple_pma_alloc_page(struct protected_memory_allocator_device *pma_dev, unsigne
size_t bit;
size_t count;
dev_dbg(epma_dev->dev, "%s(pma_dev=%px, order=%u\n", __func__, (void *)pma_dev, order);
dev_dbg(epma_dev->dev, "%s(pma_dev=%px, order=%u\n",
__func__, (void *)pma_dev, order);
/* This is an example function that follows an extremely simple logic
* and is very likely to fail to allocate memory if put under stress.
@@ -255,18 +260,22 @@ simple_pma_alloc_page(struct protected_memory_allocator_device *pma_dev, unsigne
count = 0;
for (bit = 0; bit < PAGES_PER_BITFIELD_ELEM; bit++) {
if (0 == (bitfields[i] & (1ULL << bit))) {
if (0 == (bitfields[i] & (1ULL << bit))) {
if ((count + 1) >= num_pages_to_alloc) {
/*
* We've found enough free, consecutive pages with which to
* make an allocation
*/
small_granularity_alloc(epma_dev, i, bit - count,
order, pma);
small_granularity_alloc(
epma_dev, i,
bit - count, order,
pma);
epma_dev->num_free_pages -= num_pages_to_alloc;
epma_dev->num_free_pages -=
num_pages_to_alloc;
spin_unlock(&epma_dev->rmem_lock);
spin_unlock(
&epma_dev->rmem_lock);
return pma;
}
@@ -298,10 +307,12 @@ simple_pma_alloc_page(struct protected_memory_allocator_device *pma_dev, unsigne
if (bitfields[i] == 0) {
count += PAGES_PER_BITFIELD_ELEM;
if (count >= (1ULL << order)) {
if (count >= (1 << order)) {
size_t start_idx = (i + 1) - num_bitfield_elements_needed;
large_granularity_alloc(epma_dev, start_idx, order, pma);
large_granularity_alloc(epma_dev,
start_idx,
order, pma);
epma_dev->num_free_pages -= 1 << order;
spin_unlock(&epma_dev->rmem_lock);
@@ -316,26 +327,28 @@ simple_pma_alloc_page(struct protected_memory_allocator_device *pma_dev, unsigne
spin_unlock(&epma_dev->rmem_lock);
devm_kfree(epma_dev->dev, pma);
dev_err(epma_dev->dev,
"not enough contiguous pages (need %zu), total free pages left %zu\n",
dev_err(epma_dev->dev, "not enough contiguous pages (need %zu), total free pages left %zu\n",
num_pages_to_alloc, epma_dev->num_free_pages);
return NULL;
}
static phys_addr_t simple_pma_get_phys_addr(struct protected_memory_allocator_device *pma_dev,
struct protected_memory_allocation *pma)
static phys_addr_t simple_pma_get_phys_addr(
struct protected_memory_allocator_device *pma_dev,
struct protected_memory_allocation *pma)
{
struct simple_pma_device *const epma_dev =
container_of(pma_dev, struct simple_pma_device, pma_dev);
dev_dbg(epma_dev->dev, "%s(pma_dev=%px, pma=%px, pa=%pK\n", __func__, (void *)pma_dev,
(void *)pma, (void *)pma->pa);
dev_dbg(epma_dev->dev, "%s(pma_dev=%px, pma=%px, pa=%llx\n",
__func__, (void *)pma_dev, (void *)pma,
(unsigned long long)pma->pa);
return pma->pa;
}
static void simple_pma_free_page(struct protected_memory_allocator_device *pma_dev,
struct protected_memory_allocation *pma)
static void simple_pma_free_page(
struct protected_memory_allocator_device *pma_dev,
struct protected_memory_allocation *pma)
{
struct simple_pma_device *const epma_dev =
container_of(pma_dev, struct simple_pma_device, pma_dev);
@@ -351,8 +364,9 @@ static void simple_pma_free_page(struct protected_memory_allocator_device *pma_d
WARN_ON(pma == NULL);
dev_dbg(epma_dev->dev, "%s(pma_dev=%px, pma=%px, pa=%pK\n", __func__, (void *)pma_dev,
(void *)pma, (void *)pma->pa);
dev_dbg(epma_dev->dev, "%s(pma_dev=%px, pma=%px, pa=%llx\n",
__func__, (void *)pma_dev, (void *)pma,
(unsigned long long)pma->pa);
WARN_ON(pma->pa < epma_dev->rmem_base);
@@ -388,14 +402,14 @@ static void simple_pma_free_page(struct protected_memory_allocator_device *pma_d
*bitfield &= ~(((1ULL << num_pages_in_allocation) - 1) << bitfield_start_bit);
} else {
WARN(page_num % PAGES_PER_BITFIELD_ELEM,
"%s: Expecting allocs of order >= %d to be %zu-page aligned\n", __func__,
ORDER_OF_PAGES_PER_BITFIELD_ELEM, PAGES_PER_BITFIELD_ELEM);
"%s: Expecting allocs of order >= %d to be %zu-page aligned\n",
__func__, ORDER_OF_PAGES_PER_BITFIELD_ELEM, PAGES_PER_BITFIELD_ELEM);
for (i = 0; i < num_bitfield_elems_used_by_alloc; i++) {
bitfield = &epma_dev->allocated_pages_bitfield_arr[bitfield_idx + i];
/* We expect all bits to be set (all pages allocated) */
WARN((*bitfield != ~0ULL),
WARN((*bitfield != ~0),
"%s: alloc being freed is not fully allocated: of=%zu np=%zu bf=%.16llx\n",
__func__, offset, num_pages_in_allocation, *bitfield);
@@ -466,8 +480,8 @@ static int protected_memory_allocator_probe(struct platform_device *pdev)
alloc_bitmap_pages_arr_size = ALLOC_PAGES_BITFIELD_ARR_SIZE(epma_dev->rmem_size);
epma_dev->allocated_pages_bitfield_arr = devm_kzalloc(
&pdev->dev, alloc_bitmap_pages_arr_size * BITFIELD_ELEM_SIZE, GFP_KERNEL);
epma_dev->allocated_pages_bitfield_arr = devm_kzalloc(&pdev->dev,
alloc_bitmap_pages_arr_size * BITFIELD_ELEM_SIZE, GFP_KERNEL);
if (!epma_dev->allocated_pages_bitfield_arr) {
dev_err(&pdev->dev, "failed to allocate resources\n");
@@ -477,27 +491,31 @@ static int protected_memory_allocator_probe(struct platform_device *pdev)
if (epma_dev->rmem_size % PAGES_PER_BITFIELD_ELEM) {
size_t extra_pages =
alloc_bitmap_pages_arr_size * PAGES_PER_BITFIELD_ELEM - epma_dev->rmem_size;
alloc_bitmap_pages_arr_size * PAGES_PER_BITFIELD_ELEM -
epma_dev->rmem_size;
size_t last_bitfield_index = alloc_bitmap_pages_arr_size - 1;
/* Mark the extra pages (that lie outside the reserved range) as
* always in use.
*/
epma_dev->allocated_pages_bitfield_arr[last_bitfield_index] =
((1ULL << extra_pages) - 1) << (PAGES_PER_BITFIELD_ELEM - extra_pages);
((1ULL << extra_pages) - 1) <<
(PAGES_PER_BITFIELD_ELEM - extra_pages);
}
platform_set_drvdata(pdev, &epma_dev->pma_dev);
dev_info(&pdev->dev, "Protected memory allocator probed successfully\n");
dev_info(&pdev->dev, "Protected memory region: base=%pK num pages=%zu\n", (void *)rmem_base,
rmem_size);
dev_info(&pdev->dev,
"Protected memory allocator probed successfully\n");
dev_info(&pdev->dev, "Protected memory region: base=%llx num pages=%zu\n",
(unsigned long long)rmem_base, rmem_size);
return 0;
}
static int protected_memory_allocator_remove(struct platform_device *pdev)
{
struct protected_memory_allocator_device *pma_dev = platform_get_drvdata(pdev);
struct protected_memory_allocator_device *pma_dev =
platform_get_drvdata(pdev);
struct simple_pma_device *epma_dev;
struct device *dev;
@@ -509,14 +527,15 @@ static int protected_memory_allocator_remove(struct platform_device *pdev)
if (epma_dev->num_free_pages < epma_dev->rmem_size) {
dev_warn(&pdev->dev, "Leaking %zu pages of protected memory\n",
epma_dev->rmem_size - epma_dev->num_free_pages);
epma_dev->rmem_size - epma_dev->num_free_pages);
}
platform_set_drvdata(pdev, NULL);
devm_kfree(dev, epma_dev->allocated_pages_bitfield_arr);
devm_kfree(dev, epma_dev);
dev_info(&pdev->dev, "Protected memory allocator removed successfully\n");
dev_info(&pdev->dev,
"Protected memory allocator removed successfully\n");
return 0;
}
@@ -527,14 +546,14 @@ static const struct of_device_id protected_memory_allocator_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, protected_memory_allocator_dt_ids);
static struct platform_driver
protected_memory_allocator_driver = { .probe = protected_memory_allocator_probe,
.remove = protected_memory_allocator_remove,
.driver = {
.name = "simple_protected_memory_allocator",
.of_match_table = of_match_ptr(
protected_memory_allocator_dt_ids),
} };
static struct platform_driver protected_memory_allocator_driver = {
.probe = protected_memory_allocator_probe,
.remove = protected_memory_allocator_remove,
.driver = {
.name = "simple_protected_memory_allocator",
.of_match_table = of_match_ptr(protected_memory_allocator_dt_ids),
}
};
module_platform_driver(protected_memory_allocator_driver);

View File

@@ -69,7 +69,7 @@ endif
#
# Driver version string which is returned to userspace via an ioctl
MALI_RELEASE_NAME ?= '"g21p0-01eac0"'
MALI_RELEASE_NAME ?= '"g18p0-01eac0"'
# Set up defaults if not defined by build system
ifeq ($(CONFIG_MALI_BIFROST_DEBUG), y)
MALI_UNIT_TEST = 1
@@ -149,7 +149,6 @@ bifrost_kbase-y := \
mali_kbase_cache_policy.o \
mali_kbase_ccswe.o \
mali_kbase_mem.o \
mali_kbase_reg_track.o \
mali_kbase_mem_migrate.o \
mali_kbase_mem_pool_group.o \
mali_kbase_native_mgm.o \
@@ -158,6 +157,7 @@ bifrost_kbase-y := \
mali_kbase_pm.o \
mali_kbase_config.o \
mali_kbase_kinstr_prfcnt.o \
mali_kbase_vinstr.o \
mali_kbase_softjobs.o \
mali_kbase_hw.o \
mali_kbase_debug.o \
@@ -173,6 +173,7 @@ bifrost_kbase-y := \
mali_kbase_mem_pool.o \
mali_kbase_mem_pool_debugfs.o \
mali_kbase_debugfs_helper.o \
mali_kbase_strings.o \
mali_kbase_as_fault_debugfs.o \
mali_kbase_regs_history_debugfs.o \
mali_kbase_dvfs_debugfs.o \
@@ -189,10 +190,6 @@ bifrost_kbase-$(CONFIG_SYNC_FILE) += \
mali_kbase_sync_file.o \
mali_kbase_sync_common.o
bifrost_kbase-$(CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD) += \
mali_power_gpu_work_period_trace.o \
mali_kbase_gpu_metrics.o
ifneq ($(CONFIG_MALI_CSF_SUPPORT),y)
bifrost_kbase-y += \
mali_kbase_jm.o \
@@ -220,7 +217,6 @@ INCLUDE_SUBDIR = \
$(src)/tl/Kbuild \
$(src)/hwcnt/Kbuild \
$(src)/gpu/Kbuild \
$(src)/hw_access/Kbuild \
$(src)/thirdparty/Kbuild \
$(src)/platform/$(MALI_PLATFORM_DIR)/Kbuild

View File

@@ -63,18 +63,11 @@ config MALI_BIFROST_NO_MALI
All calls to the simulated hardware will complete immediately as if the hardware
completed the task.
config MALI_NO_MALI_DEFAULT_GPU
string "Default GPU for No Mali"
depends on MALI_BIFROST_NO_MALI
default "tMIx"
help
This option sets the default GPU to identify as for No Mali builds.
endchoice
menu "Platform specific options"
source "$(MALI_KCONFIG_EXT_PREFIX)drivers/gpu/arm/bifrost/platform/Kconfig"
source "drivers/gpu/arm/bifrost/platform/Kconfig"
endmenu
config MALI_CSF_SUPPORT
@@ -170,36 +163,32 @@ menuconfig MALI_BIFROST_EXPERT
if MALI_BIFROST_EXPERT
config LARGE_PAGE_SUPPORT
bool "Support for 2MB page allocations"
config LARGE_PAGE_ALLOC_OVERRIDE
bool "Override default setting of 2MB pages"
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
default y
default n
help
Rather than allocating all GPU memory page-by-page, allow the system
to decide whether to attempt to allocate 2MB pages from the kernel.
This reduces TLB pressure.
An override config for LARGE_PAGE_ALLOC config.
When LARGE_PAGE_ALLOC_OVERRIDE is Y, 2MB page allocation will be
enabled by LARGE_PAGE_ALLOC. When this is N, the feature will be
enabled when GPU HW satisfies requirements.
Note that this option only enables the support for the module parameter
and does not necessarily mean that 2MB pages will be used automatically.
This depends on GPU support.
If in doubt, say N
If in doubt, say Y.
config PAGE_MIGRATION_SUPPORT
bool "Enable support for page migration"
config LARGE_PAGE_ALLOC
bool "Attempt to allocate 2MB pages"
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
default y
default n if ANDROID
default n
help
Compile in support for page migration.
If set to disabled ('n') then page migration cannot
be enabled at all, and related symbols are not compiled in.
If not set, page migration is compiled in by default, and
if not explicitly enabled or disabled with the insmod parameter,
page migration becomes automatically enabled with large pages.
Rather than allocating all GPU memory page-by-page, attempt to
allocate 2MB pages from the kernel. This reduces TLB pressure and
helps to prevent memory fragmentation.
If in doubt, say Y. To strip out page migration symbols and support,
say N.
Note this config applies only when LARGE_PAGE_ALLOC_OVERRIDE config
is enabled and enabling this on a GPU HW that does not satisfy
requirements can cause serious problem.
If in doubt, say N
config MALI_MEMORY_FULLY_BACKED
bool "Enable memory fully physically-backed"
@@ -394,16 +383,7 @@ config MALI_ARBITRATION
virtualization setup for Mali
If unsure, say N.
config MALI_TRACE_POWER_GPU_WORK_PERIOD
bool "Enable per-application GPU metrics tracepoints"
depends on MALI_BIFROST
default y
help
This option enables per-application GPU metrics tracepoints.
If unsure, say N.
# source "$(MALI_KCONFIG_EXT_PREFIX)drivers/gpu/arm/bifrost/tests/Kconfig"
# source "drivers/gpu/arm/bifrost/tests/Kconfig"
endif

View File

@@ -20,7 +20,6 @@
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
KDIR ?= $(KERNEL_SRC)
M ?= $(shell pwd)
ifeq ($(KDIR),)
$(error Must specify KDIR to point to the kernel to target))
@@ -32,169 +31,158 @@ endif
# Dependency resolution is done through statements as Kconfig
# is not supported for out-of-tree builds.
#
CONFIGS :=
ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
CONFIG_MALI_BIFROST ?= m
ifeq ($(CONFIG_MALI_BIFROST),m)
CONFIG_MALI_PLATFORM_NAME ?= "devicetree"
CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD ?= y
CONFIG_MALI_BIFROST_GATOR_SUPPORT ?= y
CONFIG_MALI_ARBITRATION ?= n
CONFIG_MALI_PARTITION_MANAGER ?= n
CONFIG_MALI_64BIT_HW_ACCESS ?= n
ifneq ($(CONFIG_MALI_BIFROST_NO_MALI),y)
# Prevent misuse when CONFIG_MALI_BIFROST_NO_MALI=y
CONFIG_MALI_REAL_HW ?= y
CONFIG_MALI_CORESIGHT = n
endif
CONFIG_MALI_BIFROST ?= m
ifeq ($(CONFIG_MALI_BIFROST),m)
CONFIG_MALI_PLATFORM_NAME ?= "devicetree"
CONFIG_MALI_BIFROST_GATOR_SUPPORT ?= y
CONFIG_MALI_ARBITRATION ?= n
CONFIG_MALI_PARTITION_MANAGER ?= n
ifneq ($(CONFIG_MALI_BIFROST_NO_MALI),y)
# Prevent misuse when CONFIG_MALI_BIFROST_NO_MALI
CONFIG_MALI_REAL_HW ?= y
CONFIG_MALI_CORESIGHT = n
endif
ifeq ($(CONFIG_MALI_BIFROST_DVFS),y)
# Prevent misuse when CONFIG_MALI_BIFROST_DVFS=y
CONFIG_MALI_BIFROST_DEVFREQ ?= n
else
CONFIG_MALI_BIFROST_DEVFREQ ?= y
endif
ifeq ($(CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND), y)
# Prevent misuse when CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND=y
CONFIG_MALI_DMA_BUF_LEGACY_COMPAT = n
endif
ifeq ($(CONFIG_MALI_CSF_SUPPORT), y)
CONFIG_MALI_CORESIGHT ?= n
endif
#
# Expert/Debug/Test released configurations
#
ifeq ($(CONFIG_MALI_BIFROST_EXPERT), y)
ifeq ($(CONFIG_MALI_BIFROST_NO_MALI), y)
CONFIG_MALI_REAL_HW = n
ifeq ($(CONFIG_MALI_BIFROST_DVFS),y)
# Prevent misuse when CONFIG_MALI_BIFROST_DVFS=y
CONFIG_MALI_BIFROST_DEVFREQ ?= n
else
CONFIG_MALI_BIFROST_DEVFREQ ?= y
# Prevent misuse when CONFIG_MALI_BIFROST_NO_MALI=n
CONFIG_MALI_REAL_HW = y
CONFIG_MALI_BIFROST_ERROR_INJECT = n
endif
ifeq ($(CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND), y)
# Prevent misuse when CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND=y
CONFIG_MALI_DMA_BUF_LEGACY_COMPAT = n
ifeq ($(CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED), y)
# Prevent misuse when CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED=y
CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE = n
endif
ifeq ($(CONFIG_MALI_CSF_SUPPORT), y)
CONFIG_MALI_CORESIGHT ?= n
endif
#
# Expert/Debug/Test released configurations
#
ifeq ($(CONFIG_MALI_BIFROST_EXPERT), y)
ifeq ($(CONFIG_MALI_BIFROST_NO_MALI), y)
CONFIG_MALI_REAL_HW = n
CONFIG_MALI_NO_MALI_DEFAULT_GPU ?= "tMIx"
ifeq ($(CONFIG_MALI_BIFROST_DEBUG), y)
CONFIG_MALI_BIFROST_ENABLE_TRACE ?= y
CONFIG_MALI_BIFROST_SYSTEM_TRACE ?= y
ifeq ($(CONFIG_SYNC_FILE), y)
CONFIG_MALI_BIFROST_FENCE_DEBUG ?= y
else
# Prevent misuse when CONFIG_MALI_BIFROST_NO_MALI=n
CONFIG_MALI_REAL_HW = y
CONFIG_MALI_BIFROST_ERROR_INJECT = n
endif
ifeq ($(CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED), y)
# Prevent misuse when CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED=y
CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE = n
endif
ifeq ($(CONFIG_MALI_BIFROST_DEBUG), y)
CONFIG_MALI_BIFROST_ENABLE_TRACE ?= y
CONFIG_MALI_BIFROST_SYSTEM_TRACE ?= y
ifeq ($(CONFIG_SYNC_FILE), y)
CONFIG_MALI_BIFROST_FENCE_DEBUG ?= y
else
CONFIG_MALI_BIFROST_FENCE_DEBUG = n
endif
else
# Prevent misuse when CONFIG_MALI_BIFROST_DEBUG=n
CONFIG_MALI_BIFROST_ENABLE_TRACE = n
CONFIG_MALI_BIFROST_SYSTEM_TRACE = n
CONFIG_MALI_BIFROST_FENCE_DEBUG = n
endif
else
# Prevent misuse when CONFIG_MALI_BIFROST_EXPERT=n
CONFIG_MALI_CORESTACK = n
CONFIG_LARGE_PAGE_SUPPORT = y
CONFIG_MALI_PWRSOFT_765 = n
CONFIG_MALI_MEMORY_FULLY_BACKED = n
CONFIG_MALI_JOB_DUMP = n
CONFIG_MALI_BIFROST_NO_MALI = n
CONFIG_MALI_REAL_HW = y
CONFIG_MALI_BIFROST_ERROR_INJECT = n
CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED = n
CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE = n
CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS = n
CONFIG_MALI_BIFROST_DEBUG = n
# Prevent misuse when CONFIG_MALI_BIFROST_DEBUG=n
CONFIG_MALI_BIFROST_ENABLE_TRACE = n
CONFIG_MALI_BIFROST_SYSTEM_TRACE = n
CONFIG_MALI_BIFROST_FENCE_DEBUG = n
endif
else
# Prevent misuse when CONFIG_MALI_BIFROST_EXPERT=n
CONFIG_MALI_CORESTACK = n
CONFIG_LARGE_PAGE_ALLOC_OVERRIDE = n
CONFIG_LARGE_PAGE_ALLOC = n
CONFIG_MALI_PWRSOFT_765 = n
CONFIG_MALI_MEMORY_FULLY_BACKED = n
CONFIG_MALI_JOB_DUMP = n
CONFIG_MALI_BIFROST_NO_MALI = n
CONFIG_MALI_REAL_HW = y
CONFIG_MALI_BIFROST_ERROR_INJECT = n
CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED = n
CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE = n
CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS = n
CONFIG_MALI_BIFROST_DEBUG = n
CONFIG_MALI_BIFROST_ENABLE_TRACE = n
CONFIG_MALI_BIFROST_SYSTEM_TRACE = n
CONFIG_MALI_BIFROST_FENCE_DEBUG = n
endif
ifeq ($(CONFIG_MALI_BIFROST_DEBUG), y)
CONFIG_MALI_KUTF ?= y
ifeq ($(CONFIG_MALI_KUTF), y)
CONFIG_MALI_KUTF_IRQ_TEST ?= y
CONFIG_MALI_KUTF_CLK_RATE_TRACE ?= y
CONFIG_MALI_KUTF_MGM_INTEGRATION_TEST ?= y
ifeq ($(CONFIG_MALI_BIFROST_DEVFREQ), y)
ifeq ($(CONFIG_MALI_BIFROST_NO_MALI), y)
CONFIG_MALI_KUTF_IPA_UNIT_TEST ?= y
endif
endif
else
# Prevent misuse when CONFIG_MALI_KUTF=n
CONFIG_MALI_KUTF_IRQ_TEST = n
CONFIG_MALI_KUTF_CLK_RATE_TRACE = n
CONFIG_MALI_KUTF_MGM_INTEGRATION_TEST = n
endif
ifeq ($(CONFIG_MALI_BIFROST_DEBUG), y)
CONFIG_MALI_KUTF ?= y
ifeq ($(CONFIG_MALI_KUTF), y)
CONFIG_MALI_KUTF_IRQ_TEST ?= y
CONFIG_MALI_KUTF_CLK_RATE_TRACE ?= y
CONFIG_MALI_KUTF_MGM_INTEGRATION_TEST ?= y
else
# Prevent misuse when CONFIG_MALI_BIFROST_DEBUG=n
CONFIG_MALI_KUTF = n
# Prevent misuse when CONFIG_MALI_KUTF=n
CONFIG_MALI_KUTF_IRQ_TEST = n
CONFIG_MALI_KUTF_CLK_RATE_TRACE = n
CONFIG_MALI_KUTF_MGM_INTEGRATION_TEST = n
endif
else
# Prevent misuse when CONFIG_MALI_BIFROST=n
CONFIG_MALI_ARBITRATION = n
# Prevent misuse when CONFIG_MALI_BIFROST_DEBUG=n
CONFIG_MALI_KUTF = n
CONFIG_MALI_KUTF_IRQ_TEST = n
CONFIG_MALI_KUTF_CLK_RATE_TRACE = n
CONFIG_MALI_KUTF_MGM_INTEGRATION_TEST = n
endif
# All Mali CONFIG should be listed here
CONFIGS += \
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 \
CONFIG_MALI_BIFROST_DEVFREQ \
CONFIG_MALI_BIFROST_DVFS \
CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND \
CONFIG_MALI_DMA_BUF_LEGACY_COMPAT \
CONFIG_MALI_BIFROST_EXPERT \
CONFIG_MALI_CORESTACK \
CONFIG_LARGE_PAGE_SUPPORT \
CONFIG_MALI_PWRSOFT_765 \
CONFIG_MALI_MEMORY_FULLY_BACKED \
CONFIG_MALI_JOB_DUMP \
CONFIG_MALI_BIFROST_NO_MALI \
CONFIG_MALI_BIFROST_ERROR_INJECT \
CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED \
CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE \
CONFIG_MALI_PRFCNT_SET_PRIMARY \
CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY \
CONFIG_MALI_PRFCNT_SET_TERTIARY \
CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS \
CONFIG_MALI_BIFROST_DEBUG \
CONFIG_MALI_BIFROST_ENABLE_TRACE \
CONFIG_MALI_BIFROST_SYSTEM_TRACE \
CONFIG_MALI_BIFROST_FENCE_DEBUG \
CONFIG_MALI_KUTF \
CONFIG_MALI_KUTF_IRQ_TEST \
CONFIG_MALI_KUTF_CLK_RATE_TRACE \
CONFIG_MALI_KUTF_MGM_INTEGRATION_TEST \
CONFIG_MALI_XEN \
CONFIG_MALI_CORESIGHT \
CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD
else
# Prevent misuse when CONFIG_MALI_BIFROST=n
CONFIG_MALI_ARBITRATION = n
CONFIG_MALI_KUTF = n
CONFIG_MALI_KUTF_IRQ_TEST = n
CONFIG_MALI_KUTF_CLK_RATE_TRACE = n
CONFIG_MALI_KUTF_MGM_INTEGRATION_TEST = n
endif
# All Mali CONFIG should be listed here
CONFIGS := \
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 \
CONFIG_MALI_BIFROST_DEVFREQ \
CONFIG_MALI_BIFROST_DVFS \
CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND \
CONFIG_MALI_DMA_BUF_LEGACY_COMPAT \
CONFIG_MALI_BIFROST_EXPERT \
CONFIG_MALI_CORESTACK \
CONFIG_LARGE_PAGE_ALLOC_OVERRIDE \
CONFIG_LARGE_PAGE_ALLOC \
CONFIG_MALI_PWRSOFT_765 \
CONFIG_MALI_MEMORY_FULLY_BACKED \
CONFIG_MALI_JOB_DUMP \
CONFIG_MALI_BIFROST_NO_MALI \
CONFIG_MALI_BIFROST_ERROR_INJECT \
CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED \
CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE \
CONFIG_MALI_PRFCNT_SET_PRIMARY \
CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY \
CONFIG_MALI_PRFCNT_SET_TERTIARY \
CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS \
CONFIG_MALI_BIFROST_DEBUG \
CONFIG_MALI_BIFROST_ENABLE_TRACE \
CONFIG_MALI_BIFROST_SYSTEM_TRACE \
CONFIG_MALI_BIFROST_FENCE_DEBUG \
CONFIG_MALI_KUTF \
CONFIG_MALI_KUTF_IRQ_TEST \
CONFIG_MALI_KUTF_CLK_RATE_TRACE \
CONFIG_MALI_KUTF_MGM_INTEGRATION_TEST \
CONFIG_MALI_XEN \
CONFIG_MALI_CORESIGHT
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
-include $(THIS_DIR)/../arbitration/Makefile
@@ -209,9 +197,7 @@ MAKE_ARGS := $(foreach config,$(CONFIGS), \
$(value config)=$(value $(value config)), \
$(value config)=n))
ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
MAKE_ARGS += CONFIG_MALI_PLATFORM_NAME=$(CONFIG_MALI_PLATFORM_NAME)
endif
MAKE_ARGS += CONFIG_MALI_PLATFORM_NAME=$(CONFIG_MALI_PLATFORM_NAME)
#
# EXTRA_CFLAGS to define the custom CONFIGs on out-of-tree build
@@ -223,78 +209,71 @@ EXTRA_CFLAGS := $(foreach config,$(CONFIGS), \
$(if $(filter y m,$(value $(value config))), \
-D$(value config)=1))
ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
EXTRA_CFLAGS += -DCONFIG_MALI_PLATFORM_NAME='\"$(CONFIG_MALI_PLATFORM_NAME)\"'
EXTRA_CFLAGS += -DCONFIG_MALI_NO_MALI_DEFAULT_GPU='\"$(CONFIG_MALI_NO_MALI_DEFAULT_GPU)\"'
endif
EXTRA_CFLAGS += -DCONFIG_MALI_PLATFORM_NAME=$(CONFIG_MALI_PLATFORM_NAME)
#
# KBUILD_EXTRA_SYMBOLS to prevent warnings about unknown functions
#
BASE_SYMBOLS = $(M)/../../base/arm/Module.symvers
EXTRA_SYMBOLS += \
$(BASE_SYMBOLS)
CFLAGS_MODULE += -Wall -Werror
KBUILD_CFLAGS += -Wall -Werror
# The following were added to align with W=1 in scripts/Makefile.extrawarn
# from the Linux source tree (v5.18.14)
CFLAGS_MODULE += -Wextra -Wunused -Wno-unused-parameter
CFLAGS_MODULE += -Wmissing-declarations
CFLAGS_MODULE += -Wmissing-format-attribute
CFLAGS_MODULE += -Wmissing-prototypes
CFLAGS_MODULE += -Wold-style-definition
KBUILD_CFLAGS += -Wextra -Wunused -Wno-unused-parameter
KBUILD_CFLAGS += -Wmissing-declarations
KBUILD_CFLAGS += -Wmissing-format-attribute
KBUILD_CFLAGS += -Wmissing-prototypes
KBUILD_CFLAGS += -Wold-style-definition
# The -Wmissing-include-dirs cannot be enabled as the path to some of the
# included directories change depending on whether it is an in-tree or
# out-of-tree build.
CFLAGS_MODULE += $(call cc-option, -Wunused-but-set-variable)
CFLAGS_MODULE += $(call cc-option, -Wunused-const-variable)
CFLAGS_MODULE += $(call cc-option, -Wpacked-not-aligned)
CFLAGS_MODULE += $(call cc-option, -Wstringop-truncation)
KBUILD_CFLAGS += $(call cc-option, -Wunused-but-set-variable)
KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable)
KBUILD_CFLAGS += $(call cc-option, -Wpacked-not-aligned)
KBUILD_CFLAGS += $(call cc-option, -Wstringop-truncation)
# The following turn off the warnings enabled by -Wextra
CFLAGS_MODULE += -Wno-sign-compare
CFLAGS_MODULE += -Wno-shift-negative-value
KBUILD_CFLAGS += -Wno-sign-compare
KBUILD_CFLAGS += -Wno-shift-negative-value
# This flag is needed to avoid build errors on older kernels
CFLAGS_MODULE += $(call cc-option, -Wno-cast-function-type)
KBUILD_CFLAGS += $(call cc-option, -Wno-cast-function-type)
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1
# The following were added to align with W=2 in scripts/Makefile.extrawarn
# from the Linux source tree (v5.18.14)
CFLAGS_MODULE += -Wdisabled-optimization
KBUILD_CFLAGS += -Wdisabled-optimization
# The -Wshadow flag cannot be enabled unless upstream kernels are
# patched to fix redefinitions of certain built-in functions and
# global variables.
CFLAGS_MODULE += $(call cc-option, -Wlogical-op)
CFLAGS_MODULE += -Wmissing-field-initializers
KBUILD_CFLAGS += $(call cc-option, -Wlogical-op)
KBUILD_CFLAGS += -Wmissing-field-initializers
# -Wtype-limits must be disabled due to build failures on kernel 5.x
CFLAGS_MODULE += -Wno-type-limits
CFLAGS_MODULE += $(call cc-option, -Wmaybe-uninitialized)
CFLAGS_MODULE += $(call cc-option, -Wunused-macros)
KBUILD_CFLAGS += -Wno-type-limit
KBUILD_CFLAGS += $(call cc-option, -Wmaybe-uninitialized)
KBUILD_CFLAGS += $(call cc-option, -Wunused-macros)
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2
# This warning is disabled to avoid build failures in some kernel versions
CFLAGS_MODULE += -Wno-ignored-qualifiers
KBUILD_CFLAGS += -Wno-ignored-qualifiers
ifeq ($(CONFIG_GCOV_KERNEL),y)
CFLAGS_MODULE += $(call cc-option, -ftest-coverage)
CFLAGS_MODULE += $(call cc-option, -fprofile-arcs)
KBUILD_CFLAGS += $(call cc-option, -ftest-coverage)
KBUILD_CFLAGS += $(call cc-option, -fprofile-arcs)
EXTRA_CFLAGS += -DGCOV_PROFILE=1
endif
ifeq ($(CONFIG_MALI_KCOV),y)
CFLAGS_MODULE += $(call cc-option, -fsanitize-coverage=trace-cmp)
KBUILD_CFLAGS += $(call cc-option, -fsanitize-coverage=trace-cmp)
EXTRA_CFLAGS += -DKCOV=1
EXTRA_CFLAGS += -DKCOV_ENABLE_COMPARISONS=1
endif
all:
$(MAKE) -C $(KDIR) M=$(M) $(MAKE_ARGS) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" modules
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" modules
modules_install:
$(MAKE) -C $(KDIR) M=$(M) $(MAKE_ARGS) modules_install
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) modules_install
clean:
$(MAKE) -C $(KDIR) M=$(M) $(MAKE_ARGS) clean
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) clean

View File

@@ -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-2022 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
@@ -32,11 +32,13 @@
/* Arbiter interface version against which was implemented this module */
#define MALI_REQUIRED_KBASE_ARBITER_INTERFACE_VERSION 5
#if MALI_REQUIRED_KBASE_ARBITER_INTERFACE_VERSION != MALI_ARBITER_INTERFACE_VERSION
#if MALI_REQUIRED_KBASE_ARBITER_INTERFACE_VERSION != \
MALI_ARBITER_INTERFACE_VERSION
#error "Unsupported Mali Arbiter interface version."
#endif
static void on_max_config(struct device *dev, uint32_t max_l2_slices, uint32_t max_core_mask)
static void on_max_config(struct device *dev, uint32_t max_l2_slices,
uint32_t max_core_mask)
{
struct kbase_device *kbdev;
@@ -52,7 +54,9 @@ static void on_max_config(struct device *dev, uint32_t max_l2_slices, uint32_t m
}
if (!max_l2_slices || !max_core_mask) {
dev_dbg(dev, "%s(): max_config ignored as one of the fields is zero", __func__);
dev_dbg(dev,
"%s(): max_config ignored as one of the fields is zero",
__func__);
return;
}
@@ -183,7 +187,8 @@ int kbase_arbif_init(struct kbase_device *kbdev)
dev_dbg(kbdev->dev, "%s\n", __func__);
arbiter_if_node = of_parse_phandle(kbdev->dev->of_node, "arbiter_if", 0);
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");
/* no arbiter interface defined in device tree */
@@ -225,9 +230,10 @@ int kbase_arbif_init(struct kbase_device *kbdev)
/* register kbase arbiter_if callbacks */
if (arb_if->vm_ops.vm_arb_register_dev) {
err = arb_if->vm_ops.vm_arb_register_dev(arb_if, kbdev->dev, &ops);
err = arb_if->vm_ops.vm_arb_register_dev(arb_if,
kbdev->dev, &ops);
if (err) {
dev_err(&pdev->dev, "Failed to register with arbiter. (err = %d)\n", err);
dev_err(&pdev->dev, "Failed to register with arbiter\n");
module_put(pdev->dev.driver->owner);
put_device(&pdev->dev);
if (err != -EPROBE_DEFER)

File diff suppressed because it is too large Load Diff

View File

@@ -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-2022 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
@@ -114,7 +114,8 @@ int kbase_arbiter_pm_install_interrupts(struct kbase_device *kbdev);
* The state machine function. Receives events and transitions states
* according the event received and the current state
*/
void kbase_arbiter_pm_vm_event(struct kbase_device *kbdev, enum kbase_arbif_evt event);
void kbase_arbiter_pm_vm_event(struct kbase_device *kbdev,
enum kbase_arbif_evt event);
/**
* kbase_arbiter_pm_ctx_active_handle_suspend() - Handle suspend operation for
@@ -130,7 +131,8 @@ void kbase_arbiter_pm_vm_event(struct kbase_device *kbdev, enum kbase_arbif_evt
* Return: 0 if success, 1 if failure due to system suspending/suspended
*/
int kbase_arbiter_pm_ctx_active_handle_suspend(struct kbase_device *kbdev,
enum kbase_pm_suspend_handler suspend_handler);
enum kbase_pm_suspend_handler suspend_handler);
/**
* kbase_arbiter_pm_vm_stopped() - Handle stop event for the VM
@@ -150,7 +152,8 @@ void kbase_arbiter_pm_vm_stopped(struct kbase_device *kbdev);
* This function handles a stop event for the VM.
* It will update the VM state and forward the stop event to the driver.
*/
void kbase_arbiter_set_max_config(struct kbase_device *kbdev, uint32_t max_l2_slices,
void kbase_arbiter_set_max_config(struct kbase_device *kbdev,
uint32_t max_l2_slices,
uint32_t max_core_mask);
/**
@@ -187,6 +190,7 @@ struct kbase_arbiter_freq {
*
* Updates the GPU frequency and triggers any notifications
*/
void kbase_arbiter_pm_update_gpu_freq(struct kbase_arbiter_freq *arb_freq, uint32_t freq);
void kbase_arbiter_pm_update_gpu_freq(struct kbase_arbiter_freq *arb_freq,
uint32_t freq);
#endif /*_MALI_KBASE_ARBITER_PM_H_ */

View File

@@ -22,6 +22,7 @@ bifrost_kbase-y += \
backend/gpu/mali_kbase_cache_policy_backend.o \
backend/gpu/mali_kbase_gpuprops_backend.o \
backend/gpu/mali_kbase_irq_linux.o \
backend/gpu/mali_kbase_js_backend.o \
backend/gpu/mali_kbase_pm_backend.o \
backend/gpu/mali_kbase_pm_driver.o \
backend/gpu/mali_kbase_pm_metrics.o \
@@ -39,8 +40,7 @@ ifeq ($(MALI_USE_CSF),0)
backend/gpu/mali_kbase_jm_as.o \
backend/gpu/mali_kbase_debug_job_fault_backend.o \
backend/gpu/mali_kbase_jm_hw.o \
backend/gpu/mali_kbase_jm_rb.o \
backend/gpu/mali_kbase_js_backend.o
backend/gpu/mali_kbase_jm_rb.o
endif

View File

@@ -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-2018, 2020-2021 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
@@ -27,3 +27,4 @@
#define _KBASE_BACKEND_CONFIG_H_
#endif /* _KBASE_BACKEND_CONFIG_H_ */

View File

@@ -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-2016, 2018, 2020-2022 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
@@ -22,43 +22,71 @@
#include "backend/gpu/mali_kbase_cache_policy_backend.h"
#include <device/mali_kbase_device.h>
void kbase_cache_set_coherency_mode(struct kbase_device *kbdev, u32 mode)
/**
* kbasep_amba_register_present() - Check AMBA_<> register is present
* in the GPU.
* @kbdev: Device pointer
*
* Note: Only for arch version 12.x.1 onwards.
*
* Return: true if AMBA_FEATURES/ENABLE registers are present.
*/
static bool kbasep_amba_register_present(struct kbase_device *kbdev)
{
return (ARCH_MAJOR_REV_REG(kbdev->gpu_props.props.raw_props.gpu_id) >=
GPU_ID2_ARCH_MAJOR_REV_MAKE(12, 1));
}
void kbase_cache_set_coherency_mode(struct kbase_device *kbdev,
u32 mode)
{
kbdev->current_gpu_coherency_mode = mode;
#if MALI_USE_CSF
if (kbdev->gpu_props.gpu_id.arch_id >= GPU_ID_ARCH_MAKE(12, 0, 1)) {
/* AMBA_ENABLE present from 12.0.1 */
u32 val = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(AMBA_ENABLE));
if (kbasep_amba_register_present(kbdev)) {
u32 val = kbase_reg_read(kbdev, AMBA_ENABLE);
val = AMBA_ENABLE_COHERENCY_PROTOCOL_SET(val, mode);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(AMBA_ENABLE), val);
} else {
/* Fallback to COHERENCY_ENABLE for older versions */
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(COHERENCY_ENABLE), mode);
}
#else /* MALI_USE_CSF */
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(COHERENCY_ENABLE), mode);
#endif /* MALI_USE_CSF */
kbase_reg_write(kbdev, AMBA_ENABLE, val);
} else
kbase_reg_write(kbdev, COHERENCY_ENABLE, mode);
}
void kbase_amba_set_shareable_cache_support(struct kbase_device *kbdev)
u32 kbase_cache_get_coherency_features(struct kbase_device *kbdev)
{
#if MALI_USE_CSF
u32 coherency_features;
/* AMBA registers only present from 12.0.1 */
if (kbdev->gpu_props.gpu_id.arch_id < GPU_ID_ARCH_MAKE(12, 0, 1))
return;
if (kbasep_amba_register_present(kbdev))
coherency_features =
kbase_reg_read(kbdev, GPU_CONTROL_REG(AMBA_FEATURES));
else
coherency_features = kbase_reg_read(
kbdev, GPU_CONTROL_REG(COHERENCY_FEATURES));
if (kbdev->system_coherency != COHERENCY_NONE) {
u32 val = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(AMBA_FEATURES));
if (AMBA_FEATURES_SHAREABLE_CACHE_SUPPORT_GET(val)) {
val = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(AMBA_ENABLE));
val = AMBA_ENABLE_SHAREABLE_CACHE_SUPPORT_SET(val, 1);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(AMBA_ENABLE), val);
}
}
#endif /* MALI_USE_CSF */
return coherency_features;
}
void kbase_amba_set_memory_cache_support(struct kbase_device *kbdev,
bool enable)
{
if (kbasep_amba_register_present(kbdev)) {
u32 val = kbase_reg_read(kbdev, AMBA_ENABLE);
val = AMBA_ENABLE_MEMORY_CACHE_SUPPORT_SET(val, enable);
kbase_reg_write(kbdev, AMBA_ENABLE, val);
} else {
WARN(1, "memory_cache_support not supported");
}
}
void kbase_amba_set_invalidate_hint(struct kbase_device *kbdev, bool enable)
{
if (kbasep_amba_register_present(kbdev)) {
u32 val = kbase_reg_read(kbdev, AMBA_ENABLE);
val = AMBA_ENABLE_INVALIDATE_HINT_SET(val, enable);
kbase_reg_write(kbdev, AMBA_ENABLE, val);
} else {
WARN(1, "invalidate_hint not supported");
}
}

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