mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
MALI: rockchip: upgrade bifrost DDK to g7p1-01bet0, from g6p0-01eac0
Including modifications under drivers/base/ from the new DDK. Resolve lots of conflicts. Fix compilation errors when CONFIG_DEBUG_FS is disabled. Change-Id: I69f9ac87d927441d0b92b8dac8b704922aeb6a0a Signed-off-by: Zhen Chen <chenzhen@rock-chips.com>
This commit is contained in:
@@ -15,10 +15,11 @@
|
||||
|
||||
What: /sys/class/misc/mali%u/device/core_mask
|
||||
Description:
|
||||
This attribute is used to restrict number of shader core
|
||||
available, is useful for debugging purposes. Reading
|
||||
this attribute provides us mask of cores available.
|
||||
Writing to it will set the current core mask.
|
||||
This attribute is used to restrict the number of shader cores
|
||||
available in this instance, is useful for debugging purposes.
|
||||
Reading this attribute provides us mask of all cores available.
|
||||
Writing to it will set the current core mask. Doesn't
|
||||
allow disabling all the cores present in this instance.
|
||||
|
||||
What: /sys/class/misc/mali%u/device/debug_command
|
||||
Description:
|
||||
@@ -43,6 +44,14 @@ Description:
|
||||
Its a readonly attribute and on reading gives details on the
|
||||
options used with the dummy workaround.
|
||||
|
||||
What: /sys/class/misc/mali%u/device/fw_timeout
|
||||
Description:
|
||||
This attribute is available only with mali platform
|
||||
device-driver that supports a CSF GPU. This attribute is
|
||||
used to set the duration value in milliseconds for the
|
||||
waiting timeout used for a GPU status change request being
|
||||
acknowledged by the FW.
|
||||
|
||||
What: /sys/class/misc/mali%u/device/gpuinfo
|
||||
Description:
|
||||
This attribute provides description of the present Mali GPU.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2013-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
@@ -97,6 +97,8 @@ 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
|
||||
"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.
|
||||
If not set then no coherency is used.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2019-2020 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2019-2020 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2017, 2019-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
|
||||
42
Documentation/dma-buf-test-exporter.txt
Normal file
42
Documentation/dma-buf-test-exporter.txt
Normal file
@@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2012-2013, 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
|
||||
# Foundation, and any use by you of this program is subject to the terms
|
||||
# of such GNU license.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
#
|
||||
|
||||
=====================
|
||||
dma-buf-test-exporter
|
||||
=====================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The dma-buf-test-exporter is a simple exporter of dma_buf objects.
|
||||
It has a private API to allocate and manipulate the buffers which are represented as dma_buf fds.
|
||||
The private API allows:
|
||||
* simple allocation of physically non-contiguous buffers
|
||||
* simple allocation of physically contiguous buffers
|
||||
* query kernel side API usage stats (number of attachments, number of mappings, mmaps)
|
||||
* failure mode configuration (fail attach, mapping, mmap)
|
||||
* kernel side memset of buffers
|
||||
|
||||
The buffers support all of the dma_buf API, including mmap.
|
||||
|
||||
It supports being compiled as a module both in-tree and out-of-tree.
|
||||
|
||||
See include/linux/dma-buf-test-exporter.h for the ioctl interface.
|
||||
See Documentation/dma-buf-sharing.txt for details on dma_buf.
|
||||
@@ -183,8 +183,7 @@ config SOC_BUS
|
||||
|
||||
source "drivers/base/regmap/Kconfig"
|
||||
|
||||
source "drivers/base/arm/memory_group_manager/Kconfig"
|
||||
source "drivers/base/arm/protected_memory_allocator/Kconfig"
|
||||
source "drivers/base/arm/Kconfig"
|
||||
|
||||
config DMA_SHARED_BUFFER
|
||||
bool
|
||||
|
||||
34
drivers/base/arm/Kbuild
Normal file
34
drivers/base/arm/Kbuild
Normal file
@@ -0,0 +1,34 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 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
|
||||
# Foundation, and any use by you of this program is subject to the terms
|
||||
# of such GNU license.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
#
|
||||
|
||||
#
|
||||
# ccflags
|
||||
#
|
||||
ccflags-y += -I$(src)/../../../include
|
||||
|
||||
subdir-ccflags-y += $(ccflags-y)
|
||||
|
||||
#
|
||||
# Kernel modules
|
||||
#
|
||||
obj-$(CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER) += dma_buf_test_exporter/
|
||||
obj-$(CONFIG_MALI_MEMORY_GROUP_MANAGER) += memory_group_manager/
|
||||
obj-$(CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR) += protected_memory_allocator/
|
||||
|
||||
64
drivers/base/arm/Kconfig
Normal file
64
drivers/base/arm/Kconfig
Normal file
@@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 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
|
||||
# Foundation, and any use by you of this program is subject to the terms
|
||||
# of such GNU license.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
#
|
||||
|
||||
menuconfig MALI_BASE_MODULES
|
||||
bool "Mali Base extra modules"
|
||||
default n
|
||||
help
|
||||
Enable this option to build support for a Arm Mali base modules.
|
||||
Those modules provide extra features or debug interfaces and,
|
||||
are optional for the use of the Mali GPU modules.
|
||||
|
||||
config DMA_SHARED_BUFFER_TEST_EXPORTER
|
||||
bool "Build dma-buf framework test exporter module"
|
||||
depends on MALI_BASE_MODULES && DMA_SHARED_BUFFER
|
||||
default y
|
||||
help
|
||||
This option will build the dma-buf framework test exporter module.
|
||||
Usable to help test importers.
|
||||
|
||||
Modules:
|
||||
- dma-buf-test-exporter.ko
|
||||
|
||||
config MALI_MEMORY_GROUP_MANAGER
|
||||
bool "Build Mali Memory Group Manager module"
|
||||
depends on MALI_BASE_MODULES
|
||||
default y
|
||||
help
|
||||
This option will build the memory group manager module.
|
||||
This is an example implementation for allocation and release of pages
|
||||
for memory pools managed by Mali GPU device drivers.
|
||||
|
||||
Modules:
|
||||
- memory_group_manager.ko
|
||||
|
||||
config MALI_PROTECTED_MEMORY_ALLOCATOR
|
||||
bool "Build Mali Protected Memory Allocator module"
|
||||
depends on MALI_BASE_MODULES && MALI_CSF_SUPPORT
|
||||
default y
|
||||
help
|
||||
This option will build the protected memory allocator module.
|
||||
This is an example implementation for allocation and release of pages
|
||||
of secure memory intended to be used by the firmware
|
||||
of Mali GPU device drivers.
|
||||
|
||||
Modules:
|
||||
- protected_memory_allocator.ko
|
||||
|
||||
98
drivers/base/arm/Makefile
Normal file
98
drivers/base/arm/Makefile
Normal file
@@ -0,0 +1,98 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 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
|
||||
# Foundation, and any use by you of this program is subject to the terms
|
||||
# of such GNU license.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
#
|
||||
|
||||
#
|
||||
# Paths
|
||||
#
|
||||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
KDIR ?= $(KERNEL_SRC)
|
||||
|
||||
ifeq ($(KDIR),)
|
||||
$(error Must specify KDIR to point to the kernel to target))
|
||||
endif
|
||||
|
||||
vars :=
|
||||
#
|
||||
# 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
|
||||
|
||||
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
|
||||
#
|
||||
# Generate the list of CONFIGs and values.
|
||||
# $(value config) is the name of the CONFIG option.
|
||||
# $(value $(value config)) is its value (y, m).
|
||||
# When the CONFIG is not set to y or m, it defaults to n.
|
||||
MAKE_ARGS := $(foreach config,$(CONFIGS), \
|
||||
$(if $(filter y m,$(value $(value config))), \
|
||||
$(value config)=$(value $(value config)), \
|
||||
$(value config)=n))
|
||||
|
||||
#
|
||||
# EXTRA_CFLAGS to define the custom CONFIGs on out-of-tree build
|
||||
#
|
||||
# Generate the list of CONFIGs defines with values from CONFIGS.
|
||||
# $(value config) is the name of the CONFIG option.
|
||||
# When set to y or m, the CONFIG gets defined to 1.
|
||||
EXTRA_CFLAGS := $(foreach config,$(CONFIGS), \
|
||||
$(if $(filter y m,$(value $(value config))), \
|
||||
-D$(value config)=1))
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" modules
|
||||
|
||||
modules_install:
|
||||
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) modules_install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) clean
|
||||
64
drivers/base/arm/Mconfig
Normal file
64
drivers/base/arm/Mconfig
Normal file
@@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 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
|
||||
# Foundation, and any use by you of this program is subject to the terms
|
||||
# of such GNU license.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
#
|
||||
|
||||
menuconfig MALI_BASE_MODULES
|
||||
bool "Mali Base extra modules"
|
||||
default y if BACKEND_KERNEL
|
||||
help
|
||||
Enable this option to build support for a Arm Mali base modules.
|
||||
Those modules provide extra features or debug interfaces and,
|
||||
are optional for the use of the Mali GPU modules.
|
||||
|
||||
config DMA_SHARED_BUFFER_TEST_EXPORTER
|
||||
bool "Build dma-buf framework test exporter module"
|
||||
depends on MALI_BASE_MODULES
|
||||
default y
|
||||
help
|
||||
This option will build the dma-buf framework test exporter module.
|
||||
Usable to help test importers.
|
||||
|
||||
Modules:
|
||||
- dma-buf-test-exporter.ko
|
||||
|
||||
config MALI_MEMORY_GROUP_MANAGER
|
||||
bool "Build Mali Memory Group Manager module"
|
||||
depends on MALI_BASE_MODULES
|
||||
default y
|
||||
help
|
||||
This option will build the memory group manager module.
|
||||
This is an example implementation for allocation and release of pages
|
||||
for memory pools managed by Mali GPU device drivers.
|
||||
|
||||
Modules:
|
||||
- memory_group_manager.ko
|
||||
|
||||
config MALI_PROTECTED_MEMORY_ALLOCATOR
|
||||
bool "Build Mali Protected Memory Allocator module"
|
||||
depends on MALI_BASE_MODULES && GPU_HAS_CSF
|
||||
default y
|
||||
help
|
||||
This option will build the protected memory allocator module.
|
||||
This is an example implementation for allocation and release of pages
|
||||
of secure memory intended to be used by the firmware
|
||||
of Mali GPU device drivers.
|
||||
|
||||
Modules:
|
||||
- protected_memory_allocator.ko
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2017, 2020 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 2012, 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
|
||||
@@ -18,9 +18,6 @@
|
||||
#
|
||||
#
|
||||
|
||||
config MALI_KUTF
|
||||
tristate "Mali Kernel Unit Test Framework"
|
||||
default m
|
||||
help
|
||||
Enables MALI testing framework. To compile it as a module,
|
||||
choose M here - this will generate a single module called kutf.
|
||||
ifeq ($(CONFIG_DMA_SHARED_BUFFER), y)
|
||||
obj-m := dma_buf_lock.o
|
||||
endif
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 2012, 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,8 +27,10 @@ ARCH ?= $(shell uname -m)
|
||||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
KDIR ?= $(KERNEL_SRC)
|
||||
|
||||
all:
|
||||
$(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../../include" modules CONFIG_MALI_MEMORY_GROUP_MANAGER=m
|
||||
all: dma_buf_lock
|
||||
|
||||
dma_buf_lock:
|
||||
$(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../../../include"
|
||||
|
||||
clean:
|
||||
$(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
|
||||
898
drivers/base/arm/dma_buf_lock/src/dma_buf_lock.c
Normal file
898
drivers/base/arm/dma_buf_lock/src/dma_buf_lock.c
Normal file
@@ -0,0 +1,898 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2012-2014, 2017-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
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/atomic.h>
|
||||
#if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
|
||||
#include <linux/reservation.h>
|
||||
#else
|
||||
#include <linux/dma-resv.h>
|
||||
#endif
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/anon_inodes.h>
|
||||
#include <linux/file.h>
|
||||
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
|
||||
#include <linux/fence.h>
|
||||
|
||||
#define dma_fence_context_alloc(a) fence_context_alloc(a)
|
||||
#define dma_fence_init(a, b, c, d, e) fence_init(a, b, c, d, e)
|
||||
#define dma_fence_get(a) fence_get(a)
|
||||
#define dma_fence_put(a) fence_put(a)
|
||||
#define dma_fence_signal(a) fence_signal(a)
|
||||
#define dma_fence_is_signaled(a) fence_is_signaled(a)
|
||||
#define dma_fence_add_callback(a, b, c) fence_add_callback(a, b, c)
|
||||
#define dma_fence_remove_callback(a, b) fence_remove_callback(a, b)
|
||||
|
||||
#if (KERNEL_VERSION(4, 9, 68) > LINUX_VERSION_CODE)
|
||||
#define dma_fence_get_status(a) (fence_is_signaled(a) ? (a)->status ?: 1 : 0)
|
||||
#else
|
||||
#define dma_fence_get_status(a) (fence_is_signaled(a) ? (a)->error ?: 1 : 0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <linux/dma-fence.h>
|
||||
|
||||
#if (KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE)
|
||||
#define dma_fence_get_status(a) (dma_fence_is_signaled(a) ? \
|
||||
(a)->status ?: 1 \
|
||||
: 0)
|
||||
#endif
|
||||
|
||||
#endif /* < 4.10.0 */
|
||||
|
||||
#include "dma_buf_lock.h"
|
||||
|
||||
/* Maximum number of buffers that a single handle can address */
|
||||
#define DMA_BUF_LOCK_BUF_MAX 32
|
||||
|
||||
#define DMA_BUF_LOCK_DEBUG 1
|
||||
|
||||
#define DMA_BUF_LOCK_INIT_BIAS 0xFF
|
||||
|
||||
static dev_t dma_buf_lock_dev;
|
||||
static struct cdev dma_buf_lock_cdev;
|
||||
static struct class *dma_buf_lock_class;
|
||||
static char dma_buf_lock_dev_name[] = "dma_buf_lock";
|
||||
|
||||
#ifdef HAVE_UNLOCKED_IOCTL
|
||||
static long dma_buf_lock_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
|
||||
#else
|
||||
static int dma_buf_lock_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
|
||||
#endif
|
||||
|
||||
static struct file_operations dma_buf_lock_fops =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef HAVE_UNLOCKED_IOCTL
|
||||
.unlocked_ioctl = dma_buf_lock_ioctl,
|
||||
#else
|
||||
.ioctl = dma_buf_lock_ioctl,
|
||||
#endif
|
||||
.compat_ioctl = dma_buf_lock_ioctl,
|
||||
};
|
||||
|
||||
typedef struct dma_buf_lock_resource
|
||||
{
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
struct fence fence;
|
||||
#else
|
||||
struct dma_fence fence;
|
||||
#endif
|
||||
int *list_of_dma_buf_fds; /* List of buffers copied from userspace */
|
||||
atomic_t locked; /* Status of lock */
|
||||
struct dma_buf **dma_bufs;
|
||||
unsigned long exclusive; /* Exclusive access bitmap */
|
||||
atomic_t fence_dep_count; /* Number of dma-fence dependencies */
|
||||
struct list_head dma_fence_callbacks; /* list of all callbacks set up to wait on other fences */
|
||||
wait_queue_head_t wait;
|
||||
struct kref refcount;
|
||||
struct list_head link;
|
||||
struct work_struct work;
|
||||
int count;
|
||||
} dma_buf_lock_resource;
|
||||
|
||||
/**
|
||||
* struct dma_buf_lock_fence_cb - Callback data struct for dma-fence
|
||||
* @fence_cb: Callback function
|
||||
* @fence: Pointer to the fence object on which this callback is waiting
|
||||
* @res: Pointer to dma_buf_lock_resource that is waiting on this callback
|
||||
* @node: List head for linking this callback to the lock resource
|
||||
*/
|
||||
struct dma_buf_lock_fence_cb {
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
struct fence_cb fence_cb;
|
||||
struct fence *fence;
|
||||
#else
|
||||
struct dma_fence_cb fence_cb;
|
||||
struct dma_fence *fence;
|
||||
#endif
|
||||
struct dma_buf_lock_resource *res;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
static LIST_HEAD(dma_buf_lock_resource_list);
|
||||
static DEFINE_MUTEX(dma_buf_lock_mutex);
|
||||
|
||||
static inline int is_dma_buf_lock_file(struct file *);
|
||||
static void dma_buf_lock_dounlock(struct kref *ref);
|
||||
|
||||
|
||||
/*** dma_buf_lock fence part ***/
|
||||
|
||||
/* Spin lock protecting all Mali fences as fence->lock. */
|
||||
static DEFINE_SPINLOCK(dma_buf_lock_fence_lock);
|
||||
|
||||
static const char *
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
dma_buf_lock_fence_get_driver_name(struct fence *fence)
|
||||
#else
|
||||
dma_buf_lock_fence_get_driver_name(struct dma_fence *fence)
|
||||
#endif
|
||||
{
|
||||
return "dma_buf_lock";
|
||||
}
|
||||
|
||||
static const char *
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
dma_buf_lock_fence_get_timeline_name(struct fence *fence)
|
||||
#else
|
||||
dma_buf_lock_fence_get_timeline_name(struct dma_fence *fence)
|
||||
#endif
|
||||
{
|
||||
return "dma_buf_lock.timeline";
|
||||
}
|
||||
|
||||
static bool
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
dma_buf_lock_fence_enable_signaling(struct fence *fence)
|
||||
#else
|
||||
dma_buf_lock_fence_enable_signaling(struct dma_fence *fence)
|
||||
#endif
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
const struct fence_ops dma_buf_lock_fence_ops = {
|
||||
.wait = fence_default_wait,
|
||||
#else
|
||||
const struct dma_fence_ops dma_buf_lock_fence_ops = {
|
||||
.wait = dma_fence_default_wait,
|
||||
#endif
|
||||
.get_driver_name = dma_buf_lock_fence_get_driver_name,
|
||||
.get_timeline_name = dma_buf_lock_fence_get_timeline_name,
|
||||
.enable_signaling = dma_buf_lock_fence_enable_signaling,
|
||||
};
|
||||
|
||||
static void
|
||||
dma_buf_lock_fence_init(dma_buf_lock_resource *resource)
|
||||
{
|
||||
dma_fence_init(&resource->fence,
|
||||
&dma_buf_lock_fence_ops,
|
||||
&dma_buf_lock_fence_lock,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
dma_buf_lock_fence_free_callbacks(dma_buf_lock_resource *resource)
|
||||
{
|
||||
struct dma_buf_lock_fence_cb *cb, *tmp;
|
||||
|
||||
/* Clean up and free callbacks. */
|
||||
list_for_each_entry_safe(cb, tmp, &resource->dma_fence_callbacks, node) {
|
||||
/* Cancel callbacks that hasn't been called yet and release the
|
||||
* reference taken in dma_buf_lock_fence_add_callback().
|
||||
*/
|
||||
dma_fence_remove_callback(cb->fence, &cb->fence_cb);
|
||||
dma_fence_put(cb->fence);
|
||||
list_del(&cb->node);
|
||||
kfree(cb);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dma_buf_lock_fence_work(struct work_struct *pwork)
|
||||
{
|
||||
dma_buf_lock_resource *resource =
|
||||
container_of(pwork, dma_buf_lock_resource, work);
|
||||
|
||||
WARN_ON(atomic_read(&resource->fence_dep_count));
|
||||
WARN_ON(!atomic_read(&resource->locked));
|
||||
WARN_ON(!resource->exclusive);
|
||||
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
dma_buf_lock_fence_callback(struct fence *fence, struct fence_cb *cb)
|
||||
#else
|
||||
dma_buf_lock_fence_callback(struct dma_fence *fence, struct dma_fence_cb *cb)
|
||||
#endif
|
||||
{
|
||||
struct dma_buf_lock_fence_cb *dma_buf_lock_cb = container_of(cb,
|
||||
struct dma_buf_lock_fence_cb,
|
||||
fence_cb);
|
||||
dma_buf_lock_resource *resource = dma_buf_lock_cb->res;
|
||||
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk(KERN_DEBUG "dma_buf_lock_fence_callback\n");
|
||||
#endif
|
||||
|
||||
/* Callback function will be invoked in atomic context. */
|
||||
|
||||
if (atomic_dec_and_test(&resource->fence_dep_count)) {
|
||||
atomic_set(&resource->locked, 1);
|
||||
wake_up(&resource->wait);
|
||||
|
||||
if (resource->exclusive)
|
||||
/* Warn if the work was already queued */
|
||||
WARN_ON(!schedule_work(&resource->work));
|
||||
}
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
static int
|
||||
dma_buf_lock_fence_add_callback(dma_buf_lock_resource *resource,
|
||||
struct fence *fence,
|
||||
fence_func_t callback)
|
||||
#else
|
||||
static int
|
||||
dma_buf_lock_fence_add_callback(dma_buf_lock_resource *resource,
|
||||
struct dma_fence *fence,
|
||||
dma_fence_func_t callback)
|
||||
#endif
|
||||
{
|
||||
int err = 0;
|
||||
struct dma_buf_lock_fence_cb *fence_cb;
|
||||
|
||||
if (!fence)
|
||||
return -EINVAL;
|
||||
|
||||
fence_cb = kmalloc(sizeof(*fence_cb), GFP_KERNEL);
|
||||
if (!fence_cb)
|
||||
return -ENOMEM;
|
||||
|
||||
fence_cb->fence = fence;
|
||||
fence_cb->res = resource;
|
||||
INIT_LIST_HEAD(&fence_cb->node);
|
||||
|
||||
err = dma_fence_add_callback(fence, &fence_cb->fence_cb,
|
||||
callback);
|
||||
|
||||
if (err == -ENOENT) {
|
||||
/* Fence signaled, get the completion result */
|
||||
err = dma_fence_get_status(fence);
|
||||
|
||||
/* remap success completion to err code */
|
||||
if (err == 1)
|
||||
err = 0;
|
||||
|
||||
kfree(fence_cb);
|
||||
} else if (err) {
|
||||
kfree(fence_cb);
|
||||
} else {
|
||||
/*
|
||||
* Get reference to fence that will be kept until callback gets
|
||||
* cleaned up in dma_buf_lock_fence_free_callbacks().
|
||||
*/
|
||||
dma_fence_get(fence);
|
||||
atomic_inc(&resource->fence_dep_count);
|
||||
/* Add callback to resource's list of callbacks */
|
||||
list_add(&fence_cb->node, &resource->dma_fence_callbacks);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
|
||||
static int
|
||||
dma_buf_lock_add_fence_reservation_callback(dma_buf_lock_resource *resource,
|
||||
struct reservation_object *resv,
|
||||
bool exclusive)
|
||||
#else
|
||||
static int
|
||||
dma_buf_lock_add_fence_reservation_callback(dma_buf_lock_resource *resource,
|
||||
struct dma_resv *resv,
|
||||
bool exclusive)
|
||||
#endif
|
||||
{
|
||||
#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE)
|
||||
struct fence *excl_fence = NULL;
|
||||
struct fence **shared_fences = NULL;
|
||||
#else
|
||||
struct dma_fence *excl_fence = NULL;
|
||||
struct dma_fence **shared_fences = NULL;
|
||||
#endif
|
||||
unsigned int shared_count = 0;
|
||||
int err, i;
|
||||
|
||||
#if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
|
||||
err = reservation_object_get_fences_rcu(
|
||||
#else
|
||||
err = dma_resv_get_fences_rcu(
|
||||
#endif
|
||||
resv,
|
||||
&excl_fence,
|
||||
&shared_count,
|
||||
&shared_fences);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (excl_fence) {
|
||||
err = dma_buf_lock_fence_add_callback(resource,
|
||||
excl_fence,
|
||||
dma_buf_lock_fence_callback);
|
||||
|
||||
/* Release our reference, taken by reservation_object_get_fences_rcu(),
|
||||
* to the fence. We have set up our callback (if that was possible),
|
||||
* and it's the fence's owner is responsible for singling the fence
|
||||
* before allowing it to disappear.
|
||||
*/
|
||||
dma_fence_put(excl_fence);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (exclusive) {
|
||||
for (i = 0; i < shared_count; i++) {
|
||||
err = dma_buf_lock_fence_add_callback(resource,
|
||||
shared_fences[i],
|
||||
dma_buf_lock_fence_callback);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release all our references to the shared fences, taken by
|
||||
* reservation_object_get_fences_rcu(). We have set up our callback (if
|
||||
* that was possible), and it's the fence's owner is responsible for
|
||||
* signaling the fence before allowing it to disappear.
|
||||
*/
|
||||
out:
|
||||
for (i = 0; i < shared_count; i++)
|
||||
dma_fence_put(shared_fences[i]);
|
||||
kfree(shared_fences);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
dma_buf_lock_release_fence_reservation(dma_buf_lock_resource *resource,
|
||||
struct ww_acquire_ctx *ctx)
|
||||
{
|
||||
unsigned int r;
|
||||
|
||||
for (r = 0; r < resource->count; r++)
|
||||
ww_mutex_unlock(&resource->dma_bufs[r]->resv->lock);
|
||||
ww_acquire_fini(ctx);
|
||||
}
|
||||
|
||||
static int
|
||||
dma_buf_lock_acquire_fence_reservation(dma_buf_lock_resource *resource,
|
||||
struct ww_acquire_ctx *ctx)
|
||||
{
|
||||
#if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
|
||||
struct reservation_object *content_resv = NULL;
|
||||
#else
|
||||
struct dma_resv *content_resv = NULL;
|
||||
#endif
|
||||
unsigned int content_resv_idx = 0;
|
||||
unsigned int r;
|
||||
int err = 0;
|
||||
|
||||
ww_acquire_init(ctx, &reservation_ww_class);
|
||||
|
||||
retry:
|
||||
for (r = 0; r < resource->count; r++) {
|
||||
if (resource->dma_bufs[r]->resv == content_resv) {
|
||||
content_resv = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
err = ww_mutex_lock(&resource->dma_bufs[r]->resv->lock, ctx);
|
||||
if (err)
|
||||
goto error;
|
||||
}
|
||||
|
||||
ww_acquire_done(ctx);
|
||||
return err;
|
||||
|
||||
error:
|
||||
content_resv_idx = r;
|
||||
|
||||
/* Unlock the locked one ones */
|
||||
while (r--)
|
||||
ww_mutex_unlock(&resource->dma_bufs[r]->resv->lock);
|
||||
|
||||
if (content_resv)
|
||||
ww_mutex_unlock(&content_resv->lock);
|
||||
|
||||
/* If we deadlock try with lock_slow and retry */
|
||||
if (err == -EDEADLK) {
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk(KERN_DEBUG "deadlock at dma_buf fd %i\n",
|
||||
resource->list_of_dma_buf_fds[content_resv_idx]);
|
||||
#endif
|
||||
content_resv = resource->dma_bufs[content_resv_idx]->resv;
|
||||
ww_mutex_lock_slow(&content_resv->lock, ctx);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* If we are here the function failed */
|
||||
ww_acquire_fini(ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dma_buf_lock_handle_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
dma_buf_lock_resource *resource;
|
||||
|
||||
if (!is_dma_buf_lock_file(file))
|
||||
return -EINVAL;
|
||||
|
||||
resource = file->private_data;
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk("dma_buf_lock_handle_release\n");
|
||||
#endif
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int dma_buf_lock_handle_poll(struct file *file,
|
||||
struct poll_table_struct *wait)
|
||||
{
|
||||
dma_buf_lock_resource *resource;
|
||||
unsigned int ret = 0;
|
||||
|
||||
if (!is_dma_buf_lock_file(file))
|
||||
return POLLERR;
|
||||
|
||||
resource = file->private_data;
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk("dma_buf_lock_handle_poll\n");
|
||||
#endif
|
||||
if (atomic_read(&resource->locked) == 1) {
|
||||
/* Resources have been locked */
|
||||
ret = POLLIN | POLLRDNORM;
|
||||
if (resource->exclusive)
|
||||
ret |= POLLOUT | POLLWRNORM;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!poll_does_not_wait(wait))
|
||||
poll_wait(file, &resource->wait, wait);
|
||||
}
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk("dma_buf_lock_handle_poll : return %i\n", ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations dma_buf_lock_handle_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.release = dma_buf_lock_handle_release,
|
||||
.poll = dma_buf_lock_handle_poll,
|
||||
};
|
||||
|
||||
/*
|
||||
* is_dma_buf_lock_file - Check if struct file* is associated with dma_buf_lock
|
||||
*/
|
||||
static inline int is_dma_buf_lock_file(struct file *file)
|
||||
{
|
||||
return file->f_op == &dma_buf_lock_handle_fops;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Start requested lock.
|
||||
*
|
||||
* Allocates required memory, copies dma_buf_fd list from userspace,
|
||||
* acquires related reservation objects, and starts the lock.
|
||||
*/
|
||||
static int dma_buf_lock_dolock(dma_buf_lock_k_request *request)
|
||||
{
|
||||
dma_buf_lock_resource *resource;
|
||||
struct ww_acquire_ctx ww_ctx;
|
||||
int size;
|
||||
int fd;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (request->list_of_dma_buf_fds == NULL)
|
||||
return -EINVAL;
|
||||
if (request->count <= 0)
|
||||
return -EINVAL;
|
||||
if (request->count > DMA_BUF_LOCK_BUF_MAX)
|
||||
return -EINVAL;
|
||||
if (request->exclusive != DMA_BUF_LOCK_NONEXCLUSIVE &&
|
||||
request->exclusive != DMA_BUF_LOCK_EXCLUSIVE)
|
||||
return -EINVAL;
|
||||
|
||||
resource = kzalloc(sizeof(dma_buf_lock_resource), GFP_KERNEL);
|
||||
if (resource == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
atomic_set(&resource->locked, 0);
|
||||
kref_init(&resource->refcount);
|
||||
INIT_LIST_HEAD(&resource->link);
|
||||
INIT_WORK(&resource->work, dma_buf_lock_fence_work);
|
||||
resource->count = request->count;
|
||||
|
||||
/* Allocate space to store dma_buf_fds received from user space */
|
||||
size = request->count * sizeof(int);
|
||||
resource->list_of_dma_buf_fds = kmalloc(size, GFP_KERNEL);
|
||||
|
||||
if (resource->list_of_dma_buf_fds == NULL) {
|
||||
kfree(resource);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Allocate space to store dma_buf pointers associated with dma_buf_fds */
|
||||
size = sizeof(struct dma_buf *) * request->count;
|
||||
resource->dma_bufs = kmalloc(size, GFP_KERNEL);
|
||||
|
||||
if (resource->dma_bufs == NULL) {
|
||||
kfree(resource->list_of_dma_buf_fds);
|
||||
kfree(resource);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Copy requested list of dma_buf_fds from user space */
|
||||
size = request->count * sizeof(int);
|
||||
if (copy_from_user(resource->list_of_dma_buf_fds,
|
||||
(void __user *)request->list_of_dma_buf_fds,
|
||||
size) != 0) {
|
||||
kfree(resource->list_of_dma_buf_fds);
|
||||
kfree(resource->dma_bufs);
|
||||
kfree(resource);
|
||||
return -ENOMEM;
|
||||
}
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
for (i = 0; i < request->count; i++)
|
||||
printk("dma_buf %i = %X\n", i, resource->list_of_dma_buf_fds[i]);
|
||||
#endif
|
||||
|
||||
/* Initialize the fence associated with dma_buf_lock resource */
|
||||
dma_buf_lock_fence_init(resource);
|
||||
|
||||
INIT_LIST_HEAD(&resource->dma_fence_callbacks);
|
||||
|
||||
atomic_set(&resource->fence_dep_count, DMA_BUF_LOCK_INIT_BIAS);
|
||||
|
||||
/* Add resource to global list */
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
|
||||
list_add(&resource->link, &dma_buf_lock_resource_list);
|
||||
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
|
||||
for (i = 0; i < request->count; i++)
|
||||
{
|
||||
/* Convert fd into dma_buf structure */
|
||||
resource->dma_bufs[i] = dma_buf_get(resource->list_of_dma_buf_fds[i]);
|
||||
|
||||
if (IS_ERR_VALUE(PTR_ERR(resource->dma_bufs[i])))
|
||||
{
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*Check the reservation object associated with dma_buf */
|
||||
if (resource->dma_bufs[i]->resv == NULL) {
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk(KERN_DEBUG "dma_buf_lock_dolock : dma_buf_fd %i dma_buf %p dma_fence reservation %p\n",
|
||||
resource->list_of_dma_buf_fds[i], resource->dma_bufs[i], resource->dma_bufs[i]->resv);
|
||||
#endif
|
||||
}
|
||||
|
||||
init_waitqueue_head(&resource->wait);
|
||||
|
||||
kref_get(&resource->refcount);
|
||||
|
||||
/* Create file descriptor associated with lock request */
|
||||
fd = anon_inode_getfd("dma_buf_lock", &dma_buf_lock_handle_fops,
|
||||
(void *)resource, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
return fd;
|
||||
}
|
||||
|
||||
resource->exclusive = request->exclusive;
|
||||
|
||||
/* Start locking process */
|
||||
ret = dma_buf_lock_acquire_fence_reservation(resource, &ww_ctx);
|
||||
if (ret) {
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk(KERN_DEBUG "dma_buf_lock_dolock : Error %d locking reservations.\n", ret);
|
||||
#endif
|
||||
put_unused_fd(fd);
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Take an extra reference for exclusive access, which will be dropped
|
||||
* once the pre-existing fences attached to dma-buf resources, for which
|
||||
* we have commited for exclusive access, are signaled.
|
||||
* At a given time there can be only one exclusive fence attached to a
|
||||
* reservation object, so the new exclusive fence replaces the original
|
||||
* fence and the future sync is done against the new fence which is
|
||||
* supposed to be signaled only after the original fence was signaled.
|
||||
* If the new exclusive fence is signaled prematurely then the resources
|
||||
* would become available for new access while they are already being
|
||||
* written to by the original owner.
|
||||
*/
|
||||
if (resource->exclusive)
|
||||
kref_get(&resource->refcount);
|
||||
|
||||
for (i = 0; i < request->count; i++) {
|
||||
#if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
|
||||
struct reservation_object *resv = resource->dma_bufs[i]->resv;
|
||||
#else
|
||||
struct dma_resv *resv = resource->dma_bufs[i]->resv;
|
||||
#endif
|
||||
if (!test_bit(i, &resource->exclusive)) {
|
||||
|
||||
#if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
|
||||
ret = reservation_object_reserve_shared(resv);
|
||||
#else
|
||||
ret = dma_resv_reserve_shared(resv, 0);
|
||||
#endif
|
||||
if (ret) {
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk(KERN_DEBUG "dma_buf_lock_dolock : Error %d reserving space for shared fence.\n", ret);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
ret = dma_buf_lock_add_fence_reservation_callback(resource,
|
||||
resv,
|
||||
false);
|
||||
if (ret) {
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk(KERN_DEBUG "dma_buf_lock_dolock : Error %d adding reservation to callback.\n", ret);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
|
||||
reservation_object_add_shared_fence(resv, &resource->fence);
|
||||
#else
|
||||
dma_resv_add_shared_fence(resv, &resource->fence);
|
||||
#endif
|
||||
} else {
|
||||
ret = dma_buf_lock_add_fence_reservation_callback(resource,
|
||||
resv,
|
||||
true);
|
||||
if (ret) {
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk(KERN_DEBUG "dma_buf_lock_dolock : Error %d adding reservation to callback.\n", ret);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE)
|
||||
reservation_object_add_excl_fence(resv, &resource->fence);
|
||||
#else
|
||||
dma_resv_add_excl_fence(resv, &resource->fence);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
dma_buf_lock_release_fence_reservation(resource, &ww_ctx);
|
||||
|
||||
/* Test if the callbacks were already triggered */
|
||||
if (!atomic_sub_return(DMA_BUF_LOCK_INIT_BIAS, &resource->fence_dep_count)) {
|
||||
atomic_set(&resource->locked, 1);
|
||||
|
||||
/* Drop the extra reference taken for exclusive access */
|
||||
if (resource->exclusive)
|
||||
dma_buf_lock_fence_work(&resource->work);
|
||||
}
|
||||
|
||||
if (IS_ERR_VALUE((unsigned long)ret))
|
||||
{
|
||||
put_unused_fd(fd);
|
||||
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk("dma_buf_lock_dolock : complete\n");
|
||||
#endif
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void dma_buf_lock_dounlock(struct kref *ref)
|
||||
{
|
||||
int i;
|
||||
dma_buf_lock_resource *resource = container_of(ref, dma_buf_lock_resource, refcount);
|
||||
|
||||
atomic_set(&resource->locked, 0);
|
||||
|
||||
/* Signal the resource's fence. */
|
||||
dma_fence_signal(&resource->fence);
|
||||
|
||||
dma_buf_lock_fence_free_callbacks(resource);
|
||||
|
||||
list_del(&resource->link);
|
||||
|
||||
for (i = 0; i < resource->count; i++)
|
||||
{
|
||||
if (resource->dma_bufs[i])
|
||||
dma_buf_put(resource->dma_bufs[i]);
|
||||
}
|
||||
|
||||
kfree(resource->dma_bufs);
|
||||
kfree(resource->list_of_dma_buf_fds);
|
||||
dma_fence_put(&resource->fence);
|
||||
}
|
||||
|
||||
static int __init dma_buf_lock_init(void)
|
||||
{
|
||||
int err;
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk("dma_buf_lock_init\n");
|
||||
#endif
|
||||
err = alloc_chrdev_region(&dma_buf_lock_dev, 0, 1, dma_buf_lock_dev_name);
|
||||
|
||||
if (err == 0) {
|
||||
cdev_init(&dma_buf_lock_cdev, &dma_buf_lock_fops);
|
||||
|
||||
err = cdev_add(&dma_buf_lock_cdev, dma_buf_lock_dev, 1);
|
||||
|
||||
if (err == 0) {
|
||||
dma_buf_lock_class = class_create(THIS_MODULE, dma_buf_lock_dev_name);
|
||||
if (IS_ERR(dma_buf_lock_class))
|
||||
err = PTR_ERR(dma_buf_lock_class);
|
||||
else
|
||||
{
|
||||
struct device *mdev;
|
||||
mdev = device_create(dma_buf_lock_class, NULL, dma_buf_lock_dev, NULL, dma_buf_lock_dev_name);
|
||||
if (!IS_ERR(mdev))
|
||||
return 0;
|
||||
|
||||
err = PTR_ERR(mdev);
|
||||
class_destroy(dma_buf_lock_class);
|
||||
}
|
||||
cdev_del(&dma_buf_lock_cdev);
|
||||
}
|
||||
|
||||
unregister_chrdev_region(dma_buf_lock_dev, 1);
|
||||
}
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk("dma_buf_lock_init failed\n");
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit dma_buf_lock_exit(void)
|
||||
{
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk("dma_buf_lock_exit\n");
|
||||
#endif
|
||||
|
||||
/* Unlock all outstanding references */
|
||||
while (1)
|
||||
{
|
||||
mutex_lock(&dma_buf_lock_mutex);
|
||||
if (list_empty(&dma_buf_lock_resource_list))
|
||||
{
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_buf_lock_resource *resource = list_entry(dma_buf_lock_resource_list.next,
|
||||
dma_buf_lock_resource, link);
|
||||
kref_put(&resource->refcount, dma_buf_lock_dounlock);
|
||||
mutex_unlock(&dma_buf_lock_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
device_destroy(dma_buf_lock_class, dma_buf_lock_dev);
|
||||
|
||||
class_destroy(dma_buf_lock_class);
|
||||
|
||||
cdev_del(&dma_buf_lock_cdev);
|
||||
|
||||
unregister_chrdev_region(dma_buf_lock_dev, 1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_UNLOCKED_IOCTL
|
||||
static long dma_buf_lock_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
#else
|
||||
static int dma_buf_lock_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
#endif
|
||||
{
|
||||
dma_buf_lock_k_request request;
|
||||
int size = _IOC_SIZE(cmd);
|
||||
|
||||
if (_IOC_TYPE(cmd) != DMA_BUF_LOCK_IOC_MAGIC)
|
||||
return -ENOTTY;
|
||||
if ((_IOC_NR(cmd) < DMA_BUF_LOCK_IOC_MINNR) || (_IOC_NR(cmd) > DMA_BUF_LOCK_IOC_MAXNR))
|
||||
return -ENOTTY;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case DMA_BUF_LOCK_FUNC_LOCK_ASYNC:
|
||||
if (size != sizeof(dma_buf_lock_k_request))
|
||||
return -ENOTTY;
|
||||
if (copy_from_user(&request, (void __user *)arg, size))
|
||||
return -EFAULT;
|
||||
#if DMA_BUF_LOCK_DEBUG
|
||||
printk("DMA_BUF_LOCK_FUNC_LOCK_ASYNC - %i\n", request.count);
|
||||
#endif
|
||||
return dma_buf_lock_dolock(&request);
|
||||
}
|
||||
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
module_init(dma_buf_lock_init);
|
||||
module_exit(dma_buf_lock_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
46
drivers/base/arm/dma_buf_lock/src/dma_buf_lock.h
Normal file
46
drivers/base/arm/dma_buf_lock/src/dma_buf_lock.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2012, 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
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DMA_BUF_LOCK_H
|
||||
#define _DMA_BUF_LOCK_H
|
||||
|
||||
typedef enum dma_buf_lock_exclusive
|
||||
{
|
||||
DMA_BUF_LOCK_NONEXCLUSIVE = 0,
|
||||
DMA_BUF_LOCK_EXCLUSIVE = -1
|
||||
} dma_buf_lock_exclusive;
|
||||
|
||||
typedef struct dma_buf_lock_k_request
|
||||
{
|
||||
int count;
|
||||
int *list_of_dma_buf_fds;
|
||||
int timeout;
|
||||
dma_buf_lock_exclusive exclusive;
|
||||
} dma_buf_lock_k_request;
|
||||
|
||||
#define DMA_BUF_LOCK_IOC_MAGIC '~'
|
||||
|
||||
#define DMA_BUF_LOCK_FUNC_LOCK_ASYNC _IOW(DMA_BUF_LOCK_IOC_MAGIC, 11, dma_buf_lock_k_request)
|
||||
|
||||
#define DMA_BUF_LOCK_IOC_MINNR 11
|
||||
#define DMA_BUF_LOCK_IOC_MAXNR 11
|
||||
|
||||
#endif /* _DMA_BUF_LOCK_H */
|
||||
23
drivers/base/arm/dma_buf_test_exporter/Kbuild
Normal file
23
drivers/base/arm/dma_buf_test_exporter/Kbuild
Normal file
@@ -0,0 +1,23 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2012, 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
|
||||
# Foundation, and any use by you of this program is subject to the terms
|
||||
# of such GNU license.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
#
|
||||
|
||||
ifeq ($(CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER), y)
|
||||
obj-m += dma-buf-test-exporter.o
|
||||
endif
|
||||
36
drivers/base/arm/dma_buf_test_exporter/build.bp
Normal file
36
drivers/base/arm/dma_buf_test_exporter/build.bp
Normal file
@@ -0,0 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2017, 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
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
bob_kernel_module {
|
||||
name: "dma-buf-test-exporter",
|
||||
defaults: [
|
||||
"kernel_defaults"
|
||||
],
|
||||
srcs: [
|
||||
"Kbuild",
|
||||
"dma-buf-test-exporter.c",
|
||||
],
|
||||
enabled: false,
|
||||
dma_shared_buffer_test_exporter: {
|
||||
kbuild_options: ["CONFIG_DMA_SHARED_BUFFER_TEST_EXPORTER=y"],
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
824
drivers/base/arm/dma_buf_test_exporter/dma-buf-test-exporter.c
Normal file
824
drivers/base/arm/dma_buf_test_exporter/dma-buf-test-exporter.c
Normal file
@@ -0,0 +1,824 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2012-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
|
||||
* Foundation, and any use by you of this program is subject to the terms
|
||||
* of such GNU license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can access it online at
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/dma-buf-test-exporter.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/highmem.h>
|
||||
#if (KERNEL_VERSION(4, 8, 0) > LINUX_VERSION_CODE)
|
||||
#include <linux/dma-attrs.h>
|
||||
#endif
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
/* Maximum size allowed in a single DMA_BUF_TE_ALLOC call */
|
||||
#define DMA_BUF_TE_ALLOC_MAX_SIZE ((8ull << 30) >> PAGE_SHIFT) /* 8 GB */
|
||||
|
||||
/* Since kernel version 5.0 CONFIG_ARCH_NO_SG_CHAIN replaced CONFIG_ARCH_HAS_SG_CHAIN */
|
||||
#if KERNEL_VERSION(5, 0, 0) > LINUX_VERSION_CODE
|
||||
#if (!defined(ARCH_HAS_SG_CHAIN) && !defined(CONFIG_ARCH_HAS_SG_CHAIN))
|
||||
#define NO_SG_CHAIN
|
||||
#endif
|
||||
#elif defined(CONFIG_ARCH_NO_SG_CHAIN)
|
||||
#define NO_SG_CHAIN
|
||||
#endif
|
||||
|
||||
struct dma_buf_te_alloc {
|
||||
/* the real alloc */
|
||||
size_t nr_pages;
|
||||
struct page **pages;
|
||||
|
||||
/* the debug usage tracking */
|
||||
int nr_attached_devices;
|
||||
int nr_device_mappings;
|
||||
int nr_cpu_mappings;
|
||||
|
||||
/* failure simulation */
|
||||
int fail_attach;
|
||||
int fail_map;
|
||||
int fail_mmap;
|
||||
|
||||
bool contiguous;
|
||||
dma_addr_t contig_dma_addr;
|
||||
void *contig_cpu_addr;
|
||||
};
|
||||
|
||||
struct dma_buf_te_attachment {
|
||||
struct sg_table *sg;
|
||||
bool attachment_mapped;
|
||||
};
|
||||
|
||||
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)
|
||||
#else
|
||||
static int dma_buf_te_attach(struct dma_buf *buf, struct dma_buf_attachment *attachment)
|
||||
#endif
|
||||
{
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
alloc = buf->priv;
|
||||
|
||||
if (alloc->fail_attach)
|
||||
return -EFAULT;
|
||||
|
||||
attachment->priv = kzalloc(sizeof(struct dma_buf_te_attachment), GFP_KERNEL);
|
||||
if (!attachment->priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* dma_buf is externally locked during call */
|
||||
alloc->nr_attached_devices++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dma_buf_te_detach(struct dma_buf *buf, struct dma_buf_attachment *attachment)
|
||||
{
|
||||
struct dma_buf_te_alloc *alloc = buf->priv;
|
||||
struct dma_buf_te_attachment *pa = attachment->priv;
|
||||
|
||||
/* dma_buf is externally locked during call */
|
||||
|
||||
WARN(pa->attachment_mapped, "WARNING: dma-buf-test-exporter detected detach with open device mappings");
|
||||
|
||||
alloc->nr_attached_devices--;
|
||||
|
||||
kfree(pa);
|
||||
}
|
||||
|
||||
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_attachment *pa = attachment->priv;
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
alloc = attachment->dmabuf->priv;
|
||||
|
||||
if (alloc->fail_map)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (WARN(pa->attachment_mapped,
|
||||
"WARNING: Attempted to map already mapped attachment."))
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
#ifdef NO_SG_CHAIN
|
||||
/* if the ARCH can't chain we can't have allocs larger than a single sg can hold */
|
||||
if (alloc->nr_pages > SG_MAX_SINGLE_ALLOC)
|
||||
return ERR_PTR(-EINVAL);
|
||||
#endif /* NO_SG_CHAIN */
|
||||
|
||||
sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
|
||||
if (!sg)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* from here we access the allocation object, so lock the dmabuf pointing to it */
|
||||
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(&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_dma_address(sg->sgl) = alloc->contig_dma_addr;
|
||||
} else {
|
||||
for_each_sg(sg->sgl, iter, alloc->nr_pages, i)
|
||||
sg_set_page(iter, alloc->pages[i], PAGE_SIZE, 0);
|
||||
}
|
||||
|
||||
if (!dma_map_sg(attachment->dev, sg->sgl, sg->nents, direction)) {
|
||||
mutex_unlock(&attachment->dmabuf->lock);
|
||||
sg_free_table(sg);
|
||||
kfree(sg);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
alloc->nr_device_mappings++;
|
||||
pa->attachment_mapped = true;
|
||||
pa->sg = sg;
|
||||
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)
|
||||
{
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
struct dma_buf_te_attachment *pa = attachment->priv;
|
||||
|
||||
alloc = attachment->dmabuf->priv;
|
||||
|
||||
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(&attachment->dmabuf->lock);
|
||||
|
||||
dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, direction);
|
||||
sg_free_table(sg);
|
||||
kfree(sg);
|
||||
}
|
||||
|
||||
static void dma_buf_te_release(struct dma_buf *buf)
|
||||
{
|
||||
size_t i;
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
alloc = buf->priv;
|
||||
/* no need for locking */
|
||||
|
||||
if (alloc->contiguous) {
|
||||
#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE)
|
||||
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
|
||||
DEFINE_DMA_ATTRS(attrs);
|
||||
|
||||
dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
|
||||
dma_free_attrs(te_device.this_device,
|
||||
alloc->nr_pages * PAGE_SIZE,
|
||||
alloc->contig_cpu_addr, alloc->contig_dma_addr, &attrs);
|
||||
#endif
|
||||
} else {
|
||||
for (i = 0; i < alloc->nr_pages; i++)
|
||||
__free_page(alloc->pages[i]);
|
||||
}
|
||||
#if (KERNEL_VERSION(4, 12, 0) <= LINUX_VERSION_CODE)
|
||||
kvfree(alloc->pages);
|
||||
#else
|
||||
kfree(alloc->pages);
|
||||
#endif
|
||||
kfree(alloc);
|
||||
}
|
||||
|
||||
static int dma_buf_te_sync(struct dma_buf *dmabuf,
|
||||
enum dma_data_direction direction,
|
||||
bool start_cpu_access)
|
||||
{
|
||||
struct dma_buf_attachment *attachment;
|
||||
|
||||
mutex_lock(&dmabuf->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));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (start_cpu_access) {
|
||||
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));
|
||||
|
||||
dma_sync_sg_for_device(attachment->dev, sg->sgl, sg->nents, direction);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&dmabuf->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE)
|
||||
static int dma_buf_te_begin_cpu_access(struct dma_buf *dmabuf,
|
||||
enum dma_data_direction direction)
|
||||
#else
|
||||
static int dma_buf_te_begin_cpu_access(struct dma_buf *dmabuf, size_t start,
|
||||
size_t len,
|
||||
enum dma_data_direction direction)
|
||||
#endif
|
||||
{
|
||||
return dma_buf_te_sync(dmabuf, direction, true);
|
||||
}
|
||||
|
||||
#if (KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE)
|
||||
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);
|
||||
}
|
||||
#else
|
||||
static void dma_buf_te_end_cpu_access(struct dma_buf *dmabuf, size_t start,
|
||||
size_t len,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
dma_buf_te_sync(dmabuf, direction, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dma_buf_te_mmap_open(struct vm_area_struct *vma)
|
||||
{
|
||||
struct dma_buf *dma_buf;
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
dma_buf = vma->vm_private_data;
|
||||
alloc = dma_buf->priv;
|
||||
|
||||
mutex_lock(&dma_buf->lock);
|
||||
alloc->nr_cpu_mappings++;
|
||||
mutex_unlock(&dma_buf->lock);
|
||||
}
|
||||
|
||||
static void dma_buf_te_mmap_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct dma_buf *dma_buf;
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
dma_buf = vma->vm_private_data;
|
||||
alloc = dma_buf->priv;
|
||||
|
||||
BUG_ON(alloc->nr_cpu_mappings <= 0);
|
||||
mutex_lock(&dma_buf->lock);
|
||||
alloc->nr_cpu_mappings--;
|
||||
mutex_unlock(&dma_buf->lock);
|
||||
}
|
||||
|
||||
#if KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE
|
||||
static int dma_buf_te_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
#elif KERNEL_VERSION(5, 1, 0) > LINUX_VERSION_CODE
|
||||
static int dma_buf_te_mmap_fault(struct vm_fault *vmf)
|
||||
#else
|
||||
static vm_fault_t dma_buf_te_mmap_fault(struct vm_fault *vmf)
|
||||
#endif
|
||||
{
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
struct dma_buf *dmabuf;
|
||||
struct page *pageptr;
|
||||
|
||||
#if KERNEL_VERSION(4, 11, 0) > LINUX_VERSION_CODE
|
||||
dmabuf = vma->vm_private_data;
|
||||
#else
|
||||
dmabuf = vmf->vma->vm_private_data;
|
||||
#endif
|
||||
alloc = dmabuf->priv;
|
||||
|
||||
if (vmf->pgoff > alloc->nr_pages)
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
||||
pageptr = alloc->pages[vmf->pgoff];
|
||||
|
||||
BUG_ON(!pageptr);
|
||||
|
||||
get_page(pageptr);
|
||||
vmf->page = pageptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
alloc = dmabuf->priv;
|
||||
|
||||
if (alloc->fail_mmap)
|
||||
return -ENOMEM;
|
||||
|
||||
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
|
||||
vma->vm_ops = &dma_buf_te_vm_ops;
|
||||
vma->vm_private_data = dmabuf;
|
||||
|
||||
/* we fault in the pages on access */
|
||||
|
||||
/* call open to do the ref-counting */
|
||||
dma_buf_te_vm_ops.open(vma);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE
|
||||
static void *dma_buf_te_kmap_atomic(struct dma_buf *buf, unsigned long page_num)
|
||||
{
|
||||
/* IGNORE */
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *dma_buf_te_kmap(struct dma_buf *buf, unsigned long page_num)
|
||||
{
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
|
||||
alloc = buf->priv;
|
||||
if (page_num >= alloc->nr_pages)
|
||||
return NULL;
|
||||
|
||||
return kmap(alloc->pages[page_num]);
|
||||
}
|
||||
static void dma_buf_te_kunmap(struct dma_buf *buf,
|
||||
unsigned long page_num, void *addr)
|
||||
{
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
|
||||
alloc = buf->priv;
|
||||
if (page_num >= alloc->nr_pages)
|
||||
return;
|
||||
|
||||
kunmap(alloc->pages[page_num]);
|
||||
return;
|
||||
}
|
||||
|
||||
static struct dma_buf_ops dma_buf_te_ops = {
|
||||
/* real handlers */
|
||||
.attach = dma_buf_te_attach,
|
||||
.detach = dma_buf_te_detach,
|
||||
.map_dma_buf = dma_buf_te_map,
|
||||
.unmap_dma_buf = dma_buf_te_unmap,
|
||||
.release = dma_buf_te_release,
|
||||
.mmap = dma_buf_te_mmap,
|
||||
.begin_cpu_access = dma_buf_te_begin_cpu_access,
|
||||
.end_cpu_access = dma_buf_te_end_cpu_access,
|
||||
#if KERNEL_VERSION(4, 12, 0) > LINUX_VERSION_CODE
|
||||
.kmap = dma_buf_te_kmap,
|
||||
.kunmap = dma_buf_te_kunmap,
|
||||
|
||||
/* nop handlers for mandatory functions we ignore */
|
||||
.kmap_atomic = dma_buf_te_kmap_atomic
|
||||
#else
|
||||
#if KERNEL_VERSION(5, 6, 0) > LINUX_VERSION_CODE
|
||||
.map = dma_buf_te_kmap,
|
||||
.unmap = dma_buf_te_kunmap,
|
||||
#endif
|
||||
|
||||
#if KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE
|
||||
/* nop handlers for mandatory functions we ignore */
|
||||
.map_atomic = dma_buf_te_kmap_atomic
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
static int do_dma_buf_te_ioctl_version(struct dma_buf_te_ioctl_version __user *buf)
|
||||
{
|
||||
struct dma_buf_te_ioctl_version v;
|
||||
|
||||
if (copy_from_user(&v, buf, sizeof(v)))
|
||||
return -EFAULT;
|
||||
|
||||
if (v.op != DMA_BUF_TE_ENQ)
|
||||
return -EFAULT;
|
||||
|
||||
v.op = DMA_BUF_TE_ACK;
|
||||
v.major = DMA_BUF_TE_VER_MAJOR;
|
||||
v.minor = DMA_BUF_TE_VER_MINOR;
|
||||
|
||||
if (copy_to_user(buf, &v, sizeof(v)))
|
||||
return -EFAULT;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_dma_buf_te_ioctl_alloc(struct dma_buf_te_ioctl_alloc __user *buf, bool contiguous)
|
||||
{
|
||||
struct dma_buf_te_ioctl_alloc alloc_req;
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
struct dma_buf *dma_buf;
|
||||
size_t i = 0;
|
||||
size_t max_nr_pages = DMA_BUF_TE_ALLOC_MAX_SIZE;
|
||||
int fd;
|
||||
|
||||
if (copy_from_user(&alloc_req, buf, sizeof(alloc_req))) {
|
||||
dev_err(te_device.this_device, "%s: couldn't get user data", __func__);
|
||||
goto no_input;
|
||||
}
|
||||
|
||||
if (!alloc_req.size) {
|
||||
dev_err(te_device.this_device, "%s: no size specified", __func__);
|
||||
goto invalid_size;
|
||||
}
|
||||
|
||||
#ifdef NO_SG_CHAIN
|
||||
/* Whilst it is possible to allocate larger buffer, we won't be able to
|
||||
* map it during actual usage (mmap() still succeeds). We fail here so
|
||||
* userspace code can deal with it early than having driver failure
|
||||
* later on.
|
||||
*/
|
||||
if (max_nr_pages > SG_MAX_SINGLE_ALLOC)
|
||||
max_nr_pages = SG_MAX_SINGLE_ALLOC;
|
||||
#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);
|
||||
goto invalid_size;
|
||||
}
|
||||
|
||||
alloc = kzalloc(sizeof(struct dma_buf_te_alloc), GFP_KERNEL);
|
||||
if (alloc == NULL) {
|
||||
dev_err(te_device.this_device, "%s: couldn't alloc object", __func__);
|
||||
goto no_alloc_object;
|
||||
}
|
||||
|
||||
alloc->nr_pages = alloc_req.size;
|
||||
alloc->contiguous = contiguous;
|
||||
|
||||
#if (KERNEL_VERSION(4, 12, 0) <= LINUX_VERSION_CODE)
|
||||
alloc->pages = kvzalloc(sizeof(struct page *) * alloc->nr_pages, GFP_KERNEL);
|
||||
#else
|
||||
alloc->pages = kzalloc(sizeof(struct page *) * alloc->nr_pages, GFP_KERNEL);
|
||||
#endif
|
||||
|
||||
if (!alloc->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;
|
||||
|
||||
#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE)
|
||||
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);
|
||||
#else
|
||||
DEFINE_DMA_ATTRS(attrs);
|
||||
|
||||
dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
|
||||
alloc->contig_cpu_addr = dma_alloc_attrs(te_device.this_device,
|
||||
alloc->nr_pages * PAGE_SIZE,
|
||||
&alloc->contig_dma_addr,
|
||||
GFP_KERNEL | __GFP_ZERO, &attrs);
|
||||
#endif
|
||||
if (!alloc->contig_cpu_addr) {
|
||||
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;
|
||||
for (i = 0; i < alloc->nr_pages; i++) {
|
||||
alloc->pages[i] = pfn_to_page(PFN_DOWN(dma_aux));
|
||||
dma_aux += PAGE_SIZE;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < alloc->nr_pages; i++) {
|
||||
alloc->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (alloc->pages[i] == NULL) {
|
||||
dev_err(te_device.this_device, "%s: couldn't alloc page", __func__);
|
||||
goto no_page;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* alloc ready, let's export it */
|
||||
{
|
||||
struct dma_buf_export_info export_info = {
|
||||
.exp_name = "dma_buf_te",
|
||||
.owner = THIS_MODULE,
|
||||
.ops = &dma_buf_te_ops,
|
||||
.size = alloc->nr_pages << PAGE_SHIFT,
|
||||
.flags = O_CLOEXEC | O_RDWR,
|
||||
.priv = alloc,
|
||||
};
|
||||
|
||||
dma_buf = dma_buf_export(&export_info);
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(dma_buf)) {
|
||||
dev_err(te_device.this_device, "%s: couldn't export dma_buf", __func__);
|
||||
goto no_export;
|
||||
}
|
||||
|
||||
/* get fd for buf */
|
||||
fd = dma_buf_fd(dma_buf, O_CLOEXEC);
|
||||
|
||||
if (fd < 0) {
|
||||
dev_err(te_device.this_device, "%s: couldn't get fd from dma_buf", __func__);
|
||||
goto no_fd;
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
||||
no_fd:
|
||||
dma_buf_put(dma_buf);
|
||||
no_export:
|
||||
/* i still valid */
|
||||
no_page:
|
||||
if (contiguous) {
|
||||
#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE)
|
||||
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
|
||||
DEFINE_DMA_ATTRS(attrs);
|
||||
|
||||
dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
|
||||
dma_free_attrs(te_device.this_device,
|
||||
alloc->nr_pages * PAGE_SIZE,
|
||||
alloc->contig_cpu_addr, alloc->contig_dma_addr, &attrs);
|
||||
#endif
|
||||
} else {
|
||||
while (i-- > 0)
|
||||
__free_page(alloc->pages[i]);
|
||||
}
|
||||
free_page_struct:
|
||||
#if (KERNEL_VERSION(4, 12, 0) <= LINUX_VERSION_CODE)
|
||||
kvfree(alloc->pages);
|
||||
#else
|
||||
kfree(alloc->pages);
|
||||
#endif
|
||||
free_alloc_object:
|
||||
kfree(alloc);
|
||||
no_alloc_object:
|
||||
invalid_size:
|
||||
no_input:
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static int do_dma_buf_te_ioctl_status(struct dma_buf_te_ioctl_status __user *arg)
|
||||
{
|
||||
struct dma_buf_te_ioctl_status status;
|
||||
struct dma_buf *dmabuf;
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
int res = -EINVAL;
|
||||
|
||||
if (copy_from_user(&status, arg, sizeof(status)))
|
||||
return -EFAULT;
|
||||
|
||||
dmabuf = dma_buf_get(status.fd);
|
||||
if (IS_ERR_OR_NULL(dmabuf))
|
||||
return -EINVAL;
|
||||
|
||||
/* verify it's one of ours */
|
||||
if (dmabuf->ops != &dma_buf_te_ops)
|
||||
goto err_have_dmabuf;
|
||||
|
||||
/* ours, get the current status */
|
||||
alloc = dmabuf->priv;
|
||||
|
||||
/* lock while reading status to take a snapshot */
|
||||
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(&dmabuf->lock);
|
||||
|
||||
if (copy_to_user(arg, &status, sizeof(status)))
|
||||
goto err_have_dmabuf;
|
||||
|
||||
/* All OK */
|
||||
res = 0;
|
||||
|
||||
err_have_dmabuf:
|
||||
dma_buf_put(dmabuf);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int do_dma_buf_te_ioctl_set_failing(struct dma_buf_te_ioctl_set_failing __user *arg)
|
||||
{
|
||||
struct dma_buf *dmabuf;
|
||||
struct dma_buf_te_ioctl_set_failing f;
|
||||
struct dma_buf_te_alloc *alloc;
|
||||
int res = -EINVAL;
|
||||
|
||||
if (copy_from_user(&f, arg, sizeof(f)))
|
||||
return -EFAULT;
|
||||
|
||||
dmabuf = dma_buf_get(f.fd);
|
||||
if (IS_ERR_OR_NULL(dmabuf))
|
||||
return -EINVAL;
|
||||
|
||||
/* verify it's one of ours */
|
||||
if (dmabuf->ops != &dma_buf_te_ops)
|
||||
goto err_have_dmabuf;
|
||||
|
||||
/* ours, set the fail modes */
|
||||
alloc = dmabuf->priv;
|
||||
/* lock to set the fail modes atomically */
|
||||
mutex_lock(&dmabuf->lock);
|
||||
alloc->fail_attach = f.fail_attach;
|
||||
alloc->fail_map = f.fail_map;
|
||||
alloc->fail_mmap = f.fail_mmap;
|
||||
mutex_unlock(&dmabuf->lock);
|
||||
|
||||
/* success */
|
||||
res = 0;
|
||||
|
||||
err_have_dmabuf:
|
||||
dma_buf_put(dmabuf);
|
||||
return res;
|
||||
}
|
||||
|
||||
static u32 dma_te_buf_fill(struct dma_buf *dma_buf, unsigned int value)
|
||||
{
|
||||
struct dma_buf_attachment *attachment;
|
||||
struct sg_table *sgt;
|
||||
struct scatterlist *sg;
|
||||
unsigned int count;
|
||||
unsigned int offset = 0;
|
||||
int ret = 0;
|
||||
size_t i;
|
||||
|
||||
attachment = dma_buf_attach(dma_buf, te_device.this_device);
|
||||
if (IS_ERR_OR_NULL(attachment))
|
||||
return -EBUSY;
|
||||
|
||||
sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
|
||||
if (IS_ERR_OR_NULL(sgt)) {
|
||||
ret = PTR_ERR(sgt);
|
||||
goto no_import;
|
||||
}
|
||||
|
||||
ret = dma_buf_begin_cpu_access(dma_buf,
|
||||
#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
|
||||
0, dma_buf->size,
|
||||
#endif
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (ret)
|
||||
goto no_cpu_access;
|
||||
|
||||
for_each_sg(sgt->sgl, sg, sgt->nents, count) {
|
||||
for (i = 0; i < sg_dma_len(sg); i = i + PAGE_SIZE) {
|
||||
void *addr = NULL;
|
||||
#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE
|
||||
addr = dma_buf_te_kmap(dma_buf, i >> PAGE_SHIFT);
|
||||
#else
|
||||
addr = dma_buf_kmap(dma_buf, i >> PAGE_SHIFT);
|
||||
#endif
|
||||
if (!addr) {
|
||||
ret = -EPERM;
|
||||
goto no_kmap;
|
||||
}
|
||||
memset(addr, value, PAGE_SIZE);
|
||||
#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE
|
||||
dma_buf_te_kunmap(dma_buf, i >> PAGE_SHIFT, addr);
|
||||
#else
|
||||
dma_buf_kunmap(dma_buf, i >> PAGE_SHIFT, addr);
|
||||
#endif
|
||||
}
|
||||
offset += sg_dma_len(sg);
|
||||
}
|
||||
|
||||
no_kmap:
|
||||
dma_buf_end_cpu_access(dma_buf,
|
||||
#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE
|
||||
0, dma_buf->size,
|
||||
#endif
|
||||
DMA_BIDIRECTIONAL);
|
||||
no_cpu_access:
|
||||
dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
|
||||
no_import:
|
||||
dma_buf_detach(dma_buf, attachment);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (copy_from_user(&f, arg, sizeof(f)))
|
||||
return -EFAULT;
|
||||
|
||||
dmabuf = dma_buf_get(f.fd);
|
||||
if (IS_ERR_OR_NULL(dmabuf))
|
||||
return -EINVAL;
|
||||
|
||||
ret = dma_te_buf_fill(dmabuf, f.value);
|
||||
dma_buf_put(dmabuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long dma_buf_te_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
case DMA_BUF_TE_FILL:
|
||||
return do_dma_buf_te_ioctl_fill((struct dma_buf_te_ioctl_fill __user *)arg);
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct file_operations dma_buf_te_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.unlocked_ioctl = dma_buf_te_ioctl,
|
||||
.compat_ioctl = dma_buf_te_ioctl,
|
||||
};
|
||||
|
||||
static int __init dma_buf_te_init(void)
|
||||
{
|
||||
int res;
|
||||
te_device.minor = MISC_DYNAMIC_MINOR;
|
||||
te_device.name = "dma_buf_te";
|
||||
te_device.fops = &dma_buf_te_fops;
|
||||
|
||||
res = misc_register(&te_device);
|
||||
if (res) {
|
||||
printk(KERN_WARNING"Misc device registration failed of 'dma_buf_te'\n");
|
||||
return res;
|
||||
}
|
||||
te_device.this_device->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
dev_info(te_device.this_device, "dma_buf_te ready\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void __exit dma_buf_te_exit(void)
|
||||
{
|
||||
misc_deregister(&te_device);
|
||||
}
|
||||
|
||||
module_init(dma_buf_te_init);
|
||||
module_exit(dma_buf_te_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
@@ -18,4 +18,6 @@
|
||||
#
|
||||
#
|
||||
|
||||
obj-$(CONFIG_MALI_MEMORY_GROUP_MANAGER) := memory_group_manager.o
|
||||
ifeq ($(CONFIG_MALI_MEMORY_GROUP_MANAGER), y)
|
||||
obj-m := memory_group_manager.o
|
||||
endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -21,10 +21,16 @@
|
||||
|
||||
bob_kernel_module {
|
||||
name: "memory_group_manager",
|
||||
defaults: [
|
||||
"kernel_defaults"
|
||||
],
|
||||
srcs: [
|
||||
"Kbuild",
|
||||
"memory_group_manager.c",
|
||||
],
|
||||
kbuild_options: ["CONFIG_MALI_MEMORY_GROUP_MANAGER=m"],
|
||||
defaults: ["kernel_defaults"],
|
||||
enabled: false,
|
||||
mali_memory_group_manager: {
|
||||
kbuild_options: ["CONFIG_MALI_MEMORY_GROUP_MANAGER=y"],
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
#include <linux/debugfs.h>
|
||||
#endif
|
||||
#include <linux/mm.h>
|
||||
@@ -97,12 +97,12 @@ struct mgm_group {
|
||||
struct mgm_groups {
|
||||
struct mgm_group groups[MEMORY_GROUP_MANAGER_NR_GROUPS];
|
||||
struct device *dev;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
struct dentry *mgm_debugfs_root;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
|
||||
static int mgm_size_get(void *data, u64 *val)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
@@ -18,4 +18,6 @@
|
||||
#
|
||||
#
|
||||
|
||||
obj-$(CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR) := protected_memory_allocator.o
|
||||
ifeq ($(CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR), y)
|
||||
obj-m := protected_memory_allocator.o
|
||||
endif
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# (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
|
||||
# Foundation, and any use by you of this program is subject to the terms
|
||||
# of such GNU license.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can access it online at
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
#
|
||||
#
|
||||
|
||||
# linux build system bootstrap for out-of-tree module
|
||||
|
||||
# default to building for the host
|
||||
ARCH ?= $(shell uname -m)
|
||||
|
||||
# Handle Android Common Kernel source naming
|
||||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
KDIR ?= $(KERNEL_SRC)
|
||||
|
||||
all:
|
||||
$(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../../include" modules CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR=m
|
||||
|
||||
clean:
|
||||
$(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
|
||||
|
||||
modules_install:
|
||||
$(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules_install
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -21,14 +21,16 @@
|
||||
|
||||
bob_kernel_module {
|
||||
name: "protected_memory_allocator",
|
||||
defaults: [
|
||||
"kernel_defaults"
|
||||
],
|
||||
srcs: [
|
||||
"Kbuild",
|
||||
"protected_memory_allocator.c",
|
||||
],
|
||||
kbuild_options: ["CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR=m"],
|
||||
defaults: ["kernel_defaults"],
|
||||
enabled: false,
|
||||
build_csf_only_module: {
|
||||
mali_protected_memory_allocator: {
|
||||
kbuild_options: ["CONFIG_MALI_PROTECTED_MEMORY_ALLOCATOR=y"],
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2012-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
@@ -18,221 +18,237 @@
|
||||
#
|
||||
#
|
||||
|
||||
# Driver version string which is returned to userspace via an ioctl
|
||||
MALI_RELEASE_NAME ?= '"g6p0-01eac0"'
|
||||
|
||||
# Paths required for build
|
||||
|
||||
# make $(src) as absolute path if it is not already, by prefixing $(srctree)
|
||||
# This is to prevent any build issue due to wrong path.
|
||||
src:=$(if $(patsubst /%,,$(src)),$(srctree)/$(src),$(src))
|
||||
KBASE_PATH = $(src)
|
||||
KBASE_PLATFORM_PATH = $(KBASE_PATH)/platform_dummy
|
||||
UMP_PATH = $(src)/../../../base
|
||||
|
||||
#
|
||||
# Prevent misuse when Kernel configurations are not present by default
|
||||
# in out-of-tree builds
|
||||
#
|
||||
ifneq ($(CONFIG_ANDROID),n)
|
||||
ifeq ($(CONFIG_GPU_TRACEPOINTS),n)
|
||||
$(error CONFIG_GPU_TRACEPOINTS must be set in Kernel configuration)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DMA_SHARED_BUFFER),n)
|
||||
$(error CONFIG_DMA_SHARED_BUFFER must be set in Kernel configuration)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PM_DEVFREQ),n)
|
||||
$(error CONFIG_PM_DEVFREQ must be set in Kernel configuration)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DEVFREQ_THERMAL),n)
|
||||
$(error CONFIG_DEVFREQ_THERMAL must be set in Kernel configuration)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND),n)
|
||||
$(error CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND must be set in Kernel configuration)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS), y)
|
||||
ifneq ($(CONFIG_DEBUG_FS), y)
|
||||
$(error CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS depends on CONFIG_DEBUG_FS to be set in Kernel configuration)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MALI_BIFROST_FENCE_DEBUG), y)
|
||||
ifneq ($(CONFIG_SYNC), y)
|
||||
ifneq ($(CONFIG_SYNC_FILE), y)
|
||||
$(error CONFIG_MALI_BIFROST_FENCE_DEBUG depends on CONFIG_SYNC || CONFIG_SYNC_FILE to be set in Kernel configuration)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# Configurations
|
||||
#
|
||||
|
||||
# Driver version string which is returned to userspace via an ioctl
|
||||
MALI_RELEASE_NAME ?= '"g7p1-01bet0"'
|
||||
# Set up defaults if not defined by build system
|
||||
MALI_CUSTOMER_RELEASE ?= 1
|
||||
MALI_UNIT_TEST ?= 0
|
||||
ifeq ($(CONFIG_MALI_BIFROST_DEBUG), y)
|
||||
MALI_UNIT_TEST = 1
|
||||
MALI_CUSTOMER_RELEASE ?= 0
|
||||
else
|
||||
MALI_UNIT_TEST ?= 0
|
||||
MALI_CUSTOMER_RELEASE ?= 1
|
||||
endif
|
||||
MALI_COVERAGE ?= 0
|
||||
|
||||
CONFIG_MALI_PLATFORM_NAME ?= "devicetree"
|
||||
|
||||
# Kconfig passes in the name with quotes for in-tree builds - remove them.
|
||||
MALI_PLATFORM_DIR := $(shell echo $(CONFIG_MALI_PLATFORM_NAME))
|
||||
|
||||
ifeq ($(CONFIG_MALI_CSF_SUPPORT),y)
|
||||
MALI_JIT_PRESSURE_LIMIT_BASE = 0
|
||||
MALI_USE_CSF = 1
|
||||
else
|
||||
MALI_JIT_PRESSURE_LIMIT_BASE ?= 1
|
||||
MALI_USE_CSF ?= 0
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_MALI_KUTF), n)
|
||||
MALI_KERNEL_TEST_API ?= 1
|
||||
else
|
||||
MALI_KERNEL_TEST_API ?= 0
|
||||
endif
|
||||
|
||||
# Experimental features (corresponding -D definition should be appended to
|
||||
# DEFINES below, e.g. for MALI_EXPERIMENTAL_FEATURE,
|
||||
# ccflags-y below, e.g. for MALI_EXPERIMENTAL_FEATURE,
|
||||
# -DMALI_EXPERIMENTAL_FEATURE=$(MALI_EXPERIMENTAL_FEATURE) should be appended)
|
||||
#
|
||||
# Experimental features must default to disabled, e.g.:
|
||||
# MALI_EXPERIMENTAL_FEATURE ?= 0
|
||||
MALI_INCREMENTAL_RENDERING ?= 0
|
||||
|
||||
ifeq ($(CONFIG_MALI_CSF_SUPPORT),y)
|
||||
MALI_JIT_PRESSURE_LIMIT_BASE = 0
|
||||
MALI_USE_CSF = 1
|
||||
else
|
||||
MALI_JIT_PRESSURE_LIMIT_BASE ?= 1
|
||||
MALI_USE_CSF ?= 0
|
||||
endif
|
||||
#
|
||||
# ccflags
|
||||
#
|
||||
ccflags-y = \
|
||||
-DMALI_CUSTOMER_RELEASE=$(MALI_CUSTOMER_RELEASE) \
|
||||
-DMALI_USE_CSF=$(MALI_USE_CSF) \
|
||||
-DMALI_KERNEL_TEST_API=$(MALI_KERNEL_TEST_API) \
|
||||
-DMALI_UNIT_TEST=$(MALI_UNIT_TEST) \
|
||||
-DMALI_COVERAGE=$(MALI_COVERAGE) \
|
||||
-DMALI_RELEASE_NAME=$(MALI_RELEASE_NAME) \
|
||||
-DMALI_JIT_PRESSURE_LIMIT_BASE=$(MALI_JIT_PRESSURE_LIMIT_BASE) \
|
||||
-DMALI_INCREMENTAL_RENDERING=$(MALI_INCREMENTAL_RENDERING) \
|
||||
-DMALI_KBASE_BUILD \
|
||||
-DMALI_PLATFORM_DIR=$(MALI_PLATFORM_DIR)
|
||||
|
||||
ifneq ($(CONFIG_MALI_KUTF), n)
|
||||
MALI_KERNEL_TEST_API ?= 1
|
||||
else
|
||||
MALI_KERNEL_TEST_API ?= 0
|
||||
endif
|
||||
|
||||
# Set up our defines, which will be passed to gcc
|
||||
DEFINES = \
|
||||
-DMALI_CUSTOMER_RELEASE=$(MALI_CUSTOMER_RELEASE) \
|
||||
-DMALI_USE_CSF=$(MALI_USE_CSF) \
|
||||
-DMALI_KERNEL_TEST_API=$(MALI_KERNEL_TEST_API) \
|
||||
-DMALI_UNIT_TEST=$(MALI_UNIT_TEST) \
|
||||
-DMALI_COVERAGE=$(MALI_COVERAGE) \
|
||||
-DMALI_RELEASE_NAME=$(MALI_RELEASE_NAME) \
|
||||
-DMALI_JIT_PRESSURE_LIMIT_BASE=$(MALI_JIT_PRESSURE_LIMIT_BASE) \
|
||||
-DMALI_INCREMENTAL_RENDERING=$(MALI_INCREMENTAL_RENDERING)
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
# in-tree
|
||||
DEFINES +=-DMALI_KBASE_PLATFORM_PATH=../../$(src)/platform/$(CONFIG_MALI_PLATFORM_NAME)
|
||||
ccflags-y +=-DMALI_KBASE_PLATFORM_PATH=../../$(src)/platform/$(CONFIG_MALI_PLATFORM_NAME)
|
||||
else
|
||||
# out-of-tree
|
||||
DEFINES +=-DMALI_KBASE_PLATFORM_PATH=$(src)/platform/$(CONFIG_MALI_PLATFORM_NAME)
|
||||
ccflags-y +=-DMALI_KBASE_PLATFORM_PATH=$(src)/platform/$(CONFIG_MALI_PLATFORM_NAME)
|
||||
endif
|
||||
|
||||
DEFINES += -I$(srctree)/drivers/staging/android
|
||||
ccflags-y += \
|
||||
-I$(srctree)/include/linux \
|
||||
-I$(srctree)/drivers/staging/android \
|
||||
-I$(src) \
|
||||
-I$(src)/platform/$(MALI_PLATFORM_DIR) \
|
||||
-I$(src)/../../../base \
|
||||
-I$(src)/../../../../include
|
||||
|
||||
DEFINES += -DMALI_KBASE_BUILD
|
||||
subdir-ccflags-y += $(ccflags-y)
|
||||
|
||||
# Use our defines when compiling
|
||||
ccflags-y += $(DEFINES) -I$(KBASE_PATH) -I$(KBASE_PLATFORM_PATH) -I$(UMP_PATH) -I$(srctree)/include/linux
|
||||
subdir-ccflags-y += $(DEFINES) -I$(KBASE_PATH) -I$(KBASE_PLATFORM_PATH) -I$(UMP_PATH) -I$(srctree)/include/linux
|
||||
|
||||
SRC := \
|
||||
context/mali_kbase_context.c \
|
||||
debug/mali_kbase_debug_ktrace.c \
|
||||
device/mali_kbase_device.c \
|
||||
device/mali_kbase_device_hw.c \
|
||||
mali_kbase_cache_policy.c \
|
||||
mali_kbase_ccswe.c \
|
||||
mali_kbase_mem.c \
|
||||
mali_kbase_mem_pool_group.c \
|
||||
mali_kbase_native_mgm.c \
|
||||
mali_kbase_ctx_sched.c \
|
||||
mali_kbase_jm.c \
|
||||
mali_kbase_gpuprops.c \
|
||||
mali_kbase_pm.c \
|
||||
mali_kbase_config.c \
|
||||
mali_kbase_vinstr.c \
|
||||
mali_kbase_hwcnt.c \
|
||||
mali_kbase_hwcnt_gpu.c \
|
||||
mali_kbase_hwcnt_legacy.c \
|
||||
mali_kbase_hwcnt_types.c \
|
||||
mali_kbase_hwcnt_virtualizer.c \
|
||||
mali_kbase_softjobs.c \
|
||||
mali_kbase_hw.c \
|
||||
mali_kbase_debug.c \
|
||||
mali_kbase_gpu_memory_debugfs.c \
|
||||
mali_kbase_mem_linux.c \
|
||||
mali_kbase_core_linux.c \
|
||||
mali_kbase_mem_profile_debugfs.c \
|
||||
mmu/mali_kbase_mmu.c \
|
||||
mmu/mali_kbase_mmu_hw_direct.c \
|
||||
mmu/mali_kbase_mmu_mode_aarch64.c \
|
||||
mali_kbase_disjoint_events.c \
|
||||
mali_kbase_debug_mem_view.c \
|
||||
mali_kbase_smc.c \
|
||||
mali_kbase_mem_pool.c \
|
||||
mali_kbase_mem_pool_debugfs.c \
|
||||
mali_kbase_debugfs_helper.c \
|
||||
mali_kbase_strings.c \
|
||||
mali_kbase_as_fault_debugfs.c \
|
||||
mali_kbase_regs_history_debugfs.c \
|
||||
mali_kbase_dvfs_debugfs.c \
|
||||
mali_power_gpu_frequency_trace.c \
|
||||
mali_kbase_trace_gpu_mem.c \
|
||||
thirdparty/mali_kbase_mmap.c \
|
||||
tl/mali_kbase_timeline.c \
|
||||
tl/mali_kbase_timeline_io.c \
|
||||
tl/mali_kbase_tlstream.c \
|
||||
tl/mali_kbase_tracepoints.c \
|
||||
gpu/mali_kbase_gpu.c
|
||||
|
||||
ifeq ($(MALI_USE_CSF),1)
|
||||
SRC += \
|
||||
mali_kbase_hwcnt_backend_csf.c \
|
||||
mali_kbase_hwcnt_backend_csf_if_fw.c \
|
||||
debug/backend/mali_kbase_debug_ktrace_csf.c \
|
||||
device/backend/mali_kbase_device_csf.c \
|
||||
device/backend/mali_kbase_device_hw_csf.c \
|
||||
gpu/backend/mali_kbase_gpu_fault_csf.c \
|
||||
tl/backend/mali_kbase_timeline_csf.c \
|
||||
mmu/backend/mali_kbase_mmu_csf.c \
|
||||
context/backend/mali_kbase_context_csf.c
|
||||
else
|
||||
SRC += \
|
||||
mali_kbase_hwcnt_backend_jm.c \
|
||||
mali_kbase_dummy_job_wa.c \
|
||||
mali_kbase_debug_job_fault.c \
|
||||
mali_kbase_event.c \
|
||||
mali_kbase_jd.c \
|
||||
mali_kbase_jd_debugfs.c \
|
||||
mali_kbase_js.c \
|
||||
mali_kbase_js_ctx_attr.c \
|
||||
mali_kbase_kinstr_jm.c \
|
||||
debug/backend/mali_kbase_debug_ktrace_jm.c \
|
||||
device/backend/mali_kbase_device_jm.c \
|
||||
device/backend/mali_kbase_device_hw_jm.c \
|
||||
gpu/backend/mali_kbase_gpu_fault_jm.c \
|
||||
tl/backend/mali_kbase_timeline_jm.c \
|
||||
mmu/backend/mali_kbase_mmu_jm.c \
|
||||
context/backend/mali_kbase_context_jm.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MALI_CINSTR_GWT),y)
|
||||
SRC += mali_kbase_gwt.c
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(MALI_CUSTOMER_RELEASE),0)
|
||||
SRC += mali_kbase_regs_dump_debugfs.c
|
||||
endif
|
||||
|
||||
|
||||
ccflags-y += -I$(KBASE_PATH) -I$(KBASE_PATH)/debug \
|
||||
-I$(KBASE_PATH)/debug/backend
|
||||
|
||||
# Tell the Linux build system from which .o file to create the kernel module
|
||||
#
|
||||
# Kernel Modules
|
||||
#
|
||||
obj-$(CONFIG_MALI_BIFROST) += bifrost_kbase.o
|
||||
obj-$(CONFIG_MALI_KUTF) += tests/
|
||||
|
||||
# Tell the Linux build system to enable building of our .c files
|
||||
bifrost_kbase-y := $(SRC:.c=.o)
|
||||
bifrost_kbase-y := \
|
||||
mali_kbase_cache_policy.o \
|
||||
mali_kbase_ccswe.o \
|
||||
mali_kbase_mem.o \
|
||||
mali_kbase_mem_pool_group.o \
|
||||
mali_kbase_native_mgm.o \
|
||||
mali_kbase_ctx_sched.o \
|
||||
mali_kbase_gpuprops.o \
|
||||
mali_kbase_pm.o \
|
||||
mali_kbase_config.o \
|
||||
mali_kbase_vinstr.o \
|
||||
mali_kbase_hwcnt.o \
|
||||
mali_kbase_hwcnt_gpu.o \
|
||||
mali_kbase_hwcnt_legacy.o \
|
||||
mali_kbase_hwcnt_types.o \
|
||||
mali_kbase_hwcnt_virtualizer.o \
|
||||
mali_kbase_softjobs.o \
|
||||
mali_kbase_hw.o \
|
||||
mali_kbase_debug.o \
|
||||
mali_kbase_gpu_memory_debugfs.o \
|
||||
mali_kbase_mem_linux.o \
|
||||
mali_kbase_core_linux.o \
|
||||
mali_kbase_mem_profile_debugfs.o \
|
||||
mali_kbase_disjoint_events.o \
|
||||
mali_kbase_debug_mem_view.o \
|
||||
mali_kbase_smc.o \
|
||||
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 \
|
||||
mali_power_gpu_frequency_trace.o \
|
||||
mali_kbase_trace_gpu_mem.o
|
||||
|
||||
# Kconfig passes in the name with quotes for in-tree builds - remove them.
|
||||
platform_name := $(shell echo $(CONFIG_MALI_PLATFORM_NAME))
|
||||
MALI_PLATFORM_DIR := platform/$(platform_name)
|
||||
ccflags-y += -I$(src)/$(MALI_PLATFORM_DIR)
|
||||
include $(src)/$(MALI_PLATFORM_DIR)/Kbuild
|
||||
bifrost_kbase-$(CONFIG_MALI_CINSTR_GWT) += mali_kbase_gwt.o
|
||||
|
||||
ifeq ($(CONFIG_MALI_BIFROST_DEVFREQ),y)
|
||||
ifeq ($(CONFIG_DEVFREQ_THERMAL),y)
|
||||
include $(src)/ipa/Kbuild
|
||||
endif
|
||||
bifrost_kbase-$(CONFIG_SYNC) += \
|
||||
mali_kbase_sync_android.o \
|
||||
mali_kbase_sync_common.o
|
||||
|
||||
bifrost_kbase-$(CONFIG_SYNC_FILE) += \
|
||||
mali_kbase_fence_ops.o \
|
||||
mali_kbase_sync_file.o \
|
||||
mali_kbase_sync_common.o
|
||||
|
||||
ifeq ($(CONFIG_MALI_CSF_SUPPORT),y)
|
||||
bifrost_kbase-y += \
|
||||
mali_kbase_hwcnt_backend_csf.o \
|
||||
mali_kbase_hwcnt_backend_csf_if_fw.o
|
||||
else
|
||||
bifrost_kbase-y += \
|
||||
mali_kbase_jm.o \
|
||||
mali_kbase_hwcnt_backend_jm.o \
|
||||
mali_kbase_dummy_job_wa.o \
|
||||
mali_kbase_debug_job_fault.o \
|
||||
mali_kbase_event.o \
|
||||
mali_kbase_jd.o \
|
||||
mali_kbase_jd_debugfs.o \
|
||||
mali_kbase_js.o \
|
||||
mali_kbase_js_ctx_attr.o \
|
||||
mali_kbase_kinstr_jm.o
|
||||
|
||||
bifrost_kbase-$(CONFIG_MALI_BIFROST_DMA_FENCE) += \
|
||||
mali_kbase_fence_ops.o \
|
||||
mali_kbase_dma_fence.o \
|
||||
mali_kbase_fence.o
|
||||
|
||||
bifrost_kbase-$(CONFIG_SYNC_FILE) += \
|
||||
mali_kbase_fence_ops.o \
|
||||
mali_kbase_fence.o
|
||||
endif
|
||||
|
||||
ifeq ($(MALI_USE_CSF),1)
|
||||
include $(src)/csf/Kbuild
|
||||
else
|
||||
# empty
|
||||
|
||||
INCLUDE_SUBDIR = \
|
||||
$(src)/context/Kbuild \
|
||||
$(src)/debug/Kbuild \
|
||||
$(src)/device/Kbuild \
|
||||
$(src)/backend/gpu/Kbuild \
|
||||
$(src)/mmu/Kbuild \
|
||||
$(src)/tl/Kbuild \
|
||||
$(src)/gpu/Kbuild \
|
||||
$(src)/thirdparty/Kbuild \
|
||||
$(src)/platform/$(MALI_PLATFORM_DIR)/Kbuild
|
||||
|
||||
ifeq ($(CONFIG_MALI_CSF_SUPPORT),y)
|
||||
INCLUDE_SUBDIR += $(src)/csf/Kbuild
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MALI_ARBITER_SUPPORT),y)
|
||||
include $(src)/arbiter/Kbuild
|
||||
INCLUDE_SUBDIR += $(src)/arbiter/Kbuild
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MALI_BIFROST_DEVFREQ),y)
|
||||
ifeq ($(CONFIG_DEVFREQ_THERMAL),y)
|
||||
INCLUDE_SUBDIR += $(src)/ipa/Kbuild
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
# in-tree
|
||||
-include $(INCLUDE_SUBDIR)
|
||||
else
|
||||
# empty
|
||||
# out-of-tree
|
||||
include $(INCLUDE_SUBDIR)
|
||||
endif
|
||||
|
||||
ifeq ($(MALI_USE_CSF),0)
|
||||
bifrost_kbase-$(CONFIG_MALI_BIFROST_DMA_FENCE) += \
|
||||
mali_kbase_fence_ops.o \
|
||||
mali_kbase_dma_fence.o \
|
||||
mali_kbase_fence.o
|
||||
|
||||
bifrost_kbase-$(CONFIG_SYNC_FILE) += \
|
||||
mali_kbase_fence_ops.o \
|
||||
mali_kbase_fence.o
|
||||
endif
|
||||
|
||||
bifrost_kbase-$(CONFIG_SYNC) += \
|
||||
mali_kbase_sync_android.o \
|
||||
mali_kbase_sync_common.o
|
||||
|
||||
bifrost_kbase-$(CONFIG_SYNC_FILE) += \
|
||||
mali_kbase_fence_ops.o \
|
||||
mali_kbase_sync_file.o \
|
||||
mali_kbase_sync_common.o
|
||||
|
||||
include $(src)/backend/gpu/Kbuild
|
||||
bifrost_kbase-y += $(BACKEND:.c=.o)
|
||||
|
||||
|
||||
ccflags-y += -I$(src)/backend/gpu
|
||||
subdir-ccflags-y += -I$(src)/backend/gpu
|
||||
|
||||
# For kutf and mali_kutf_irq_latency_test
|
||||
obj-$(CONFIG_MALI_KUTF) += tests/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2012-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
@@ -18,11 +18,12 @@
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
menuconfig MALI_BIFROST
|
||||
tristate "Mali Bifrost series support"
|
||||
select GPU_TRACEPOINTS if ANDROID
|
||||
select DMA_SHARED_BUFFER
|
||||
select PM_DEVFREQ
|
||||
select DEVFREQ_THERMAL
|
||||
default n
|
||||
help
|
||||
Enable this option to build support for a ARM Mali Bifrost GPU.
|
||||
@@ -30,20 +31,43 @@ menuconfig MALI_BIFROST
|
||||
To compile this driver as a module, choose M here:
|
||||
this will generate a single module, called mali_kbase.
|
||||
|
||||
if MALI_BIFROST
|
||||
|
||||
config MALI_PLATFORM_NAME
|
||||
depends on MALI_BIFROST
|
||||
string "Platform name"
|
||||
default "devicetree"
|
||||
help
|
||||
Enter the name of the desired platform configuration directory to
|
||||
include in the build. 'platform/$(MALI_PLATFORM_NAME)/Makefile' must
|
||||
exist.
|
||||
|
||||
config MALI_REAL_HW
|
||||
depends on MALI_BIFROST
|
||||
def_bool !MALI_BIFROST_NO_MALI
|
||||
|
||||
menu "Platform specific options"
|
||||
source "drivers/gpu/arm/midgard/platform/Kconfig"
|
||||
endmenu
|
||||
|
||||
config MALI_CSF_SUPPORT
|
||||
bool "Mali CSF based GPU support"
|
||||
bool "Enable Mali CSF based GPU support"
|
||||
depends on MALI_BIFROST=m
|
||||
default n
|
||||
help
|
||||
Enables support for CSF based GPUs.
|
||||
|
||||
config MALI_BIFROST_GATOR_SUPPORT
|
||||
bool "Enable Streamline tracing support"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
config MALI_BIFROST_DEVFREQ
|
||||
bool "Enable devfreq support for Mali"
|
||||
depends on MALI_BIFROST && PM_DEVFREQ
|
||||
select DEVFREQ_GOV_SIMPLE_ONDEMAND
|
||||
default y
|
||||
help
|
||||
Enables kbase tracing used by the Arm Streamline Performance Analyzer.
|
||||
The tracepoints are used to derive GPU activity charts in Streamline.
|
||||
Support devfreq for Mali.
|
||||
|
||||
Using the devfreq framework and, by default, the simple on-demand
|
||||
governor, the frequency of Mali will be dynamically selected from the
|
||||
available OPPs.
|
||||
|
||||
config MALI_BIFROST_DVFS
|
||||
bool "Enable legacy DVFS"
|
||||
@@ -52,28 +76,25 @@ config MALI_BIFROST_DVFS
|
||||
help
|
||||
Choose this option to enable legacy DVFS in the Mali Midgard DDK.
|
||||
|
||||
config MALI_BIFROST_GATOR_SUPPORT
|
||||
bool "Enable Streamline tracing support"
|
||||
depends on MALI_BIFROST
|
||||
default y
|
||||
help
|
||||
Enables kbase tracing used by the Arm Streamline Performance Analyzer.
|
||||
The tracepoints are used to derive GPU activity charts in Streamline.
|
||||
|
||||
config MALI_BIFROST_ENABLE_TRACE
|
||||
bool "Enable kbase tracing"
|
||||
depends on MALI_BIFROST
|
||||
default y if MALI_BIFROST_DEBUG
|
||||
default n
|
||||
help
|
||||
Enables tracing in kbase. Trace log available through
|
||||
Enables tracing in kbase. Trace log available through
|
||||
the "mali_trace" debugfs file, when the CONFIG_DEBUG_FS is enabled
|
||||
|
||||
config MALI_BIFROST_DEVFREQ
|
||||
bool "devfreq support for Mali"
|
||||
depends on MALI_BIFROST && PM_DEVFREQ
|
||||
select DEVFREQ_GOV_SIMPLE_ONDEMAND
|
||||
help
|
||||
Support devfreq for Mali.
|
||||
|
||||
Using the devfreq framework and, by default, the simpleondemand
|
||||
governor, the frequency of Mali will be dynamically selected from the
|
||||
available OPPs.
|
||||
|
||||
config MALI_BIFROST_DMA_FENCE
|
||||
bool "DMA_BUF fence support for Mali"
|
||||
bool "Enable DMA_BUF fence support for Mali"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
help
|
||||
@@ -82,18 +103,9 @@ config MALI_BIFROST_DMA_FENCE
|
||||
This option should only be enabled if the Linux Kernel has built in
|
||||
support for DMA_BUF fences.
|
||||
|
||||
config MALI_PLATFORM_NAME
|
||||
depends on MALI_BIFROST
|
||||
string "Platform name"
|
||||
default "devicetree"
|
||||
help
|
||||
Enter the name of the desired platform configuration directory to
|
||||
include in the build. 'platform/$(MALI_PLATFORM_NAME)/Kbuild' must
|
||||
exist.
|
||||
|
||||
config MALI_ARBITER_SUPPORT
|
||||
bool "Enable arbiter support for Mali"
|
||||
depends on MALI_BIFROST
|
||||
depends on MALI_BIFROST && !MALI_CSF_SUPPORT
|
||||
default n
|
||||
help
|
||||
Enable support for the arbiter interface in the driver.
|
||||
@@ -102,126 +114,13 @@ config MALI_ARBITER_SUPPORT
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
# MALI_BIFROST_EXPERT configuration options
|
||||
|
||||
menuconfig MALI_BIFROST_EXPERT
|
||||
depends on MALI_BIFROST
|
||||
bool "Enable Expert Settings"
|
||||
default n
|
||||
help
|
||||
Enabling this option and modifying the default settings may produce a driver with performance or
|
||||
other limitations.
|
||||
|
||||
config MALI_CORESTACK
|
||||
bool "Support controlling power to the GPU core stack"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
Enabling this feature on supported GPUs will let the driver powering
|
||||
on/off the GPU core stack independently without involving the Power
|
||||
Domain Controller. This should only be enabled on platforms which
|
||||
integration of the PDC to the Mali GPU is known to be problematic.
|
||||
This feature is currently only supported on t-Six and t-HEx GPUs.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config MALI_BIFROST_DEBUG
|
||||
bool "Debug build"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
Select this option for increased checking and reporting of errors.
|
||||
|
||||
config MALI_BIFROST_FENCE_DEBUG
|
||||
bool "Debug sync fence usage"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT && (SYNC || SYNC_FILE)
|
||||
default y if MALI_BIFROST_DEBUG
|
||||
help
|
||||
Select this option to enable additional checking and reporting on the
|
||||
use of sync fences in the Mali driver.
|
||||
|
||||
This will add a 3s timeout to all sync fence waits in the Mali
|
||||
driver, so that when work for Mali has been waiting on a sync fence
|
||||
for a long time a debug message will be printed, detailing what fence
|
||||
is causing the block, and which dependent Mali atoms are blocked as a
|
||||
result of this.
|
||||
|
||||
The timeout can be changed at runtime through the js_soft_timeout
|
||||
device attribute, where the timeout is specified in milliseconds.
|
||||
|
||||
config MALI_BIFROST_NO_MALI
|
||||
bool "No Mali"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This can be used to test the driver in a simulated environment
|
||||
whereby the hardware is not physically present. If the hardware is physically
|
||||
present it will not be used. This can be used to test the majority of the
|
||||
driver without needing actual hardware or for software benchmarking.
|
||||
All calls to the simulated hardware will complete immediately as if the hardware
|
||||
completed the task.
|
||||
|
||||
config MALI_REAL_HW
|
||||
def_bool !MALI_BIFROST_NO_MALI
|
||||
|
||||
config MALI_BIFROST_ERROR_INJECT
|
||||
bool "Error injection"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT && MALI_BIFROST_NO_MALI
|
||||
default n
|
||||
help
|
||||
Enables insertion of errors to test module failure and recovery mechanisms.
|
||||
|
||||
config MALI_BIFROST_SYSTEM_TRACE
|
||||
bool "Enable system event tracing support"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default y if MALI_BIFROST_DEBUG
|
||||
default n
|
||||
help
|
||||
Choose this option to enable system trace events for each
|
||||
kbase event. This is typically used for debugging but has
|
||||
minimal overhead when not in use. Enable only if you know what
|
||||
you are doing.
|
||||
|
||||
config MALI_2MB_ALLOC
|
||||
bool "Attempt to allocate 2MB pages"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
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 N
|
||||
|
||||
config MALI_PWRSOFT_765
|
||||
bool "PWRSOFT-765 ticket"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
PWRSOFT-765 fixes devfreq cooling devices issues. The fix was merged
|
||||
in kernel v4.10, however if backported into the kernel then this
|
||||
option must be manually selected.
|
||||
|
||||
If using kernel >= v4.10 then say N, otherwise if devfreq cooling
|
||||
changes have been backported say Y to avoid compilation errors.
|
||||
|
||||
config MALI_MEMORY_FULLY_BACKED
|
||||
bool "Memory fully physically-backed"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This option enables full physical backing of all virtual
|
||||
memory allocations in the kernel. Notice that this build
|
||||
option only affects allocations of grow-on-GPU-page-fault
|
||||
memory.
|
||||
|
||||
config MALI_DMA_BUF_MAP_ON_DEMAND
|
||||
bool "Map imported dma-bufs on demand"
|
||||
bool "Enable map imported dma-bufs on demand"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
help
|
||||
This option caused kbase to set up the GPU mapping of imported
|
||||
dma-buf when needed to run atoms. This is the legacy behaviour.
|
||||
dma-buf when needed to run atoms. This is the legacy behavior.
|
||||
|
||||
This is intended for testing and the option will get removed in the
|
||||
future.
|
||||
@@ -240,51 +139,123 @@ config MALI_DMA_BUF_LEGACY_COMPAT
|
||||
flushes in other drivers. This only has an effect for clients using
|
||||
UK 11.18 or older. For later UK versions it is not possible.
|
||||
|
||||
config MALI_HW_ERRATA_1485982_NOT_AFFECTED
|
||||
bool "Disable workaround for BASE_HW_ISSUE_GPU2017_1336"
|
||||
menuconfig MALI_BIFROST_EXPERT
|
||||
depends on MALI_BIFROST
|
||||
bool "Enable Expert Settings"
|
||||
default n
|
||||
help
|
||||
Enabling this option and modifying the default settings may produce
|
||||
a driver with performance or other limitations.
|
||||
|
||||
if MALI_BIFROST_EXPERT
|
||||
|
||||
config MALI_2MB_ALLOC
|
||||
bool "Attempt to allocate 2MB pages"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This option disables the default workaround for GPU2017-1336. The
|
||||
workaround keeps the L2 cache powered up except for powerdown and reset.
|
||||
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.
|
||||
|
||||
The workaround introduces a limitation that will prevent the running of
|
||||
protected mode content on fully coherent platforms, as the switch to IO
|
||||
coherency mode requires the L2 to be turned off.
|
||||
If in doubt, say N
|
||||
|
||||
config MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE
|
||||
bool "Use alternative workaround for BASE_HW_ISSUE_GPU2017_1336"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT && !MALI_HW_ERRATA_1485982_NOT_AFFECTED
|
||||
config MALI_MEMORY_FULLY_BACKED
|
||||
bool "Enable memory fully physically-backed"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This option uses an alternative workaround for GPU2017-1336. Lowering
|
||||
the GPU clock to a, platform specific, known good frequeuncy before
|
||||
powering down the L2 cache. The clock can be specified in the device
|
||||
tree using the property, opp-mali-errata-1485982. Otherwise the
|
||||
slowest clock will be selected.
|
||||
This option enables full physical backing of all virtual
|
||||
memory allocations in the kernel. Notice that this build
|
||||
option only affects allocations of grow-on-GPU-page-fault
|
||||
memory.
|
||||
|
||||
config MALI_CORESTACK
|
||||
bool "Enable support of GPU core stack power control"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
Enabling this feature on supported GPUs will let the driver powering
|
||||
on/off the GPU core stack independently without involving the Power
|
||||
Domain Controller. This should only be enabled on platforms which
|
||||
integration of the PDC to the Mali GPU is known to be problematic.
|
||||
This feature is currently only supported on t-Six and t-HEx GPUs.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
comment "Platform options"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
|
||||
config MALI_BIFROST_NO_MALI
|
||||
bool "Enable No Mali"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This can be used to test the driver in a simulated environment
|
||||
whereby the hardware is not physically present. If the hardware is physically
|
||||
present it will not be used. This can be used to test the majority of the
|
||||
driver without needing actual hardware or for software benchmarking.
|
||||
All calls to the simulated hardware will complete immediately as if the hardware
|
||||
completed the task.
|
||||
|
||||
config MALI_BIFROST_ERROR_INJECT
|
||||
bool "Enable No Mali error injection"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT && MALI_BIFROST_NO_MALI
|
||||
default n
|
||||
help
|
||||
Enables insertion of errors to test module failure and recovery mechanisms.
|
||||
|
||||
config MALI_GEM5_BUILD
|
||||
bool "Enable build of Mali kernel driver for GEM5"
|
||||
depends on MALI_BIFROST
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This option is to do a Mali GEM5 build.
|
||||
If unsure, say N.
|
||||
|
||||
# Instrumentation options.
|
||||
comment "Debug options"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
|
||||
config MALI_JOB_DUMP
|
||||
bool "Enable system level support needed for job dumping"
|
||||
config MALI_BIFROST_DEBUG
|
||||
bool "Enable debug build"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
Choose this option to enable system level support needed for
|
||||
job dumping. This is typically used for instrumentation but has
|
||||
Select this option for increased checking and reporting of errors.
|
||||
|
||||
config MALI_BIFROST_FENCE_DEBUG
|
||||
bool "Enable debug sync fence usage"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT && (SYNC || SYNC_FILE)
|
||||
default y if MALI_BIFROST_DEBUG
|
||||
help
|
||||
Select this option to enable additional checking and reporting on the
|
||||
use of sync fences in the Mali driver.
|
||||
|
||||
This will add a 3s timeout to all sync fence waits in the Mali
|
||||
driver, so that when work for Mali has been waiting on a sync fence
|
||||
for a long time a debug message will be printed, detailing what fence
|
||||
is causing the block, and which dependent Mali atoms are blocked as a
|
||||
result of this.
|
||||
|
||||
The timeout can be changed at runtime through the js_soft_timeout
|
||||
device attribute, where the timeout is specified in milliseconds.
|
||||
|
||||
config MALI_BIFROST_SYSTEM_TRACE
|
||||
bool "Enable system event tracing support"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default y if MALI_BIFROST_DEBUG
|
||||
default n
|
||||
help
|
||||
Choose this option to enable system trace events for each
|
||||
kbase event. This is typically used for debugging but has
|
||||
minimal overhead when not in use. Enable only if you know what
|
||||
you are doing.
|
||||
|
||||
comment "Instrumentation options"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
|
||||
choice
|
||||
prompt "Performance counters set"
|
||||
prompt "Select Performance counters set"
|
||||
default MALI_PRFCNT_SET_PRIMARY
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
|
||||
@@ -321,7 +292,7 @@ config MALI_PRFCNT_SET_TERTIARY
|
||||
endchoice
|
||||
|
||||
config MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS
|
||||
bool "Allow runtime selection of performance counters set via debugfs"
|
||||
bool "Enable runtime selection of performance counters set via debugfs"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT && DEBUG_FS
|
||||
default n
|
||||
help
|
||||
@@ -343,5 +314,65 @@ config MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
source "drivers/gpu/arm/midgard/platform/Kconfig"
|
||||
# source "drivers/gpu/arm/midgard/tests/Kconfig"
|
||||
config MALI_JOB_DUMP
|
||||
bool "Enable system level support needed for job dumping"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
Choose this option to enable system level support needed for
|
||||
job dumping. This is typically used for instrumentation but has
|
||||
minimal overhead when not in use. Enable only if you know what
|
||||
you are doing.
|
||||
|
||||
comment "Workarounds"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
|
||||
config MALI_PWRSOFT_765
|
||||
bool "Enable workaround for PWRSOFT-765"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
PWRSOFT-765 fixes devfreq cooling devices issues. The fix was merged
|
||||
in kernel v4.10, however if backported into the kernel then this
|
||||
option must be manually selected.
|
||||
|
||||
If using kernel >= v4.10 then say N, otherwise if devfreq cooling
|
||||
changes have been backported say Y to avoid compilation errors.
|
||||
|
||||
config MALI_HW_ERRATA_1485982_NOT_AFFECTED
|
||||
bool "Disable workaround for BASE_HW_ISSUE_GPU2017_1336"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This option disables the default workaround for GPU2017-1336. The
|
||||
workaround keeps the L2 cache powered up except for powerdown and reset.
|
||||
|
||||
The workaround introduces a limitation that will prevent the running of
|
||||
protected mode content on fully coherent platforms, as the switch to IO
|
||||
coherency mode requires the L2 to be turned off.
|
||||
|
||||
config MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE
|
||||
bool "Use alternative workaround for BASE_HW_ISSUE_GPU2017_1336"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT && !MALI_HW_ERRATA_1485982_NOT_AFFECTED
|
||||
default n
|
||||
help
|
||||
This option uses an alternative workaround for GPU2017-1336. Lowering
|
||||
the GPU clock to a, platform specific, known good frequency before
|
||||
powering down the L2 cache. The clock can be specified in the device
|
||||
tree using the property, opp-mali-errata-1485982. Otherwise the
|
||||
slowest clock will be selected.
|
||||
|
||||
endif
|
||||
|
||||
config MALI_ARBITRATION
|
||||
bool "Enable Virtualization reference code"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
help
|
||||
Enables the build of several reference modules used in the reference
|
||||
virtualization setup for Mali
|
||||
If unsure, say N.
|
||||
|
||||
source "drivers/gpu/arm/midgard/tests/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
@@ -18,47 +18,198 @@
|
||||
#
|
||||
#
|
||||
|
||||
# Handle Android Common Kernel source naming
|
||||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
KDIR ?= $(KERNEL_SRC)
|
||||
|
||||
# out-of-tree
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
export CONFIG_MALI_MIDGARD?=m
|
||||
|
||||
ifneq ($(CONFIG_MALI_MIDGARD),n)
|
||||
export CONFIG_MALI_CSF_SUPPORT?=n
|
||||
export CONFIG_MALI_KUTF?=m
|
||||
export CONFIG_MALI_REAL_HW?=y
|
||||
|
||||
# Handle default y/m in Kconfig
|
||||
export CONFIG_MALI_BIFROST_GATOR_SUPPORT?=y
|
||||
export CONFIG_MALI_BIFROST_DEVFREQ?=n
|
||||
ifneq ($(CONFIG_PM_DEVFREQ),n)
|
||||
export CONFIG_MALI_BIFROST_DEVFREQ?=y
|
||||
ifeq ($(KDIR),)
|
||||
$(error Must specify KDIR to point to the kernel to target))
|
||||
endif
|
||||
|
||||
DEFINES += -DCONFIG_MALI_MIDGARD=$(CONFIG_MALI_MIDGARD) \
|
||||
-DCONFIG_MALI_CSF_SUPPORT=$(CONFIG_MALI_CSF_SUPPORT) \
|
||||
-DCONFIG_MALI_KUTF=$(CONFIG_MALI_KUTF) \
|
||||
-DCONFIG_MALI_REAL_HW=$(CONFIG_MALI_REAL_HW) \
|
||||
-DCONFIG_MALI_GATOR_SUPPORT=$(CONFIG_MALI_BIFROST_GATOR_SUPPORT) \
|
||||
-DCONFIG_MALI_DEVFREQ=$(CONFIG_MALI_BIFROST_DEVFREQ)
|
||||
#
|
||||
# Default configuration values
|
||||
#
|
||||
# Dependency resolution is done through statements as Kconfig
|
||||
# is not supported for out-of-tree builds.
|
||||
#
|
||||
|
||||
export DEFINES
|
||||
CONFIG_MALI_BIFROST ?= m
|
||||
ifeq ($(CONFIG_MALI_BIFROST),m)
|
||||
CONFIG_MALI_BIFROST_GATOR_SUPPORT ?= y
|
||||
CONFIG_MALI_ARBITRATION ?= n
|
||||
CONFIG_MALI_PARTITION_MANAGER ?= n
|
||||
|
||||
endif
|
||||
ifneq ($(CONFIG_MALI_BIFROST_NO_MALI),y)
|
||||
# Prevent misuse when CONFIG_MALI_BIFROST_NO_MALI=y
|
||||
CONFIG_MALI_REAL_HW ?= y
|
||||
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_BSP_HAS_HYPERVISOR),y)
|
||||
ifneq ($(CONFIG_MALI_ARBITRATION), n)
|
||||
CONFIG_MALI_XEN ?= m
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# Expert/Debug/Test released configurations
|
||||
#
|
||||
ifeq ($(CONFIG_MALI_BIFROST_EXPERT), y)
|
||||
ifeq ($(CONFIG_MALI_BIFROST_NO_MALI), y)
|
||||
CONFIG_MALI_REAL_HW = n
|
||||
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), y)
|
||||
CONFIG_MALI_BIFROST_FENCE_DEBUG ?= y
|
||||
else
|
||||
ifeq ($(CONFIG_SYNC_FILE), y)
|
||||
CONFIG_MALI_BIFROST_FENCE_DEBUG ?= y
|
||||
else
|
||||
CONFIG_MALI_BIFROST_FENCE_DEBUG = n
|
||||
endif
|
||||
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_MALI_2MB_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
|
||||
else
|
||||
# Prevent misuse when CONFIG_MALI_KUTF=n
|
||||
CONFIG_MALI_KUTF_IRQ_TEST = n
|
||||
CONFIG_MALI_KUTF_CLK_RATE_TRACE = n
|
||||
endif
|
||||
else
|
||||
# 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
|
||||
endif
|
||||
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
|
||||
endif
|
||||
|
||||
KBASE_PATH_RELATIVE = $(CURDIR)
|
||||
# All Mali CONFIG should be listed here
|
||||
CONFIGS := \
|
||||
CONFIG_MALI_BIFROST \
|
||||
CONFIG_MALI_CSF_SUPPORT \
|
||||
CONFIG_MALI_BIFROST_GATOR_SUPPORT \
|
||||
CONFIG_MALI_BIFROST_DMA_FENCE \
|
||||
CONFIG_MALI_ARBITER_SUPPORT \
|
||||
CONFIG_MALI_ARBITRATION \
|
||||
CONFIG_MALI_PARTITION_MANAGER \
|
||||
CONFIG_MALI_REAL_HW \
|
||||
CONFIG_MALI_GEM5_BUILD \
|
||||
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_MALI_2MB_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_XEN
|
||||
|
||||
|
||||
# we get the symbols from modules using KBUILD_EXTRA_SYMBOLS to prevent warnings about unknown functions
|
||||
#
|
||||
# MAKE_ARGS to pass the custom CONFIGs on out-of-tree build
|
||||
#
|
||||
# Generate the list of CONFIGs and values.
|
||||
# $(value config) is the name of the CONFIG option.
|
||||
# $(value $(value config)) is its value (y, m).
|
||||
# When the CONFIG is not set to y or m, it defaults to n.
|
||||
MAKE_ARGS := $(foreach config,$(CONFIGS), \
|
||||
$(if $(filter y m,$(value $(value config))), \
|
||||
$(value config)=$(value $(value config)), \
|
||||
$(value config)=n))
|
||||
|
||||
#
|
||||
# EXTRA_CFLAGS to define the custom CONFIGs on out-of-tree build
|
||||
#
|
||||
# Generate the list of CONFIGs defines with values from CONFIGS.
|
||||
# $(value config) is the name of the CONFIG option.
|
||||
# When set to y or m, the CONFIG gets defined to 1.
|
||||
EXTRA_CFLAGS := $(foreach config,$(CONFIGS), \
|
||||
$(if $(filter y m,$(value $(value config))), \
|
||||
-D$(value config)=1))
|
||||
|
||||
#
|
||||
# KBUILD_EXTRA_SYMBOLS to prevent warnings about unknown functions
|
||||
#
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../../include -I$(CURDIR)/../../../../tests/include $(SCONS_CFLAGS)" $(SCONS_CONFIGS) 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=$(CURDIR) modules_install
|
||||
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) modules_install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
|
||||
$(MAKE) -C $(KDIR) M=$(CURDIR) $(MAKE_ARGS) clean
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2012-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
@@ -27,13 +27,52 @@ menuconfig MALI_BIFROST
|
||||
To compile this driver as a module, choose M here:
|
||||
this will generate a single module, called mali_kbase.
|
||||
|
||||
config MALI_CSF_SUPPORT
|
||||
bool "Mali CSF based GPU support"
|
||||
config MALI_PLATFORM_NAME
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
string "Platform name"
|
||||
default "hisilicon" if PLATFORM_HIKEY960
|
||||
default "hisilicon" if PLATFORM_HIKEY970
|
||||
default "devicetree"
|
||||
help
|
||||
Enter the name of the desired platform configuration directory to
|
||||
include in the build. 'platform/$(MALI_PLATFORM_NAME)/Makefile' must
|
||||
exist.
|
||||
|
||||
When PLATFORM_CUSTOM is set, this needs to be set manually to
|
||||
pick up the desired platform files.
|
||||
|
||||
config MALI_REAL_HW
|
||||
bool
|
||||
depends on MALI_BIFROST
|
||||
default y
|
||||
default n if NO_MALI
|
||||
|
||||
config MALI_CSF_SUPPORT
|
||||
bool "Enable Mali CSF based GPU support"
|
||||
depends on MALI_BIFROST
|
||||
default y if GPU_HAS_CSF
|
||||
help
|
||||
Enables support for CSF based GPUs.
|
||||
|
||||
config MALI_BIFROST_DEVFREQ
|
||||
bool "Enable devfreq support for Mali"
|
||||
depends on MALI_BIFROST
|
||||
default y if PLATFORM_JUNO
|
||||
default y if PLATFORM_CUSTOM
|
||||
help
|
||||
Support devfreq for Mali.
|
||||
|
||||
Using the devfreq framework and, by default, the simple on-demand
|
||||
governor, the frequency of Mali will be dynamically selected from the
|
||||
available OPPs.
|
||||
|
||||
config MALI_BIFROST_DVFS
|
||||
bool "Enable legacy DVFS"
|
||||
depends on MALI_BIFROST && !MALI_BIFROST_DEVFREQ
|
||||
default n
|
||||
help
|
||||
Choose this option to enable legacy DVFS in the Mali Midgard DDK.
|
||||
|
||||
config MALI_BIFROST_GATOR_SUPPORT
|
||||
bool "Enable Streamline tracing support"
|
||||
depends on MALI_BIFROST && !BACKEND_USER
|
||||
@@ -42,35 +81,17 @@ config MALI_BIFROST_GATOR_SUPPORT
|
||||
Enables kbase tracing used by the Arm Streamline Performance Analyzer.
|
||||
The tracepoints are used to derive GPU activity charts in Streamline.
|
||||
|
||||
config MALI_BIFROST_DVFS
|
||||
bool "Enable legacy DVFS"
|
||||
depends on MALI_BIFROST && !MALI_BIFROST_DEVFREQ
|
||||
default n
|
||||
help
|
||||
Choose this option to enable legacy DVFS in the Mali Midgard DDK.
|
||||
|
||||
config MALI_BIFROST_ENABLE_TRACE
|
||||
bool "Enable kbase tracing"
|
||||
depends on MALI_BIFROST
|
||||
default y if MALI_BIFROST_DEBUG
|
||||
default n
|
||||
help
|
||||
Enables tracing in kbase. Trace log available through
|
||||
Enables tracing in kbase. Trace log available through
|
||||
the "mali_trace" debugfs file, when the CONFIG_DEBUG_FS is enabled
|
||||
|
||||
config MALI_BIFROST_DEVFREQ
|
||||
bool "devfreq support for Mali"
|
||||
depends on MALI_BIFROST
|
||||
default y if PLATFORM_JUNO
|
||||
default y if PLATFORM_CUSTOM
|
||||
help
|
||||
Support devfreq for Mali.
|
||||
|
||||
Using the devfreq framework and, by default, the simpleondemand
|
||||
governor, the frequency of Mali will be dynamically selected from the
|
||||
available OPPs.
|
||||
|
||||
config MALI_BIFROST_DMA_FENCE
|
||||
bool "DMA_BUF fence support for Mali"
|
||||
bool "Enable DMA_BUF fence support for Mali"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
help
|
||||
@@ -79,23 +100,9 @@ config MALI_BIFROST_DMA_FENCE
|
||||
This option should only be enabled if the Linux Kernel has built in
|
||||
support for DMA_BUF fences.
|
||||
|
||||
config MALI_PLATFORM_NAME
|
||||
depends on MALI_BIFROST
|
||||
string "Platform name"
|
||||
default "hisilicon" if PLATFORM_HIKEY960
|
||||
default "hisilicon" if PLATFORM_HIKEY970
|
||||
default "devicetree"
|
||||
help
|
||||
Enter the name of the desired platform configuration directory to
|
||||
include in the build. 'platform/$(MALI_PLATFORM_NAME)/Kbuild' must
|
||||
exist.
|
||||
|
||||
When PLATFORM_CUSTOM is set, this needs to be set manually to
|
||||
pick up the desired platform files.
|
||||
|
||||
config MALI_ARBITER_SUPPORT
|
||||
bool "Enable arbiter support for Mali"
|
||||
depends on MALI_BIFROST && !GPU_HAS_CSF
|
||||
depends on MALI_BIFROST && !MALI_CSF_SUPPORT
|
||||
default n
|
||||
help
|
||||
Enable support for the arbiter interface in the driver.
|
||||
@@ -104,18 +111,68 @@ config MALI_ARBITER_SUPPORT
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
# MALI_BIFROST_EXPERT configuration options
|
||||
config DMA_BUF_SYNC_IOCTL_SUPPORTED
|
||||
bool "Enable Kernel DMA buffers support DMA_BUF_IOCTL_SYNC"
|
||||
depends on MALI_BIFROST && BACKEND_KERNEL
|
||||
default y
|
||||
|
||||
config MALI_DMA_BUF_MAP_ON_DEMAND
|
||||
bool "Enable map imported dma-bufs on demand"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
default y if !DMA_BUF_SYNC_IOCTL_SUPPORTED
|
||||
help
|
||||
This option caused kbase to set up the GPU mapping of imported
|
||||
dma-buf when needed to run atoms. This is the legacy behavior.
|
||||
|
||||
This is intended for testing and the option will get removed in the
|
||||
future.
|
||||
|
||||
config MALI_DMA_BUF_LEGACY_COMPAT
|
||||
bool "Enable legacy compatibility cache flush on dma-buf map"
|
||||
depends on MALI_BIFROST && !MALI_DMA_BUF_MAP_ON_DEMAND
|
||||
default n
|
||||
help
|
||||
This option enables compatibility with legacy dma-buf mapping
|
||||
behavior, then the dma-buf is mapped on import, by adding cache
|
||||
maintenance where MALI_DMA_BUF_MAP_ON_DEMAND would do the mapping,
|
||||
including a cache flush.
|
||||
|
||||
This option might work-around issues related to missing cache
|
||||
flushes in other drivers. This only has an effect for clients using
|
||||
UK 11.18 or older. For later UK versions it is not possible.
|
||||
|
||||
menuconfig MALI_BIFROST_EXPERT
|
||||
depends on MALI_BIFROST
|
||||
bool "Enable Expert Settings"
|
||||
default y
|
||||
help
|
||||
Enabling this option and modifying the default settings may produce a driver with performance or
|
||||
other limitations.
|
||||
Enabling this option and modifying the default settings may produce
|
||||
a driver with performance or other limitations.
|
||||
|
||||
config MALI_2MB_ALLOC
|
||||
bool "Attempt to allocate 2MB pages"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
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 N
|
||||
|
||||
config MALI_MEMORY_FULLY_BACKED
|
||||
bool "Enable memory fully physically-backed"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This option enables full physical backing of all virtual
|
||||
memory allocations in the kernel. Notice that this build
|
||||
option only affects allocations of grow-on-GPU-page-fault
|
||||
memory.
|
||||
|
||||
config MALI_CORESTACK
|
||||
bool "Support controlling power to the GPU core stack"
|
||||
bool "Enable support of GPU core stack power control"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
@@ -127,39 +184,16 @@ config MALI_CORESTACK
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config MALI_BIFROST_DEBUG
|
||||
bool "Debug build"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default y if DEBUG
|
||||
default n
|
||||
help
|
||||
Select this option for increased checking and reporting of errors.
|
||||
|
||||
config MALI_BIFROST_FENCE_DEBUG
|
||||
bool "Debug sync fence usage"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default y if MALI_BIFROST_DEBUG
|
||||
help
|
||||
Select this option to enable additional checking and reporting on the
|
||||
use of sync fences in the Mali driver.
|
||||
|
||||
This will add a 3s timeout to all sync fence waits in the Mali
|
||||
driver, so that when work for Mali has been waiting on a sync fence
|
||||
for a long time a debug message will be printed, detailing what fence
|
||||
is causing the block, and which dependent Mali atoms are blocked as a
|
||||
result of this.
|
||||
|
||||
The timeout can be changed at runtime through the js_soft_timeout
|
||||
device attribute, where the timeout is specified in milliseconds.
|
||||
|
||||
choice
|
||||
prompt "Error injection level"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default MALI_ERROR_INJECT_NONE
|
||||
help
|
||||
Enables insertion of errors to test module failure and recovery mechanisms.
|
||||
|
||||
config MALI_ERROR_INJECT_NONE
|
||||
bool "disabled"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
help
|
||||
Error injection is disabled.
|
||||
|
||||
@@ -179,14 +213,49 @@ endchoice
|
||||
|
||||
config MALI_ERROR_INJECT_ON
|
||||
string
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default "0" if MALI_ERROR_INJECT_NONE
|
||||
default "1" if MALI_ERROR_INJECT_TRACK_LIST
|
||||
default "2" if MALI_ERROR_INJECT_RANDOM
|
||||
|
||||
config MALI_BIFROST_ERROR_INJECT
|
||||
bool
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default y if !MALI_ERROR_INJECT_NONE
|
||||
|
||||
config MALI_GEM5_BUILD
|
||||
bool "Enable build of Mali kernel driver for GEM5"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
This option is to do a Mali GEM5 build.
|
||||
If unsure, say N.
|
||||
|
||||
config MALI_BIFROST_DEBUG
|
||||
bool "Enable debug build"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default y if DEBUG
|
||||
default n
|
||||
help
|
||||
Select this option for increased checking and reporting of errors.
|
||||
|
||||
config MALI_BIFROST_FENCE_DEBUG
|
||||
bool "Enable debug sync fence usage"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default y if MALI_BIFROST_DEBUG
|
||||
help
|
||||
Select this option to enable additional checking and reporting on the
|
||||
use of sync fences in the Mali driver.
|
||||
|
||||
This will add a 3s timeout to all sync fence waits in the Mali
|
||||
driver, so that when work for Mali has been waiting on a sync fence
|
||||
for a long time a debug message will be printed, detailing what fence
|
||||
is causing the block, and which dependent Mali atoms are blocked as a
|
||||
result of this.
|
||||
|
||||
The timeout can be changed at runtime through the js_soft_timeout
|
||||
device attribute, where the timeout is specified in milliseconds.
|
||||
|
||||
config MALI_BIFROST_SYSTEM_TRACE
|
||||
bool "Enable system event tracing support"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
@@ -198,56 +267,35 @@ config MALI_BIFROST_SYSTEM_TRACE
|
||||
minimal overhead when not in use. Enable only if you know what
|
||||
you are doing.
|
||||
|
||||
config MALI_2MB_ALLOC
|
||||
bool "Attempt to allocate 2MB pages"
|
||||
# Instrumentation options.
|
||||
|
||||
# config MALI_PRFCNT_SET_PRIMARY exists in the Kernel Kconfig but is configured using CINSTR_PRIMARY_HWC in Mconfig.
|
||||
# config MALI_BIFROST_PRFCNT_SET_SECONDARY exists in the Kernel Kconfig but is configured using CINSTR_SECONDARY_HWC in Mconfig.
|
||||
# config MALI_PRFCNT_SET_TERTIARY exists in the Kernel Kconfig but is configured using CINSTR_TERTIARY_HWC in Mconfig.
|
||||
# config MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS exists in the Kernel Kconfig but is configured using CINSTR_HWC_SET_SELECT_VIA_DEBUG_FS in Mconfig.
|
||||
|
||||
config MALI_JOB_DUMP
|
||||
bool "Enable system level support needed for job dumping"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
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 N
|
||||
Choose this option to enable system level support needed for
|
||||
job dumping. This is typically used for instrumentation but has
|
||||
minimal overhead when not in use. Enable only if you know what
|
||||
you are doing.
|
||||
|
||||
config MALI_PWRSOFT_765
|
||||
bool "PWRSOFT-765 ticket"
|
||||
bool "Enable workaround for PWRSOFT-765"
|
||||
depends on MALI_BIFROST && MALI_BIFROST_EXPERT
|
||||
default n
|
||||
help
|
||||
PWRSOFT-765 fixes devfreq cooling devices issues. However, they are
|
||||
not merged in mainline kernel yet. So this define helps to guard those
|
||||
parts of the code.
|
||||
PWRSOFT-765 fixes devfreq cooling devices issues. The fix was merged
|
||||
in kernel v4.10, however if backported into the kernel then this
|
||||
option must be manually selected.
|
||||
|
||||
config MALI_MEMORY_FULLY_BACKED
|
||||
bool "Memory fully physically-backed"
|
||||
default n
|
||||
help
|
||||
This option enables full backing of all virtual memory allocations
|
||||
for the kernel. This only affects grow-on-GPU-page-fault memory.
|
||||
If using kernel >= v4.10 then say N, otherwise if devfreq cooling
|
||||
changes have been backported say Y to avoid compilation errors.
|
||||
|
||||
config MALI_DMA_BUF_MAP_ON_DEMAND
|
||||
bool "Map imported dma-bufs on demand"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
default y if !DMA_BUF_SYNC_IOCTL_SUPPORTED
|
||||
help
|
||||
This option caused kbase to set up the GPU mapping of imported
|
||||
dma-buf when needed to run atoms. This is the legacy behaviour.
|
||||
|
||||
config MALI_DMA_BUF_LEGACY_COMPAT
|
||||
bool "Enable legacy compatibility cache flush on dma-buf map"
|
||||
depends on MALI_BIFROST && !MALI_DMA_BUF_MAP_ON_DEMAND
|
||||
default n
|
||||
help
|
||||
This option enables compatibility with legacy dma-buf mapping
|
||||
behavior, then the dma-buf is mapped on import, by adding cache
|
||||
maintenance where MALI_DMA_BUF_MAP_ON_DEMAND would do the mapping,
|
||||
including a cache flush.
|
||||
|
||||
config MALI_REAL_HW
|
||||
bool
|
||||
default y
|
||||
default n if NO_MALI
|
||||
|
||||
config MALI_HW_ERRATA_1485982_NOT_AFFECTED
|
||||
bool "Disable workaround for BASE_HW_ISSUE_GPU2017_1336"
|
||||
@@ -273,20 +321,6 @@ config MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE
|
||||
tree using the property, opp-mali-errata-1485982. Otherwise the
|
||||
slowest clock will be selected.
|
||||
|
||||
config MALI_GEM5_BUILD
|
||||
bool "Enable build of Mali kernel driver for GEM5"
|
||||
depends on MALI_BIFROST
|
||||
default n
|
||||
help
|
||||
This option is to do a Mali GEM5 build.
|
||||
If unsure, say N.
|
||||
|
||||
# Instrumentation options.
|
||||
|
||||
# config MALI_JOB_DUMP exists in the Kernel Kconfig but is configured using CINSTR_JOB_DUMP in Mconfig.
|
||||
# config MALI_PRFCNT_SET_PRIMARY exists in the Kernel Kconfig but is configured using CINSTR_PRIMARY_HWC in Mconfig.
|
||||
# config MALI_BIFROST_PRFCNT_SET_SECONDARY exists in the Kernel Kconfig but is configured using CINSTR_SECONDARY_HWC in Mconfig.
|
||||
# config MALI_PRFCNT_SET_TERTIARY exists in the Kernel Kconfig but is configured using CINSTR_TERTIARY_HWC in Mconfig.
|
||||
# config MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS exists in the Kernel Kconfig but is configured using CINSTR_HWC_SET_SELECT_VIA_DEBUG_FS in Mconfig.
|
||||
|
||||
source "kernel/drivers/gpu/arm/midgard/arbitration/Mconfig"
|
||||
source "kernel/drivers/gpu/arm/midgard/tests/Mconfig"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2019-2020 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
|
||||
@@ -19,5 +19,5 @@
|
||||
#
|
||||
|
||||
bifrost_kbase-y += \
|
||||
arbiter/mali_kbase_arbif.o \
|
||||
arbiter/mali_kbase_arbiter_pm.o
|
||||
arbiter/mali_kbase_arbif.o \
|
||||
arbiter/mali_kbase_arbiter_pm.o
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -170,11 +170,15 @@ static void on_gpu_lost(struct device *dev)
|
||||
*
|
||||
* Initialise Kbase Arbiter interface and assign callback functions.
|
||||
*
|
||||
* Return: 0 on success else a Linux error code
|
||||
* Return:
|
||||
* * 0 - the interface was initialized or was not specified
|
||||
* * in the device tree.
|
||||
* * -EFAULT - the interface was specified but failed to initialize.
|
||||
* * -EPROBE_DEFER - module dependencies are not yet available.
|
||||
*/
|
||||
int kbase_arbif_init(struct kbase_device *kbdev)
|
||||
{
|
||||
#ifdef CONFIG_OF
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
struct arbiter_if_arb_vm_ops ops;
|
||||
struct arbiter_if_dev *arb_if;
|
||||
struct device_node *arbiter_if_node;
|
||||
@@ -218,8 +222,8 @@ int kbase_arbif_init(struct kbase_device *kbdev)
|
||||
ops.arb_vm_max_config = on_max_config;
|
||||
ops.arb_vm_update_freq = on_update_freq;
|
||||
|
||||
|
||||
kbdev->arb.arb_freq.arb_freq = 0;
|
||||
kbdev->arb.arb_freq.freq_updated = false;
|
||||
mutex_init(&kbdev->arb.arb_freq.arb_freq_lock);
|
||||
|
||||
/* register kbase arbiter_if callbacks */
|
||||
@@ -229,6 +233,8 @@ int kbase_arbif_init(struct kbase_device *kbdev)
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to register with arbiter\n");
|
||||
module_put(pdev->dev.driver->owner);
|
||||
if (err != -EPROBE_DEFER)
|
||||
err = -EFAULT;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -307,6 +313,8 @@ void kbase_arbif_gpu_stopped(struct kbase_device *kbdev, u8 gpu_required)
|
||||
if (arb_if && arb_if->vm_ops.vm_arb_gpu_stopped) {
|
||||
dev_dbg(kbdev->dev, "%s\n", __func__);
|
||||
KBASE_TLSTREAM_TL_ARBITER_STOPPED(kbdev, kbdev);
|
||||
if (gpu_required)
|
||||
KBASE_TLSTREAM_TL_ARBITER_REQUESTED(kbdev, kbdev);
|
||||
arb_if->vm_ops.vm_arb_gpu_stopped(arb_if, gpu_required);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -57,8 +57,11 @@ enum kbase_arbif_evt {
|
||||
* Initialize the arbiter interface and also determines
|
||||
* if Arbiter functionality is required.
|
||||
*
|
||||
* Return: 0 if the Arbiter interface was successfully initialized or the
|
||||
* Arbiter was not required.
|
||||
* Return:
|
||||
* * 0 - the interface was initialized or was not specified
|
||||
* * in the device tree.
|
||||
* * -EFAULT - the interface was specified but failed to initialize.
|
||||
* * -EPROBE_DEFER - module dependencies are not yet available.
|
||||
*/
|
||||
int kbase_arbif_init(struct kbase_device *kbdev);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -132,6 +132,11 @@ struct arbiter_if_vm_arb_ops {
|
||||
* @dev: The device structure to supply in the callbacks.
|
||||
* @ops: The callbacks that the device driver supports
|
||||
* (none are optional).
|
||||
*
|
||||
* Return:
|
||||
* * 0 - successful.
|
||||
* * -EINVAL - invalid argument.
|
||||
* * -EPROBE_DEFER - module dependencies are not yet available.
|
||||
*/
|
||||
int (*vm_arb_register_dev)(struct arbiter_if_dev *arbif_dev,
|
||||
struct device *dev, struct arbiter_if_arb_vm_ops *ops);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -27,9 +27,9 @@
|
||||
#include <mali_kbase.h>
|
||||
#include <mali_kbase_pm.h>
|
||||
#include <mali_kbase_hwaccess_jm.h>
|
||||
#include <mali_kbase_irq_internal.h>
|
||||
#include <backend/gpu/mali_kbase_irq_internal.h>
|
||||
#include <mali_kbase_hwcnt_context.h>
|
||||
#include <mali_kbase_pm_internal.h>
|
||||
#include <backend/gpu/mali_kbase_pm_internal.h>
|
||||
#include <tl/mali_kbase_tracepoints.h>
|
||||
#include <mali_kbase_gpuprops.h>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
* after the following time (in milliseconds) has ellapsed.
|
||||
*/
|
||||
#define GPU_REQUEST_TIMEOUT 1000
|
||||
#define KHZ_TO_HZ 1000
|
||||
|
||||
#define MAX_L2_SLICES_MASK 0xFF
|
||||
|
||||
@@ -528,8 +529,16 @@ int kbase_arbiter_pm_gpu_assigned(struct kbase_device *kbdev)
|
||||
static void kbase_arbiter_pm_vm_gpu_start(struct kbase_device *kbdev)
|
||||
{
|
||||
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
|
||||
bool freq_updated = false;
|
||||
|
||||
lockdep_assert_held(&arb_vm_state->vm_state_lock);
|
||||
mutex_lock(&kbdev->arb.arb_freq.arb_freq_lock);
|
||||
if (kbdev->arb.arb_freq.freq_updated) {
|
||||
kbdev->arb.arb_freq.freq_updated = false;
|
||||
freq_updated = true;
|
||||
}
|
||||
mutex_unlock(&kbdev->arb.arb_freq.arb_freq_lock);
|
||||
|
||||
cancel_request_timer(kbdev);
|
||||
switch (arb_vm_state->vm_state) {
|
||||
case KBASE_VM_STATE_INITIALIZING:
|
||||
@@ -555,9 +564,16 @@ static void kbase_arbiter_pm_vm_gpu_start(struct kbase_device *kbdev)
|
||||
kbase_arbiter_pm_vm_set_state(kbdev, KBASE_VM_STATE_SUSPENDED);
|
||||
break;
|
||||
default:
|
||||
dev_warn(kbdev->dev,
|
||||
"GPU_GRANTED when not expected - state %s\n",
|
||||
kbase_arbiter_pm_vm_state_str(arb_vm_state->vm_state));
|
||||
/*
|
||||
* GPU_GRANTED can be received when there is a frequency update
|
||||
* Only show a warning if received in an unexpected state
|
||||
* without a frequency update
|
||||
*/
|
||||
if (!freq_updated)
|
||||
dev_warn(kbdev->dev,
|
||||
"GPU_GRANTED when not expected - state %s\n",
|
||||
kbase_arbiter_pm_vm_state_str(
|
||||
arb_vm_state->vm_state));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1005,13 +1021,25 @@ int kbase_arbiter_pm_ctx_active_handle_suspend(struct kbase_device *kbdev,
|
||||
* kbase_arbiter_pm_update_gpu_freq() - Updates GPU clock frequency received
|
||||
* from arbiter.
|
||||
* @arb_freq - Pointer to struchture holding GPU clock frequenecy data
|
||||
* @freq - New frequency value
|
||||
* @freq - New frequency value in KHz
|
||||
*/
|
||||
void kbase_arbiter_pm_update_gpu_freq(struct kbase_arbiter_freq *arb_freq,
|
||||
uint32_t freq)
|
||||
uint32_t freq)
|
||||
{
|
||||
struct kbase_gpu_clk_notifier_data ndata;
|
||||
|
||||
mutex_lock(&arb_freq->arb_freq_lock);
|
||||
arb_freq->arb_freq = freq;
|
||||
if (arb_freq->arb_freq != freq) {
|
||||
ndata.new_rate = freq * KHZ_TO_HZ;
|
||||
ndata.old_rate = arb_freq->arb_freq * KHZ_TO_HZ;
|
||||
ndata.gpu_clk_handle = arb_freq;
|
||||
arb_freq->arb_freq = freq;
|
||||
arb_freq->freq_updated = true;
|
||||
if (arb_freq->nb)
|
||||
arb_freq->nb->notifier_call(arb_freq->nb,
|
||||
POST_RATE_CHANGE, &ndata);
|
||||
}
|
||||
|
||||
mutex_unlock(&arb_freq->arb_freq_lock);
|
||||
}
|
||||
|
||||
@@ -1046,14 +1074,64 @@ static unsigned long get_arb_gpu_clk_rate(struct kbase_device *kbdev,
|
||||
(struct kbase_arbiter_freq *) gpu_clk_handle;
|
||||
|
||||
mutex_lock(&arb_dev_freq->arb_freq_lock);
|
||||
freq = arb_dev_freq->arb_freq;
|
||||
/* Convert from KHz to Hz */
|
||||
freq = arb_dev_freq->arb_freq * KHZ_TO_HZ;
|
||||
mutex_unlock(&arb_dev_freq->arb_freq_lock);
|
||||
return freq;
|
||||
}
|
||||
|
||||
/**
|
||||
* arb_gpu_clk_notifier_register() - Register a clock rate change notifier.
|
||||
* @kbdev - kbase_device pointer
|
||||
* @gpu_clk_handle - Handle unique to the enumerated GPU clock
|
||||
* @nb - notifier block containing the callback function pointer
|
||||
*
|
||||
* Returns 0 on success, negative error code otherwise.
|
||||
*
|
||||
* This function registers a callback function that is invoked whenever the
|
||||
* frequency of the clock corresponding to @gpu_clk_handle changes.
|
||||
*/
|
||||
static int arb_gpu_clk_notifier_register(struct kbase_device *kbdev,
|
||||
void *gpu_clk_handle, struct notifier_block *nb)
|
||||
{
|
||||
int ret = 0;
|
||||
struct kbase_arbiter_freq *arb_dev_freq =
|
||||
(struct kbase_arbiter_freq *)gpu_clk_handle;
|
||||
|
||||
if (!arb_dev_freq->nb)
|
||||
arb_dev_freq->nb = nb;
|
||||
else
|
||||
ret = -EBUSY;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gpu_clk_notifier_unregister() - Unregister clock rate change notifier
|
||||
* @kbdev - kbase_device pointer
|
||||
* @gpu_clk_handle - Handle unique to the enumerated GPU clock
|
||||
* @nb - notifier block containing the callback function pointer
|
||||
*
|
||||
* This function pointer is used to unregister a callback function that
|
||||
* was previously registered to get notified of a frequency change of the
|
||||
* clock corresponding to @gpu_clk_handle.
|
||||
*/
|
||||
static void arb_gpu_clk_notifier_unregister(struct kbase_device *kbdev,
|
||||
void *gpu_clk_handle, struct notifier_block *nb)
|
||||
{
|
||||
struct kbase_arbiter_freq *arb_dev_freq =
|
||||
(struct kbase_arbiter_freq *)gpu_clk_handle;
|
||||
if (arb_dev_freq->nb == nb) {
|
||||
arb_dev_freq->nb = NULL;
|
||||
} else {
|
||||
dev_err(kbdev->dev, "%s - notifier did not match\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
||||
struct kbase_clk_rate_trace_op_conf arb_clk_rate_trace_ops = {
|
||||
.get_gpu_clk_rate = get_arb_gpu_clk_rate,
|
||||
.enumerate_gpu_clk = enumerate_arb_gpu_clk,
|
||||
.gpu_clk_notifier_register = NULL,
|
||||
.gpu_clk_notifier_unregister = NULL
|
||||
.gpu_clk_notifier_register = arb_gpu_clk_notifier_register,
|
||||
.gpu_clk_notifier_unregister = arb_gpu_clk_notifier_unregister
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -168,15 +168,27 @@ extern struct kbase_clk_rate_trace_op_conf arb_clk_rate_trace_ops;
|
||||
/**
|
||||
* struct kbase_arbiter_freq - Holding the GPU clock frequency data retrieved
|
||||
* from arbiter
|
||||
* @arb_freq: GPU clock frequency value
|
||||
* @arb_freq_lock: Mutex protecting access to arbfreq value
|
||||
* @arb_freq: GPU clock frequency value
|
||||
* @arb_freq_lock: Mutex protecting access to arbfreq value
|
||||
* @nb: Notifier block to receive rate change callbacks
|
||||
* @freq_updated: Flag to indicate whether a frequency changed has just been
|
||||
* communicated to avoid "GPU_GRANTED when not expected" warning
|
||||
*/
|
||||
struct kbase_arbiter_freq {
|
||||
uint32_t arb_freq;
|
||||
struct mutex arb_freq_lock;
|
||||
struct notifier_block *nb;
|
||||
bool freq_updated;
|
||||
};
|
||||
|
||||
/**
|
||||
* kbase_arbiter_pm_update_gpu_freq() - Update GPU frequency
|
||||
* @arb_freq: Pointer to GPU clock frequency data
|
||||
* @freq: The new frequency
|
||||
*
|
||||
* Updates the GPU frequency and triggers any notifications
|
||||
*/
|
||||
void kbase_arbiter_pm_update_gpu_freq(struct kbase_arbiter_freq *arb_freq,
|
||||
uint32_t freq);
|
||||
uint32_t freq);
|
||||
|
||||
#endif /*_MALI_KBASE_ARBITER_PM_H_ */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2014-2021 ARM Limited. All rights reserved.
|
||||
#
|
||||
@@ -18,47 +18,32 @@
|
||||
#
|
||||
#
|
||||
|
||||
BACKEND += \
|
||||
backend/gpu/mali_kbase_cache_policy_backend.c \
|
||||
backend/gpu/mali_kbase_gpuprops_backend.c \
|
||||
backend/gpu/mali_kbase_irq_linux.c \
|
||||
backend/gpu/mali_kbase_js_backend.c \
|
||||
backend/gpu/mali_kbase_pm_backend.c \
|
||||
backend/gpu/mali_kbase_pm_driver.c \
|
||||
backend/gpu/mali_kbase_pm_metrics.c \
|
||||
backend/gpu/mali_kbase_pm_ca.c \
|
||||
backend/gpu/mali_kbase_pm_always_on.c \
|
||||
backend/gpu/mali_kbase_pm_coarse_demand.c \
|
||||
backend/gpu/mali_kbase_pm_policy.c \
|
||||
backend/gpu/mali_kbase_time.c \
|
||||
backend/gpu/mali_kbase_l2_mmu_config.c \
|
||||
backend/gpu/mali_kbase_clk_rate_trace_mgr.c
|
||||
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 \
|
||||
backend/gpu/mali_kbase_pm_ca.o \
|
||||
backend/gpu/mali_kbase_pm_always_on.o \
|
||||
backend/gpu/mali_kbase_pm_coarse_demand.o \
|
||||
backend/gpu/mali_kbase_pm_policy.o \
|
||||
backend/gpu/mali_kbase_time.o \
|
||||
backend/gpu/mali_kbase_l2_mmu_config.o \
|
||||
backend/gpu/mali_kbase_clk_rate_trace_mgr.o
|
||||
|
||||
ifeq ($(MALI_USE_CSF),1)
|
||||
# empty
|
||||
else
|
||||
BACKEND += \
|
||||
backend/gpu/mali_kbase_instr_backend.c \
|
||||
backend/gpu/mali_kbase_jm_as.c \
|
||||
backend/gpu/mali_kbase_debug_job_fault_backend.c \
|
||||
backend/gpu/mali_kbase_jm_hw.c \
|
||||
backend/gpu/mali_kbase_jm_rb.c
|
||||
ifeq ($(MALI_USE_CSF),0)
|
||||
bifrost_kbase-y += \
|
||||
backend/gpu/mali_kbase_instr_backend.o \
|
||||
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
|
||||
endif
|
||||
|
||||
ifeq ($(MALI_CUSTOMER_RELEASE),0)
|
||||
BACKEND += \
|
||||
backend/gpu/mali_kbase_pm_always_on_demand.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MALI_BIFROST_DEVFREQ),y)
|
||||
BACKEND += \
|
||||
backend/gpu/mali_kbase_devfreq.c
|
||||
endif
|
||||
bifrost_kbase-$(CONFIG_MALI_BIFROST_DEVFREQ) += \
|
||||
backend/gpu/mali_kbase_devfreq.o
|
||||
|
||||
ifeq ($(CONFIG_MALI_BIFROST_NO_MALI),y)
|
||||
# Dummy model
|
||||
BACKEND += backend/gpu/mali_kbase_model_dummy.c
|
||||
BACKEND += backend/gpu/mali_kbase_model_linux.c
|
||||
# HW error simulation
|
||||
BACKEND += backend/gpu/mali_kbase_model_error_generator.c
|
||||
endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2018, 2020 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2016, 2018, 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-2016, 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2016, 2020-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2021 ARM Limited. All rights reserved.
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <mali_kbase_config_defaults.h>
|
||||
#include <linux/clk.h>
|
||||
#include <asm/div64.h>
|
||||
#include "mali_kbase_clk_rate_trace_mgr.h"
|
||||
#include "backend/gpu/mali_kbase_clk_rate_trace_mgr.h"
|
||||
|
||||
#ifdef CONFIG_TRACE_POWER_GPU_FREQUENCY
|
||||
#include <trace/events/power_gpu_frequency.h>
|
||||
@@ -299,8 +299,8 @@ void kbase_clk_rate_trace_manager_notify_all(
|
||||
|
||||
kbdev = container_of(clk_rtm, struct kbase_device, pm.clk_rtm);
|
||||
|
||||
dev_dbg(kbdev->dev, "GPU clock %u rate changed to %lu",
|
||||
clk_index, new_rate);
|
||||
dev_dbg(kbdev->dev, "%s - GPU clock %u rate changed to %lu, pid: %d",
|
||||
__func__, clk_index, new_rate, current->pid);
|
||||
|
||||
/* Raise standard `power/gpu_frequency` ftrace event */
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2012-2015, 2018-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2012-2015, 2018-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
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <device/mali_kbase_device.h>
|
||||
#include "mali_kbase_debug_job_fault.h"
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
|
||||
/*GPU_CONTROL_REG(r)*/
|
||||
static int gpu_control_reg_snapshot[] = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2020 ARM Limited. All rights reserved.
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/devfreq.h>
|
||||
#ifdef CONFIG_DEVFREQ_THERMAL
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_THERMAL)
|
||||
#include <linux/devfreq_cooling.h>
|
||||
#endif
|
||||
|
||||
@@ -190,7 +190,7 @@ kbase_devfreq_target(struct device *dev, unsigned long *target_freq, u32 flags)
|
||||
|
||||
dev_dbg(dev, "%lu-->%lu\n", kbdev->current_nominal_freq, nominal_freq);
|
||||
|
||||
#ifdef CONFIG_REGULATOR
|
||||
#if IS_ENABLED(CONFIG_REGULATOR)
|
||||
/* Regulators and clocks work in pairs: every clock has a regulator,
|
||||
* and we never expect to have more regulators than clocks.
|
||||
*
|
||||
@@ -242,7 +242,7 @@ kbase_devfreq_target(struct device *dev, unsigned long *target_freq, u32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_REGULATOR
|
||||
#if IS_ENABLED(CONFIG_REGULATOR)
|
||||
for (i = 0; i < kbdev->nr_clocks; i++) {
|
||||
if (kbdev->regulators[i] &&
|
||||
kbdev->current_voltages[i] != volts[i] &&
|
||||
@@ -381,18 +381,21 @@ static void kbase_devfreq_term_freq_table(struct kbase_device *kbdev)
|
||||
struct devfreq_dev_profile *dp = &kbdev->devfreq_profile;
|
||||
|
||||
kfree(dp->freq_table);
|
||||
dp->freq_table = NULL;
|
||||
}
|
||||
|
||||
static void kbase_devfreq_term_core_mask_table(struct kbase_device *kbdev)
|
||||
{
|
||||
kfree(kbdev->devfreq_table);
|
||||
kbdev->devfreq_table = NULL;
|
||||
}
|
||||
|
||||
static void kbase_devfreq_exit(struct device *dev)
|
||||
{
|
||||
struct kbase_device *kbdev = dev_get_drvdata(dev);
|
||||
|
||||
kbase_devfreq_term_freq_table(kbdev);
|
||||
if (kbdev)
|
||||
kbase_devfreq_term_freq_table(kbdev);
|
||||
}
|
||||
|
||||
static void kbasep_devfreq_read_suspend_clock(struct kbase_device *kbdev,
|
||||
@@ -464,7 +467,7 @@ static int kbase_devfreq_init_core_mask_table(struct kbase_device *kbdev)
|
||||
u64 core_mask, opp_freq,
|
||||
real_freqs[BASE_MAX_NR_CLOCKS_REGULATORS];
|
||||
int err;
|
||||
#ifdef CONFIG_REGULATOR
|
||||
#if IS_ENABLED(CONFIG_REGULATOR)
|
||||
u32 opp_volts[BASE_MAX_NR_CLOCKS_REGULATORS];
|
||||
#endif
|
||||
|
||||
@@ -492,7 +495,7 @@ static int kbase_devfreq_init_core_mask_table(struct kbase_device *kbdev)
|
||||
err);
|
||||
continue;
|
||||
}
|
||||
#ifdef CONFIG_REGULATOR
|
||||
#if IS_ENABLED(CONFIG_REGULATOR)
|
||||
err = of_property_read_u32_array(node,
|
||||
"opp-microvolt", opp_volts, kbdev->nr_regulators);
|
||||
if (err < 0) {
|
||||
@@ -546,7 +549,7 @@ static int kbase_devfreq_init_core_mask_table(struct kbase_device *kbdev)
|
||||
kbdev->devfreq_table[i].real_freqs[j] =
|
||||
real_freqs[j];
|
||||
}
|
||||
#ifdef CONFIG_REGULATOR
|
||||
#if IS_ENABLED(CONFIG_REGULATOR)
|
||||
if (kbdev->nr_regulators > 0) {
|
||||
int j;
|
||||
|
||||
@@ -631,8 +634,12 @@ void kbase_devfreq_enqueue_work(struct kbase_device *kbdev,
|
||||
|
||||
WARN_ON(work_type == DEVFREQ_WORK_NONE);
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
kbdev->devfreq_queue.req_type = work_type;
|
||||
queue_work(kbdev->devfreq_queue.workq, &kbdev->devfreq_queue.work);
|
||||
/* Skip enqueuing a work if workqueue has already been terminated. */
|
||||
if (likely(kbdev->devfreq_queue.workq)) {
|
||||
kbdev->devfreq_queue.req_type = work_type;
|
||||
queue_work(kbdev->devfreq_queue.workq,
|
||||
&kbdev->devfreq_queue.work);
|
||||
}
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
dev_dbg(kbdev->dev, "Enqueuing devfreq req: %s\n",
|
||||
kbase_devfreq_req_type_name(work_type));
|
||||
@@ -654,11 +661,19 @@ static int kbase_devfreq_work_init(struct kbase_device *kbdev)
|
||||
|
||||
static void kbase_devfreq_work_term(struct kbase_device *kbdev)
|
||||
{
|
||||
destroy_workqueue(kbdev->devfreq_queue.workq);
|
||||
unsigned long flags;
|
||||
struct workqueue_struct *workq;
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
workq = kbdev->devfreq_queue.workq;
|
||||
kbdev->devfreq_queue.workq = NULL;
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
destroy_workqueue(workq);
|
||||
}
|
||||
|
||||
static unsigned long kbase_devfreq_get_static_power(struct devfreq *devfreq,
|
||||
unsigned long voltage)
|
||||
unsigned long voltage)
|
||||
{
|
||||
struct device *dev = devfreq->dev.parent;
|
||||
struct kbase_device *kbdev = dev_get_drvdata(dev);
|
||||
@@ -718,14 +733,6 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Initialise devfreq suspend/resume workqueue */
|
||||
err = kbase_devfreq_work_init(kbdev);
|
||||
if (err) {
|
||||
kbase_devfreq_term_freq_table(kbdev);
|
||||
dev_err(kbdev->dev, "Devfreq initialization failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
of_property_read_u32(np, "upthreshold",
|
||||
&ondemand_data.upthreshold);
|
||||
of_property_read_u32(np, "downdifferential",
|
||||
@@ -734,8 +741,21 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
"simple_ondemand", &ondemand_data);
|
||||
if (IS_ERR(kbdev->devfreq)) {
|
||||
err = PTR_ERR(kbdev->devfreq);
|
||||
kbase_devfreq_work_term(kbdev);
|
||||
kbdev->devfreq = NULL;
|
||||
kbase_devfreq_term_core_mask_table(kbdev);
|
||||
kbase_devfreq_term_freq_table(kbdev);
|
||||
dev_err(kbdev->dev, "Fail to add devfreq device(%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Initialize devfreq suspend/resume workqueue */
|
||||
err = kbase_devfreq_work_init(kbdev);
|
||||
if (err) {
|
||||
if (devfreq_remove_device(kbdev->devfreq))
|
||||
dev_err(kbdev->dev, "Fail to rm devfreq\n");
|
||||
kbdev->devfreq = NULL;
|
||||
kbase_devfreq_term_core_mask_table(kbdev);
|
||||
dev_err(kbdev->dev, "Fail to init devfreq workqueue\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -759,12 +779,12 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
|
||||
mali_mdevp.data = kbdev->devfreq;
|
||||
kbdev->mdev_info = rockchip_system_monitor_register(kbdev->dev,
|
||||
&mali_mdevp);
|
||||
&mali_mdevp);
|
||||
if (IS_ERR(kbdev->mdev_info)) {
|
||||
dev_dbg(kbdev->dev, "without system monitor\n");
|
||||
kbdev->mdev_info = NULL;
|
||||
kbdev->mdev_info = NULL;
|
||||
}
|
||||
#ifdef CONFIG_DEVFREQ_THERMAL
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_THERMAL)
|
||||
if (of_find_compatible_node(kbdev->dev->of_node, NULL,
|
||||
"simple-power-model")) {
|
||||
of_property_read_u32(kbdev->dev->of_node,
|
||||
@@ -782,23 +802,23 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
if (!kbase_dcp->dyn_power_coeff) {
|
||||
err = -EINVAL;
|
||||
dev_err(kbdev->dev, "failed to get dynamic-coefficient\n");
|
||||
goto cooling_failed;
|
||||
goto ipa_init_failed;
|
||||
}
|
||||
|
||||
kbdev->devfreq_cooling =
|
||||
of_devfreq_cooling_register_power(kbdev->dev->of_node,
|
||||
kbdev->devfreq,
|
||||
kbase_dcp);
|
||||
kbdev->devfreq,
|
||||
kbase_dcp);
|
||||
if (IS_ERR(kbdev->devfreq_cooling)) {
|
||||
err = PTR_ERR(kbdev->devfreq_cooling);
|
||||
dev_err(kbdev->dev, "failed to register cooling device\n");
|
||||
goto cooling_failed;
|
||||
goto cooling_reg_failed;
|
||||
}
|
||||
} else {
|
||||
err = kbase_ipa_init(kbdev);
|
||||
if (err) {
|
||||
dev_err(kbdev->dev, "IPA initialization failed\n");
|
||||
goto cooling_failed;
|
||||
goto ipa_init_failed;
|
||||
}
|
||||
|
||||
kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
|
||||
@@ -808,26 +828,32 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
if (IS_ERR(kbdev->devfreq_cooling)) {
|
||||
err = PTR_ERR(kbdev->devfreq_cooling);
|
||||
dev_err(kbdev->dev,
|
||||
"Failed to register cooling device (%d)\n",
|
||||
err);
|
||||
goto cooling_failed;
|
||||
}
|
||||
"Failed to register cooling device (%d)\n",
|
||||
err);
|
||||
goto cooling_reg_failed;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_DEVFREQ_THERMAL
|
||||
cooling_failed:
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_THERMAL)
|
||||
cooling_reg_failed:
|
||||
kbase_ipa_term(kbdev);
|
||||
ipa_init_failed:
|
||||
devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);
|
||||
#endif /* CONFIG_DEVFREQ_THERMAL */
|
||||
|
||||
opp_notifier_failed:
|
||||
kbase_devfreq_work_term(kbdev);
|
||||
|
||||
if (devfreq_remove_device(kbdev->devfreq))
|
||||
dev_err(kbdev->dev, "Failed to terminate devfreq (%d)\n", err);
|
||||
else
|
||||
kbdev->devfreq = NULL;
|
||||
|
||||
kbase_devfreq_work_term(kbdev);
|
||||
kbdev->devfreq = NULL;
|
||||
|
||||
kbase_devfreq_term_core_mask_table(kbdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -838,8 +864,7 @@ void kbase_devfreq_term(struct kbase_device *kbdev)
|
||||
|
||||
dev_dbg(kbdev->dev, "Term Mali devfreq\n");
|
||||
|
||||
rockchip_system_monitor_unregister(kbdev->mdev_info);
|
||||
#ifdef CONFIG_DEVFREQ_THERMAL
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_THERMAL)
|
||||
if (kbdev->devfreq_cooling)
|
||||
devfreq_cooling_unregister(kbdev->devfreq_cooling);
|
||||
|
||||
@@ -850,6 +875,8 @@ void kbase_devfreq_term(struct kbase_device *kbdev)
|
||||
|
||||
devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);
|
||||
|
||||
kbase_devfreq_work_term(kbdev);
|
||||
|
||||
err = devfreq_remove_device(kbdev->devfreq);
|
||||
if (err)
|
||||
dev_err(kbdev->dev, "Failed to terminate devfreq (%d)\n", err);
|
||||
@@ -857,6 +884,4 @@ void kbase_devfreq_term(struct kbase_device *kbdev)
|
||||
kbdev->devfreq = NULL;
|
||||
|
||||
kbase_devfreq_term_core_mask_table(kbdev);
|
||||
|
||||
kbase_devfreq_work_term(kbdev);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014, 2019-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014, 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2021 ARM Limited. All rights reserved.
|
||||
@@ -45,6 +45,12 @@ int kbase_backend_gpuprops_get(struct kbase_device *kbdev,
|
||||
registers.core_features = kbase_reg_read(kbdev,
|
||||
GPU_CONTROL_REG(CORE_FEATURES));
|
||||
#else /* !MALI_USE_CSF */
|
||||
if (((registers.gpu_id & GPU_ID2_PRODUCT_MODEL) ==
|
||||
GPU_ID2_PRODUCT_TGRX) ||
|
||||
((registers.gpu_id & GPU_ID2_PRODUCT_MODEL) ==
|
||||
GPU_ID2_PRODUCT_TVAX))
|
||||
registers.core_features =
|
||||
kbase_reg_read(kbdev, GPU_CONTROL_REG(CORE_FEATURES));
|
||||
#endif /* MALI_USE_CSF */
|
||||
registers.tiler_features = kbase_reg_read(kbdev,
|
||||
GPU_CONTROL_REG(TILER_FEATURES));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014, 2016, 2018-2021 ARM Limited. All rights reserved.
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef _KBASE_INSTR_DEFS_H_
|
||||
#define _KBASE_INSTR_DEFS_H_
|
||||
|
||||
#include "../../mali_kbase_hwcnt_gpu.h"
|
||||
#include <mali_kbase_hwcnt_gpu.h>
|
||||
|
||||
/*
|
||||
* Instrumentation State Machine States
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014, 2018, 2020 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2015, 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-2015, 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2016,2018-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-2016, 2018-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
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#if !defined(CONFIG_MALI_BIFROST_NO_MALI)
|
||||
#if !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
|
||||
|
||||
/* GPU IRQ Tags */
|
||||
#define JOB_IRQ_TAG 0
|
||||
@@ -232,7 +232,7 @@ int kbase_set_custom_irq_handler(struct kbase_device *kbdev,
|
||||
result = -EINVAL;
|
||||
dev_err(kbdev->dev, "Can't request interrupt %d (index %d)\n",
|
||||
kbdev->irqs[irq_type].irq, irq_type);
|
||||
#ifdef CONFIG_SPARSE_IRQ
|
||||
#if IS_ENABLED(CONFIG_SPARSE_IRQ)
|
||||
dev_err(kbdev->dev, "You have CONFIG_SPARSE_IRQ support enabled - is the interrupt number correct for this configuration?\n");
|
||||
#endif /* CONFIG_SPARSE_IRQ */
|
||||
}
|
||||
@@ -461,7 +461,7 @@ int kbase_install_interrupts(struct kbase_device *kbdev)
|
||||
if (err) {
|
||||
dev_err(kbdev->dev, "Can't request interrupt %d (index %d)\n",
|
||||
kbdev->irqs[i].irq, i);
|
||||
#ifdef CONFIG_SPARSE_IRQ
|
||||
#if IS_ENABLED(CONFIG_SPARSE_IRQ)
|
||||
dev_err(kbdev->dev, "You have CONFIG_SPARSE_IRQ support enabled - is the interrupt number correct for this configuration?\n");
|
||||
#endif /* CONFIG_SPARSE_IRQ */
|
||||
goto release;
|
||||
@@ -501,4 +501,4 @@ void kbase_synchronize_irqs(struct kbase_device *kbdev)
|
||||
|
||||
KBASE_EXPORT_TEST_API(kbase_synchronize_irqs);
|
||||
|
||||
#endif /* !defined(CONFIG_MALI_BIFROST_NO_MALI) */
|
||||
#endif /* !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI) */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
|
||||
@@ -300,7 +300,7 @@ void kbase_job_hw_submit(struct kbase_device *kbdev,
|
||||
&kbdev->gpu_props.props.raw_props.js_features[js],
|
||||
"ctx_nr,atom_nr");
|
||||
kbase_kinstr_jm_atom_hw_submit(katom);
|
||||
#ifdef CONFIG_GPU_TRACEPOINTS
|
||||
#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS)
|
||||
if (!kbase_backend_nr_atoms_submitted(kbdev, js)) {
|
||||
/* If this is the only job on the slot, trace it as starting */
|
||||
char js_string[16];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2011-2016, 2018-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2011-2016, 2018-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
|
||||
@@ -59,7 +59,7 @@ void kbase_job_submit_nolock(struct kbase_device *kbdev,
|
||||
void kbase_job_done_slot(struct kbase_device *kbdev, int s, u32 completion_code,
|
||||
u64 job_tail, ktime_t *end_timestamp);
|
||||
|
||||
#ifdef CONFIG_GPU_TRACEPOINTS
|
||||
#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS)
|
||||
static inline char *kbasep_make_job_slot_string(int js, char *js_string,
|
||||
size_t js_size)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2021 ARM Limited. All rights reserved.
|
||||
@@ -289,9 +289,11 @@ static void kbase_gpu_release_atom(struct kbase_device *kbdev,
|
||||
katom->gpu_rb_state = KBASE_ATOM_GPU_RB_READY;
|
||||
kbase_pm_metrics_update(kbdev, end_timestamp);
|
||||
|
||||
/* Inform platform at start/finish of atom */
|
||||
kbasep_platform_event_atom_complete(katom);
|
||||
|
||||
if (katom->core_req & BASE_JD_REQ_PERMON)
|
||||
kbase_pm_release_gpu_cycle_counter_nolock(kbdev);
|
||||
/* ***FALLTHROUGH: TRANSITION TO LOWER STATE*** */
|
||||
|
||||
KBASE_TLSTREAM_TL_NRET_ATOM_LPU(kbdev, katom,
|
||||
&kbdev->gpu_props.props.raw_props.js_features
|
||||
@@ -301,6 +303,8 @@ static void kbase_gpu_release_atom(struct kbase_device *kbdev,
|
||||
&kbdev->gpu_props.props.raw_props.js_features
|
||||
[katom->slot_nr]);
|
||||
|
||||
/* ***FALLTHROUGH: TRANSITION TO LOWER STATE*** */
|
||||
|
||||
case KBASE_ATOM_GPU_RB_READY:
|
||||
/* ***FALLTHROUGH: TRANSITION TO LOWER STATE*** */
|
||||
|
||||
@@ -847,7 +851,7 @@ void kbase_backend_slot_update(struct kbase_device *kbdev)
|
||||
break;
|
||||
|
||||
katom[idx]->gpu_rb_state =
|
||||
KBASE_ATOM_GPU_RB_WAITING_PROTECTED_MODE_PREV;
|
||||
KBASE_ATOM_GPU_RB_WAITING_PROTECTED_MODE_PREV;
|
||||
|
||||
/* ***TRANSITION TO HIGHER STATE*** */
|
||||
/* fallthrough */
|
||||
@@ -987,7 +991,11 @@ void kbase_backend_slot_update(struct kbase_device *kbdev)
|
||||
|
||||
kbase_job_hw_submit(kbdev, katom[idx], js);
|
||||
katom[idx]->gpu_rb_state =
|
||||
KBASE_ATOM_GPU_RB_SUBMITTED;
|
||||
KBASE_ATOM_GPU_RB_SUBMITTED;
|
||||
|
||||
/* ***TRANSITION TO HIGHER STATE*** */
|
||||
/* fallthrough */
|
||||
case KBASE_ATOM_GPU_RB_SUBMITTED:
|
||||
|
||||
/* Inform power management at start/finish of
|
||||
* atom so it can update its GPU utilisation
|
||||
@@ -996,10 +1004,9 @@ void kbase_backend_slot_update(struct kbase_device *kbdev)
|
||||
kbase_pm_metrics_update(kbdev,
|
||||
&katom[idx]->start_timestamp);
|
||||
|
||||
/* ***TRANSITION TO HIGHER STATE*** */
|
||||
/* fallthrough */
|
||||
case KBASE_ATOM_GPU_RB_SUBMITTED:
|
||||
/* Atom submitted to HW, nothing else to do */
|
||||
/* Inform platform at start/finish of atom */
|
||||
kbasep_platform_event_atom_submit(katom[idx]);
|
||||
|
||||
break;
|
||||
|
||||
case KBASE_ATOM_GPU_RB_RETURN_TO_JS:
|
||||
@@ -1225,7 +1232,7 @@ void kbase_gpu_complete_hw(struct kbase_device *kbdev, int js,
|
||||
* - Schedule out the parent context if necessary, and schedule a new
|
||||
* one in.
|
||||
*/
|
||||
#ifdef CONFIG_GPU_TRACEPOINTS
|
||||
#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS)
|
||||
{
|
||||
/* The atom in the HEAD */
|
||||
struct kbase_jd_atom *next_katom = kbase_gpu_inspect(kbdev, js,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2018, 2020 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2015, 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2014-2015, 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2020 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2020 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2015, 2018-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2010-2015, 2018-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
|
||||
@@ -58,6 +58,7 @@ const struct kbase_pm_policy kbase_pm_always_on_policy_ops = {
|
||||
always_on_term, /* term */
|
||||
always_on_shaders_needed, /* shaders_needed */
|
||||
always_on_get_core_active, /* get_core_active */
|
||||
NULL, /* handle_event */
|
||||
KBASE_PM_POLICY_ID_ALWAYS_ON, /* id */
|
||||
#if MALI_USE_CSF
|
||||
ALWAYS_ON_PM_SCHED_FLAGS, /* pm_sched_flags */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2011-2015, 2018, 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2011-2015, 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <backend/gpu/mali_kbase_pm_internal.h>
|
||||
#include <backend/gpu/mali_kbase_devfreq.h>
|
||||
#include <mali_kbase_dummy_job_wa.h>
|
||||
#include <mali_kbase_irq_internal.h>
|
||||
#include <backend/gpu/mali_kbase_irq_internal.h>
|
||||
|
||||
static void kbase_pm_gpu_poweroff_wait_wq(struct work_struct *data);
|
||||
static void kbase_pm_hwcnt_disable_worker(struct work_struct *data);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2013-2018, 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2013-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
|
||||
@@ -26,9 +26,6 @@
|
||||
#include <mali_kbase.h>
|
||||
#include <mali_kbase_pm.h>
|
||||
#include <backend/gpu/mali_kbase_pm_internal.h>
|
||||
#ifdef MALI_BIFROST_NO_MALI
|
||||
#include <backend/gpu/mali_kbase_model_dummy.h>
|
||||
#endif
|
||||
#include <mali_kbase_dummy_job_wa.h>
|
||||
|
||||
int kbase_pm_ca_init(struct kbase_device *kbdev)
|
||||
@@ -123,9 +120,7 @@ u64 kbase_pm_ca_get_instr_core_mask(struct kbase_device *kbdev)
|
||||
{
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
#ifdef CONFIG_MALI_BIFROST_NO_MALI
|
||||
return (((1ull) << KBASE_DUMMY_MODEL_MAX_SHADER_CORES) - 1);
|
||||
#elif MALI_USE_CSF
|
||||
#if MALI_USE_CSF
|
||||
return kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_SHADER);
|
||||
#else
|
||||
return kbdev->pm.backend.pm_shaders_core_mask;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2011-2018, 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2011-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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2017, 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2017, 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2012-2016, 2018-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2012-2016, 2018-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
|
||||
@@ -57,6 +57,7 @@ const struct kbase_pm_policy kbase_pm_coarse_demand_policy_ops = {
|
||||
coarse_demand_term, /* term */
|
||||
coarse_demand_shaders_needed, /* shaders_needed */
|
||||
coarse_demand_get_core_active, /* get_core_active */
|
||||
NULL, /* handle_event */
|
||||
KBASE_PM_POLICY_ID_COARSE_DEMAND, /* id */
|
||||
#if MALI_USE_CSF
|
||||
COARSE_ON_DEMAND_PM_SCHED_FLAGS, /* pm_sched_flags */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2012-2015, 2018, 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2012-2015, 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2021 ARM Limited. All rights reserved.
|
||||
@@ -28,9 +28,6 @@
|
||||
|
||||
#include "mali_kbase_pm_always_on.h"
|
||||
#include "mali_kbase_pm_coarse_demand.h"
|
||||
#if !MALI_CUSTOMER_RELEASE
|
||||
#include "mali_kbase_pm_always_on_demand.h"
|
||||
#endif
|
||||
|
||||
/* Forward definition - see mali_kbase.h */
|
||||
struct kbase_device;
|
||||
@@ -179,8 +176,12 @@ struct kbasep_pm_metrics_state {
|
||||
* @work: Work item which cancels the timer
|
||||
* @timer: Timer for powering off the shader cores
|
||||
* @configured_interval: Period of GPU poweroff timer
|
||||
* @configured_ticks: User-configured number of ticks to wait after the shader
|
||||
* power down request is received before turning off the cores
|
||||
* @default_ticks: User-configured number of ticks to wait after the shader
|
||||
* power down request is received before turning off the cores
|
||||
* @configured_ticks: Power-policy configured number of ticks to wait after the
|
||||
* shader power down request is received before turning off
|
||||
* the cores. For simple power policies, this is equivalent
|
||||
* to @default_ticks.
|
||||
* @remaining_ticks: Number of remaining timer ticks until shaders are powered off
|
||||
* @cancel_queued: True if the cancellation work item has been queued. This is
|
||||
* required to ensure that it is not queued twice, e.g. after
|
||||
@@ -194,6 +195,7 @@ struct kbasep_pm_tick_timer_state {
|
||||
struct hrtimer timer;
|
||||
|
||||
ktime_t configured_interval;
|
||||
unsigned int default_ticks;
|
||||
unsigned int configured_ticks;
|
||||
unsigned int remaining_ticks;
|
||||
|
||||
@@ -204,9 +206,6 @@ struct kbasep_pm_tick_timer_state {
|
||||
union kbase_pm_policy_data {
|
||||
struct kbasep_pm_policy_always_on always_on;
|
||||
struct kbasep_pm_policy_coarse_demand coarse_demand;
|
||||
#if !MALI_CUSTOMER_RELEASE
|
||||
struct kbasep_pm_policy_always_on_demand always_on_demand;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -217,7 +216,8 @@ union kbase_pm_policy_data {
|
||||
*
|
||||
* @pm_current_policy: The policy that is currently actively controlling the
|
||||
* power state.
|
||||
* @pm_policy_data: Private data for current PM policy
|
||||
* @pm_policy_data: Private data for current PM policy. This is automatically
|
||||
* zeroed when a policy change occurs.
|
||||
* @reset_done: Flag when a reset is complete
|
||||
* @reset_done_wait: Wait queue to wait for changes to @reset_done
|
||||
* @gpu_cycle_counter_requests: The reference count of active gpu cycle counter
|
||||
@@ -464,6 +464,33 @@ enum kbase_pm_policy_id {
|
||||
KBASE_PM_POLICY_ID_ALWAYS_ON
|
||||
};
|
||||
|
||||
/**
|
||||
* enum kbase_pm_policy_event - PM Policy event ID
|
||||
*/
|
||||
enum kbase_pm_policy_event {
|
||||
/**
|
||||
* @KBASE_PM_POLICY_EVENT_IDLE: Indicates that the GPU power state
|
||||
* model has determined that the GPU has gone idle.
|
||||
*/
|
||||
KBASE_PM_POLICY_EVENT_IDLE,
|
||||
/**
|
||||
* @KBASE_PM_POLICY_EVENT_POWER_ON: Indicates that the GPU state model
|
||||
* is preparing to power on the GPU.
|
||||
*/
|
||||
KBASE_PM_POLICY_EVENT_POWER_ON,
|
||||
/**
|
||||
* @KBASE_PM_POLICY_EVENT_TIMER_HIT: Indicates that the GPU became
|
||||
* active while the Shader Tick Timer was holding the GPU in a powered
|
||||
* on state.
|
||||
*/
|
||||
KBASE_PM_POLICY_EVENT_TIMER_HIT,
|
||||
/**
|
||||
* @KBASE_PM_POLICY_EVENT_TIMER_MISS: Indicates that the GPU did not
|
||||
* become active before the Shader Tick Timer timeout occurred.
|
||||
*/
|
||||
KBASE_PM_POLICY_EVENT_TIMER_MISS,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct kbase_pm_policy - Power policy structure.
|
||||
*
|
||||
@@ -476,6 +503,9 @@ enum kbase_pm_policy_id {
|
||||
* @shaders_needed: Function called to find out if shader cores are needed
|
||||
* @get_core_active: Function called to get the current overall GPU power
|
||||
* state
|
||||
* @handle_event: Function called when a PM policy event occurs. Should be
|
||||
* set to NULL if the power policy doesn't require any
|
||||
* event notifications.
|
||||
* @id: Field indicating an ID for this policy. This is not
|
||||
* necessarily the same as its index in the list returned
|
||||
* by kbase_pm_list_policies().
|
||||
@@ -536,6 +566,16 @@ struct kbase_pm_policy {
|
||||
*/
|
||||
bool (*get_core_active)(struct kbase_device *kbdev);
|
||||
|
||||
/**
|
||||
* Function called when a power event occurs
|
||||
*
|
||||
* @kbdev: The kbase device structure for the device (must be a
|
||||
* valid pointer)
|
||||
* @event: The id of the power event that has occurred
|
||||
*/
|
||||
void (*handle_event)(struct kbase_device *kbdev,
|
||||
enum kbase_pm_policy_event event);
|
||||
|
||||
enum kbase_pm_policy_id id;
|
||||
|
||||
#if MALI_USE_CSF
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
|
||||
@@ -244,7 +244,7 @@ static u32 core_type_to_reg(enum kbase_pm_core_type core_type,
|
||||
return (u32)core_type + (u32)action;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
#if IS_ENABLED(CONFIG_ARM64)
|
||||
static void mali_cci_flush_l2(struct kbase_device *kbdev)
|
||||
{
|
||||
const u32 mask = CLEAN_CACHES_COMPLETED | RESET_COMPLETED;
|
||||
@@ -1343,6 +1343,12 @@ static int kbase_pm_shaders_update_state(struct kbase_device *kbdev)
|
||||
kbase_pm_invoke(kbdev, KBASE_PM_CORE_SHADER,
|
||||
backend->shaders_avail, ACTION_PWRON);
|
||||
|
||||
if (backend->pm_current_policy &&
|
||||
backend->pm_current_policy->handle_event)
|
||||
backend->pm_current_policy->handle_event(
|
||||
kbdev,
|
||||
KBASE_PM_POLICY_EVENT_POWER_ON);
|
||||
|
||||
backend->shaders_state = KBASE_SHADERS_PEND_ON_CORESTACK_ON;
|
||||
}
|
||||
break;
|
||||
@@ -1395,6 +1401,12 @@ static int kbase_pm_shaders_update_state(struct kbase_device *kbdev)
|
||||
/* Wait for being disabled */
|
||||
;
|
||||
} else if (!backend->shaders_desired) {
|
||||
if (backend->pm_current_policy &&
|
||||
backend->pm_current_policy->handle_event)
|
||||
backend->pm_current_policy->handle_event(
|
||||
kbdev,
|
||||
KBASE_PM_POLICY_EVENT_IDLE);
|
||||
|
||||
if (kbdev->pm.backend.protected_transition_override ||
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
kbase_pm_is_suspending(kbdev) ||
|
||||
@@ -1455,9 +1467,21 @@ static int kbase_pm_shaders_update_state(struct kbase_device *kbdev)
|
||||
}
|
||||
|
||||
if (backend->shaders_desired) {
|
||||
if (backend->pm_current_policy &&
|
||||
backend->pm_current_policy->handle_event)
|
||||
backend->pm_current_policy->handle_event(
|
||||
kbdev,
|
||||
KBASE_PM_POLICY_EVENT_TIMER_HIT);
|
||||
|
||||
stt->remaining_ticks = 0;
|
||||
backend->shaders_state = KBASE_SHADERS_ON_CORESTACK_ON_RECHECK;
|
||||
} else if (stt->remaining_ticks == 0) {
|
||||
if (backend->pm_current_policy &&
|
||||
backend->pm_current_policy->handle_event)
|
||||
backend->pm_current_policy->handle_event(
|
||||
kbdev,
|
||||
KBASE_PM_POLICY_EVENT_TIMER_MISS);
|
||||
|
||||
backend->shaders_state = KBASE_SHADERS_WAIT_FINISHED_CORESTACK_ON;
|
||||
#ifdef CONFIG_MALI_ARBITER_SUPPORT
|
||||
} else if (kbase_pm_is_suspending(kbdev) ||
|
||||
@@ -1776,7 +1800,8 @@ int kbase_pm_state_machine_init(struct kbase_device *kbdev)
|
||||
hrtimer_init(&stt->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
stt->timer.function = shader_tick_timer_callback;
|
||||
stt->configured_interval = HR_TIMER_DELAY_NSEC(DEFAULT_PM_GPU_POWEROFF_TICK_NS);
|
||||
stt->configured_ticks = DEFAULT_PM_POWEROFF_TICK_SHADER;
|
||||
stt->default_ticks = DEFAULT_PM_POWEROFF_TICK_SHADER;
|
||||
stt->configured_ticks = stt->default_ticks;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1912,24 +1937,43 @@ static void kbase_pm_timed_out(struct kbase_device *kbdev)
|
||||
kbase_reset_gpu(kbdev);
|
||||
}
|
||||
|
||||
void kbase_pm_wait_for_l2_powered(struct kbase_device *kbdev)
|
||||
int kbase_pm_wait_for_l2_powered(struct kbase_device *kbdev)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long timeout;
|
||||
int err;
|
||||
long remaining;
|
||||
int err = 0;
|
||||
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
kbase_pm_update_state(kbdev);
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
|
||||
timeout = jiffies + msecs_to_jiffies(PM_TIMEOUT_MS);
|
||||
#if MALI_USE_CSF
|
||||
timeout = kbase_csf_timeout_in_jiffies(PM_TIMEOUT_MS);
|
||||
#else
|
||||
timeout = msecs_to_jiffies(PM_TIMEOUT_MS);
|
||||
#endif
|
||||
|
||||
/* Wait for cores */
|
||||
err = wait_event_killable(kbdev->pm.backend.gpu_in_desired_state_wait,
|
||||
kbase_pm_is_in_desired_state_with_l2_powered(kbdev));
|
||||
#if KERNEL_VERSION(4, 13, 1) <= LINUX_VERSION_CODE
|
||||
remaining = wait_event_killable_timeout(
|
||||
#else
|
||||
remaining = wait_event_timeout(
|
||||
#endif
|
||||
kbdev->pm.backend.gpu_in_desired_state_wait,
|
||||
kbase_pm_is_in_desired_state_with_l2_powered(kbdev), timeout);
|
||||
|
||||
if (err < 0 && time_after(jiffies, timeout))
|
||||
if (!remaining) {
|
||||
kbase_pm_timed_out(kbdev);
|
||||
err = -ETIMEDOUT;
|
||||
} else if (remaining < 0) {
|
||||
dev_info(
|
||||
kbdev->dev,
|
||||
"Wait for desired PM state with L2 powered got interrupted");
|
||||
err = (int)remaining;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int kbase_pm_wait_for_desired_state(struct kbase_device *kbdev)
|
||||
@@ -2045,6 +2089,7 @@ static void update_user_reg_page_mapping(struct kbase_device *kbdev)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* pmu layout:
|
||||
* 0x0000: PMU TAG (RO) (0xCAFECAFE)
|
||||
@@ -2462,7 +2507,7 @@ void kbase_pm_cache_snoop_enable(struct kbase_device *kbdev)
|
||||
{
|
||||
if ((kbdev->current_gpu_coherency_mode == COHERENCY_ACE) &&
|
||||
!kbdev->cci_snoop_enabled) {
|
||||
#ifdef CONFIG_ARM64
|
||||
#if IS_ENABLED(CONFIG_ARM64)
|
||||
if (kbdev->snoop_enable_smc != 0)
|
||||
kbase_invoke_smc_fid(kbdev->snoop_enable_smc, 0, 0, 0);
|
||||
#endif /* CONFIG_ARM64 */
|
||||
@@ -2474,7 +2519,7 @@ void kbase_pm_cache_snoop_enable(struct kbase_device *kbdev)
|
||||
void kbase_pm_cache_snoop_disable(struct kbase_device *kbdev)
|
||||
{
|
||||
if (kbdev->cci_snoop_enabled) {
|
||||
#ifdef CONFIG_ARM64
|
||||
#if IS_ENABLED(CONFIG_ARM64)
|
||||
if (kbdev->snoop_disable_smc != 0) {
|
||||
mali_cci_flush_l2(kbdev);
|
||||
kbase_invoke_smc_fid(kbdev->snoop_disable_smc, 0, 0, 0);
|
||||
@@ -2754,9 +2799,8 @@ kbase_pm_request_gpu_cycle_counter_do_request(struct kbase_device *kbdev)
|
||||
/* This might happen after GPU reset.
|
||||
* Then counter needs to be kicked.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI) &&
|
||||
(!(kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_STATUS)) &
|
||||
GPU_STATUS_CYCLE_COUNT_ACTIVE))) {
|
||||
if (!(kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_STATUS)) &
|
||||
GPU_STATUS_CYCLE_COUNT_ACTIVE)) {
|
||||
kbase_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND),
|
||||
GPU_COMMAND_CYCLE_COUNT_START);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <mali_kbase_hwaccess_pm.h>
|
||||
|
||||
#include "mali_kbase_pm_ca.h"
|
||||
#include "backend/gpu/mali_kbase_pm_ca.h"
|
||||
#include "mali_kbase_pm_policy.h"
|
||||
|
||||
|
||||
@@ -263,8 +263,10 @@ int kbase_pm_wait_for_desired_state(struct kbase_device *kbdev);
|
||||
* because this function will take that lock itself.
|
||||
*
|
||||
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
||||
*
|
||||
* Return: 0 on success, error code on error
|
||||
*/
|
||||
void kbase_pm_wait_for_l2_powered(struct kbase_device *kbdev);
|
||||
int kbase_pm_wait_for_l2_powered(struct kbase_device *kbdev);
|
||||
|
||||
/**
|
||||
* kbase_pm_update_dynamic_cores_onoff - Update the L2 and shader power state
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2011-2021 ARM Limited. All rights reserved.
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <backend/gpu/mali_kbase_pm_internal.h>
|
||||
|
||||
#if MALI_USE_CSF
|
||||
#include "mali_kbase_clk_rate_trace_mgr.h"
|
||||
#include "backend/gpu/mali_kbase_clk_rate_trace_mgr.h"
|
||||
#include <csf/ipa_control/mali_kbase_csf_ipa_control.h>
|
||||
#else
|
||||
#include <backend/gpu/mali_kbase_jm_rb.h>
|
||||
@@ -206,7 +206,7 @@ static void kbase_pm_get_dvfs_utilisation_calc(struct kbase_device *kbdev)
|
||||
"Failed to query the increment of GPU_ACTIVE counter: err=%d",
|
||||
err);
|
||||
} else {
|
||||
u64 diff_ns, margin_ns;
|
||||
u64 diff_ns;
|
||||
s64 diff_ns_signed;
|
||||
u32 ns_time;
|
||||
ktime_t diff = ktime_sub(
|
||||
@@ -219,15 +219,7 @@ static void kbase_pm_get_dvfs_utilisation_calc(struct kbase_device *kbdev)
|
||||
|
||||
diff_ns = (u64)diff_ns_signed;
|
||||
|
||||
/* Use a margin value that is approximately 1% of the time
|
||||
* difference.
|
||||
*/
|
||||
margin_ns = diff_ns >> 6;
|
||||
|
||||
/* Calculate time difference in units of 256ns */
|
||||
ns_time = (u32)(diff_ns >> KBASE_PM_TIME_SHIFT);
|
||||
|
||||
#ifndef CONFIG_MALI_BIFROST_NO_MALI
|
||||
#if !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
|
||||
/* The GPU_ACTIVE counter shouldn't clock-up more time than has
|
||||
* actually elapsed - but still some margin needs to be given
|
||||
* when doing the comparison. There could be some drift between
|
||||
@@ -239,6 +231,10 @@ static void kbase_pm_get_dvfs_utilisation_calc(struct kbase_device *kbdev)
|
||||
* time.
|
||||
*/
|
||||
if (!kbdev->pm.backend.metrics.skip_gpu_active_sanity_check) {
|
||||
/* Use a margin value that is approximately 1% of the time
|
||||
* difference.
|
||||
*/
|
||||
u64 margin_ns = diff_ns >> 6;
|
||||
if (gpu_active_counter > (diff_ns + margin_ns)) {
|
||||
dev_info(
|
||||
kbdev->dev,
|
||||
@@ -247,9 +243,9 @@ static void kbase_pm_get_dvfs_utilisation_calc(struct kbase_device *kbdev)
|
||||
(unsigned long long)diff_ns);
|
||||
}
|
||||
}
|
||||
#else
|
||||
CSTD_UNUSED(margin_ns);
|
||||
#endif
|
||||
/* Calculate time difference in units of 256ns */
|
||||
ns_time = (u32)(diff_ns >> KBASE_PM_TIME_SHIFT);
|
||||
|
||||
/* Add protected_time to gpu_active_counter so that time in
|
||||
* protected mode is included in the apparent GPU active time,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
|
||||
@@ -33,29 +33,30 @@
|
||||
#include <csf/mali_kbase_csf_firmware.h>
|
||||
#endif
|
||||
|
||||
#include <linux/of.h>
|
||||
|
||||
static const struct kbase_pm_policy *const all_policy_list[] = {
|
||||
#ifdef CONFIG_MALI_BIFROST_NO_MALI
|
||||
&kbase_pm_always_on_policy_ops,
|
||||
&kbase_pm_coarse_demand_policy_ops,
|
||||
#if !MALI_CUSTOMER_RELEASE
|
||||
&kbase_pm_always_on_demand_policy_ops,
|
||||
#endif
|
||||
#else /* CONFIG_MALI_BIFROST_NO_MALI */
|
||||
&kbase_pm_coarse_demand_policy_ops,
|
||||
#if !MALI_CUSTOMER_RELEASE
|
||||
&kbase_pm_always_on_demand_policy_ops,
|
||||
#endif
|
||||
&kbase_pm_always_on_policy_ops
|
||||
#endif /* CONFIG_MALI_BIFROST_NO_MALI */
|
||||
};
|
||||
|
||||
#if MALI_USE_CSF
|
||||
void kbase_pm_policy_init(struct kbase_device *kbdev)
|
||||
{
|
||||
unsigned long flags;
|
||||
const struct kbase_pm_policy *default_policy = all_policy_list[0];
|
||||
struct device_node *np = kbdev->dev->of_node;
|
||||
const char *power_policy_name;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
#if defined CONFIG_MALI_BIFROST_DEBUG
|
||||
if (of_property_read_string(np, "power_policy", &power_policy_name) == 0) {
|
||||
for (i = 0; i < ARRAY_SIZE(all_policy_list); i++)
|
||||
if (sysfs_streq(all_policy_list[i]->name, power_policy_name)) {
|
||||
default_policy = all_policy_list[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if MALI_USE_CSF && defined(CONFIG_MALI_BIFROST_DEBUG)
|
||||
/* Use always_on policy if module param fw_debug=1 is
|
||||
* passed, to aid firmware debugging.
|
||||
*/
|
||||
@@ -63,31 +64,18 @@ void kbase_pm_policy_init(struct kbase_device *kbdev)
|
||||
default_policy = &kbase_pm_always_on_policy_ops;
|
||||
#endif
|
||||
|
||||
|
||||
default_policy->init(kbdev);
|
||||
|
||||
#if MALI_USE_CSF
|
||||
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
|
||||
kbdev->pm.backend.pm_current_policy = default_policy;
|
||||
kbdev->pm.backend.csf_pm_sched_flags =
|
||||
default_policy->pm_sched_flags;
|
||||
kbdev->pm.backend.csf_pm_sched_flags = default_policy->pm_sched_flags;
|
||||
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
|
||||
}
|
||||
#else /* MALI_USE_CSF */
|
||||
void kbase_pm_policy_init(struct kbase_device *kbdev)
|
||||
{
|
||||
kbdev->pm.backend.pm_current_policy = all_policy_list[0];
|
||||
|
||||
#if MALI_USE_CSF && defined CONFIG_MALI_BIFROST_DEBUG
|
||||
/* Use always_on policy if module param fw_debug=1 is
|
||||
* passed, to aid firmware debugging.
|
||||
*/
|
||||
if (fw_debug)
|
||||
kbdev->pm.backend.pm_current_policy =
|
||||
&kbase_pm_always_on_policy_ops;
|
||||
#else
|
||||
CSTD_UNUSED(flags);
|
||||
kbdev->pm.backend.pm_current_policy = default_policy;
|
||||
#endif
|
||||
kbdev->pm.backend.pm_current_policy->init(kbdev);
|
||||
}
|
||||
#endif /* MALI_USE_CSF */
|
||||
|
||||
void kbase_pm_policy_term(struct kbase_device *kbdev)
|
||||
{
|
||||
@@ -373,6 +361,9 @@ void kbase_pm_set_policy(struct kbase_device *kbdev,
|
||||
if (old_policy->term)
|
||||
old_policy->term(kbdev);
|
||||
|
||||
memset(&kbdev->pm.backend.pm_policy_data, 0,
|
||||
sizeof(union kbase_pm_policy_data));
|
||||
|
||||
KBASE_KTRACE_ADD(kbdev, PM_CURRENT_POLICY_INIT, NULL, new_policy->id);
|
||||
if (new_policy->init)
|
||||
new_policy->init(kbdev);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2010-2015, 2018-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2010-2015, 2018-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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2021 ARM Limited. All rights reserved.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2014-2016, 2018-2021 ARM Limited. All rights reserved.
|
||||
@@ -76,9 +76,6 @@ void kbase_backend_get_gpu_time_norequest(struct kbase_device *kbdev,
|
||||
*/
|
||||
static bool timedwait_cycle_count_active(struct kbase_device *kbdev)
|
||||
{
|
||||
#ifdef CONFIG_MALI_BIFROST_NO_MALI
|
||||
return true;
|
||||
#else
|
||||
bool success = false;
|
||||
const unsigned int timeout = 100;
|
||||
const unsigned long remaining = jiffies + msecs_to_jiffies(timeout);
|
||||
@@ -91,7 +88,6 @@ static bool timedwait_cycle_count_active(struct kbase_device *kbdev)
|
||||
}
|
||||
}
|
||||
return success;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2017-2021 ARM Limited. All rights reserved.
|
||||
@@ -25,14 +25,17 @@
|
||||
* both mali_kbase and the test modules. */
|
||||
bob_defaults {
|
||||
name: "mali_kbase_shared_config_defaults",
|
||||
defaults: [
|
||||
"kernel_defaults",
|
||||
],
|
||||
no_mali: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_NO_MALI=y"],
|
||||
kbuild_options: [
|
||||
"CONFIG_MALI_BIFROST_NO_MALI=y",
|
||||
"CONFIG_MALI_NO_MALI_DEFAULT_GPU={{.gpu}}",
|
||||
],
|
||||
},
|
||||
mali_real_hw: {
|
||||
kbuild_options: ["CONFIG_MALI_REAL_HW=y"],
|
||||
},
|
||||
mali_dma_fence: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_DMA_FENCE=y"],
|
||||
gpu_has_csf: {
|
||||
kbuild_options: ["CONFIG_MALI_CSF_SUPPORT=y"],
|
||||
},
|
||||
mali_devfreq: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_DEVFREQ=y"],
|
||||
@@ -40,8 +43,62 @@ bob_defaults {
|
||||
mali_midgard_dvfs: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_DVFS=y"],
|
||||
},
|
||||
mali_gator_support: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_GATOR_SUPPORT=y"],
|
||||
},
|
||||
mali_midgard_enable_trace: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_ENABLE_TRACE=y"],
|
||||
},
|
||||
mali_dma_fence: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_DMA_FENCE=y"],
|
||||
},
|
||||
mali_arbiter_support: {
|
||||
kbuild_options: ["CONFIG_MALI_ARBITER_SUPPORT=y"],
|
||||
},
|
||||
mali_dma_buf_map_on_demand: {
|
||||
kbuild_options: ["CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND=y"],
|
||||
},
|
||||
mali_dma_buf_legacy_compat: {
|
||||
kbuild_options: ["CONFIG_MALI_DMA_BUF_LEGACY_COMPAT=y"],
|
||||
},
|
||||
mali_2mb_alloc: {
|
||||
kbuild_options: ["CONFIG_MALI_2MB_ALLOC=y"],
|
||||
},
|
||||
mali_memory_fully_backed: {
|
||||
kbuild_options: ["CONFIG_MALI_MEMORY_FULLY_BACKED=y"],
|
||||
},
|
||||
mali_corestack: {
|
||||
kbuild_options: ["CONFIG_MALI_CORESTACK=y"],
|
||||
},
|
||||
mali_real_hw: {
|
||||
kbuild_options: ["CONFIG_MALI_REAL_HW=y"],
|
||||
},
|
||||
mali_error_inject_none: {
|
||||
kbuild_options: ["CONFIG_MALI_ERROR_INJECT_NONE=y"],
|
||||
},
|
||||
mali_error_inject_track_list: {
|
||||
kbuild_options: ["CONFIG_MALI_ERROR_INJECT_TRACK_LIST=y"],
|
||||
},
|
||||
mali_error_inject_random: {
|
||||
kbuild_options: ["CONFIG_MALI_ERROR_INJECT_RANDOM=y"],
|
||||
},
|
||||
mali_error_inject: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_ERROR_INJECT=y"],
|
||||
},
|
||||
mali_gem5_build: {
|
||||
kbuild_options: ["CONFIG_MALI_GEM5_BUILD=y"],
|
||||
},
|
||||
mali_debug: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_DEBUG=y"],
|
||||
kbuild_options: [
|
||||
"CONFIG_MALI_BIFROST_DEBUG=y",
|
||||
"MALI_KERNEL_TEST_API={{.debug}}",
|
||||
],
|
||||
},
|
||||
mali_fence_debug: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_FENCE_DEBUG=y"],
|
||||
},
|
||||
mali_system_trace: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_SYSTEM_TRACE=y"],
|
||||
},
|
||||
buslog: {
|
||||
kbuild_options: ["CONFIG_MALI_BUSLOG=y"],
|
||||
@@ -52,91 +109,8 @@ bob_defaults {
|
||||
cinstr_gwt: {
|
||||
kbuild_options: ["CONFIG_MALI_CINSTR_GWT=y"],
|
||||
},
|
||||
mali_gator_support: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_GATOR_SUPPORT=y"],
|
||||
},
|
||||
mali_midgard_enable_trace: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_ENABLE_TRACE=y"],
|
||||
},
|
||||
mali_system_trace: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_SYSTEM_TRACE=y"],
|
||||
},
|
||||
mali_pwrsoft_765: {
|
||||
kbuild_options: ["CONFIG_MALI_PWRSOFT_765=y"],
|
||||
},
|
||||
mali_memory_fully_backed: {
|
||||
kbuild_options: ["CONFIG_MALI_MEMORY_FULLY_BACKED=y"],
|
||||
},
|
||||
mali_dma_buf_map_on_demand: {
|
||||
kbuild_options: ["CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND=y"],
|
||||
},
|
||||
mali_dma_buf_legacy_compat: {
|
||||
kbuild_options: ["CONFIG_MALI_DMA_BUF_LEGACY_COMPAT=y"],
|
||||
},
|
||||
mali_arbiter_support: {
|
||||
kbuild_options: ["CONFIG_MALI_ARBITER_SUPPORT=y"],
|
||||
},
|
||||
mali_gem5_build: {
|
||||
kbuild_options: ["CONFIG_MALI_GEM5_BUILD=y"],
|
||||
},
|
||||
kbuild_options: [
|
||||
"MALI_UNIT_TEST={{.unit_test_code}}",
|
||||
"MALI_CUSTOMER_RELEASE={{.release}}",
|
||||
"MALI_USE_CSF={{.gpu_has_csf}}",
|
||||
"MALI_KERNEL_TEST_API={{.debug}}",
|
||||
],
|
||||
defaults: ["kernel_defaults"],
|
||||
}
|
||||
|
||||
bob_kernel_module {
|
||||
name: "mali_kbase",
|
||||
srcs: [
|
||||
"*.c",
|
||||
"*.h",
|
||||
"Kbuild",
|
||||
"backend/gpu/*.c",
|
||||
"backend/gpu/*.h",
|
||||
"backend/gpu/Kbuild",
|
||||
"context/*.c",
|
||||
"context/*.h",
|
||||
"ipa/*.c",
|
||||
"ipa/*.h",
|
||||
"ipa/Kbuild",
|
||||
"platform/*.h",
|
||||
"platform/*/*.c",
|
||||
"platform/*/*.h",
|
||||
"platform/*/Kbuild",
|
||||
"thirdparty/*.c",
|
||||
"debug/*.c",
|
||||
"debug/*.h",
|
||||
"device/*.c",
|
||||
"device/*.h",
|
||||
"gpu/*.c",
|
||||
"gpu/*.h",
|
||||
"tl/*.c",
|
||||
"tl/*.h",
|
||||
"mmu/*.c",
|
||||
"mmu/*.h",
|
||||
],
|
||||
kbuild_options: [
|
||||
"CONFIG_MALI_KUTF=n",
|
||||
"CONFIG_MALI_MIDGARD=m",
|
||||
"CONFIG_MALI_NO_MALI_DEFAULT_GPU={{.gpu}}",
|
||||
"CONFIG_MALI_PLATFORM_NAME={{.mali_platform_name}}",
|
||||
],
|
||||
buslog: {
|
||||
extra_symbols: [
|
||||
"bus_logger",
|
||||
],
|
||||
},
|
||||
mali_corestack: {
|
||||
kbuild_options: ["CONFIG_MALI_CORESTACK=y"],
|
||||
},
|
||||
mali_error_inject: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_ERROR_INJECT=y"],
|
||||
},
|
||||
mali_error_inject_random: {
|
||||
kbuild_options: ["CONFIG_MALI_ERROR_INJECT_RANDOM=y"],
|
||||
cinstr_primary_hwc: {
|
||||
kbuild_options: ["CONFIG_MALI_PRFCNT_SET_PRIMARY=y"],
|
||||
},
|
||||
cinstr_secondary_hwc: {
|
||||
kbuild_options: ["CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY=y"],
|
||||
@@ -147,8 +121,11 @@ bob_kernel_module {
|
||||
cinstr_hwc_set_select_via_debug_fs: {
|
||||
kbuild_options: ["CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS=y"],
|
||||
},
|
||||
mali_2mb_alloc: {
|
||||
kbuild_options: ["CONFIG_MALI_2MB_ALLOC=y"],
|
||||
mali_job_dump: {
|
||||
kbuild_options: ["CONFIG_MALI_JOB_DUMP"],
|
||||
},
|
||||
mali_pwrsoft_765: {
|
||||
kbuild_options: ["CONFIG_MALI_PWRSOFT_765=y"],
|
||||
},
|
||||
mali_hw_errata_1485982_not_affected: {
|
||||
kbuild_options: ["CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED=y"],
|
||||
@@ -156,6 +133,71 @@ bob_kernel_module {
|
||||
mali_hw_errata_1485982_use_clock_alternative: {
|
||||
kbuild_options: ["CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE=y"],
|
||||
},
|
||||
kbuild_options: [
|
||||
"CONFIG_MALI_PLATFORM_NAME={{.mali_platform_name}}",
|
||||
"MALI_CUSTOMER_RELEASE={{.release}}",
|
||||
"MALI_UNIT_TEST={{.unit_test_code}}",
|
||||
"MALI_USE_CSF={{.gpu_has_csf}}",
|
||||
"MALI_JIT_PRESSURE_LIMIT_BASE={{.jit_pressure_limit_base}}",
|
||||
|
||||
// Start of CS experimental features definitions.
|
||||
// If there is nothing below, definition should be added as follows:
|
||||
// "MALI_EXPERIMENTAL_FEATURE={{.experimental_feature}}"
|
||||
// experimental_feature above comes from Mconfig in
|
||||
// <ddk_root>/product/base/
|
||||
// However, in Mconfig, experimental_feature should be looked up (for
|
||||
// similar explanation to this one) as ALLCAPS, i.e.
|
||||
// EXPERIMENTAL_FEATURE.
|
||||
//
|
||||
// IMPORTANT: MALI_CS_EXPERIMENTAL should NEVER be defined below as it
|
||||
// is an umbrella feature that would be open for inappropriate use
|
||||
// (catch-all for experimental CS code without separating it into
|
||||
// different features).
|
||||
"MALI_INCREMENTAL_RENDERING={{.incremental_rendering}}",
|
||||
"GPU_TIMESTAMP_CORRECTION={{.gpu_timestamp_correction}}",
|
||||
],
|
||||
}
|
||||
|
||||
bob_kernel_module {
|
||||
name: "mali_kbase",
|
||||
defaults: [
|
||||
"mali_kbase_shared_config_defaults",
|
||||
],
|
||||
srcs: [
|
||||
"*.c",
|
||||
"*.h",
|
||||
"Kbuild",
|
||||
"backend/gpu/*.c",
|
||||
"backend/gpu/*.h",
|
||||
"backend/gpu/Kbuild",
|
||||
"context/*.c",
|
||||
"context/*.h",
|
||||
"context/Kbuild",
|
||||
"ipa/*.c",
|
||||
"ipa/*.h",
|
||||
"ipa/Kbuild",
|
||||
"platform/*.h",
|
||||
"platform/*/*.c",
|
||||
"platform/*/*.h",
|
||||
"platform/*/Kbuild",
|
||||
"thirdparty/*.c",
|
||||
"thirdparty/Kbuild",
|
||||
"debug/*.c",
|
||||
"debug/*.h",
|
||||
"debug/Kbuild",
|
||||
"device/*.c",
|
||||
"device/*.h",
|
||||
"device/Kbuild",
|
||||
"gpu/*.c",
|
||||
"gpu/*.h",
|
||||
"gpu/Kbuild",
|
||||
"tl/*.c",
|
||||
"tl/*.h",
|
||||
"tl/Kbuild",
|
||||
"mmu/*.c",
|
||||
"mmu/*.h",
|
||||
"mmu/Kbuild",
|
||||
],
|
||||
gpu_has_job_manager: {
|
||||
srcs: [
|
||||
"context/backend/*_jm.c",
|
||||
@@ -172,7 +214,6 @@ bob_kernel_module {
|
||||
],
|
||||
},
|
||||
gpu_has_csf: {
|
||||
kbuild_options: ["CONFIG_MALI_CSF_SUPPORT=y"],
|
||||
srcs: [
|
||||
"context/backend/*_csf.c",
|
||||
"csf/*.c",
|
||||
@@ -199,5 +240,13 @@ bob_kernel_module {
|
||||
"arbiter/Kbuild",
|
||||
],
|
||||
},
|
||||
defaults: ["mali_kbase_shared_config_defaults"],
|
||||
kbuild_options: [
|
||||
"CONFIG_MALI_BIFROST=m",
|
||||
"CONFIG_MALI_KUTF=n",
|
||||
],
|
||||
buslog: {
|
||||
extra_symbols: [
|
||||
"bus_logger",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 2012-2013, 2016-2017, 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
|
||||
@@ -18,10 +18,10 @@
|
||||
#
|
||||
#
|
||||
|
||||
bifrost_kbase-y += context/mali_kbase_context.o
|
||||
|
||||
config MALI_PROTECTED_MEMORY_ALLOCATOR
|
||||
tristate "MALI_PROTECTED_MEMORY_ALLOCATOR"
|
||||
help
|
||||
This option enables an example implementation of a protected memory allocator
|
||||
for allocation and release of pages of secure memory intended to be used
|
||||
by the firmware of Mali GPU device drivers.
|
||||
ifeq ($(CONFIG_MALI_CSF_SUPPORT),y)
|
||||
bifrost_kbase-y += context/backend/mali_kbase_context_csf.o
|
||||
else
|
||||
bifrost_kbase-y += context/backend/mali_kbase_context_jm.o
|
||||
endif
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2020 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
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <mmu/mali_kbase_mmu.h>
|
||||
#include <tl/mali_kbase_timeline.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
#include <csf/mali_kbase_csf_csg_debugfs.h>
|
||||
#include <csf/mali_kbase_csf_kcpu_debugfs.h>
|
||||
#include <csf/mali_kbase_csf_tiler_heap_debugfs.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <mmu/mali_kbase_mmu.h>
|
||||
#include <tl/mali_kbase_timeline.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
#include <mali_kbase_debug_mem_view.h>
|
||||
#include <mali_kbase_mem_pool_debugfs.h>
|
||||
|
||||
@@ -147,7 +147,7 @@ static const struct kbase_context_init context_init[] = {
|
||||
"JS kctx initialization failed" },
|
||||
{ kbase_jd_init, kbase_jd_exit, "JD initialization failed" },
|
||||
{ kbase_context_submit_check, NULL, "Enabling job submission failed" },
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
{ kbase_debug_job_fault_context_init,
|
||||
kbase_debug_job_fault_context_term,
|
||||
"Job fault context initialization failed" },
|
||||
@@ -155,6 +155,8 @@ static const struct kbase_context_init context_init[] = {
|
||||
{ NULL, kbase_context_flush_jobs, NULL },
|
||||
{ kbase_context_add_to_dev_list, kbase_context_remove_from_dev_list,
|
||||
"Adding kctx to device failed" },
|
||||
{ kbasep_platform_context_init, kbasep_platform_context_term,
|
||||
"Platform callback for kctx initialization failed" },
|
||||
};
|
||||
|
||||
static void kbase_context_term_partial(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2020 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
|
||||
@@ -154,7 +154,7 @@ int kbase_context_common_init(struct kbase_context *kctx)
|
||||
atomic_set(&kctx->event_count, 0);
|
||||
#if !MALI_USE_CSF
|
||||
atomic_set(&kctx->event_closed, false);
|
||||
#ifdef CONFIG_GPU_TRACEPOINTS
|
||||
#if IS_ENABLED(CONFIG_GPU_TRACEPOINTS)
|
||||
atomic_set(&kctx->jctx.work_id, 0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2011-2017, 2019-2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 2011-2017, 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2020 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2018-2020 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 2018-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
|
||||
@@ -19,24 +19,29 @@
|
||||
#
|
||||
|
||||
bifrost_kbase-y += \
|
||||
csf/mali_kbase_csf_firmware_cfg.o \
|
||||
csf/mali_kbase_csf_trace_buffer.o \
|
||||
csf/mali_kbase_csf.o \
|
||||
csf/mali_kbase_csf_scheduler.o \
|
||||
csf/mali_kbase_csf_kcpu.o \
|
||||
csf/mali_kbase_csf_tiler_heap.o \
|
||||
csf/mali_kbase_csf_timeout.o \
|
||||
csf/mali_kbase_csf_tl_reader.o \
|
||||
csf/mali_kbase_csf_heap_context_alloc.o \
|
||||
csf/mali_kbase_csf_reset_gpu.o \
|
||||
csf/mali_kbase_csf_csg_debugfs.o \
|
||||
csf/mali_kbase_csf_kcpu_debugfs.o \
|
||||
csf/mali_kbase_csf_protected_memory.o \
|
||||
csf/mali_kbase_csf_tiler_heap_debugfs.o \
|
||||
csf/mali_kbase_csf_cpu_queue_debugfs.o
|
||||
csf/mali_kbase_csf_firmware_cfg.o \
|
||||
csf/mali_kbase_csf_trace_buffer.o \
|
||||
csf/mali_kbase_csf.o \
|
||||
csf/mali_kbase_csf_scheduler.o \
|
||||
csf/mali_kbase_csf_kcpu.o \
|
||||
csf/mali_kbase_csf_tiler_heap.o \
|
||||
csf/mali_kbase_csf_timeout.o \
|
||||
csf/mali_kbase_csf_tl_reader.o \
|
||||
csf/mali_kbase_csf_heap_context_alloc.o \
|
||||
csf/mali_kbase_csf_reset_gpu.o \
|
||||
csf/mali_kbase_csf_csg_debugfs.o \
|
||||
csf/mali_kbase_csf_kcpu_debugfs.o \
|
||||
csf/mali_kbase_csf_protected_memory.o \
|
||||
csf/mali_kbase_csf_tiler_heap_debugfs.o \
|
||||
csf/mali_kbase_csf_cpu_queue_debugfs.o
|
||||
|
||||
bifrost_kbase-$(CONFIG_MALI_REAL_HW) += csf/mali_kbase_csf_firmware.o
|
||||
|
||||
bifrost_kbase-$(CONFIG_MALI_BIFROST_NO_MALI) += csf/mali_kbase_csf_firmware_no_mali.o
|
||||
|
||||
include $(src)/csf/ipa_control/Kbuild
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
# in-tree
|
||||
-include $(src)/csf/ipa_control/Kbuild
|
||||
else
|
||||
# out-of-tree
|
||||
include $(src)/csf/ipa_control/Kbuild
|
||||
endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
|
||||
# (C) COPYRIGHT 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
|
||||
@@ -19,4 +19,4 @@
|
||||
#
|
||||
|
||||
bifrost_kbase-y += \
|
||||
csf/ipa_control/mali_kbase_csf_ipa_control.o
|
||||
csf/ipa_control/mali_kbase_csf_ipa_control.o
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 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
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
#include <mali_kbase.h>
|
||||
#include "mali_kbase_clk_rate_trace_mgr.h"
|
||||
#include "backend/gpu/mali_kbase_clk_rate_trace_mgr.h"
|
||||
#include "mali_kbase_csf_ipa_control.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020 ARM Limited. All rights reserved.
|
||||
* (C) COPYRIGHT 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2021 ARM Limited. All rights reserved.
|
||||
@@ -144,14 +144,21 @@ static void gpu_munmap_user_io_pages(struct kbase_context *kctx,
|
||||
mutex_unlock(&kctx->kbdev->csf.reg_lock);
|
||||
}
|
||||
|
||||
static void init_user_output_page(struct kbase_queue *queue)
|
||||
static void init_user_io_pages(struct kbase_queue *queue)
|
||||
{
|
||||
u32 *addr = (u32 *)(queue->user_io_addr + PAGE_SIZE);
|
||||
u32 *input_addr = (u32 *)(queue->user_io_addr);
|
||||
u32 *output_addr = (u32 *)(queue->user_io_addr + PAGE_SIZE);
|
||||
|
||||
addr[CS_EXTRACT_LO/4] = 0;
|
||||
addr[CS_EXTRACT_HI/4] = 0;
|
||||
input_addr[CS_INSERT_LO/4] = 0;
|
||||
input_addr[CS_INSERT_HI/4] = 0;
|
||||
|
||||
addr[CS_ACTIVE/4] = 0;
|
||||
input_addr[CS_EXTRACT_INIT_LO/4] = 0;
|
||||
input_addr[CS_EXTRACT_INIT_HI/4] = 0;
|
||||
|
||||
output_addr[CS_EXTRACT_LO/4] = 0;
|
||||
output_addr[CS_EXTRACT_HI/4] = 0;
|
||||
|
||||
output_addr[CS_ACTIVE/4] = 0;
|
||||
}
|
||||
|
||||
/* Map the input/output pages in the shared interface segment of MCU firmware
|
||||
@@ -350,7 +357,7 @@ int kbase_csf_alloc_command_stream_user_pages(struct kbase_context *kctx,
|
||||
if (ret)
|
||||
goto kernel_map_failed;
|
||||
|
||||
init_user_output_page(queue);
|
||||
init_user_io_pages(queue);
|
||||
|
||||
ret = gpu_mmap_user_io_pages(kctx->kbdev, queue->phys, reg);
|
||||
if (ret)
|
||||
@@ -455,19 +462,39 @@ static void release_queue(struct kbase_queue *queue)
|
||||
static void oom_event_worker(struct work_struct *data);
|
||||
static void fatal_event_worker(struct work_struct *data);
|
||||
|
||||
int kbase_csf_queue_register(struct kbase_context *kctx,
|
||||
struct kbase_ioctl_cs_queue_register *reg)
|
||||
/* Between reg and reg_ex, one and only one must be null */
|
||||
static int csf_queue_register_internal(struct kbase_context *kctx,
|
||||
struct kbase_ioctl_cs_queue_register *reg,
|
||||
struct kbase_ioctl_cs_queue_register_ex *reg_ex)
|
||||
{
|
||||
struct kbase_queue *queue;
|
||||
int ret = 0;
|
||||
struct kbase_va_region *region;
|
||||
u64 queue_addr = reg->buffer_gpu_addr;
|
||||
size_t queue_size = reg->buffer_size >> PAGE_SHIFT;
|
||||
u64 queue_addr;
|
||||
size_t queue_size;
|
||||
|
||||
/* Only one pointer expected, otherwise coding error */
|
||||
if ((reg == NULL && reg_ex == NULL) || (reg && reg_ex)) {
|
||||
dev_err(kctx->kbdev->dev,
|
||||
"Error, one and only one param-ptr expected!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* struct kbase_ioctl_cs_queue_register_ex contains a full
|
||||
* struct kbase_ioctl_cs_queue_register at the start address. So
|
||||
* the pointer can be safely cast to pointing to a
|
||||
* kbase_ioctl_cs_queue_register object.
|
||||
*/
|
||||
if (reg_ex)
|
||||
reg = (struct kbase_ioctl_cs_queue_register *)reg_ex;
|
||||
|
||||
/* Validate the queue priority */
|
||||
if (reg->priority > BASE_QUEUE_MAX_PRIORITY)
|
||||
return -EINVAL;
|
||||
|
||||
queue_addr = reg->buffer_gpu_addr;
|
||||
queue_size = reg->buffer_size >> PAGE_SHIFT;
|
||||
|
||||
mutex_lock(&kctx->csf.lock);
|
||||
|
||||
/* Check if queue is already registered */
|
||||
@@ -492,6 +519,35 @@ int kbase_csf_queue_register(struct kbase_context *kctx,
|
||||
goto out_unlock_vm;
|
||||
}
|
||||
|
||||
/* Check address validity on cs_trace buffer etc. Don't care
|
||||
* if not enabled (i.e. when size is 0).
|
||||
*/
|
||||
if (reg_ex && reg_ex->ex_buffer_size) {
|
||||
int buf_pages = (reg_ex->ex_buffer_size +
|
||||
(1 << PAGE_SHIFT) - 1) >> PAGE_SHIFT;
|
||||
|
||||
region = kbase_region_tracker_find_region_enclosing_address(
|
||||
kctx, reg_ex->ex_buffer_base);
|
||||
if (kbase_is_region_invalid_or_free(region)) {
|
||||
ret = -ENOENT;
|
||||
goto out_unlock_vm;
|
||||
}
|
||||
|
||||
if (buf_pages > (region->nr_pages -
|
||||
((reg_ex->ex_buffer_base >> PAGE_SHIFT) -
|
||||
region->start_pfn))) {
|
||||
ret = -EINVAL;
|
||||
goto out_unlock_vm;
|
||||
}
|
||||
|
||||
region = kbase_region_tracker_find_region_enclosing_address(
|
||||
kctx, reg_ex->ex_offset_var_addr);
|
||||
if (kbase_is_region_invalid_or_free(region)) {
|
||||
ret = -ENOENT;
|
||||
goto out_unlock_vm;
|
||||
}
|
||||
}
|
||||
|
||||
queue = kzalloc(sizeof(struct kbase_queue), GFP_KERNEL);
|
||||
|
||||
if (!queue) {
|
||||
@@ -529,6 +585,22 @@ int kbase_csf_queue_register(struct kbase_context *kctx,
|
||||
|
||||
region->flags |= KBASE_REG_NO_USER_FREE;
|
||||
|
||||
/* Initialize the cs_trace configuration parameters, When buffer_size
|
||||
* is 0, trace is disabled. Here we only update the fields when
|
||||
* enabled, otherwise leave them as default zeros.
|
||||
*/
|
||||
if (reg_ex && reg_ex->ex_buffer_size) {
|
||||
u32 cfg = CS_INSTR_CONFIG_EVENT_SIZE_SET(
|
||||
0, reg_ex->ex_event_size);
|
||||
cfg = CS_INSTR_CONFIG_EVENT_STATE_SET(
|
||||
cfg, reg_ex->ex_event_state);
|
||||
|
||||
queue->trace_cfg = cfg;
|
||||
queue->trace_buffer_size = reg_ex->ex_buffer_size;
|
||||
queue->trace_buffer_base = reg_ex->ex_buffer_base;
|
||||
queue->trace_offset_ptr = reg_ex->ex_offset_var_addr;
|
||||
}
|
||||
|
||||
out_unlock_vm:
|
||||
kbase_gpu_vm_unlock(kctx);
|
||||
out:
|
||||
@@ -537,6 +609,37 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kbase_csf_queue_register(struct kbase_context *kctx,
|
||||
struct kbase_ioctl_cs_queue_register *reg)
|
||||
{
|
||||
return csf_queue_register_internal(kctx, reg, NULL);
|
||||
}
|
||||
|
||||
int kbase_csf_queue_register_ex(struct kbase_context *kctx,
|
||||
struct kbase_ioctl_cs_queue_register_ex *reg)
|
||||
{
|
||||
struct kbase_csf_global_iface const *const iface =
|
||||
&kctx->kbdev->csf.global_iface;
|
||||
u32 const glb_version = iface->version;
|
||||
u32 instr = iface->instr_features;
|
||||
u8 max_size = GLB_INSTR_FEATURES_EVENT_SIZE_MAX_GET(instr);
|
||||
u32 min_buf_size = (1u << reg->ex_event_size) *
|
||||
GLB_INSTR_FEATURES_OFFSET_UPDATE_RATE_GET(instr);
|
||||
|
||||
/* If cs_trace_command not supported, the call fails */
|
||||
if (glb_version < kbase_csf_interface_version(1, 1, 0))
|
||||
return -EINVAL;
|
||||
|
||||
/* Validate the cs_trace configuration parameters */
|
||||
if (reg->ex_buffer_size &&
|
||||
((reg->ex_event_size > max_size) ||
|
||||
(reg->ex_buffer_size & (reg->ex_buffer_size - 1)) ||
|
||||
(reg->ex_buffer_size < min_buf_size)))
|
||||
return -EINVAL;
|
||||
|
||||
return csf_queue_register_internal(kctx, NULL, reg);
|
||||
}
|
||||
|
||||
static void unbind_queue(struct kbase_context *kctx,
|
||||
struct kbase_queue *queue);
|
||||
|
||||
@@ -787,6 +890,8 @@ static void unbind_stopped_queue(struct kbase_context *kctx,
|
||||
kbase_csf_scheduler_spin_lock(kctx->kbdev, &flags);
|
||||
bitmap_clear(queue->group->protm_pending_bitmap,
|
||||
queue->csi_index, 1);
|
||||
KBASE_KTRACE_ADD_CSF_GRP_Q(kctx->kbdev, PROTM_PENDING_CLEAR,
|
||||
queue->group, queue, queue->group->protm_pending_bitmap[0]);
|
||||
queue->group->bound_queues[queue->csi_index] = NULL;
|
||||
queue->group = NULL;
|
||||
kbase_csf_scheduler_spin_unlock(kctx->kbdev, flags);
|
||||
@@ -1913,6 +2018,7 @@ void kbase_csf_event_signal(struct kbase_context *kctx, bool notify_gpu)
|
||||
spin_lock_irqsave(&kctx->kbdev->hwaccess_lock, flags);
|
||||
if (kctx->kbdev->pm.backend.gpu_powered)
|
||||
kbase_csf_ring_doorbell(kctx->kbdev, CSF_KERNEL_DOORBELL_NR);
|
||||
KBASE_KTRACE_ADD(kctx->kbdev, SYNC_UPDATE_EVENT_NOTIFY_GPU, kctx, 0u);
|
||||
spin_unlock_irqrestore(&kctx->kbdev->hwaccess_lock, flags);
|
||||
}
|
||||
|
||||
@@ -2251,7 +2357,11 @@ static void protm_event_worker(struct work_struct *data)
|
||||
struct kbase_queue_group *const group =
|
||||
container_of(data, struct kbase_queue_group, protm_event_work);
|
||||
|
||||
KBASE_KTRACE_ADD_CSF_GRP(group->kctx->kbdev, PROTM_EVENT_WORKER_BEGIN,
|
||||
group, 0u);
|
||||
kbase_csf_scheduler_group_protm_enter(group);
|
||||
KBASE_KTRACE_ADD_CSF_GRP(group->kctx->kbdev, PROTM_EVENT_WORKER_END,
|
||||
group, 0u);
|
||||
}
|
||||
|
||||
static void report_queue_fatal_error(struct kbase_queue *const queue,
|
||||
@@ -2308,13 +2418,16 @@ handle_fault_event(struct kbase_queue *const queue,
|
||||
|
||||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
|
||||
dev_warn(kbdev->dev, "CSI: %d\n"
|
||||
"CS_FAULT.EXCEPTION_TYPE: 0x%x (%s)\n"
|
||||
"CS_FAULT.EXCEPTION_DATA: 0x%x\n"
|
||||
"CS_FAULT_INFO.EXCEPTION_DATA: 0x%llx\n",
|
||||
queue->csi_index, cs_fault_exception_type,
|
||||
kbase_gpu_exception_name(cs_fault_exception_type),
|
||||
cs_fault_exception_data, cs_fault_info_exception_data);
|
||||
dev_warn(kbdev->dev,
|
||||
"Ctx %d_%d Group %d CSG %d CSI: %d\n"
|
||||
"CS_FAULT.EXCEPTION_TYPE: 0x%x (%s)\n"
|
||||
"CS_FAULT.EXCEPTION_DATA: 0x%x\n"
|
||||
"CS_FAULT_INFO.EXCEPTION_DATA: 0x%llx\n",
|
||||
queue->kctx->tgid, queue->kctx->id, queue->group->handle,
|
||||
queue->group->csg_nr, queue->csi_index,
|
||||
cs_fault_exception_type,
|
||||
kbase_gpu_exception_name(cs_fault_exception_type),
|
||||
cs_fault_exception_data, cs_fault_info_exception_data);
|
||||
|
||||
if (cs_fault_exception_type ==
|
||||
CS_FAULT_EXCEPTION_TYPE_RESOURCE_EVICTION_TIMEOUT)
|
||||
@@ -2398,11 +2511,12 @@ handle_fatal_event(struct kbase_queue *const queue,
|
||||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
|
||||
dev_warn(kbdev->dev,
|
||||
"CSG: %d, CSI: %d\n"
|
||||
"Ctx %d_%d Group %d CSG %d CSI: %d\n"
|
||||
"CS_FATAL.EXCEPTION_TYPE: 0x%x (%s)\n"
|
||||
"CS_FATAL.EXCEPTION_DATA: 0x%x\n"
|
||||
"CS_FATAL_INFO.EXCEPTION_DATA: 0x%llx\n",
|
||||
queue->group->handle, queue->csi_index,
|
||||
queue->kctx->tgid, queue->kctx->id, queue->group->handle,
|
||||
queue->group->csg_nr, queue->csi_index,
|
||||
cs_fatal_exception_type,
|
||||
kbase_gpu_exception_name(cs_fatal_exception_type),
|
||||
cs_fatal_exception_data, cs_fatal_info_exception_data);
|
||||
@@ -2505,23 +2619,28 @@ static void process_cs_interrupts(struct kbase_queue_group *const group,
|
||||
if ((cs_req & CS_REQ_EXCEPTION_MASK) ^
|
||||
(cs_ack & CS_ACK_EXCEPTION_MASK)) {
|
||||
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_FAULT_INTERRUPT, group, queue, cs_req ^ cs_ack);
|
||||
handle_queue_exception_event(queue, cs_req,
|
||||
cs_ack);
|
||||
handle_queue_exception_event(queue, cs_req, cs_ack);
|
||||
}
|
||||
|
||||
/* PROTM_PEND and TILER_OOM can be safely ignored
|
||||
* because they will be raised again if the group
|
||||
* is assigned a CSG slot in future.
|
||||
*/
|
||||
if (group_suspending)
|
||||
if (group_suspending) {
|
||||
u32 const cs_req_remain = cs_req & ~CS_REQ_EXCEPTION_MASK;
|
||||
u32 const cs_ack_remain = cs_ack & ~CS_ACK_EXCEPTION_MASK;
|
||||
|
||||
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_IGNORED_INTERRUPTS_GROUP_SUSPEND,
|
||||
group, queue, cs_req_remain ^ cs_ack_remain);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((cs_req & CS_REQ_TILER_OOM_MASK) ^
|
||||
(cs_ack & CS_ACK_TILER_OOM_MASK))) {
|
||||
get_queue(queue);
|
||||
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_TILER_OOM_INTERRUPT, group, queue, cs_req ^ cs_ack);
|
||||
if (WARN_ON(!queue_work(
|
||||
wq, &queue->oom_event_work))) {
|
||||
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_TILER_OOM_INTERRUPT, group, queue,
|
||||
cs_req ^ cs_ack);
|
||||
if (WARN_ON(!queue_work(wq, &queue->oom_event_work))) {
|
||||
/* The work item shall not have been
|
||||
* already queued, there can be only
|
||||
* one pending OoM event for a
|
||||
@@ -2533,12 +2652,17 @@ static void process_cs_interrupts(struct kbase_queue_group *const group,
|
||||
|
||||
if ((cs_req & CS_REQ_PROTM_PEND_MASK) ^
|
||||
(cs_ack & CS_ACK_PROTM_PEND_MASK)) {
|
||||
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_PROTM_PEND_INTERRUPT, group, queue,
|
||||
cs_req ^ cs_ack);
|
||||
|
||||
dev_dbg(kbdev->dev,
|
||||
"Protected mode entry request for queue on csi %d bound to group-%d on slot %d",
|
||||
queue->csi_index, group->handle,
|
||||
group->csg_nr);
|
||||
|
||||
bitmap_set(group->protm_pending_bitmap, i, 1);
|
||||
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, PROTM_PENDING_SET, group, queue,
|
||||
group->protm_pending_bitmap[0]);
|
||||
protm_pend = true;
|
||||
}
|
||||
}
|
||||
@@ -2567,7 +2691,7 @@ static void process_csg_interrupts(struct kbase_device *const kbdev,
|
||||
int const csg_nr)
|
||||
{
|
||||
struct kbase_csf_cmd_stream_group_info *ginfo;
|
||||
struct kbase_queue_group *group;
|
||||
struct kbase_queue_group *group = NULL;
|
||||
u32 req, ack, irqreq, irqack;
|
||||
|
||||
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
|
||||
@@ -2575,6 +2699,8 @@ static void process_csg_interrupts(struct kbase_device *const kbdev,
|
||||
if (WARN_ON(csg_nr >= kbdev->csf.global_iface.group_num))
|
||||
return;
|
||||
|
||||
KBASE_KTRACE_ADD(kbdev, CSG_INTERRUPT_PROCESS, NULL, csg_nr);
|
||||
|
||||
ginfo = &kbdev->csf.global_iface.groups[csg_nr];
|
||||
req = kbase_csf_firmware_csg_input_read(ginfo, CSG_REQ);
|
||||
ack = kbase_csf_firmware_csg_output(ginfo, CSG_ACK);
|
||||
@@ -2583,7 +2709,7 @@ static void process_csg_interrupts(struct kbase_device *const kbdev,
|
||||
|
||||
/* There may not be any pending CSG/CS interrupts to process */
|
||||
if ((req == ack) && (irqreq == irqack))
|
||||
return;
|
||||
goto out;
|
||||
|
||||
/* Immediately set IRQ_ACK bits to be same as the IRQ_REQ bits before
|
||||
* examining the CS_ACK & CS_REQ bits. This would ensure that Host
|
||||
@@ -2604,10 +2730,10 @@ static void process_csg_interrupts(struct kbase_device *const kbdev,
|
||||
* slot scheduler spinlock is required.
|
||||
*/
|
||||
if (!group)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
if (WARN_ON(kbase_csf_scheduler_group_get_slot_locked(group) != csg_nr))
|
||||
return;
|
||||
goto out;
|
||||
|
||||
if ((req ^ ack) & CSG_REQ_SYNC_UPDATE_MASK) {
|
||||
kbase_csf_firmware_csg_input_mask(ginfo,
|
||||
@@ -2624,7 +2750,8 @@ static void process_csg_interrupts(struct kbase_device *const kbdev,
|
||||
CSG_REQ_IDLE_MASK);
|
||||
|
||||
set_bit(csg_nr, scheduler->csg_slots_idle_mask);
|
||||
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_SLOT_IDLE_SET, group,
|
||||
scheduler->csg_slots_idle_mask[0]);
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_IDLE_INTERRUPT, group, req ^ ack);
|
||||
dev_dbg(kbdev->dev, "Idle notification received for Group %u on slot %d\n",
|
||||
group->handle, csg_nr);
|
||||
@@ -2640,6 +2767,8 @@ static void process_csg_interrupts(struct kbase_device *const kbdev,
|
||||
kbase_csf_firmware_csg_input_mask(ginfo, CSG_REQ, ack,
|
||||
CSG_REQ_PROGRESS_TIMER_EVENT_MASK);
|
||||
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_PROGRESS_TIMER_INTERRUPT,
|
||||
group, req ^ ack);
|
||||
dev_info(kbdev->dev,
|
||||
"Timeout notification received for group %u of ctx %d_%d on slot %d\n",
|
||||
group->handle, group->kctx->tgid, group->kctx->id, csg_nr);
|
||||
@@ -2648,6 +2777,11 @@ static void process_csg_interrupts(struct kbase_device *const kbdev,
|
||||
}
|
||||
|
||||
process_cs_interrupts(group, ginfo, irqreq, irqack);
|
||||
|
||||
out:
|
||||
/* group may still be NULL here */
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, CSG_INTERRUPT_PROCESS_END, group,
|
||||
((u64)req ^ ack) | (((u64)irqreq ^ irqack) << 32));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2741,6 +2875,7 @@ void kbase_csf_interrupt(struct kbase_device *kbdev, u32 val)
|
||||
|
||||
lockdep_assert_held(&kbdev->hwaccess_lock);
|
||||
|
||||
KBASE_KTRACE_ADD(kbdev, CSF_INTERRUPT, NULL, val);
|
||||
kbase_reg_write(kbdev, JOB_CONTROL_REG(JOB_IRQ_CLEAR), val);
|
||||
|
||||
if (val & JOB_IRQ_GLOBAL_IF) {
|
||||
@@ -2761,6 +2896,7 @@ void kbase_csf_interrupt(struct kbase_device *kbdev, u32 val)
|
||||
global_iface, GLB_REQ);
|
||||
glb_ack = kbase_csf_firmware_global_output(
|
||||
global_iface, GLB_ACK);
|
||||
KBASE_KTRACE_ADD(kbdev, GLB_REQ_ACQ, NULL, glb_req ^ glb_ack);
|
||||
|
||||
if ((glb_req ^ glb_ack) & GLB_REQ_PROTM_EXIT_MASK) {
|
||||
dev_dbg(kbdev->dev, "Protected mode exit interrupt received");
|
||||
@@ -2768,8 +2904,8 @@ void kbase_csf_interrupt(struct kbase_device *kbdev, u32 val)
|
||||
global_iface, GLB_REQ, glb_ack,
|
||||
GLB_REQ_PROTM_EXIT_MASK);
|
||||
WARN_ON(!kbase_csf_scheduler_protected_mode_in_use(kbdev));
|
||||
KBASE_KTRACE_ADD_CSF_GRP(kbdev, SCHEDULER_EXIT_PROTM, scheduler->active_protm_grp, 0u);
|
||||
scheduler->active_protm_grp = NULL;
|
||||
KBASE_KTRACE_ADD(kbdev, SCHEDULER_EXIT_PROTM, NULL, 0u);
|
||||
kbdev->protected_mode = false;
|
||||
kbase_ipa_control_protm_exited(kbdev);
|
||||
kbase_hwcnt_backend_csf_protm_exited(
|
||||
@@ -2778,13 +2914,20 @@ void kbase_csf_interrupt(struct kbase_device *kbdev, u32 val)
|
||||
|
||||
/* Handle IDLE Hysteresis notification event */
|
||||
if ((glb_req ^ glb_ack) & GLB_REQ_IDLE_EVENT_MASK) {
|
||||
int non_idle_offslot_grps;
|
||||
bool can_suspend_on_idle;
|
||||
dev_dbg(kbdev->dev, "Idle-hysteresis event flagged");
|
||||
kbase_csf_firmware_global_input_mask(
|
||||
global_iface, GLB_REQ, glb_ack,
|
||||
GLB_REQ_IDLE_EVENT_MASK);
|
||||
|
||||
if (!atomic_read(&scheduler->non_idle_offslot_grps)) {
|
||||
if (kbase_pm_idle_groups_sched_suspendable(kbdev))
|
||||
non_idle_offslot_grps = atomic_read(&scheduler->non_idle_offslot_grps);
|
||||
can_suspend_on_idle = kbase_pm_idle_groups_sched_suspendable(kbdev);
|
||||
KBASE_KTRACE_ADD(kbdev, SCHEDULER_CAN_IDLE, NULL,
|
||||
((u64)(u32)non_idle_offslot_grps) | (((u64)can_suspend_on_idle) << 32));
|
||||
|
||||
if (!non_idle_offslot_grps) {
|
||||
if (can_suspend_on_idle)
|
||||
queue_work(system_highpri_wq,
|
||||
&scheduler->gpu_idle_work);
|
||||
} else {
|
||||
@@ -2809,6 +2952,7 @@ void kbase_csf_interrupt(struct kbase_device *kbdev, u32 val)
|
||||
|
||||
if (!remaining) {
|
||||
wake_up_all(&kbdev->csf.event_wait);
|
||||
KBASE_KTRACE_ADD(kbdev, CSF_INTERRUPT_END, NULL, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2823,6 +2967,7 @@ void kbase_csf_interrupt(struct kbase_device *kbdev, u32 val)
|
||||
kbase_csf_scheduler_spin_unlock(kbdev, flags);
|
||||
|
||||
wake_up_all(&kbdev->csf.event_wait);
|
||||
KBASE_KTRACE_ADD(kbdev, CSF_INTERRUPT_END, NULL, val);
|
||||
}
|
||||
|
||||
void kbase_csf_doorbell_mapping_term(struct kbase_device *kbdev)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2021 ARM Limited. All rights reserved.
|
||||
@@ -39,7 +39,7 @@
|
||||
*/
|
||||
#define KBASEP_USER_DB_NR_INVALID ((s8)-1)
|
||||
|
||||
#define FIRMWARE_PING_INTERVAL_MS (2000) /* 2 seconds */
|
||||
#define FIRMWARE_PING_INTERVAL_MS (4000) /* 4 seconds */
|
||||
|
||||
#define FIRMWARE_IDLE_HYSTERESIS_TIME_MS (10) /* Default 10 milliseconds */
|
||||
|
||||
@@ -212,6 +212,22 @@ void kbase_csf_ctx_term(struct kbase_context *kctx);
|
||||
int kbase_csf_queue_register(struct kbase_context *kctx,
|
||||
struct kbase_ioctl_cs_queue_register *reg);
|
||||
|
||||
/**
|
||||
* kbase_csf_queue_register_ex - Register a GPU command queue with
|
||||
* extended format.
|
||||
*
|
||||
* @kctx: Pointer to the kbase context within which the
|
||||
* queue is to be registered.
|
||||
* @reg: Pointer to the structure which contains details of the
|
||||
* queue to be registered within the provided
|
||||
* context, together with the extended parameter fields
|
||||
* for supporting cs trace command.
|
||||
*
|
||||
* Return: 0 on success, or negative on failure.
|
||||
*/
|
||||
int kbase_csf_queue_register_ex(struct kbase_context *kctx,
|
||||
struct kbase_ioctl_cs_queue_register_ex *reg);
|
||||
|
||||
/**
|
||||
* kbase_csf_queue_terminate - Terminate a GPU command queue.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2021 ARM Limited. All rights reserved.
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <mali_kbase.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
|
||||
bool kbase_csf_cpu_queue_read_dump_req(struct kbase_context *kctx,
|
||||
struct base_csf_notification *req)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2020-2021 ARM Limited. All rights reserved.
|
||||
@@ -68,7 +68,7 @@ bool kbase_csf_cpu_queue_read_dump_req(struct kbase_context *kctx,
|
||||
*/
|
||||
static inline bool kbase_csf_cpu_queue_dump_needed(struct kbase_context *kctx)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
return (atomic_read(&kctx->csf.cpu_queue.dump_req_status) ==
|
||||
BASE_CSF_CPU_QUEUE_DUMP_ISSUED);
|
||||
#else
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2020 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
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <csf/mali_kbase_csf_trace_buffer.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
#include "mali_kbase_csf_tl_reader.h"
|
||||
|
||||
/**
|
||||
@@ -87,6 +87,32 @@ static void kbasep_csf_scheduler_dump_active_queue_cs_status_wait(
|
||||
blocked_reason)));
|
||||
}
|
||||
|
||||
static void kbasep_csf_scheduler_dump_active_cs_trace(struct seq_file *file,
|
||||
struct kbase_csf_cmd_stream_info const *const stream)
|
||||
{
|
||||
u32 val = kbase_csf_firmware_cs_input_read(stream,
|
||||
CS_INSTR_BUFFER_BASE_LO);
|
||||
u64 addr = ((u64)kbase_csf_firmware_cs_input_read(stream,
|
||||
CS_INSTR_BUFFER_BASE_HI) << 32) | val;
|
||||
val = kbase_csf_firmware_cs_input_read(stream,
|
||||
CS_INSTR_BUFFER_SIZE);
|
||||
|
||||
seq_printf(file, "CS_TRACE_BUF_ADDR: 0x%16llx, SIZE: %u\n", addr, val);
|
||||
|
||||
/* Write offset variable address (pointer) */
|
||||
val = kbase_csf_firmware_cs_input_read(stream,
|
||||
CS_INSTR_BUFFER_OFFSET_POINTER_LO);
|
||||
addr = ((u64)kbase_csf_firmware_cs_input_read(stream,
|
||||
CS_INSTR_BUFFER_OFFSET_POINTER_HI) << 32) | val;
|
||||
seq_printf(file, "CS_TRACE_BUF_OFFSET_PTR: 0x%16llx\n", addr);
|
||||
|
||||
/* EVENT_SIZE and EVENT_STATEs */
|
||||
val = kbase_csf_firmware_cs_input_read(stream, CS_INSTR_CONFIG);
|
||||
seq_printf(file, "TRACE_EVENT_SIZE: 0x%x, TRACE_EVENT_STAES 0x%x\n",
|
||||
CS_INSTR_CONFIG_EVENT_SIZE_GET(val),
|
||||
CS_INSTR_CONFIG_EVENT_STATE_GET(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* kbasep_csf_scheduler_dump_active_queue() - Print GPU command queue
|
||||
* debug information
|
||||
@@ -134,7 +160,9 @@ static void kbasep_csf_scheduler_dump_active_queue(struct seq_file *file,
|
||||
queue->csi_index, queue->base_addr, queue->priority,
|
||||
cs_insert, cs_extract, cs_active, queue->doorbell_nr);
|
||||
|
||||
/* Print status information for blocked group waiting for sync object */
|
||||
/* Print status information for blocked group waiting for sync object. For on-slot queues,
|
||||
* if cs_trace is enabled, dump the interface's cs_trace configuration.
|
||||
*/
|
||||
if (kbase_csf_scheduler_group_get_slot(queue->group) < 0) {
|
||||
if (CS_STATUS_WAIT_SYNC_WAIT_GET(queue->status_wait)) {
|
||||
wait_status = queue->status_wait;
|
||||
@@ -212,6 +240,11 @@ static void kbasep_csf_scheduler_dump_active_queue(struct seq_file *file,
|
||||
file, wait_status, wait_sync_value,
|
||||
wait_sync_live_value, wait_sync_pointer, sb_status,
|
||||
blocked_reason);
|
||||
/* Dealing with cs_trace */
|
||||
if (kbase_csf_scheduler_queue_has_trace(queue))
|
||||
kbasep_csf_scheduler_dump_active_cs_trace(file, stream);
|
||||
else
|
||||
seq_puts(file, "NO CS_TRACE\n");
|
||||
}
|
||||
|
||||
seq_puts(file, "\n");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2019-2020 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2021 ARM Limited. All rights reserved.
|
||||
@@ -314,6 +314,10 @@ struct kbase_csf_notification {
|
||||
* are non-zero
|
||||
* @blocked_reason: Value shows if the queue is blocked, and if so,
|
||||
* the reason why it is blocked
|
||||
* @trace_buffer_base: CS trace buffer base address.
|
||||
* @trace_offset_ptr: Pointer to the CS trace buffer offset variable.
|
||||
* @trace_buffer_size: CS trace buffer size for the queue.
|
||||
* @trace_cfg: CS trace configuration parameters.
|
||||
* @error: GPU command queue fatal information to pass to user space.
|
||||
* @fatal_event_work: Work item to handle the CS fatal event reported for this
|
||||
* queue.
|
||||
@@ -344,6 +348,10 @@ struct kbase_queue {
|
||||
u32 sync_value;
|
||||
u32 sb_status;
|
||||
u32 blocked_reason;
|
||||
u64 trace_buffer_base;
|
||||
u64 trace_offset_ptr;
|
||||
u32 trace_buffer_size;
|
||||
u32 trace_cfg;
|
||||
struct kbase_csf_notification error;
|
||||
struct work_struct fatal_event_work;
|
||||
u64 cs_fatal_info;
|
||||
@@ -667,7 +675,7 @@ struct kbase_csf_context {
|
||||
struct vm_area_struct *user_reg_vma;
|
||||
struct kbase_csf_scheduler_context sched;
|
||||
struct list_head error_list;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||||
struct kbase_csf_cpu_queue_context cpu_queue;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2021 ARM Limited. All rights reserved.
|
||||
@@ -993,7 +993,12 @@ static int parse_capabilities(struct kbase_device *kbdev)
|
||||
|
||||
iface->group_stride = shared_info[GLB_GROUP_STRIDE/4];
|
||||
iface->prfcnt_size = shared_info[GLB_PRFCNT_SIZE/4];
|
||||
iface->instr_features = shared_info[GLB_INSTR_FEATURES / 4];
|
||||
|
||||
if (iface->version >= kbase_csf_interface_version(1, 1, 0)) {
|
||||
iface->instr_features = shared_info[GLB_INSTR_FEATURES / 4];
|
||||
} else {
|
||||
iface->instr_features = 0;
|
||||
}
|
||||
|
||||
if ((GROUP_CONTROL_0 +
|
||||
(unsigned long)iface->group_num * iface->group_stride) >
|
||||
@@ -1671,29 +1676,8 @@ u32 kbase_csf_firmware_set_mcu_core_pwroff_time(struct kbase_device *kbdev, u32
|
||||
}
|
||||
|
||||
|
||||
int kbase_csf_firmware_init(struct kbase_device *kbdev)
|
||||
int kbase_csf_firmware_early_init(struct kbase_device *kbdev)
|
||||
{
|
||||
const struct firmware *firmware;
|
||||
const u32 magic = FIRMWARE_HEADER_MAGIC;
|
||||
u8 version_major, version_minor;
|
||||
u32 version_hash;
|
||||
u32 entry_end_offset;
|
||||
u32 entry_offset;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON((kbdev->as_free & MCU_AS_BITMASK) == 0))
|
||||
return -EINVAL;
|
||||
kbdev->as_free &= ~MCU_AS_BITMASK;
|
||||
|
||||
ret = kbase_mmu_init(kbdev, &kbdev->csf.mcu_mmu, NULL,
|
||||
BASE_MEM_GROUP_DEFAULT);
|
||||
|
||||
if (ret != 0) {
|
||||
/* Release the address space */
|
||||
kbdev->as_free |= MCU_AS_BITMASK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
init_waitqueue_head(&kbdev->csf.event_wait);
|
||||
kbdev->csf.interrupt_received = false;
|
||||
kbdev->csf.fw_timeout_ms = CSF_FIRMWARE_TIMEOUT_MS;
|
||||
@@ -1708,17 +1692,46 @@ int kbase_csf_firmware_init(struct kbase_device *kbdev)
|
||||
|
||||
mutex_init(&kbdev->csf.reg_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kbase_csf_firmware_init(struct kbase_device *kbdev)
|
||||
{
|
||||
const struct firmware *firmware;
|
||||
const u32 magic = FIRMWARE_HEADER_MAGIC;
|
||||
u8 version_major, version_minor;
|
||||
u32 version_hash;
|
||||
u32 entry_end_offset;
|
||||
u32 entry_offset;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&kbdev->fw_load_lock);
|
||||
|
||||
if (WARN_ON((kbdev->as_free & MCU_AS_BITMASK) == 0))
|
||||
return -EINVAL;
|
||||
kbdev->as_free &= ~MCU_AS_BITMASK;
|
||||
|
||||
ret = kbase_mmu_init(kbdev, &kbdev->csf.mcu_mmu, NULL,
|
||||
BASE_MEM_GROUP_DEFAULT);
|
||||
|
||||
if (ret != 0) {
|
||||
/* Release the address space */
|
||||
kbdev->as_free |= MCU_AS_BITMASK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
kbdev->csf.gpu_idle_hysteresis_ms = FIRMWARE_IDLE_HYSTERESIS_TIME_MS;
|
||||
kbdev->csf.gpu_idle_dur_count = convert_dur_to_idle_count(kbdev,
|
||||
FIRMWARE_IDLE_HYSTERESIS_TIME_MS);
|
||||
kbdev->csf.gpu_idle_dur_count = convert_dur_to_idle_count(
|
||||
kbdev, FIRMWARE_IDLE_HYSTERESIS_TIME_MS);
|
||||
|
||||
kbdev->csf.mcu_core_pwroff_dur_us = DEFAULT_GLB_PWROFF_TIMEOUT_US;
|
||||
kbdev->csf.mcu_core_pwroff_dur_count =
|
||||
convert_dur_to_core_pwroff_count(kbdev, DEFAULT_GLB_PWROFF_TIMEOUT_US);
|
||||
kbdev->csf.mcu_core_pwroff_dur_count = convert_dur_to_core_pwroff_count(
|
||||
kbdev, DEFAULT_GLB_PWROFF_TIMEOUT_US);
|
||||
|
||||
ret = kbase_mcu_shared_interface_region_tracker_init(kbdev);
|
||||
if (ret != 0) {
|
||||
dev_err(kbdev->dev, "Failed to setup the rb tree for managing shared interface segment\n");
|
||||
dev_err(kbdev->dev,
|
||||
"Failed to setup the rb tree for managing shared interface segment\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -2081,7 +2094,7 @@ int kbase_csf_trigger_firmware_config_update(struct kbase_device *kbdev)
|
||||
int err = 0;
|
||||
|
||||
/* Ensure GPU is powered-up until we complete config update.*/
|
||||
kbase_pm_context_active(kbdev);
|
||||
kbase_csf_scheduler_pm_active(kbdev);
|
||||
|
||||
/* The 'reg_lock' is also taken and is held till the update is
|
||||
* complete, to ensure the config update gets serialized.
|
||||
@@ -2098,7 +2111,7 @@ int kbase_csf_trigger_firmware_config_update(struct kbase_device *kbdev)
|
||||
GLB_REQ_FIRMWARE_CONFIG_UPDATE_MASK);
|
||||
mutex_unlock(&kbdev->csf.reg_lock);
|
||||
|
||||
kbase_pm_context_idle(kbdev);
|
||||
kbase_csf_scheduler_pm_idle(kbdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
*
|
||||
* (C) COPYRIGHT 2018-2021 ARM Limited. All rights reserved.
|
||||
@@ -79,7 +79,7 @@
|
||||
#define MAX_SUPPORTED_STREAMS_PER_GROUP 32
|
||||
|
||||
/* Waiting timeout for status change acknowledgment, in milliseconds */
|
||||
#define CSF_FIRMWARE_TIMEOUT_MS (800) /* Relaxed to 800ms from 100ms */
|
||||
#define CSF_FIRMWARE_TIMEOUT_MS (3000) /* Relaxed to 3000ms from 800ms due to Android */
|
||||
|
||||
struct kbase_device;
|
||||
|
||||
@@ -266,7 +266,7 @@ u32 kbase_csf_firmware_csg_output(
|
||||
* @group_stride: Stride in bytes in JASID0 virtual address between
|
||||
* CSG capability structures.
|
||||
* @prfcnt_size: Performance counters size.
|
||||
* @instr_features: Instrumentation features.
|
||||
* @instr_features: Instrumentation features. (csf >= 1.1.0)
|
||||
* @groups: Address of an array of CSG capability structures.
|
||||
*/
|
||||
struct kbase_csf_global_iface {
|
||||
@@ -376,23 +376,31 @@ void kbase_csf_read_firmware_memory(struct kbase_device *kbdev,
|
||||
void kbase_csf_update_firmware_memory(struct kbase_device *kbdev,
|
||||
u32 gpu_addr, u32 value);
|
||||
|
||||
/**
|
||||
* kbase_csf_firmware_early_init() - Early initializatin for the firmware.
|
||||
* @kbdev: Kbase device
|
||||
*
|
||||
* Initialize resources related to the firmware. Must be called at kbase probe.
|
||||
*
|
||||
* Return: 0 if successful, negative error code on failure
|
||||
*/
|
||||
int kbase_csf_firmware_early_init(struct kbase_device *kbdev);
|
||||
|
||||
/**
|
||||
* kbase_csf_firmware_init() - Load the firmware for the CSF MCU
|
||||
* @kbdev: Kbase device
|
||||
*
|
||||
* Request the firmware from user space and load it into memory.
|
||||
*
|
||||
* Return: 0 if successful, negative error code on failure
|
||||
*
|
||||
* @kbdev: Kbase device
|
||||
*/
|
||||
int kbase_csf_firmware_init(struct kbase_device *kbdev);
|
||||
|
||||
/**
|
||||
* kbase_csf_firmware_term() - Unload the firmware
|
||||
* @kbdev: Kbase device
|
||||
*
|
||||
* Frees the memory allocated by kbase_csf_firmware_init()
|
||||
*
|
||||
* @kbdev: Kbase device
|
||||
*/
|
||||
void kbase_csf_firmware_term(struct kbase_device *kbdev);
|
||||
|
||||
@@ -443,12 +451,8 @@ void kbase_csf_enter_protected_mode(struct kbase_device *kbdev);
|
||||
|
||||
static inline bool kbase_csf_firmware_mcu_halted(struct kbase_device *kbdev)
|
||||
{
|
||||
#ifndef CONFIG_MALI_BIFROST_NO_MALI
|
||||
return (kbase_reg_read(kbdev, GPU_CONTROL_REG(MCU_STATUS)) ==
|
||||
MCU_STATUS_HALTED);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -584,6 +588,7 @@ bool kbase_csf_firmware_core_attr_updated(struct kbase_device *kbdev);
|
||||
* hardware performance counter data.
|
||||
* @instr_features: Instrumentation features. Bits 7:4 hold the max size
|
||||
* of events. Bits 3:0 hold the offset update rate.
|
||||
* (csf >= 1,1,0)
|
||||
*/
|
||||
u32 kbase_csf_firmware_get_glb_iface(
|
||||
struct kbase_device *kbdev, struct basep_cs_group_control *group_data,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user