You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
Revert "MALI: rockchip: upgrade bifrost DDK to g21p0-01eac0, from g18p0-01eac0"
This reverts commit a94d0b968a.
This commit is contained in:
committed by
Ricardo Pardini
parent
d674985810
commit
48afe9af03
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
...
|
||||
};
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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_ */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user