Add 'qcom/opensource/eva-kernel/' from commit 'c1ff9cd986e7dd66ecf6b385b92ac3de85c76f4e'
git-subtree-dir: qcom/opensource/eva-kernel git-subtree-mainline:caab746e9f
git-subtree-split:c1ff9cd986
Change-Id: repo: https://git.codelinaro.org/clo/la/platform/vendor/opensource/eva-kernel tag: CV.LA.2.0.r1-04800-lanai.0
This commit is contained in:
commit
af64423e9f
5
qcom/opensource/eva-kernel/Android.bp
Normal file
5
qcom/opensource/eva-kernel/Android.bp
Normal file
@ -0,0 +1,5 @@
|
||||
cc_library_headers {
|
||||
name: "qti_eva_kernel_headers",
|
||||
export_include_dirs: ["include/uapi/eva/media"],
|
||||
vendor_available: true
|
||||
}
|
67
qcom/opensource/eva-kernel/Android.mk
Normal file
67
qcom/opensource/eva-kernel/Android.mk
Normal file
@ -0,0 +1,67 @@
|
||||
ENABLE_EVA_KERNEL := true
|
||||
ifeq ($(TARGET_USES_QMAA), true)
|
||||
ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true)
|
||||
ENABLE_EVA_KERNEL := false
|
||||
endif
|
||||
endif
|
||||
ifeq ($(call is-board-platform-in-list,volcano),true)
|
||||
ENABLE_EVA_KERNEL := false
|
||||
endif
|
||||
ifeq ($(ENABLE_EVA_KERNEL), true)
|
||||
ifneq ($(TARGET_BOARD_PLATFORM), qssi)
|
||||
ifeq ($(call is-board-platform-in-list, $(TARGET_BOARD_PLATFORM)),true)
|
||||
|
||||
DLKM_DIR := device/qcom/common/dlkm
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
# For DDK
|
||||
LOCAL_MODULE_DDK_BUILD := true
|
||||
LOCAL_MODULE_KO_DIRS := msm/msm-eva.ko
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
# For incremental compilation
|
||||
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/**/*) $(wildcard $(LOCAL_PATH)/*)
|
||||
LOCAL_MODULE := msm-eva.ko
|
||||
LOCAL_MODULE_KBUILD_NAME := msm/msm-eva.ko
|
||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
|
||||
LOCAL_ADDITIONAL_DEPENDENCY := synx-driver.ko
|
||||
|
||||
# export to kbuild
|
||||
# Setup mmrm dependency
|
||||
LOCAL_REQUIRED_MODULES := mmrm-module-symvers
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers
|
||||
KBUILD_REQUIRED_KOS += msm-mmrm.ko
|
||||
|
||||
# Setup SynX dependency
|
||||
CONFIG_SYNX := y
|
||||
#ifdef CONFIG_SYNX
|
||||
ifeq ($(CONFIG_SYNX), y)
|
||||
$(warning Compiling SynX)
|
||||
LOCAL_REQUIRED_MODULES += synx-driver-symvers
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,synx-driver-symvers)/synx-driver-symvers
|
||||
KBUILD_REQUIRED_KOS += synx-driver.ko
|
||||
endif
|
||||
|
||||
# Setup fastRPC dependency
|
||||
CONFIG_FASTRPC := y
|
||||
ifeq ($(CONFIG_FASTRPC), y)
|
||||
$(warning Compiling FastRPC)
|
||||
LOCAL_REQUIRED_MODULES += dsp-module-symvers
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,dsp-module-symvers)/Module.symvers
|
||||
KBUILD_REQUIRED_KOS += frpc-adsprpc.ko
|
||||
endif
|
||||
|
||||
# print out variables
|
||||
$(info KBUILD_OPTIONS = $(KBUILD_OPTIONS))
|
||||
$(info intermediates mmrm symvers path = $(call intermediates-dir-for,DLKM,mmrm-module-symvers))
|
||||
$(info LOCAL_ADDITIONAL_DEPENDENCY = $(LOCAL_ADDITIONAL_DEPENDENCY))
|
||||
$(info LOCAL_ADDITIONAL_DEPENDENCIES = $(LOCAL_ADDITIONAL_DEPENDENCIES))
|
||||
$(info LOCAL_REQUIRED_MODULES = $(LOCAL_REQUIRED_MODULES))
|
||||
$(info DLKM_DIR = $(DLKM_DIR))
|
||||
|
||||
include $(DLKM_DIR)/Build_external_kernelmodule.mk
|
||||
|
||||
endif # End of check for board platform
|
||||
endif # End of check for target product
|
||||
endif # End of enable eva kernel check
|
38
qcom/opensource/eva-kernel/BUILD.bazel
Normal file
38
qcom/opensource/eva-kernel/BUILD.bazel
Normal file
@ -0,0 +1,38 @@
|
||||
load("//build/kernel/kleaf:kernel.bzl", "ddk_headers")
|
||||
|
||||
package(
|
||||
default_visibility = [
|
||||
"//visibility:public"],
|
||||
)
|
||||
|
||||
ddk_headers(
|
||||
name = "eva_drivers_configs",
|
||||
hdrs = [
|
||||
"config/waipioevaconf.h"
|
||||
],
|
||||
includes = ["config"]
|
||||
)
|
||||
ddk_headers(
|
||||
name = "uapi_headers",
|
||||
hdrs = glob([
|
||||
"include/uapi/eva/media/*.h",
|
||||
]),
|
||||
includes = ["include/uapi/eva"]
|
||||
)
|
||||
ddk_headers(
|
||||
name = "msm_headers",
|
||||
hdrs = glob([
|
||||
"msm/eva/*.h",
|
||||
"msm/eva/vm/*.h",
|
||||
]),
|
||||
includes = ["msm","msm/eva"]
|
||||
)
|
||||
|
||||
ddk_headers(
|
||||
name = "eva_drivers_headers",
|
||||
hdrs = [":eva_drivers_configs", ":uapi_headers", ":msm_headers"]
|
||||
)
|
||||
|
||||
|
||||
load(":pineapple.bzl", "define_pineapple")
|
||||
define_pineapple()
|
17
qcom/opensource/eva-kernel/Kbuild
Normal file
17
qcom/opensource/eva-kernel/Kbuild
Normal file
@ -0,0 +1,17 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
CONFIG_BUILD_VENDORSI := true
|
||||
|
||||
# auto-detect subdirs
|
||||
ifneq ($(CONFIG_BUILD_VENDORSI), true)
|
||||
ifneq ($(CONFIG_ARCH_QTI_VM), y)
|
||||
include $(srctree)/techpack/eva/config/waipioeva.conf
|
||||
LINUXINCLUDE += -include $(srctree)/techpack/eva/config/waipioevaconf.h
|
||||
endif
|
||||
|
||||
LINUXINCLUDE += -I$(srctree)/techpack/eva/include \
|
||||
-I$(srctree)/techpack/eva/include/uapi \
|
||||
-I$(srctree)/techpack/eva/include/uapi/eva
|
||||
endif
|
||||
|
||||
obj-y +=msm/
|
14
qcom/opensource/eva-kernel/Makefile
Normal file
14
qcom/opensource/eva-kernel/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
KBUILD_OPTIONS+= EVA_ROOT=$(KERNEL_SRC)/$(M)
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS)
|
||||
|
||||
modules_install:
|
||||
$(MAKE) M=$(M) -C $(KERNEL_SRC) modules_install
|
||||
|
||||
%:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(M) $@ $(KBUILD_OPTIONS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers
|
||||
rm -rf .tmp_versions
|
5
qcom/opensource/eva-kernel/config/waipioeva.conf
Normal file
5
qcom/opensource/eva-kernel/config/waipioeva.conf
Normal file
@ -0,0 +1,5 @@
|
||||
ifeq ($(CONFIG_QGKI),y)
|
||||
export CONFIG_MSM_EVA=y
|
||||
else
|
||||
export CONFIG_MSM_EVA=m
|
||||
endif
|
6
qcom/opensource/eva-kernel/config/waipioevaconf.h
Normal file
6
qcom/opensource/eva-kernel/config/waipioevaconf.h
Normal file
@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define CONFIG_MSM_EVA 1
|
18
qcom/opensource/eva-kernel/eva_kernel_board.mk
Normal file
18
qcom/opensource/eva-kernel/eva_kernel_board.mk
Normal file
@ -0,0 +1,18 @@
|
||||
# Build eva kernel driver
|
||||
|
||||
ENABLE_EVA_KERNEL := true
|
||||
ifeq ($(TARGET_USES_QMAA), true)
|
||||
ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true)
|
||||
ENABLE_EVA_KERNEL := false
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_BOARD_PLATFORM),volcano)
|
||||
ENABLE_EVA_KERNEL := false
|
||||
endif
|
||||
ifeq ($(ENABLE_EVA_KERNEL), true)
|
||||
ifneq ($(TARGET_BOARD_AUTO),true)
|
||||
ifeq ($(call is-board-platform-in-list,$(TARGET_BOARD_PLATFORM)),true)
|
||||
BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/msm-eva.ko
|
||||
endif
|
||||
endif
|
||||
endif
|
12
qcom/opensource/eva-kernel/eva_kernel_product.mk
Normal file
12
qcom/opensource/eva-kernel/eva_kernel_product.mk
Normal file
@ -0,0 +1,12 @@
|
||||
ENABLE_EVA_KERNEL := true
|
||||
ifeq ($(TARGET_USES_QMAA), true)
|
||||
ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true)
|
||||
ENABLE_EVA_KERNEL := false
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_BOARD_PLATFORM),volcano)
|
||||
ENABLE_EVA_KERNEL := false
|
||||
endif
|
||||
ifeq ($(ENABLE_EVA_KERNEL), true)
|
||||
PRODUCT_PACKAGES += msm-eva.ko
|
||||
endif
|
130
qcom/opensource/eva-kernel/eva_module_build.bzl
Normal file
130
qcom/opensource/eva-kernel/eva_module_build.bzl
Normal file
@ -0,0 +1,130 @@
|
||||
load(
|
||||
"//build/kernel/kleaf:kernel.bzl",
|
||||
"ddk_module",
|
||||
"ddk_submodule",
|
||||
"kernel_module",
|
||||
"kernel_modules_install",
|
||||
)
|
||||
load("//build/bazel_common_rules/dist:dist.bzl", "copy_to_dist_dir")
|
||||
|
||||
def _register_module_to_map(module_map, name, path, config_option, srcs, config_srcs, deps, config_deps):
|
||||
processed_config_srcs = {}
|
||||
processed_config_deps = {}
|
||||
|
||||
for config_src_name in config_srcs:
|
||||
config_src = config_srcs[config_src_name]
|
||||
|
||||
if type(config_src) == "list":
|
||||
processed_config_srcs[config_src_name] = {True: config_src}
|
||||
else:
|
||||
processed_config_srcs[config_src_name] = config_src
|
||||
|
||||
for config_deps_name in config_deps:
|
||||
config_dep = config_deps[config_deps_name]
|
||||
|
||||
if type(config_dep) == "list":
|
||||
processed_config_deps[config_deps_name] = {True: config_dep}
|
||||
else:
|
||||
processed_config_deps[config_deps_name] = config_dep
|
||||
|
||||
module = struct(
|
||||
name = name,
|
||||
path = path,
|
||||
srcs = srcs,
|
||||
config_srcs = processed_config_srcs,
|
||||
config_option = config_option,
|
||||
deps = deps,
|
||||
config_deps = processed_config_deps,
|
||||
)
|
||||
|
||||
module_map[name] = module
|
||||
|
||||
def _get_config_choices(map, options):
|
||||
choices = []
|
||||
|
||||
for option in map:
|
||||
choices.extend(map[option].get(option in options, []))
|
||||
|
||||
return choices
|
||||
|
||||
def _get_kernel_build_options(modules, config_options):
|
||||
all_options = {option: True for option in config_options}
|
||||
all_options = all_options | {module.config_option: True for module in modules if module.config_option}
|
||||
|
||||
return all_options
|
||||
|
||||
def _get_kernel_build_module_srcs(module, options, formatter):
|
||||
srcs = module.srcs + _get_config_choices(module.config_srcs, options)
|
||||
module_path = "{}/".format(module.path) if module.path else ""
|
||||
globbed_srcs = native.glob(["{}{}".format(module_path, formatter(src)) for src in srcs])
|
||||
|
||||
return globbed_srcs
|
||||
|
||||
def _get_kernel_build_module_deps(module, options, formatter):
|
||||
deps = module.deps + _get_config_choices(module.config_deps, options)
|
||||
deps = [formatter(dep) for dep in deps]
|
||||
|
||||
return deps
|
||||
|
||||
def create_module_registry(hdrs = []):
|
||||
module_map = {}
|
||||
|
||||
def register(name, path = None, config_option = None, srcs = [], config_srcs = {}, deps = [], config_deps = {}):
|
||||
_register_module_to_map(module_map, name, path, config_option, srcs, config_srcs, deps, config_deps)
|
||||
|
||||
return struct(
|
||||
register = register,
|
||||
get = module_map.get,
|
||||
hdrs = hdrs,
|
||||
module_map = module_map,
|
||||
)
|
||||
|
||||
def define_target_variant_modules(target, variant, registry, modules, config_options = []):
|
||||
kernel_build = "{}_{}".format(target, variant)
|
||||
kernel_build_label = "//msm-kernel:{}".format(kernel_build)
|
||||
modules = [registry.get(module_name) for module_name in modules]
|
||||
options = _get_kernel_build_options(modules, config_options)
|
||||
build_print = lambda message: print("{}: {}".format(kernel_build, message))
|
||||
formatter = lambda s: s.replace("%b", kernel_build).replace("%t", target)
|
||||
|
||||
headers = ["//msm-kernel:all_headers"] + registry.hdrs
|
||||
all_module_rules = []
|
||||
|
||||
for module in modules:
|
||||
rule_name = "{}_{}".format(kernel_build, module.name)
|
||||
module_srcs = _get_kernel_build_module_srcs(module, options, formatter)
|
||||
|
||||
if not module_srcs:
|
||||
continue
|
||||
|
||||
ddk_submodule(
|
||||
name = rule_name,
|
||||
srcs = module_srcs,
|
||||
out = "{}.ko".format(module.name),
|
||||
copts = ["-Wno-format"],
|
||||
deps = headers + _get_kernel_build_module_deps(module, options, formatter),
|
||||
local_defines = options.keys(),
|
||||
)
|
||||
|
||||
all_module_rules.append(rule_name)
|
||||
|
||||
ddk_module(
|
||||
name = "{}_modules".format(kernel_build),
|
||||
kernel_build = kernel_build_label,
|
||||
deps = all_module_rules,
|
||||
)
|
||||
|
||||
copy_to_dist_dir(
|
||||
name = "{}_modules_dist".format(kernel_build),
|
||||
data = [":{}_modules".format(kernel_build)],
|
||||
dist_dir = "out/target/product/{}/dlkm/lib/modules/".format(kernel_build),
|
||||
flat = True,
|
||||
wipe_dist_dir = False,
|
||||
allow_duplicate_filenames = False,
|
||||
mode_overrides = {"**/*": "644"},
|
||||
)
|
||||
|
||||
|
||||
def define_consolidate_gki_modules(target, registry, modules, config_options = []):
|
||||
define_target_variant_modules(target, "consolidate", registry, modules, config_options)
|
||||
define_target_variant_modules(target, "gki", registry, modules, config_options)
|
45
qcom/opensource/eva-kernel/eva_modules.bzl
Normal file
45
qcom/opensource/eva-kernel/eva_modules.bzl
Normal file
@ -0,0 +1,45 @@
|
||||
load(":eva_module_build.bzl", "create_module_registry")
|
||||
|
||||
EVA_KERNEL_ROOT = "eva-kernel"
|
||||
|
||||
eva_modules = create_module_registry([":eva_drivers_headers"])
|
||||
register_eva_module = eva_modules.register
|
||||
|
||||
register_eva_module(
|
||||
name = "msm-eva",
|
||||
path = "msm",
|
||||
srcs = [
|
||||
"eva/cvp.c",
|
||||
"eva/cvp_core_hfi.c",
|
||||
"eva/cvp_dump.c",
|
||||
"eva/cvp_fw_load.c",
|
||||
"eva/cvp_hfi.c",
|
||||
"eva/cvp_power.c",
|
||||
"eva/cvp_smem.c",
|
||||
"eva/hfi_packetization.c",
|
||||
"eva/hfi_response_handler.c",
|
||||
"eva/msm_cvp.c",
|
||||
"eva/msm_cvp_buf.c",
|
||||
"eva/msm_cvp_clocks.c",
|
||||
"eva/msm_cvp_common.c",
|
||||
"eva/msm_cvp_core.c",
|
||||
"eva/msm_cvp_debug.c",
|
||||
"eva/msm_cvp_dsp.c",
|
||||
"eva/msm_cvp_ioctl.c",
|
||||
"eva/msm_cvp_platform.c",
|
||||
"eva/msm_cvp_res_parse.c",
|
||||
"eva/msm_cvp_synx.c",
|
||||
"eva/vm/cvp_vm_main.c",
|
||||
"eva/vm/cvp_vm_msgq.c",
|
||||
"eva/vm/cvp_vm_resource.c",
|
||||
],
|
||||
config_deps = {
|
||||
"TARGET_SYNX_ENABLE": [
|
||||
"//vendor/qcom/opensource/synx-kernel:synx_headers",
|
||||
"//vendor/qcom/opensource/synx-kernel:%b_modules"
|
||||
],
|
||||
"TARGET_DSP_ENABLE": [
|
||||
"//vendor/qcom/opensource/dsp-kernel:%b_frpc-adsprpc"
|
||||
],
|
||||
},
|
||||
)
|
@ -0,0 +1,278 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#ifndef __MSM_EVA_PRIVATE_H__
|
||||
#define __MSM_EVA_PRIVATE_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Commands type */
|
||||
#define EVA_KMD_CMD_BASE 0x10000000
|
||||
#define EVA_KMD_CMD_START (EVA_KMD_CMD_BASE + 0x1000)
|
||||
|
||||
/*
|
||||
* userspace clients pass one of the below arguments type
|
||||
* in struct eva_kmd_arg (@type field).
|
||||
*/
|
||||
|
||||
/*
|
||||
* EVA_KMD_GET_SESSION_INFO - this argument type is used to
|
||||
* get the session information from driver. it passes
|
||||
* struct eva_kmd_session_info {}
|
||||
*/
|
||||
#define EVA_KMD_GET_SESSION_INFO (EVA_KMD_CMD_START + 1)
|
||||
|
||||
/*
|
||||
* EVA_KMD_REGISTER_BUFFER - this argument type is used to
|
||||
* register the buffer to driver. it passes
|
||||
* struct eva_kmd_buffer {}
|
||||
*/
|
||||
#define EVA_KMD_REGISTER_BUFFER (EVA_KMD_CMD_START + 3)
|
||||
|
||||
/*
|
||||
* EVA_KMD_REGISTER_BUFFER - this argument type is used to
|
||||
* unregister the buffer to driver. it passes
|
||||
* struct eva_kmd_buffer {}
|
||||
*/
|
||||
#define EVA_KMD_UNREGISTER_BUFFER (EVA_KMD_CMD_START + 4)
|
||||
|
||||
#define EVA_KMD_UPDATE_POWER (EVA_KMD_CMD_START + 17)
|
||||
|
||||
#define EVA_KMD_SEND_CMD_PKT (EVA_KMD_CMD_START + 64)
|
||||
|
||||
#define EVA_KMD_RECEIVE_MSG_PKT (EVA_KMD_CMD_START + 65)
|
||||
|
||||
#define EVA_KMD_SET_SYS_PROPERTY (EVA_KMD_CMD_START + 66)
|
||||
|
||||
#define EVA_KMD_GET_SYS_PROPERTY (EVA_KMD_CMD_START + 67)
|
||||
|
||||
#define EVA_KMD_SESSION_CONTROL (EVA_KMD_CMD_START + 68)
|
||||
|
||||
#define EVA_KMD_SEND_FENCE_CMD_PKT (EVA_KMD_CMD_START + 69)
|
||||
|
||||
#define EVA_KMD_FLUSH_ALL (EVA_KMD_CMD_START + 70)
|
||||
|
||||
#define EVA_KMD_FLUSH_FRAME (EVA_KMD_CMD_START + 71)
|
||||
|
||||
/* flags */
|
||||
#define EVA_KMD_FLAG_UNSECURE 0x00000000
|
||||
#define EVA_KMD_FLAG_SECURE 0x00000001
|
||||
|
||||
/* buffer type */
|
||||
#define EVA_KMD_BUFTYPE_INPUT 0x00000001
|
||||
#define EVA_KMD_BUFTYPE_OUTPUT 0x00000002
|
||||
#define EVA_KMD_BUFTYPE_INTERNAL_1 0x00000003
|
||||
#define EVA_KMD_BUFTYPE_INTERNAL_2 0x00000004
|
||||
|
||||
|
||||
/**
|
||||
* struct eva_kmd_session_info - session information
|
||||
* @session_id: current session id
|
||||
*/
|
||||
struct eva_kmd_session_info {
|
||||
__u32 session_id;
|
||||
__u32 reserved[10];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eva_kmd_buffer - buffer information to be registered
|
||||
* @index: index of buffer
|
||||
* @type: buffer type
|
||||
* @fd: file descriptor of buffer
|
||||
* @size: allocated size of buffer
|
||||
* @offset: offset in fd from where usable data starts
|
||||
* @pixelformat: fourcc format
|
||||
* @flags: buffer flags
|
||||
*/
|
||||
struct eva_kmd_buffer {
|
||||
__u32 index;
|
||||
__u32 type;
|
||||
__u32 fd;
|
||||
__u32 size;
|
||||
__u32 offset;
|
||||
__u32 pixelformat;
|
||||
__u32 flags;
|
||||
__u32 reserved[5];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eva_kmd_send_cmd - sending generic HFI command
|
||||
* @cmd_address_fd: file descriptor of cmd_address
|
||||
* @cmd_size: allocated size of buffer
|
||||
*/
|
||||
struct eva_kmd_send_cmd {
|
||||
__u32 cmd_address_fd;
|
||||
__u32 cmd_size;
|
||||
__u32 reserved[10];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eva_kmd_client_data - store generic client
|
||||
* data
|
||||
* @transactionid: transaction id
|
||||
* @client_data1: client data to be used during callback
|
||||
* @client_data2: client data to be used during callback
|
||||
*/
|
||||
struct eva_kmd_client_data {
|
||||
__u32 transactionid;
|
||||
__u32 client_data1;
|
||||
__u32 client_data2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Structures and macros for KMD arg data
|
||||
*/
|
||||
|
||||
#define MAX_HFI_PKT_SIZE 490
|
||||
|
||||
struct eva_kmd_hfi_packet {
|
||||
__u32 pkt_data[MAX_HFI_PKT_SIZE];
|
||||
void *oob_buf;
|
||||
};
|
||||
|
||||
#define EVA_KMD_PROP_HFI_VERSION 1
|
||||
#define EVA_KMD_PROP_SESSION_TYPE 2
|
||||
#define EVA_KMD_PROP_SESSION_KERNELMASK 3
|
||||
#define EVA_KMD_PROP_SESSION_PRIORITY 4
|
||||
#define EVA_KMD_PROP_SESSION_SECURITY 5
|
||||
#define EVA_KMD_PROP_SESSION_DSPMASK 6
|
||||
#define EVA_KMD_PROP_SESSION_DUMPOFFSET 7
|
||||
#define EVA_KMD_PROP_SESSION_DUMPSIZE 8
|
||||
#define EVA_KMD_PROP_SESSION_ERROR 9
|
||||
|
||||
#define EVA_KMD_PROP_PWR_FDU 0x10
|
||||
#define EVA_KMD_PROP_PWR_ICA 0x11
|
||||
#define EVA_KMD_PROP_PWR_OD 0x12
|
||||
#define EVA_KMD_PROP_PWR_MPU 0x13
|
||||
#define EVA_KMD_PROP_PWR_FW 0x14
|
||||
#define EVA_KMD_PROP_PWR_DDR 0x15
|
||||
#define EVA_KMD_PROP_PWR_SYSCACHE 0x16
|
||||
#define EVA_KMD_PROP_PWR_FDU_OP 0x17
|
||||
#define EVA_KMD_PROP_PWR_ICA_OP 0x18
|
||||
#define EVA_KMD_PROP_PWR_OD_OP 0x19
|
||||
#define EVA_KMD_PROP_PWR_MPU_OP 0x1A
|
||||
#define EVA_KMD_PROP_PWR_FW_OP 0x1B
|
||||
#define EVA_KMD_PROP_PWR_DDR_OP 0x1C
|
||||
#define EVA_KMD_PROP_PWR_SYSCACHE_OP 0x1D
|
||||
#define EVA_KMD_PROP_PWR_FPS_FDU 0x1E
|
||||
#define EVA_KMD_PROP_PWR_FPS_MPU 0x1F
|
||||
#define EVA_KMD_PROP_PWR_FPS_OD 0x20
|
||||
#define EVA_KMD_PROP_PWR_FPS_ICA 0x21
|
||||
|
||||
#define EVA_KMD_PROP_PWR_VADL 0x22
|
||||
#define EVA_KMD_PROP_PWR_VADL_OP 0x23
|
||||
#define EVA_KMD_PROP_PWR_FPS_VADL 0x24
|
||||
|
||||
#define EVA_KMD_PROP_PWR_TOF 0x25
|
||||
#define EVA_KMD_PROP_PWR_TOF_OP 0x26
|
||||
#define EVA_KMD_PROP_PWR_FPS_TOF 0x27
|
||||
|
||||
#define EVA_KMD_PROP_PWR_RGE 0x28
|
||||
#define EVA_KMD_PROP_PWR_RGE_OP 0x29
|
||||
#define EVA_KMD_PROP_PWR_FPS_RGE 0x2A
|
||||
|
||||
#define EVA_KMD_PROP_PWR_XRA 0x2B
|
||||
#define EVA_KMD_PROP_PWR_XRA_OP 0x2C
|
||||
#define EVA_KMD_PROP_PWR_FPS_XRA 0x2D
|
||||
|
||||
#define EVA_KMD_PROP_PWR_LSR 0x2E
|
||||
#define EVA_KMD_PROP_PWR_LSR_OP 0x2F
|
||||
#define EVA_KMD_PROP_PWR_FPS_LSR 0x30
|
||||
|
||||
|
||||
#define MAX_KMD_PROP_NUM_PER_PACKET 64
|
||||
#define MAX_KMD_PROP_TYPE (EVA_KMD_PROP_PWR_FPS_ICA + 1)
|
||||
|
||||
struct eva_kmd_sys_property {
|
||||
__u32 prop_type;
|
||||
__u32 data;
|
||||
};
|
||||
|
||||
struct eva_kmd_sys_properties {
|
||||
__u32 prop_num;
|
||||
struct eva_kmd_sys_property prop_data[MAX_KMD_PROP_NUM_PER_PACKET];
|
||||
};
|
||||
|
||||
#define SESSION_CREATE 1
|
||||
#define SESSION_DELETE 2
|
||||
#define SESSION_START 3
|
||||
#define SESSION_STOP 4
|
||||
#define SESSION_INFO 5
|
||||
|
||||
struct eva_kmd_session_control {
|
||||
__u32 ctrl_type;
|
||||
__u32 ctrl_data[8];
|
||||
};
|
||||
|
||||
#define MAX_HFI_FENCE_SIZE 64
|
||||
#define MAX_HFI_FENCE_OFFSET MAX_HFI_PKT_SIZE
|
||||
struct eva_kmd_hfi_fence_packet {
|
||||
__u32 pkt_data[MAX_HFI_FENCE_OFFSET];
|
||||
__u32 fence_data[MAX_HFI_FENCE_SIZE];
|
||||
__u64 frame_id;
|
||||
};
|
||||
|
||||
struct eva_kmd_fence {
|
||||
__u32 h_synx;
|
||||
};
|
||||
|
||||
struct eva_kmd_fence_ctrl {
|
||||
__u32 magic;
|
||||
__u32 reserved;
|
||||
__u64 frame_id;
|
||||
__u32 num_fences;
|
||||
__u32 output_index;
|
||||
struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE];
|
||||
};
|
||||
|
||||
#define MAX_FENCE_DATA_SIZE (MAX_HFI_FENCE_SIZE + 6)
|
||||
|
||||
struct eva_kmd_hfi_synx_packet {
|
||||
__u32 pkt_data[MAX_HFI_PKT_SIZE];
|
||||
union {
|
||||
__u32 fence_data[MAX_FENCE_DATA_SIZE];
|
||||
struct eva_kmd_fence_ctrl fc;
|
||||
};
|
||||
struct eva_kmd_oob_buf* oob_buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct eva_kmd_arg
|
||||
*
|
||||
* @type: command type
|
||||
* @buf_offset: offset to buffer list in the command
|
||||
* @buf_num: number of buffers in the command
|
||||
* @session: session information
|
||||
* @req_power: power information
|
||||
* @regbuf: buffer to be registered
|
||||
* @unregbuf: buffer to be unregistered
|
||||
* @send_cmd: sending generic HFI command
|
||||
|
||||
* @hfi_pkt: HFI packet created by user library
|
||||
* @sys_properties System properties read or set by user library
|
||||
* @hfi_fence_pkt: HFI fence packet created by user library
|
||||
*/
|
||||
struct eva_kmd_arg {
|
||||
__u32 type;
|
||||
__u32 buf_offset;
|
||||
__u32 buf_num;
|
||||
union eva_data_t {
|
||||
struct eva_kmd_session_info session;
|
||||
struct eva_kmd_buffer regbuf;
|
||||
struct eva_kmd_buffer unregbuf;
|
||||
struct eva_kmd_send_cmd send_cmd;
|
||||
struct eva_kmd_hfi_packet hfi_pkt;
|
||||
struct eva_kmd_sys_properties sys_properties;
|
||||
struct eva_kmd_hfi_fence_packet hfi_fence_pkt;
|
||||
struct eva_kmd_hfi_synx_packet hfi_synx_pkt;
|
||||
struct eva_kmd_session_control session_ctrl;
|
||||
__u64 frame_id;
|
||||
} data;
|
||||
};
|
||||
|
||||
struct eva_kmd_request_power {
|
||||
__u32 deprecated;
|
||||
};
|
||||
#endif
|
69
qcom/opensource/eva-kernel/msm/Kbuild
Normal file
69
qcom/opensource/eva-kernel/msm/Kbuild
Normal file
@ -0,0 +1,69 @@
|
||||
LINUXINCLUDE += -I$(EVA_ROOT)/include \
|
||||
-I$(EVA_ROOT)/include/uapi \
|
||||
-I$(EVA_ROOT)/include/uapi/eva
|
||||
|
||||
#srctree is /kernel_platform/common/
|
||||
|
||||
ccflags-y += -I$(EVA_ROOT)/msm/eva/ \
|
||||
-I$(srctree)/drivers/media/platform/msm/synx/
|
||||
|
||||
# add flag to compile mmrm actual implementatio instead of stub version.
|
||||
# to follow up with mmrm team if techpack users need to define this for long term?
|
||||
KBUILD_CPPFLAGS += -DCONFIG_MSM_MMRM
|
||||
|
||||
# ported from Android.mk
|
||||
$(info within KBUILD file KBUILD_EXTRA_SYMBOLS = $(KBUILD_EXTRA_SYMBOLS))
|
||||
|
||||
ifeq ($(CONFIG_ARCH_WAIPIO), y)
|
||||
$(info within KBUILD file CONFIG_ARCH_WAIPIO = $(CONFIG_ARCH_WAIPIO))
|
||||
# include $(EVA_ROOT)/config/waipio.mk
|
||||
KBUILD_CPPFLAGS += -DCONFIG_EVA_WAIPIO=1
|
||||
ccflags-y += -DCONFIG_EVA_WAIPIO=1
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_KALAMA), y)
|
||||
$(info within KBUILD file CONFIG_ARCH_KALAMA = $(CONFIG_ARCH_KALAMA))
|
||||
# include $(EVA_ROOT)/config/waipio.mk
|
||||
KBUILD_CPPFLAGS += -DCONFIG_EVA_KALAMA=1
|
||||
ccflags-y += -DCONFIG_EVA_KALAMA=1
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_PINEAPPLE), y)
|
||||
$(info within KBUILD file CONFIG_ARCH_PINEAPPLE = $(CONFIG_ARCH_PINEAPPLE))
|
||||
KBUILD_CPPFLAGS += -DCONFIG_EVA_PINEAPPLE=1 -DCVP_CONFIG_SYNX_V2=1
|
||||
ccflags-y += -DCONFIG_EVA_PINEAPPLE=1 -DCVP_CONFIG_SYNX_V2=1
|
||||
ccflags-y += -I$(EVA_ROOT)/../synx-kernel/msm/synx/ \
|
||||
-I$(EVA_ROOT)/../dsp-kernel/include/ \
|
||||
-I$(EVA_ROOT)/../synx-kernel/include/uapi/synx/media/
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(CONFIG_EVA_LE), 1)
|
||||
ccflags-y += -DCONFIG_EVA_TVM=1
|
||||
endif
|
||||
|
||||
msm-eva-objs := eva/cvp.o \
|
||||
eva/msm_cvp_ioctl.o \
|
||||
eva/msm_cvp_platform.o \
|
||||
eva/msm_cvp_common.o \
|
||||
eva/msm_cvp_core.o \
|
||||
eva/msm_cvp.o \
|
||||
eva/cvp_smem.o \
|
||||
eva/msm_cvp_debug.o \
|
||||
eva/msm_cvp_res_parse.o \
|
||||
eva/cvp_dump.o \
|
||||
eva/cvp_hfi.o \
|
||||
eva/hfi_response_handler.o \
|
||||
eva/hfi_packetization.o \
|
||||
eva/cvp_core_hfi.o \
|
||||
eva/msm_cvp_clocks.o\
|
||||
eva/msm_cvp_dsp.o \
|
||||
eva/msm_cvp_buf.o \
|
||||
eva/msm_cvp_synx.o \
|
||||
eva/cvp_fw_load.o \
|
||||
eva/cvp_power.o \
|
||||
eva/vm/cvp_vm_main.o \
|
||||
eva/vm/cvp_vm_msgq.o \
|
||||
eva/vm/cvp_vm_resource.o
|
||||
obj-m += msm-eva.o
|
||||
|
27
qcom/opensource/eva-kernel/msm/Makefile
Normal file
27
qcom/opensource/eva-kernel/msm/Makefile
Normal file
@ -0,0 +1,27 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
ccflags-y += -I$(srctree)/techpack/eva/msm/eva/ \
|
||||
-I$(srctree)/drivers/media/platform/msm/synx/
|
||||
|
||||
msm-eva-objs := eva/cvp.o \
|
||||
eva/msm_cvp_ioctl.o \
|
||||
eva/msm_cvp_platform.o \
|
||||
eva/msm_cvp_common.o \
|
||||
eva/msm_cvp_core.o \
|
||||
eva/msm_cvp.o \
|
||||
eva/msm_smem.o \
|
||||
eva/msm_cvp_debug.o \
|
||||
eva/msm_cvp_res_parse.o \
|
||||
eva/cvp_dump.o \
|
||||
eva/cvp_hfi.o \
|
||||
eva/hfi_response_handler.o \
|
||||
eva/hfi_packetization.o \
|
||||
eva/cvp_core_hfi.o \
|
||||
eva/msm_cvp_clocks.o\
|
||||
eva/msm_cvp_dsp.o \
|
||||
eva/msm_cvp_buf.o \
|
||||
eva/msm_cvp_synx.o \
|
||||
eva/cvp_fw_load.o \
|
||||
eva/cvp_power.o
|
||||
|
||||
obj-$(CONFIG_MSM_EVA) := msm-eva.o
|
||||
|
630
qcom/opensource/eva-kernel/msm/eva/cvp.c
Normal file
630
qcom/opensource/eva-kernel/msm/eva/cvp.c
Normal file
@ -0,0 +1,630 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/io.h>
|
||||
#include "msm_cvp_core.h"
|
||||
#include "msm_cvp_common.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "msm_cvp_internal.h"
|
||||
#include "msm_cvp_res_parse.h"
|
||||
#include "msm_cvp_resources.h"
|
||||
#include "msm_cvp_buf.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "cvp_private.h"
|
||||
#include "msm_cvp_clocks.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
#include "msm_cvp.h"
|
||||
#include "vm/cvp_vm.h"
|
||||
|
||||
#define CLASS_NAME "cvp"
|
||||
#define DRIVER_NAME "cvp"
|
||||
|
||||
struct msm_cvp_drv *cvp_driver;
|
||||
|
||||
static int cvp_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct msm_cvp_inst *inst;
|
||||
|
||||
dprintk(CVP_SESS, "%s\n", __func__);
|
||||
|
||||
inst = msm_cvp_open(MSM_CVP_USER, current);
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "Failed to create cvp instance\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
filp->private_data = inst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_close(struct inode *inode, struct file *filp)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_inst *inst = filp->private_data;
|
||||
|
||||
rc = msm_cvp_close(inst);
|
||||
filp->private_data = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static unsigned int cvp_poll(struct file *filp, struct poll_table_struct *p)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_inst *inst = filp->private_data;
|
||||
unsigned long flags = 0;
|
||||
|
||||
poll_wait(filp, &inst->event_handler.wq, p);
|
||||
|
||||
spin_lock_irqsave(&inst->event_handler.lock, flags);
|
||||
if (inst->event_handler.event == CVP_SSR_EVENT)
|
||||
rc |= POLLPRI;
|
||||
if (inst->event_handler.event == CVP_DUMP_EVENT)
|
||||
rc |= POLLIN;
|
||||
inst->event_handler.event = CVP_NO_EVENT;
|
||||
spin_unlock_irqrestore(&inst->event_handler.lock, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct file_operations cvp_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = cvp_open,
|
||||
.release = cvp_close,
|
||||
.unlocked_ioctl = cvp_unblocked_ioctl,
|
||||
.compat_ioctl = cvp_compat_ioctl,
|
||||
.poll = cvp_poll,
|
||||
};
|
||||
|
||||
static int read_platform_resources(struct msm_cvp_core *core,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!core || !pdev) {
|
||||
dprintk(CVP_ERR, "%s: Invalid params %pK %pK\n",
|
||||
__func__, core, pdev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core->hfi_type = CVP_HFI_IRIS;
|
||||
core->resources.pdev = pdev;
|
||||
if (pdev->dev.of_node) {
|
||||
/* Target supports DT, parse from it */
|
||||
rc = cvp_read_platform_resources_from_drv_data(core);
|
||||
rc = cvp_read_platform_resources_from_dt(&core->resources);
|
||||
} else {
|
||||
dprintk(CVP_ERR, "pdev node is NULL\n");
|
||||
rc = -EINVAL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cvp_initialize_core(struct platform_device *pdev,
|
||||
struct msm_cvp_core *core)
|
||||
{
|
||||
int i = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (!core)
|
||||
return -EINVAL;
|
||||
rc = read_platform_resources(core, pdev);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "Failed to get platform resources\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&core->instances);
|
||||
mutex_init(&core->lock);
|
||||
mutex_init(&core->clk_lock);
|
||||
|
||||
core->state = CVP_CORE_UNINIT;
|
||||
for (i = SYS_MSG_INDEX(SYS_MSG_START);
|
||||
i <= SYS_MSG_INDEX(SYS_MSG_END); i++) {
|
||||
init_completion(&core->completions[i]);
|
||||
}
|
||||
|
||||
INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler);
|
||||
core->ssr_count = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t link_name_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct msm_cvp_core *core = dev_get_drvdata(dev);
|
||||
|
||||
if (core)
|
||||
if (dev == core->dev)
|
||||
return snprintf(buf, PAGE_SIZE, "msm_cvp\n");
|
||||
else
|
||||
return 0;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(link_name);
|
||||
|
||||
static ssize_t pwr_collapse_delay_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
int rc = 0;
|
||||
struct msm_cvp_core *core = NULL;
|
||||
|
||||
rc = kstrtoul(buf, 0, &val);
|
||||
if (rc)
|
||||
return rc;
|
||||
else if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
if (!core)
|
||||
return -EINVAL;
|
||||
core->resources.msm_cvp_pwr_collapse_delay = val;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t pwr_collapse_delay_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct msm_cvp_core *core = NULL;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
if (!core)
|
||||
return -EINVAL;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n",
|
||||
core->resources.msm_cvp_pwr_collapse_delay);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(pwr_collapse_delay);
|
||||
|
||||
static ssize_t thermal_level_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", cvp_driver->thermal_level);
|
||||
}
|
||||
|
||||
static ssize_t thermal_level_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int rc = 0, val = 0;
|
||||
|
||||
rc = kstrtoint(buf, 0, &val);
|
||||
if (rc || val < 0) {
|
||||
dprintk(CVP_WARN,
|
||||
"Invalid thermal level value: %s\n", buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
dprintk(CVP_PWR, "Thermal level old %d new %d\n",
|
||||
cvp_driver->thermal_level, val);
|
||||
|
||||
if (val == cvp_driver->thermal_level)
|
||||
return count;
|
||||
cvp_driver->thermal_level = val;
|
||||
|
||||
msm_cvp_comm_handle_thermal_event();
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(thermal_level);
|
||||
|
||||
static ssize_t sku_version_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d",
|
||||
cvp_driver->sku_version);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(sku_version);
|
||||
|
||||
static ssize_t boot_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int rc = 0, val = 0;
|
||||
static int booted;
|
||||
|
||||
rc = kstrtoint(buf, 0, &val);
|
||||
if (rc || val < 0) {
|
||||
dprintk(CVP_WARN,
|
||||
"Invalid boot value: %s\n", buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (val == 1 && booted == 0) {
|
||||
struct msm_cvp_inst *inst;
|
||||
|
||||
inst = msm_cvp_open(MSM_CVP_BOOT, current);
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to create cvp instance\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
rc = msm_cvp_close(inst);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to close cvp instance\n");
|
||||
return rc;
|
||||
}
|
||||
} else if (val == 2) {
|
||||
struct msm_cvp_inst *inst;
|
||||
|
||||
inst = msm_cvp_open(MSM_CVP_USER, current);
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to create eva instance\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
rc = msm_cvp_session_create(inst);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR, "Failed to create eva session\n");
|
||||
|
||||
rc = msm_cvp_close(inst);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to close eva instance\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
booted = 1;
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_WO(boot);
|
||||
|
||||
static struct attribute *msm_cvp_core_attrs[] = {
|
||||
&dev_attr_pwr_collapse_delay.attr,
|
||||
&dev_attr_thermal_level.attr,
|
||||
&dev_attr_sku_version.attr,
|
||||
&dev_attr_link_name.attr,
|
||||
&dev_attr_boot.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group msm_cvp_core_attr_group = {
|
||||
.attrs = msm_cvp_core_attrs,
|
||||
};
|
||||
|
||||
static const struct of_device_id msm_cvp_plat_match[] = {
|
||||
{.compatible = "qcom,msm-cvp"},
|
||||
{.compatible = "qcom,msm-cvp,context-bank"},
|
||||
{.compatible = "qcom,msm-cvp,bus"},
|
||||
{.compatible = "qcom,msm-cvp,mem-cdsp"},
|
||||
{}
|
||||
};
|
||||
|
||||
static int msm_probe_cvp_device(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_core *core;
|
||||
|
||||
if (!cvp_driver) {
|
||||
dprintk(CVP_ERR, "Invalid cvp driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = kzalloc(sizeof(*core), GFP_KERNEL);
|
||||
if (!core)
|
||||
return -ENOMEM;
|
||||
|
||||
core->platform_data = cvp_get_drv_data(&pdev->dev);
|
||||
dev_set_drvdata(&pdev->dev, core);
|
||||
rc = msm_cvp_initialize_core(pdev, core);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "Failed to init core\n");
|
||||
goto err_core_init;
|
||||
}
|
||||
|
||||
rc = alloc_chrdev_region(&core->dev_num, 0, 1, DRIVER_NAME);
|
||||
if (rc < 0) {
|
||||
dprintk(CVP_ERR, "alloc_chrdev_region failed: %d\n",
|
||||
rc);
|
||||
goto err_alloc_chrdev;
|
||||
}
|
||||
|
||||
core->class = class_create(THIS_MODULE, CLASS_NAME);
|
||||
if (IS_ERR(core->class)) {
|
||||
rc = PTR_ERR(core->class);
|
||||
dprintk(CVP_ERR, "class_create failed: %d\n",
|
||||
rc);
|
||||
goto err_class_create;
|
||||
}
|
||||
|
||||
core->dev = device_create(core->class, NULL,
|
||||
core->dev_num, NULL, DRIVER_NAME);
|
||||
if (IS_ERR(core->dev)) {
|
||||
rc = PTR_ERR(core->dev);
|
||||
dprintk(CVP_ERR, "device_create failed: %d\n",
|
||||
rc);
|
||||
goto err_device_create;
|
||||
}
|
||||
dev_set_drvdata(core->dev, core);
|
||||
|
||||
cdev_init(&core->cdev, &cvp_fops);
|
||||
rc = cdev_add(&core->cdev,
|
||||
MKDEV(MAJOR(core->dev_num), 0), 1);
|
||||
if (rc < 0) {
|
||||
dprintk(CVP_ERR, "cdev_add failed: %d\n",
|
||||
rc);
|
||||
goto error_cdev_add;
|
||||
}
|
||||
|
||||
rc = sysfs_create_group(&core->dev->kobj, &msm_cvp_core_attr_group);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to create attributes\n");
|
||||
goto err_cores_exceeded;
|
||||
}
|
||||
|
||||
/* VM manager shall be started before HFI init */
|
||||
vm_manager.vm_ops->vm_start(core);
|
||||
|
||||
core->dev_ops = cvp_hfi_initialize(core->hfi_type,
|
||||
&core->resources, &cvp_handle_cmd_response);
|
||||
if (IS_ERR_OR_NULL(core->dev_ops)) {
|
||||
mutex_lock(&cvp_driver->lock);
|
||||
mutex_unlock(&cvp_driver->lock);
|
||||
|
||||
rc = PTR_ERR(core->dev_ops) ?: -EBADHANDLE;
|
||||
if (rc != -EPROBE_DEFER)
|
||||
dprintk(CVP_ERR, "Failed to create HFI device\n");
|
||||
else
|
||||
dprintk(CVP_CORE, "msm_cvp: request probe defer\n");
|
||||
goto err_hfi_initialize;
|
||||
}
|
||||
|
||||
cvp_synx_ftbl_init(core);
|
||||
|
||||
mutex_lock(&cvp_driver->lock);
|
||||
cvp_driver->cvp_core = core;
|
||||
mutex_unlock(&cvp_driver->lock);
|
||||
|
||||
cvp_driver->debugfs_root = msm_cvp_debugfs_init_drv();
|
||||
if (!cvp_driver->debugfs_root)
|
||||
dprintk(CVP_ERR, "Failed to create debugfs for msm_cvp\n");
|
||||
|
||||
core->debugfs_root = msm_cvp_debugfs_init_core(
|
||||
core, cvp_driver->debugfs_root);
|
||||
|
||||
cvp_driver->sku_version = core->resources.sku_version;
|
||||
|
||||
dprintk(CVP_CORE, "populating sub devices\n");
|
||||
/*
|
||||
* Trigger probe for each sub-device i.e. qcom,msm-cvp,context-bank.
|
||||
* When msm_cvp_probe is called for each sub-device, parse the
|
||||
* context-bank details and store it in core->resources.context_banks
|
||||
* list.
|
||||
*/
|
||||
rc = of_platform_populate(pdev->dev.of_node, msm_cvp_plat_match, NULL,
|
||||
&pdev->dev);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "Failed to trigger probe for sub-devices\n");
|
||||
goto err_fail_sub_device_probe;
|
||||
}
|
||||
|
||||
atomic64_set(&core->kernel_trans_id, ARRAY_SIZE(cvp_hfi_defs));
|
||||
|
||||
if (core->resources.dsp_enabled) {
|
||||
rc = cvp_dsp_device_init();
|
||||
if (rc)
|
||||
dprintk(CVP_WARN, "Failed to initialize DSP driver\n");
|
||||
} else {
|
||||
dprintk(CVP_DSP, "DSP interface not enabled\n");
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
err_fail_sub_device_probe:
|
||||
cvp_hfi_deinitialize(core->hfi_type, core->dev_ops);
|
||||
debugfs_remove_recursive(cvp_driver->debugfs_root);
|
||||
err_hfi_initialize:
|
||||
err_cores_exceeded:
|
||||
cdev_del(&core->cdev);
|
||||
error_cdev_add:
|
||||
device_destroy(core->class, core->dev_num);
|
||||
err_device_create:
|
||||
class_destroy(core->class);
|
||||
err_class_create:
|
||||
unregister_chrdev_region(core->dev_num, 1);
|
||||
err_alloc_chrdev:
|
||||
sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group);
|
||||
err_core_init:
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
kfree(core);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cvp_probe_mem_cdsp(struct platform_device *pdev)
|
||||
{
|
||||
return cvp_read_mem_cdsp_resources_from_dt(pdev);
|
||||
}
|
||||
|
||||
static int msm_cvp_probe_context_bank(struct platform_device *pdev)
|
||||
{
|
||||
return cvp_read_context_bank_resources_from_dt(pdev);
|
||||
}
|
||||
|
||||
static int msm_cvp_probe_bus(struct platform_device *pdev)
|
||||
{
|
||||
return cvp_read_bus_resources_from_dt(pdev);
|
||||
}
|
||||
|
||||
static int msm_cvp_probe(struct platform_device *pdev)
|
||||
{
|
||||
/*
|
||||
* Sub devices probe will be triggered by of_platform_populate() towards
|
||||
* the end of the probe function after msm-cvp device probe is
|
||||
* completed. Return immediately after completing sub-device probe.
|
||||
*/
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-cvp")) {
|
||||
return msm_probe_cvp_device(pdev);
|
||||
} else if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,msm-cvp,bus")) {
|
||||
return msm_cvp_probe_bus(pdev);
|
||||
} else if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,msm-cvp,context-bank")) {
|
||||
return msm_cvp_probe_context_bank(pdev);
|
||||
} else if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,msm-cvp,mem-cdsp")) {
|
||||
return msm_cvp_probe_mem_cdsp(pdev);
|
||||
}
|
||||
|
||||
/* How did we end up here? */
|
||||
MSM_CVP_ERROR(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int msm_cvp_remove(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_core *core;
|
||||
|
||||
if (!pdev) {
|
||||
dprintk(CVP_ERR, "%s invalid input %pK", __func__, pdev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = dev_get_drvdata(&pdev->dev);
|
||||
if (!core) {
|
||||
dprintk(CVP_ERR, "%s invalid core", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cvp_hfi_deinitialize(core->hfi_type, core->dev_ops);
|
||||
msm_cvp_free_platform_resources(&core->resources);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
mutex_destroy(&core->lock);
|
||||
mutex_destroy(&core->clk_lock);
|
||||
kfree(core);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cvp_pm_suspend(struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_core *core;
|
||||
|
||||
/*
|
||||
* Bail out if
|
||||
* - driver possibly not probed yet
|
||||
* - not the main device. We don't support power management on
|
||||
* subdevices (e.g. context banks)
|
||||
*/
|
||||
if (!dev || !dev->driver ||
|
||||
!of_device_is_compatible(dev->of_node, "qcom,msm-cvp"))
|
||||
return 0;
|
||||
|
||||
core = dev_get_drvdata(dev);
|
||||
if (!core) {
|
||||
dprintk(CVP_ERR, "%s invalid core\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_cvp_suspend();
|
||||
if (rc == -ENOTSUPP)
|
||||
rc = 0;
|
||||
else if (rc)
|
||||
dprintk(CVP_WARN, "Failed to suspend: %d\n", rc);
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cvp_pm_resume(struct device *dev)
|
||||
{
|
||||
dprintk(CVP_INFO, "%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops msm_cvp_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(msm_cvp_pm_suspend, msm_cvp_pm_resume)
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, msm_cvp_plat_match);
|
||||
|
||||
static struct platform_driver msm_cvp_driver = {
|
||||
.probe = msm_cvp_probe,
|
||||
.remove = msm_cvp_remove,
|
||||
.driver = {
|
||||
.name = "msm_cvp",
|
||||
.of_match_table = msm_cvp_plat_match,
|
||||
.pm = &msm_cvp_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init msm_cvp_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
cvp_driver = kzalloc(sizeof(*cvp_driver), GFP_KERNEL);
|
||||
if (!cvp_driver) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to allocate memroy for msm_cvp_drv\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&cvp_driver->lock);
|
||||
|
||||
rc = platform_driver_register(&msm_cvp_driver);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to register platform driver\n");
|
||||
kfree(cvp_driver);
|
||||
cvp_driver = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
cvp_driver->msg_cache.cache = KMEM_CACHE(cvp_session_msg, 0);
|
||||
cvp_driver->frame_cache.cache = KMEM_CACHE(msm_cvp_frame, 0);
|
||||
cvp_driver->buf_cache.cache = KMEM_CACHE(cvp_internal_buf, 0);
|
||||
cvp_driver->smem_cache.cache = KMEM_CACHE(msm_cvp_smem, 0);
|
||||
mutex_init(&wncc_buf_pool.lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __exit msm_cvp_exit(void)
|
||||
{
|
||||
cvp_dsp_device_exit();
|
||||
kmem_cache_destroy(cvp_driver->msg_cache.cache);
|
||||
kmem_cache_destroy(cvp_driver->frame_cache.cache);
|
||||
kmem_cache_destroy(cvp_driver->buf_cache.cache);
|
||||
kmem_cache_destroy(cvp_driver->smem_cache.cache);
|
||||
|
||||
platform_driver_unregister(&msm_cvp_driver);
|
||||
debugfs_remove_recursive(cvp_driver->debugfs_root);
|
||||
mutex_destroy(&cvp_driver->lock);
|
||||
mutex_destroy(&wncc_buf_pool.lock);
|
||||
kfree(cvp_driver);
|
||||
cvp_driver = NULL;
|
||||
}
|
||||
|
||||
module_init(msm_cvp_init);
|
||||
module_exit(msm_cvp_exit);
|
||||
|
||||
MODULE_SOFTDEP("pre: msm-mmrm");
|
||||
MODULE_SOFTDEP("pre: synx-driver");
|
||||
MODULE_SOFTDEP("pre: frpc-adsprpc");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_IMPORT_NS(DMA_BUF);
|
50
qcom/opensource/eva-kernel/msm/eva/cvp_comm_def.h
Normal file
50
qcom/opensource/eva-kernel/msm/eva/cvp_comm_def.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_COMM_DEF_H_
|
||||
#define _MSM_COMM_DEF_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/gunyah/gh_rm_drv.h>
|
||||
|
||||
enum op_mode {
|
||||
OP_NORMAL,
|
||||
OP_DRAINING,
|
||||
OP_FLUSH,
|
||||
OP_INVALID,
|
||||
};
|
||||
|
||||
enum queue_state {
|
||||
QUEUE_INIT,
|
||||
QUEUE_ACTIVE = 1,
|
||||
QUEUE_START,
|
||||
QUEUE_STOP,
|
||||
QUEUE_INVALID,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EVA_TVM
|
||||
|
||||
#else /* LA target starts here */
|
||||
|
||||
#ifdef CONFIG_EVA_KALAMA
|
||||
#define CVP_SYNX_ENABLED 1
|
||||
#define CVP_MMRM_ENABLED 1
|
||||
#define CVP_FASTRPC_ENABLED 1
|
||||
#endif /* End of CONFIG_EVA_KALAMA */
|
||||
|
||||
#ifdef CONFIG_EVA_PINEAPPLE
|
||||
#define CVP_MMRM_ENABLED 1
|
||||
#define CVP_SYNX_ENABLED 1
|
||||
#define CVP_FASTRPC_ENABLED 1
|
||||
#endif /* End of CONFIG_EVA_PINEAPPLE */
|
||||
|
||||
|
||||
#ifdef CONFIG_EVA_WAIPIO
|
||||
#define CVP_MINIDUMP_ENABLED 1
|
||||
#endif
|
||||
|
||||
#endif /* End CONFIG_EVA_TVM */
|
||||
|
||||
#endif
|
53
qcom/opensource/eva-kernel/msm/eva/cvp_core_hfi.c
Normal file
53
qcom/opensource/eva-kernel/msm/eva/cvp_core_hfi.c
Normal file
@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
|
||||
struct cvp_hfi_ops *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type,
|
||||
struct msm_cvp_platform_resources *res,
|
||||
hfi_cmd_response_callback callback)
|
||||
{
|
||||
struct cvp_hfi_ops *ops_tbl = NULL;
|
||||
int rc = 0;
|
||||
|
||||
ops_tbl = kzalloc(sizeof(struct cvp_hfi_ops), GFP_KERNEL);
|
||||
if (!ops_tbl) {
|
||||
dprintk(CVP_ERR, "%s: failed to allocate ops_tbl\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = cvp_iris_hfi_initialize(ops_tbl, res, callback);
|
||||
|
||||
if (rc) {
|
||||
if (rc != -EPROBE_DEFER)
|
||||
dprintk(CVP_ERR, "%s device init failed rc = %d",
|
||||
__func__, rc);
|
||||
goto err_hfi_init;
|
||||
}
|
||||
|
||||
return ops_tbl;
|
||||
|
||||
err_hfi_init:
|
||||
kfree(ops_tbl);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type,
|
||||
struct cvp_hfi_ops *ops_tbl)
|
||||
{
|
||||
if (!ops_tbl) {
|
||||
dprintk(CVP_ERR, "%s invalid device %pK", __func__, ops_tbl);
|
||||
return;
|
||||
}
|
||||
|
||||
cvp_iris_hfi_delete_device(ops_tbl->hfi_device_data);
|
||||
|
||||
kfree(ops_tbl);
|
||||
}
|
||||
|
302
qcom/opensource/eva-kernel/msm/eva/cvp_core_hfi.h
Normal file
302
qcom/opensource/eva-kernel/msm/eva/cvp_core_hfi.h
Normal file
@ -0,0 +1,302 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __H_CVP_CORE_HFI_H__
|
||||
#define __H_CVP_CORE_HFI_H__
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/soc/qcom/msm_mmrm.h>
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "cvp_hfi_helper.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "cvp_hfi.h"
|
||||
#include "msm_cvp_resources.h"
|
||||
#include "hfi_packetization.h"
|
||||
|
||||
#define HFI_MASK_QHDR_TX_TYPE 0xFF000000
|
||||
#define HFI_MASK_QHDR_RX_TYPE 0x00FF0000
|
||||
#define HFI_MASK_QHDR_PRI_TYPE 0x0000FF00
|
||||
#define HFI_MASK_QHDR_Q_ID_TYPE 0x000000FF
|
||||
#define HFI_Q_ID_HOST_TO_CTRL_CMD_Q 0x00
|
||||
#define HFI_Q_ID_CTRL_TO_HOST_MSG_Q 0x01
|
||||
#define HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q 0x02
|
||||
#define HFI_MASK_QHDR_STATUS 0x000000FF
|
||||
|
||||
#define CVP_IFACEQ_NUMQ 3
|
||||
#define CVP_IFACEQ_CMDQ_IDX 0
|
||||
#define CVP_IFACEQ_MSGQ_IDX 1
|
||||
#define CVP_IFACEQ_DBGQ_IDX 2
|
||||
#define CVP_IFACEQ_MAX_BUF_COUNT 50
|
||||
#define CVP_IFACE_MAX_PARALLEL_CLNTS 16
|
||||
#define CVP_IFACEQ_DFLT_QHDR 0x01010000
|
||||
|
||||
#define CVP_MAX_NAME_LENGTH 64
|
||||
#define CVP_MAX_PC_SKIP_COUNT 10
|
||||
#define CVP_MAX_SUBCACHES 4
|
||||
#define CVP_MAX_SUBCACHE_SIZE 52
|
||||
|
||||
struct cvp_hfi_queue_table_header {
|
||||
u32 qtbl_version;
|
||||
u32 qtbl_size;
|
||||
u32 qtbl_qhdr0_offset;
|
||||
u32 qtbl_qhdr_size;
|
||||
u32 qtbl_num_q;
|
||||
u32 qtbl_num_active_q;
|
||||
void *device_addr;
|
||||
char name[256];
|
||||
};
|
||||
|
||||
struct cvp_hfi_queue_header {
|
||||
u32 qhdr_status;
|
||||
u32 qhdr_start_addr;
|
||||
u32 qhdr_type;
|
||||
u32 qhdr_q_size;
|
||||
u32 qhdr_pkt_size;
|
||||
u32 qhdr_pkt_drop_cnt;
|
||||
u32 qhdr_rx_wm;
|
||||
u32 qhdr_tx_wm;
|
||||
u32 qhdr_rx_req;
|
||||
u32 qhdr_tx_req;
|
||||
u32 qhdr_rx_irq_status;
|
||||
u32 qhdr_tx_irq_status;
|
||||
u32 qhdr_read_idx;
|
||||
u32 qhdr_write_idx;
|
||||
};
|
||||
|
||||
struct cvp_hfi_mem_map_table {
|
||||
u32 mem_map_num_entries;
|
||||
u32 mem_map_table_base_addr;
|
||||
};
|
||||
|
||||
struct cvp_hfi_mem_map {
|
||||
u32 virtual_addr;
|
||||
u32 physical_addr;
|
||||
u32 size;
|
||||
u32 attr;
|
||||
};
|
||||
|
||||
#define CVP_IFACEQ_TABLE_SIZE (sizeof(struct cvp_hfi_queue_table_header) \
|
||||
+ sizeof(struct cvp_hfi_queue_header) * CVP_IFACEQ_NUMQ)
|
||||
|
||||
#define CVP_IFACEQ_QUEUE_SIZE (CVP_IFACEQ_MAX_PKT_SIZE * \
|
||||
CVP_IFACEQ_MAX_BUF_COUNT * CVP_IFACE_MAX_PARALLEL_CLNTS)
|
||||
|
||||
#define CVP_IFACEQ_GET_QHDR_START_ADDR(ptr, i) \
|
||||
(void *)((ptr + sizeof(struct cvp_hfi_queue_table_header)) + \
|
||||
(i * sizeof(struct cvp_hfi_queue_header)))
|
||||
|
||||
#define QDSS_SIZE 4096
|
||||
#define SFR_SIZE 1048576
|
||||
|
||||
#define QUEUE_SIZE (CVP_IFACEQ_TABLE_SIZE + \
|
||||
(CVP_IFACEQ_QUEUE_SIZE * CVP_IFACEQ_NUMQ))
|
||||
|
||||
#define ALIGNED_QDSS_SIZE ALIGN(QDSS_SIZE, SZ_4K)
|
||||
#define ALIGNED_SFR_SIZE ALIGN(SFR_SIZE, SZ_4K)
|
||||
#define ALIGNED_QUEUE_SIZE ALIGN(QUEUE_SIZE, SZ_4K)
|
||||
#define SHARED_QSIZE ALIGN(ALIGNED_SFR_SIZE + ALIGNED_QUEUE_SIZE + \
|
||||
ALIGNED_QDSS_SIZE, SZ_1M)
|
||||
|
||||
struct cvp_mem_addr {
|
||||
u32 align_device_addr;
|
||||
u8 *align_virtual_addr;
|
||||
u32 mem_size;
|
||||
struct msm_cvp_smem mem_data;
|
||||
};
|
||||
|
||||
struct cvp_iface_q_info {
|
||||
spinlock_t hfi_lock;
|
||||
void *q_hdr;
|
||||
struct cvp_mem_addr q_array;
|
||||
};
|
||||
|
||||
/*
|
||||
* These are helper macros to iterate over various lists within
|
||||
* iris_hfi_device->res. The intention is to cut down on a lot of boiler-plate
|
||||
* code
|
||||
*/
|
||||
|
||||
/* Read as "for each 'thing' in a set of 'thingies'" */
|
||||
#define iris_hfi_for_each_thing(__device, __thing, __thingy) \
|
||||
iris_hfi_for_each_thing_continue(__device, __thing, __thingy, 0)
|
||||
|
||||
#define iris_hfi_for_each_thing_reverse(__device, __thing, __thingy) \
|
||||
iris_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \
|
||||
(__device)->res->__thingy##_set.count - 1)
|
||||
|
||||
/* TODO: the __from parameter technically not required since we can figure it
|
||||
* out with some pointer magic (i.e. __thing - __thing##_tbl[0]). If this macro
|
||||
* sees extensive use, probably worth cleaning it up but for now omitting it
|
||||
* since it introduces unnecessary complexity.
|
||||
*/
|
||||
#define iris_hfi_for_each_thing_continue(__device, __thing, __thingy, __from) \
|
||||
for (__thing = &(__device)->res->\
|
||||
__thingy##_set.__thingy##_tbl[__from]; \
|
||||
__thing < &(__device)->res->__thingy##_set.__thingy##_tbl[0] + \
|
||||
((__device)->res->__thingy##_set.count - __from); \
|
||||
++__thing)
|
||||
|
||||
#define iris_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \
|
||||
__from) \
|
||||
for (__thing = &(__device)->res->\
|
||||
__thingy##_set.__thingy##_tbl[__from]; \
|
||||
__thing >= &(__device)->res->__thingy##_set.__thingy##_tbl[0]; \
|
||||
--__thing)
|
||||
|
||||
/* Regular set helpers */
|
||||
#define iris_hfi_for_each_regulator(__device, __rinfo) \
|
||||
iris_hfi_for_each_thing(__device, __rinfo, regulator)
|
||||
|
||||
#define iris_hfi_for_each_regulator_reverse(__device, __rinfo) \
|
||||
iris_hfi_for_each_thing_reverse(__device, __rinfo, regulator)
|
||||
|
||||
#define iris_hfi_for_each_regulator_reverse_continue(__device, __rinfo, \
|
||||
__from) \
|
||||
iris_hfi_for_each_thing_reverse_continue(__device, __rinfo, \
|
||||
regulator, __from)
|
||||
|
||||
/* Clock set helpers */
|
||||
#define iris_hfi_for_each_clock(__device, __cinfo) \
|
||||
iris_hfi_for_each_thing(__device, __cinfo, clock)
|
||||
|
||||
#define iris_hfi_for_each_clock_reverse(__device, __cinfo) \
|
||||
iris_hfi_for_each_thing_reverse(__device, __cinfo, clock)
|
||||
|
||||
#define iris_hfi_for_each_clock_reverse_continue(__device, __rinfo, \
|
||||
__from) \
|
||||
iris_hfi_for_each_thing_reverse_continue(__device, __rinfo, \
|
||||
clock, __from)
|
||||
|
||||
/* reset set helpers */
|
||||
#define iris_hfi_for_each_reset_clock(__device, __resetinfo) \
|
||||
iris_hfi_for_each_thing(__device, __resetinfo, reset)
|
||||
|
||||
#define iris_hfi_for_each_reset_clock_reverse(__device, __resetinfo) \
|
||||
iris_hfi_for_each_thing_reverse(__device, __resetinfo, reset)
|
||||
|
||||
/* Bus set helpers */
|
||||
#define iris_hfi_for_each_bus(__device, __binfo) \
|
||||
iris_hfi_for_each_thing(__device, __binfo, bus)
|
||||
#define iris_hfi_for_each_bus_reverse(__device, __binfo) \
|
||||
iris_hfi_for_each_thing_reverse(__device, __binfo, bus)
|
||||
|
||||
/* Subcache set helpers */
|
||||
#define iris_hfi_for_each_subcache(__device, __sinfo) \
|
||||
iris_hfi_for_each_thing(__device, __sinfo, subcache)
|
||||
#define iris_hfi_for_each_subcache_reverse(__device, __sinfo) \
|
||||
iris_hfi_for_each_thing_reverse(__device, __sinfo, subcache)
|
||||
|
||||
#define call_iris_op(d, op, args...) \
|
||||
(((d) && (d)->hal_ops && (d)->hal_ops->op) ? \
|
||||
((d)->hal_ops->op(args)):0)
|
||||
|
||||
struct cvp_hal_data {
|
||||
u32 irq;
|
||||
u32 irq_wd;
|
||||
phys_addr_t firmware_base;
|
||||
u8 __iomem *register_base;
|
||||
u8 __iomem *gcc_reg_base;
|
||||
u32 register_size;
|
||||
u32 gcc_reg_size;
|
||||
};
|
||||
|
||||
struct iris_resources {
|
||||
struct msm_cvp_fw fw;
|
||||
};
|
||||
|
||||
enum iris_hfi_state {
|
||||
IRIS_STATE_DEINIT = 1,
|
||||
IRIS_STATE_INIT,
|
||||
};
|
||||
|
||||
enum reset_state {
|
||||
INIT = 1,
|
||||
ASSERT,
|
||||
DEASSERT,
|
||||
};
|
||||
|
||||
/* Indices of hfi queues in hfi queue arrays (iface_queues & dsp_iface_queues) */
|
||||
enum hfi_queue_idx {
|
||||
CMD_Q, /* Command queue */
|
||||
MSG_Q, /* Message queue */
|
||||
DEBUG_Q, /* Debug queue */
|
||||
MAX_Q
|
||||
};
|
||||
|
||||
struct iris_hfi_device;
|
||||
|
||||
struct cvp_hal_ops {
|
||||
void (*interrupt_init)(struct iris_hfi_device *ptr);
|
||||
void (*setup_dsp_uc_memmap)(struct iris_hfi_device *device);
|
||||
void (*clock_config_on_enable)(struct iris_hfi_device *device);
|
||||
void (*power_off)(struct iris_hfi_device *device);
|
||||
void (*noc_error_info)(struct iris_hfi_device *device);
|
||||
int (*reset_control_assert_name)(struct iris_hfi_device *device, const char *name);
|
||||
int (*reset_control_deassert_name)(struct iris_hfi_device *device, const char *name);
|
||||
int (*reset_control_acquire_name)(struct iris_hfi_device *device, const char *name);
|
||||
int (*reset_control_release_name)(struct iris_hfi_device *device, const char *name);
|
||||
};
|
||||
|
||||
struct iris_hfi_device {
|
||||
struct list_head sess_head;
|
||||
u32 version;
|
||||
u32 intr_status;
|
||||
u32 clk_freq;
|
||||
u32 last_packet_type;
|
||||
u32 error;
|
||||
unsigned long clk_bitrate;
|
||||
unsigned long scaled_rate;
|
||||
struct msm_cvp_gov_data bus_vote;
|
||||
bool power_enabled;
|
||||
bool reg_dumped;
|
||||
struct mutex lock;
|
||||
msm_cvp_callback callback;
|
||||
struct cvp_mem_addr iface_q_table;
|
||||
struct cvp_mem_addr dsp_iface_q_table;
|
||||
struct cvp_mem_addr qdss;
|
||||
struct cvp_mem_addr sfr;
|
||||
struct cvp_mem_addr mem_addr;
|
||||
struct cvp_iface_q_info iface_queues[CVP_IFACEQ_NUMQ];
|
||||
struct cvp_iface_q_info dsp_iface_queues[CVP_IFACEQ_NUMQ];
|
||||
struct cvp_hal_data *cvp_hal_data;
|
||||
struct workqueue_struct *cvp_workq;
|
||||
struct workqueue_struct *iris_pm_workq;
|
||||
int spur_count;
|
||||
int reg_count;
|
||||
struct iris_resources resources;
|
||||
struct msm_cvp_platform_resources *res;
|
||||
struct mmrm_client_desc mmrm_desc;
|
||||
struct mmrm_client *mmrm_cvp;
|
||||
enum iris_hfi_state state;
|
||||
struct cvp_hfi_packetization_ops *pkt_ops;
|
||||
enum hfi_packetization_type packetization_type;
|
||||
struct msm_cvp_cb_info *response_pkt;
|
||||
u8 *raw_packet;
|
||||
struct pm_qos_request qos;
|
||||
unsigned int skip_pc_count;
|
||||
struct msm_cvp_capability *sys_init_capabilities;
|
||||
struct cvp_hal_ops *hal_ops;
|
||||
};
|
||||
|
||||
irqreturn_t cvp_hfi_isr(int irq, void *dev);
|
||||
irqreturn_t iris_hfi_core_work_handler(int irq, void *data);
|
||||
irqreturn_t iris_hfi_isr_wd(int irq, void *dev);
|
||||
void cvp_iris_hfi_delete_device(void *device);
|
||||
|
||||
int cvp_iris_hfi_initialize(struct cvp_hfi_ops *hdev,
|
||||
struct msm_cvp_platform_resources *res,
|
||||
hfi_cmd_response_callback callback);
|
||||
|
||||
int load_cvp_fw_impl(struct iris_hfi_device *device);
|
||||
int unload_cvp_fw_impl(struct iris_hfi_device *device);
|
||||
void cvp_dump_csr(struct iris_hfi_device *dev);
|
||||
#endif
|
314
qcom/opensource/eva-kernel/msm/eva/cvp_dump.c
Normal file
314
qcom/opensource/eva-kernel/msm/eva/cvp_dump.c
Normal file
@ -0,0 +1,314 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <asm/memory.h>
|
||||
#include <linux/coresight-stm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/hash.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/soc/qcom/llcc-qcom.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/soc/qcom/smem.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/reset.h>
|
||||
#include "hfi_packetization.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
#include "cvp_hfi_helper.h"
|
||||
#include "cvp_hfi_io.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
#include "msm_cvp_clocks.h"
|
||||
#include "cvp_dump.h"
|
||||
|
||||
#ifdef CVP_MINIDUMP_ENABLED
|
||||
/*Declare and init the head node of the linked list
|
||||
for queue va_md dump*/
|
||||
static LIST_HEAD(head_node_hfi_queue);
|
||||
|
||||
/*Declare and init the head node of the linked list
|
||||
for debug struct va_md dump*/
|
||||
static LIST_HEAD(head_node_dbg_struct);
|
||||
|
||||
static int eva_struct_list_notif_handler(struct notifier_block *this,
|
||||
unsigned long event, void *ptr);
|
||||
|
||||
static int eva_hfiq_list_notif_handler(struct notifier_block *this,
|
||||
unsigned long event, void *ptr);
|
||||
|
||||
static struct notifier_block eva_struct_list_notif_blk = {
|
||||
.notifier_call = eva_struct_list_notif_handler,
|
||||
.priority = INT_MAX-1,
|
||||
};
|
||||
|
||||
static struct notifier_block eva_hfiq_list_notif_blk = {
|
||||
.notifier_call = eva_hfiq_list_notif_handler,
|
||||
.priority = INT_MAX,
|
||||
};
|
||||
|
||||
struct list_head *dump_array[CVP_MAX_DUMP] = {
|
||||
[CVP_QUEUE_DUMP] = &head_node_hfi_queue,
|
||||
[CVP_DBG_DUMP] = &head_node_dbg_struct,
|
||||
};
|
||||
|
||||
int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size)
|
||||
{
|
||||
struct md_region md_entry;
|
||||
|
||||
if (msm_minidump_enabled()) {
|
||||
dprintk(CVP_INFO, "Minidump is enabled!\n");
|
||||
|
||||
strlcpy(md_entry.name, name, sizeof(md_entry.name));
|
||||
md_entry.virt_addr = (uintptr_t)virt;
|
||||
md_entry.phys_addr = phys;
|
||||
md_entry.size = size;
|
||||
if (msm_minidump_add_region(&md_entry) < 0) {
|
||||
dprintk(CVP_ERR, "Failed to add \"%s\" data in \
|
||||
Minidump\n", name);
|
||||
return 1;
|
||||
} else {
|
||||
dprintk(CVP_INFO,
|
||||
"add region success for \"%s\" with virt addr:\
|
||||
0x%x, phy addr: 0x%x, size: %d",
|
||||
md_entry.name, md_entry.virt_addr,
|
||||
md_entry.phys_addr, md_entry.size);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
dprintk(CVP_ERR, "Minidump is NOT enabled!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void cvp_va_md_register(char* name, void* notf_blk_ptr)
|
||||
{
|
||||
int rc = 0;
|
||||
struct notifier_block* notf_blk = (struct notifier_block*)notf_blk_ptr;
|
||||
|
||||
rc = qcom_va_md_register(name, notf_blk);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"\"%s\" : qcom_va_md_register failed rc = %d\n",
|
||||
name, rc);
|
||||
} else {
|
||||
dprintk(CVP_INFO, "\"%s\" : eva_queue qcom_va_md_register \
|
||||
success rc = %d\n", name, rc);
|
||||
}
|
||||
}
|
||||
|
||||
void cvp_register_va_md_region()
|
||||
{
|
||||
if (qcom_va_md_enabled()) {
|
||||
cvp_va_md_register("eva_queues", &eva_hfiq_list_notif_blk);
|
||||
cvp_va_md_register("dbg_struct", &eva_struct_list_notif_blk);
|
||||
} else {
|
||||
dprintk(CVP_ERR, "VA_Minidump is NOT enabled!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void cvp_free_va_md_list(void)
|
||||
{
|
||||
struct eva_va_md_queue *cursor, *temp;
|
||||
|
||||
list_for_each_entry_safe(cursor, temp, &head_node_hfi_queue, list) {
|
||||
list_del(&cursor->list);
|
||||
kfree(cursor);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(cursor, temp, &head_node_dbg_struct, list) {
|
||||
list_del(&cursor->list);
|
||||
kfree(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void add_va_node_to_list(enum cvp_dump_type type, void *buff_va, u32 buff_size,
|
||||
const char *region_name, bool copy)
|
||||
{
|
||||
struct list_head *head_node;
|
||||
struct eva_va_md_queue *temp_node = NULL;
|
||||
|
||||
if (type >= CVP_MAX_DUMP)
|
||||
return;
|
||||
|
||||
head_node = dump_array[type];
|
||||
|
||||
/*Creating Node*/
|
||||
temp_node = kzalloc(sizeof(struct eva_va_md_queue), GFP_KERNEL);
|
||||
if (!temp_node) {
|
||||
dprintk(CVP_ERR, "Memory allocation failed for list node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&temp_node->list);
|
||||
|
||||
temp_node->va_md_buff = buff_va;
|
||||
temp_node->va_md_buff_size = buff_size;
|
||||
strlcpy(temp_node->region_name, region_name,
|
||||
sizeof(temp_node->region_name));
|
||||
temp_node->copy = copy;
|
||||
|
||||
list_add_tail(&temp_node->list, head_node);
|
||||
dprintk(CVP_INFO,
|
||||
"\"%s\" added to buffer list, vaddr: %px size: 0x%x\n",
|
||||
temp_node->region_name, temp_node->va_md_buff,
|
||||
temp_node->va_md_buff_size);
|
||||
}
|
||||
|
||||
void add_hfi_queue_to_va_md_list(void *device)
|
||||
{
|
||||
struct cvp_iface_q_info *iface_q;
|
||||
struct iris_hfi_device *dev;
|
||||
|
||||
dev = (struct iris_hfi_device*)device;
|
||||
|
||||
iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX];
|
||||
add_va_node_to_list(CVP_QUEUE_DUMP,
|
||||
iface_q->q_array.align_virtual_addr,
|
||||
iface_q->q_array.mem_size,
|
||||
"eva_cmdq_cpu", false);
|
||||
iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX];
|
||||
add_va_node_to_list(CVP_QUEUE_DUMP,
|
||||
iface_q->q_array.align_virtual_addr,
|
||||
iface_q->q_array.mem_size,
|
||||
"eva_msgq_cpu", false);
|
||||
|
||||
iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX];
|
||||
add_va_node_to_list(CVP_QUEUE_DUMP,
|
||||
iface_q->q_array.align_virtual_addr,
|
||||
iface_q->q_array.mem_size,
|
||||
"eva_cmdq_dsp", false);
|
||||
iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX];
|
||||
add_va_node_to_list(CVP_QUEUE_DUMP,
|
||||
iface_q->q_array.align_virtual_addr,
|
||||
iface_q->q_array.mem_size,
|
||||
"eva_msgq_dsp", false);
|
||||
}
|
||||
|
||||
void add_queue_header_to_va_md_list(void *device)
|
||||
{
|
||||
struct cvp_iface_q_info *iface_q;
|
||||
struct iris_hfi_device *dev;
|
||||
struct cvp_hfi_queue_header *queue;
|
||||
|
||||
dev = (struct iris_hfi_device*)device;
|
||||
|
||||
iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX];
|
||||
queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr;
|
||||
add_va_node_to_list(CVP_DBG_DUMP,
|
||||
queue, sizeof(struct cvp_hfi_queue_header),
|
||||
"cvp_hfi_queue_header-cpucmdQ", false);
|
||||
|
||||
iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX];
|
||||
queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr;
|
||||
add_va_node_to_list(CVP_DBG_DUMP,
|
||||
queue, sizeof(struct cvp_hfi_queue_header),
|
||||
"cvp_hfi_queue_header-cpumsgQ", false);
|
||||
|
||||
iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX];
|
||||
queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr;
|
||||
add_va_node_to_list(CVP_DBG_DUMP,
|
||||
queue, sizeof(struct cvp_hfi_queue_header),
|
||||
"cvp_hfi_queue_header-dspcmdQ", false);
|
||||
|
||||
iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX];
|
||||
queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr;
|
||||
add_va_node_to_list(CVP_DBG_DUMP,
|
||||
queue, sizeof(struct cvp_hfi_queue_header),
|
||||
"cvp_hfi_queue_header-dspmsgQ", false);
|
||||
}
|
||||
|
||||
static int eva_hfiq_list_notif_handler(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct va_md_entry entry;
|
||||
struct eva_va_md_queue *cursor, *temp;
|
||||
int rc = 0;
|
||||
void *temp_data;
|
||||
|
||||
list_for_each_entry_safe(cursor, temp, &head_node_hfi_queue, list) {
|
||||
entry.vaddr = (unsigned long)cursor->va_md_buff;
|
||||
if (cursor->copy) {
|
||||
dprintk(CVP_INFO, "Copying \"%s\"(%d Bytes)\
|
||||
to intermediate buffer\n",
|
||||
cursor->region_name, cursor->va_md_buff_size);
|
||||
temp_data = kzalloc(cursor->va_md_buff_size,
|
||||
GFP_KERNEL);
|
||||
if (temp_data) {
|
||||
memcpy(temp_data, cursor->va_md_buff,
|
||||
cursor->va_md_buff_size);
|
||||
entry.vaddr = (unsigned long)temp_data;
|
||||
}
|
||||
}
|
||||
entry.size = cursor->va_md_buff_size;
|
||||
strlcpy(entry.owner, cursor->region_name, sizeof(entry.owner));
|
||||
entry.cb = NULL;
|
||||
|
||||
if (msm_cvp_minidump_enable) {
|
||||
rc = qcom_va_md_add_region(&entry);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR, "Add region \"failed\" for \
|
||||
\"%s\", vaddr: %px size: 0x%x\n", entry.owner,
|
||||
cursor->va_md_buff, entry.size);
|
||||
else
|
||||
dprintk(CVP_INFO, "Add region \"success\" for \
|
||||
\"%s\", vaddr: %px size: 0x%x\n", entry.owner,
|
||||
cursor->va_md_buff, entry.size);
|
||||
}
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int eva_struct_list_notif_handler(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct va_md_entry entry;
|
||||
struct eva_va_md_queue *cursor, *temp;
|
||||
int rc = 0;
|
||||
void *temp_data;
|
||||
|
||||
list_for_each_entry_safe(cursor, temp, &head_node_dbg_struct, list) {
|
||||
entry.vaddr = (unsigned long)cursor->va_md_buff;
|
||||
if (cursor->copy) {
|
||||
dprintk(CVP_INFO, "Copying \"%s\"(%d Bytes) to \
|
||||
intermediate buffer\n", cursor->region_name,
|
||||
cursor->va_md_buff_size);
|
||||
temp_data = kzalloc(cursor->va_md_buff_size,
|
||||
GFP_KERNEL);
|
||||
if (temp_data) {
|
||||
memcpy(temp_data, cursor->va_md_buff,
|
||||
cursor->va_md_buff_size);
|
||||
entry.vaddr = (unsigned long)temp_data;
|
||||
}
|
||||
}
|
||||
entry.size = cursor->va_md_buff_size;
|
||||
strlcpy(entry.owner, cursor->region_name, sizeof(entry.owner));
|
||||
entry.cb = NULL;
|
||||
|
||||
if (msm_cvp_minidump_enable) {
|
||||
rc = qcom_va_md_add_region(&entry);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR, "Add region \"failed\" for \
|
||||
\"%s\", vaddr: %px size: 0x%x\n",
|
||||
entry.owner, cursor->va_md_buff,
|
||||
entry.size);
|
||||
else
|
||||
dprintk(CVP_INFO, "Add region \"success\" for \
|
||||
\"%s\", vaddr: %px size: 0x%x\n", entry.owner,
|
||||
cursor->va_md_buff, entry.size);
|
||||
}
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
#endif
|
124
qcom/opensource/eva-kernel/msm/eva/cvp_dump.h
Normal file
124
qcom/opensource/eva-kernel/msm/eva/cvp_dump.h
Normal file
@ -0,0 +1,124 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __H_CVP_MINIDUMP_H__
|
||||
#define __H_CVP_MINIDUMP_H__
|
||||
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
enum cvp_dump_type {
|
||||
CVP_QUEUE_DUMP,
|
||||
CVP_DBG_DUMP,
|
||||
CVP_MAX_DUMP,
|
||||
};
|
||||
|
||||
#define MAX_REGION_NAME_LEN 32
|
||||
#define EVAFW_IMAGE_SIZE 7*1024*1024
|
||||
|
||||
#ifdef CVP_MINIDUMP_ENABLED
|
||||
#include <soc/qcom/minidump.h>
|
||||
|
||||
/*
|
||||
* wrapper for static minidump
|
||||
|
||||
* @name: Dump will be collected with this name
|
||||
* @virt: Virtual address of the buffer which needs to be dumped
|
||||
* @phys: Physical address of the buffer which needs to be dumped
|
||||
* @size: Size of the buffer which needs to be dumped
|
||||
*/
|
||||
int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size);
|
||||
|
||||
/*
|
||||
* Fucntion to add dump region to queue
|
||||
|
||||
* @type: Type of the list node which needs to be updated
|
||||
* @buff_va: Virtual address of the buffer which needs to be dumped
|
||||
* @buff_size: Size of the buffer which needs to be dumped
|
||||
* @region_name: Dump will be collected with this name
|
||||
* @copy: Flag to indicate if the buffer data needs to be copied
|
||||
* to the intermidiate buffer allocated by kzmalloc.
|
||||
*/
|
||||
void add_va_node_to_list(enum cvp_dump_type type, void *buff_va,
|
||||
u32 buff_size, const char *region_name, bool copy);
|
||||
|
||||
/*
|
||||
* Registers subsystem to minidump driver
|
||||
|
||||
* @name: Subsytem name which will get registered
|
||||
* @notf_blk_ptr: notifier block pointer.
|
||||
* notifier_call mentioned in this block will be triggered by
|
||||
* minidump driver in case of crash
|
||||
*/
|
||||
void cvp_va_md_register(char *name, void* notf_blk_ptr);
|
||||
|
||||
/* One function where we will register all the regions */
|
||||
void cvp_register_va_md_region(void);
|
||||
|
||||
/*
|
||||
* Free up the memory allocated for different va_md_list
|
||||
* Do not forget to add code for any new list in this function
|
||||
*/
|
||||
void cvp_free_va_md_list(void);
|
||||
|
||||
/* Adds the HFI queues(both for CPU and DSP) to the global hfi list head*/
|
||||
void add_hfi_queue_to_va_md_list(void *device);
|
||||
|
||||
/*Add queue header structures(both for CPU and DSP)
|
||||
to the global struct list head*/
|
||||
void add_queue_header_to_va_md_list(void *device);
|
||||
|
||||
/*
|
||||
* Node structure for VA_MD Linked List
|
||||
|
||||
* @list: linux kernel list implementation
|
||||
* @va_md_buff: Virtual address of the buffer which needs to be dumped
|
||||
* @va_md_buff_size: Size of the buffer which needs to be dumped
|
||||
* @region_name: Dump will be collected with this name
|
||||
* @copy: Flag to indicate if the buffer data needs to be copied
|
||||
* to the intermidiate buffer allocated by kzmalloc.
|
||||
*/
|
||||
struct eva_va_md_queue
|
||||
{
|
||||
struct list_head list;
|
||||
void *va_md_buff;
|
||||
u32 va_md_buff_size;
|
||||
char region_name[MAX_REGION_NAME_LEN];
|
||||
bool copy;
|
||||
};
|
||||
#else
|
||||
static inline int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void add_va_node_to_list(enum cvp_dump_type type, void *buff_va,
|
||||
u32 buff_size, const char *region_name, bool copy)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void cvp_va_md_register(char *name, void* notf_blk_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void cvp_register_va_md_region(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void cvp_free_va_md_list(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void add_hfi_queue_to_va_md_list(void *device)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void add_queue_header_to_va_md_list(void *device)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* End of CVP_MINIDUMP_ENABLED */
|
||||
#endif
|
150
qcom/opensource/eva-kernel/msm/eva/cvp_fw_load.c
Normal file
150
qcom/opensource/eva-kernel/msm/eva/cvp_fw_load.c
Normal file
@ -0,0 +1,150 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "cvp_comm_def.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
#include "cvp_hfi.h"
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
#include "cvp_dump.h"
|
||||
|
||||
#define MAX_FIRMWARE_NAME_SIZE 128
|
||||
|
||||
static int __load_fw_to_memory(struct platform_device *pdev,
|
||||
const char *fw_name)
|
||||
{
|
||||
int rc = 0;
|
||||
const struct firmware *firmware = NULL;
|
||||
char firmware_name[MAX_FIRMWARE_NAME_SIZE] = {0};
|
||||
struct device_node *node = NULL;
|
||||
struct resource res = {0};
|
||||
phys_addr_t phys = 0;
|
||||
size_t res_size = 0;
|
||||
ssize_t fw_size = 0;
|
||||
void *virt = NULL;
|
||||
int pas_id = 0;
|
||||
|
||||
if (!fw_name || !(*fw_name) || !pdev) {
|
||||
dprintk(CVP_ERR, "%s: Invalid inputs\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4) {
|
||||
dprintk(CVP_ERR, "%s: Invalid fw name\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
scnprintf(firmware_name, ARRAY_SIZE(firmware_name), "%s.mbn", fw_name);
|
||||
|
||||
rc = of_property_read_u32(pdev->dev.of_node, "pas-id", &pas_id);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: error %d while reading DT for \"pas-id\"\n",
|
||||
__func__, rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
|
||||
if (!node) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: DT error getting \"memory-region\" property\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_address_to_resource(node, 0, &res);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: error %d getting \"memory-region\" resource\n",
|
||||
__func__, rc);
|
||||
goto exit;
|
||||
}
|
||||
phys = res.start;
|
||||
res_size = (size_t)resource_size(&res);
|
||||
|
||||
rc = request_firmware(&firmware, firmware_name, &pdev->dev);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: error %d requesting \"%s\"\n",
|
||||
__func__, rc, firmware_name);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
fw_size = qcom_mdt_get_size(firmware);
|
||||
if (fw_size < 0 || res_size < (size_t)fw_size) {
|
||||
rc = -EINVAL;
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Corrupted fw image. Alloc size: %lu, fw size: %ld",
|
||||
__func__, res_size, fw_size);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
virt = memremap(phys, res_size, MEMREMAP_WC);
|
||||
if (!virt) {
|
||||
rc = -ENOMEM;
|
||||
dprintk(CVP_ERR, "%s: unable to remap firmware memory\n",
|
||||
__func__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = qcom_mdt_load(&pdev->dev, firmware, firmware_name,
|
||||
pas_id, virt, phys, res_size, NULL);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: error %d loading \"%s\"\n",
|
||||
__func__, rc, firmware_name);
|
||||
goto exit;
|
||||
}
|
||||
rc = qcom_scm_pas_auth_and_reset(pas_id);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: error %d authenticating \"%s\"\n",
|
||||
__func__, rc, firmware_name);
|
||||
goto exit;
|
||||
}
|
||||
rc = md_eva_dump("evafwdata", (uintptr_t)virt, phys, EVAFW_IMAGE_SIZE);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: error %d in dumping \"%s\"\n",
|
||||
__func__, rc, firmware_name);
|
||||
}
|
||||
|
||||
memunmap(virt);
|
||||
release_firmware(firmware);
|
||||
dprintk(CVP_CORE, "%s: firmware \"%s\" loaded successfully\n",
|
||||
__func__, firmware_name);
|
||||
return pas_id;
|
||||
|
||||
exit:
|
||||
if (virt)
|
||||
memunmap(virt);
|
||||
if (firmware)
|
||||
release_firmware(firmware);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int load_cvp_fw_impl(struct iris_hfi_device *device)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!device->resources.fw.cookie) {
|
||||
device->resources.fw.cookie =
|
||||
__load_fw_to_memory(device->res->pdev,
|
||||
device->res->fw_name);
|
||||
if (device->resources.fw.cookie <= 0) {
|
||||
dprintk(CVP_ERR, "Failed to download firmware\n");
|
||||
device->resources.fw.cookie = 0;
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int unload_cvp_fw_impl(struct iris_hfi_device *device)
|
||||
{
|
||||
qcom_scm_pas_shutdown(device->resources.fw.cookie);
|
||||
device->resources.fw.cookie = 0;
|
||||
return 0;
|
||||
}
|
5805
qcom/opensource/eva-kernel/msm/eva/cvp_hfi.c
Normal file
5805
qcom/opensource/eva-kernel/msm/eva/cvp_hfi.c
Normal file
File diff suppressed because it is too large
Load Diff
390
qcom/opensource/eva-kernel/msm/eva/cvp_hfi.h
Normal file
390
qcom/opensource/eva-kernel/msm/eva/cvp_hfi.h
Normal file
@ -0,0 +1,390 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __H_CVP_HFI_H__
|
||||
#define __H_CVP_HFI_H__
|
||||
|
||||
#include "cvp_hfi_helper.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
#define HFI_CMD_SESSION_CVP_START \
|
||||
(HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \
|
||||
HFI_CMD_START_OFFSET + 0x1000)
|
||||
|
||||
#define HFI_CMD_SESSION_CVP_SET_BUFFERS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x001)
|
||||
#define HFI_CMD_SESSION_CVP_RELEASE_BUFFERS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x002)
|
||||
|
||||
#define HFI_CMD_SESSION_CVP_DS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x003)
|
||||
#define HFI_CMD_SESSION_CVP_HCD_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x004)
|
||||
#define HFI_CMD_SESSION_CVP_HCD_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x005)
|
||||
#define HFI_CMD_SESSION_CVP_CV_HOG_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x006)
|
||||
#define HFI_CMD_SESSION_CVP_CV_HOG_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x007)
|
||||
#define HFI_CMD_SESSION_CVP_SVM\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x008)
|
||||
#define HFI_CMD_SESSION_CVP_NCC_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x009)
|
||||
#define HFI_CMD_SESSION_CVP_NCC_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x00A)
|
||||
#define HFI_CMD_SESSION_CVP_DFS_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x00B)
|
||||
#define HFI_CMD_SESSION_CVP_DFS_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x00C)
|
||||
#define HFI_CMD_SESSION_CVP_FTEXT\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x00F)
|
||||
|
||||
/* ==========CHAINED OPERATIONS===================*/
|
||||
#define HFI_CMD_SESSION_CVP_CV_HOG_SVM_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x010)
|
||||
#define HFI_CMD_SESSION_CVP_CV_HOG_SVM_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x011)
|
||||
#define HFI_CMD_SESSION_CVP_CV_HOG_SVM_HCD_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x012)
|
||||
#define HFI_CMD_SESSION_CVP_CV_HOG_SVM_HCD_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x013)
|
||||
#define HFI_CMD_SESSION_CVP_OPTICAL_FLOW\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x014)
|
||||
|
||||
/* ===========USECASE OPERATIONS===============*/
|
||||
#define HFI_CMD_SESSION_CVP_DC_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x030)
|
||||
#define HFI_CMD_SESSION_CVP_DC_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x031)
|
||||
#define HFI_CMD_SESSION_CVP_DCM_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x034)
|
||||
#define HFI_CMD_SESSION_CVP_DCM_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x035)
|
||||
|
||||
#define HFI_CMD_SESSION_CVP_DME_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x039)
|
||||
#define HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x03B)
|
||||
#define HFI_CMD_SESSION_CVP_DME_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x03A)
|
||||
|
||||
#define HFI_CMD_SESSION_EVA_DME_ONLY_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x040)
|
||||
#define HFI_CMD_SESSION_EVA_DME_ONLY_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x041)
|
||||
|
||||
#define HFI_CMD_SESSION_CVP_CV_TME_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x047)
|
||||
#define HFI_CMD_SESSION_CVP_CV_TME_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x048)
|
||||
#define HFI_CMD_SESSION_CVP_CV_OD_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x049)
|
||||
#define HFI_CMD_SESSION_CVP_CV_OD_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x04A)
|
||||
#define HFI_CMD_SESSION_CVP_CV_ODT_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x04B)
|
||||
#define HFI_CMD_SESSION_CVP_CV_ODT_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x04C)
|
||||
|
||||
#define HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x04D)
|
||||
#define HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x050)
|
||||
#define HFI_CMD_SESSION_CVP_PYS_HCD_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x051)
|
||||
#define HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x052)
|
||||
#define HFI_CMD_SESSION_CVP_FD_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x053)
|
||||
#define HFI_CMD_SESSION_CVP_FD_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x054)
|
||||
#define HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x055)
|
||||
#define HFI_CMD_SESSION_CVP_RELEASE_MODEL_BUFFERS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x056)
|
||||
#define HFI_CMD_SESSION_CVP_SGM_DFS_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x057)
|
||||
#define HFI_CMD_SESSION_CVP_SGM_DFS_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x058)
|
||||
#define HFI_CMD_SESSION_CVP_SGM_OF_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x059)
|
||||
#define HFI_CMD_SESSION_CVP_SGM_OF_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x05A)
|
||||
#define HFI_CMD_SESSION_CVP_GCE_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x05B)
|
||||
#define HFI_CMD_SESSION_CVP_GCE_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x05C)
|
||||
#define HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x05D)
|
||||
#define HFI_CMD_SESSION_CVP_WARP_NCC_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x05E)
|
||||
#define HFI_CMD_SESSION_CVP_DMM_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x05F)
|
||||
#define HFI_CMD_SESSION_CVP_DMM_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x060)
|
||||
#define HFI_CMD_SESSION_CVP_FLUSH\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x061)
|
||||
#define HFI_CMD_SESSION_CVP_WARP_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x062)
|
||||
#define HFI_CMD_SESSION_CVP_WARP_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x063)
|
||||
#define HFI_CMD_SESSION_CVP_DMM_PARAMS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x064)
|
||||
#define HFI_CMD_SESSION_CVP_WARP_DS_PARAMS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x065)
|
||||
#define HFI_CMD_SESSION_CVP_XRA_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x066)
|
||||
#define HFI_CMD_SESSION_CVP_XRA_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x067)
|
||||
#define HFI_CMD_SESSION_CVP_XRA_BLOB_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x069)
|
||||
#define HFI_CMD_SESSION_CVP_XRA_BLOB_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x06A)
|
||||
#define HFI_CMD_SESSION_CVP_XRA_PATCH_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x06B)
|
||||
#define HFI_CMD_SESSION_CVP_XRA_PATCH_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x06C)
|
||||
#define HFI_CMD_SESSION_CVP_XRA_MATCH_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x06D)
|
||||
#define HFI_CMD_SESSION_CVP_XRA_MATCH_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x06E)
|
||||
|
||||
|
||||
#define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x070)
|
||||
#define HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x071)
|
||||
#define HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x072)
|
||||
#define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x073)
|
||||
#define HFI_CMD_SESSION_EVA_ITOF_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x078)
|
||||
#define HFI_CMD_SESSION_EVA_ITOF_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x079)
|
||||
#define HFI_CMD_SESSION_EVA_DLFD_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x07C)
|
||||
#define HFI_CMD_SESSION_EVA_DLFD_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x07D)
|
||||
#define HFI_CMD_SESSION_CVP_RGE_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x07E)
|
||||
#define HFI_CMD_SESSION_CVP_RGE_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x07F)
|
||||
#define HFI_CMD_SESSION_EVA_DLFL_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x080)
|
||||
#define HFI_CMD_SESSION_EVA_DLFL_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x081)
|
||||
#define HFI_CMD_SESSION_CVP_SYNX\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x086)
|
||||
#define HFI_CMD_SESSION_EVA_START\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x088)
|
||||
#define HFI_CMD_SESSION_EVA_STOP\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x089)
|
||||
#define HFI_CMD_SESSION_CVP_ICA_FRAME\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x100)
|
||||
#define HFI_CMD_SESSION_CVP_ICA_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x101)
|
||||
#define HFI_CMD_SESSION_CVP_DS_CONFIG\
|
||||
(HFI_CMD_SESSION_CVP_START + 0x02F)
|
||||
|
||||
|
||||
#define HFI_MSG_SESSION_CVP_START \
|
||||
(HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \
|
||||
HFI_MSG_START_OFFSET + 0x1000)
|
||||
|
||||
#define HFI_MSG_SESSION_CVP_SET_BUFFERS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x001)
|
||||
#define HFI_MSG_SESSION_CVP_RELEASE_BUFFERS \
|
||||
(HFI_MSG_SESSION_CVP_START + 0x002)
|
||||
#define HFI_MSG_SESSION_CVP_DS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x003)
|
||||
#define HFI_MSG_SESSION_CVP_HCD\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x004)
|
||||
#define HFI_MSG_SESSION_CVP_CV_HOG\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x005)
|
||||
#define HFI_MSG_SESSION_CVP_SVM\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x006)
|
||||
#define HFI_MSG_SESSION_CVP_NCC\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x007)
|
||||
#define HFI_MSG_SESSION_CVP_DFS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x008)
|
||||
#define HFI_MSG_SESSION_CVP_TME\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x009)
|
||||
#define HFI_MSG_SESSION_CVP_FTEXT\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x00A)
|
||||
|
||||
#define HFI_MSG_SESSION_CVP_ICA\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x014)
|
||||
|
||||
#define HFI_MSG_SESSION_CVP_DME\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x023)
|
||||
#define HFI_MSG_SESSION_EVA_DME_ONLY\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x050)
|
||||
#define HFI_MSG_SESSION_CVP_OPERATION_CONFIG (HFI_MSG_SESSION_CVP_START + 0x030)
|
||||
|
||||
#define HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x034)
|
||||
#define HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x036)
|
||||
#define HFI_MSG_SESSION_CVP_FD\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x037)
|
||||
#define HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x038)
|
||||
#define HFI_MSG_SESSION_CVP_RELEASE_MODEL_BUFFERS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x039)
|
||||
#define HFI_MSG_SESSION_CVP_SGM_OF\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x03A)
|
||||
#define HFI_MSG_SESSION_CVP_GCE\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x03B)
|
||||
#define HFI_MSG_SESSION_CVP_WARP_NCC\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x03C)
|
||||
#define HFI_MSG_SESSION_CVP_DMM\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x03D)
|
||||
#define HFI_MSG_SESSION_CVP_SGM_DFS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x03E)
|
||||
#define HFI_MSG_SESSION_CVP_WARP\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x03F)
|
||||
#define HFI_MSG_SESSION_CVP_DMM_PARAMS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x040)
|
||||
#define HFI_MSG_SESSION_CVP_WARP_DS_PARAMS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x041)
|
||||
#define HFI_MSG_SESSION_CVP_SET_SNAPSHOT_BUFFERS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x045)
|
||||
#define HFI_MSG_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x046)
|
||||
#define HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x047)
|
||||
|
||||
#define HFI_MSG_SESSION_CVP_FLUSH\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x004A)
|
||||
#define HFI_MSG_SESSION_EVA_START\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x0058)
|
||||
#define HFI_MSG_SESSION_EVA_STOP\
|
||||
(HFI_MSG_SESSION_CVP_START + 0x0059)
|
||||
|
||||
#define CVP_IFACEQ_MAX_PKT_SIZE 1024
|
||||
#define CVP_IFACEQ_MED_PKT_SIZE 768
|
||||
#define CVP_IFACEQ_MIN_PKT_SIZE 8
|
||||
#define CVP_IFACEQ_VAR_SMALL_PKT_SIZE 100
|
||||
#define CVP_IFACEQ_VAR_LARGE_PKT_SIZE 512
|
||||
#define CVP_IFACEQ_VAR_HUGE_PKT_SIZE (1024*12)
|
||||
|
||||
/* HFI packet info needed for sanity check */
|
||||
#define HFI_DFS_CONFIG_CMD_SIZE 38
|
||||
#define HFI_DFS_FRAME_CMD_SIZE 16
|
||||
|
||||
#define HFI_DMM_CONFIG_CMD_SIZE 194
|
||||
#define HFI_DMM_BASIC_CONFIG_CMD_SIZE 51
|
||||
#define HFI_DMM_FRAME_CMD_SIZE 28
|
||||
|
||||
#define HFI_PERSIST_CMD_SIZE 11
|
||||
|
||||
#define HFI_DS_CONFIG_CMD_SIZE 11
|
||||
#define HFI_DS_CMD_SIZE 50
|
||||
|
||||
#define HFI_OF_CONFIG_CMD_SIZE 34
|
||||
#define HFI_OF_FRAME_CMD_SIZE 24
|
||||
|
||||
#define HFI_ODT_CONFIG_CMD_SIZE 23
|
||||
#define HFI_ODT_FRAME_CMD_SIZE 33
|
||||
|
||||
#define HFI_OD_CONFIG_CMD_SIZE 24
|
||||
#define HFI_OD_FRAME_CMD_SIZE 12
|
||||
|
||||
#define HFI_NCC_CONFIG_CMD_SIZE 47
|
||||
#define HFI_NCC_FRAME_CMD_SIZE 22
|
||||
|
||||
#define HFI_ICA_CONFIG_CMD_SIZE 127
|
||||
#define HFI_ICA_FRAME_CMD_SIZE 14
|
||||
|
||||
#define HFI_HCD_CONFIG_CMD_SIZE 46
|
||||
#define HFI_HCD_FRAME_CMD_SIZE 18
|
||||
|
||||
#define HFI_DCM_CONFIG_CMD_SIZE 20
|
||||
#define HFI_DCM_FRAME_CMD_SIZE 19
|
||||
|
||||
#define HFI_PYS_HCD_CONFIG_CMD_SIZE 461
|
||||
#define HFI_PYS_HCD_FRAME_CMD_SIZE 66
|
||||
|
||||
#define HFI_FD_CONFIG_CMD_SIZE 28
|
||||
#define HFI_FD_FRAME_CMD_SIZE 10
|
||||
|
||||
|
||||
struct cvp_hfi_cmd_session_flush_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 flush_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_session_get_property_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_sys_session_abort_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_sys_property_info_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[128];
|
||||
};
|
||||
|
||||
enum session_flags {
|
||||
SESSION_PAUSE = BIT(1),
|
||||
};
|
||||
|
||||
struct cvp_hal_session {
|
||||
struct list_head list;
|
||||
void *session_id;
|
||||
u32 flags;
|
||||
void *device;
|
||||
};
|
||||
|
||||
enum buf_map_type {
|
||||
MAP_PERSIST = 1,
|
||||
UNMAP_PERSIST = 2,
|
||||
MAP_FRAME = 3,
|
||||
MAP_INVALID,
|
||||
};
|
||||
|
||||
static inline enum buf_map_type cvp_find_map_type(int pkt_type)
|
||||
{
|
||||
if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS ||
|
||||
pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS ||
|
||||
pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS ||
|
||||
pkt_type == HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS ||
|
||||
pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS ||
|
||||
pkt_type == HFI_CMD_SESSION_EVA_DLFL_CONFIG)
|
||||
return MAP_PERSIST;
|
||||
else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS ||
|
||||
pkt_type ==
|
||||
HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS)
|
||||
return UNMAP_PERSIST;
|
||||
else
|
||||
return MAP_FRAME;
|
||||
}
|
||||
|
||||
static inline bool is_params_pkt(int pkt_type)
|
||||
{
|
||||
if (pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS ||
|
||||
pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
317
qcom/opensource/eva-kernel/msm/eva/cvp_hfi_api.h
Normal file
317
qcom/opensource/eva-kernel/msm/eva/cvp_hfi_api.h
Normal file
@ -0,0 +1,317 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __CVP_HFI_API_H__
|
||||
#define __CVP_HFI_API_H__
|
||||
|
||||
#include <linux/log2.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/hash.h>
|
||||
#include "msm_cvp_core.h"
|
||||
#include "msm_cvp_resources.h"
|
||||
#include "cvp_hfi_helper.h"
|
||||
|
||||
#define CONTAINS(__a, __sz, __t) (\
|
||||
(__t >= __a) && \
|
||||
(__t < __a + __sz) \
|
||||
)
|
||||
|
||||
#define OVERLAPS(__t, __tsz, __a, __asz) (\
|
||||
(__t <= __a) && \
|
||||
(__t + __tsz >= __a + __asz) \
|
||||
)
|
||||
|
||||
#define CVP_VERSION_LENGTH 128
|
||||
|
||||
/* 16 encoder and 16 decoder sessions */
|
||||
#define CVP_MAX_SESSIONS 32
|
||||
|
||||
#define HFI_VERSION_MAJOR_MASK 0xFF000000
|
||||
#define HFI_VERSION_MAJOR_SHFIT 24
|
||||
#define HFI_VERSION_MINOR_MASK 0x00FFFFE0
|
||||
#define HFI_VERSION_MINOR_SHIFT 5
|
||||
#define HFI_VERSION_BRANCH_MASK 0x0000001F
|
||||
#define HFI_VERSION_BRANCH_SHIFT 0
|
||||
|
||||
enum cvp_status {
|
||||
CVP_ERR_NONE = 0x0,
|
||||
CVP_ERR_FAIL = 0x80000000,
|
||||
CVP_ERR_ALLOC_FAIL,
|
||||
CVP_ERR_ILLEGAL_OP,
|
||||
CVP_ERR_BAD_PARAM,
|
||||
CVP_ERR_BAD_HANDLE,
|
||||
CVP_ERR_NOT_SUPPORTED,
|
||||
CVP_ERR_BAD_STATE,
|
||||
CVP_ERR_MAX_CLIENTS,
|
||||
CVP_ERR_IFRAME_EXPECTED,
|
||||
CVP_ERR_HW_FATAL,
|
||||
CVP_ERR_BITSTREAM_ERR,
|
||||
CVP_ERR_INDEX_NOMORE,
|
||||
CVP_ERR_SEQHDR_PARSE_FAIL,
|
||||
CVP_ERR_INSUFFICIENT_BUFFER,
|
||||
CVP_ERR_BAD_POWER_STATE,
|
||||
CVP_ERR_NO_VALID_SESSION,
|
||||
CVP_ERR_TIMEOUT,
|
||||
CVP_ERR_CMDQFULL,
|
||||
CVP_ERR_START_CODE_NOT_FOUND,
|
||||
CVP_ERR_NOC_ERROR,
|
||||
CVP_ERR_CLIENT_PRESENT = 0x90000001,
|
||||
CVP_ERR_CLIENT_FATAL,
|
||||
CVP_ERR_CMD_QUEUE_FULL,
|
||||
CVP_ERR_UNUSED = 0x10000000
|
||||
};
|
||||
|
||||
enum hal_property {
|
||||
HAL_UNUSED_PROPERTY = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
enum hal_ssr_trigger_type {
|
||||
SSR_ERR_FATAL = 1,
|
||||
SSR_SW_DIV_BY_ZERO,
|
||||
SSR_HW_WDOG_IRQ,
|
||||
SSR_SESSION_ABORT,
|
||||
};
|
||||
|
||||
enum hal_intra_refresh_mode {
|
||||
HAL_INTRA_REFRESH_NONE,
|
||||
HAL_INTRA_REFRESH_CYCLIC,
|
||||
HAL_INTRA_REFRESH_RANDOM,
|
||||
HAL_UNUSED_INTRA = 0x10000000,
|
||||
};
|
||||
|
||||
enum cvp_resource_id {
|
||||
CVP_RESOURCE_NONE,
|
||||
CVP_RESOURCE_SYSCACHE,
|
||||
CVP_UNUSED_RESOURCE = 0x10000000,
|
||||
};
|
||||
|
||||
struct cvp_resource_hdr {
|
||||
enum cvp_resource_id resource_id;
|
||||
void *resource_handle;
|
||||
};
|
||||
|
||||
struct cvp_hal_fw_info {
|
||||
char version[CVP_VERSION_LENGTH];
|
||||
phys_addr_t base_addr;
|
||||
int register_base;
|
||||
int register_size;
|
||||
int irq;
|
||||
};
|
||||
|
||||
enum hal_event_type {
|
||||
HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES,
|
||||
HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES,
|
||||
HAL_EVENT_RELEASE_BUFFER_REFERENCE,
|
||||
HAL_UNUSED_SEQCHG = 0x10000000,
|
||||
};
|
||||
|
||||
/* HAL Response */
|
||||
#define IS_HAL_SYS_CMD(cmd) ((cmd) >= HAL_SYS_INIT_DONE && \
|
||||
(cmd) <= HAL_SYS_ERROR)
|
||||
#define IS_HAL_SESSION_CMD(cmd) ((cmd) >= HAL_SESSION_EVENT_CHANGE && \
|
||||
(cmd) <= HAL_SESSION_ERROR)
|
||||
enum hal_command_response {
|
||||
HAL_NO_RESP,
|
||||
HAL_SYS_INIT_DONE,
|
||||
HAL_SYS_SET_RESOURCE_DONE,
|
||||
HAL_SYS_RELEASE_RESOURCE_DONE,
|
||||
HAL_SYS_PING_ACK_DONE,
|
||||
HAL_SYS_PC_PREP_DONE,
|
||||
HAL_SYS_IDLE,
|
||||
HAL_SYS_DEBUG,
|
||||
HAL_SYS_WATCHDOG_TIMEOUT,
|
||||
HAL_SYS_ERROR,
|
||||
/* SESSION COMMANDS_DONE */
|
||||
HAL_SESSION_EVENT_CHANGE,
|
||||
HAL_SESSION_INIT_DONE,
|
||||
HAL_SESSION_END_DONE,
|
||||
HAL_SESSION_SET_BUFFER_DONE,
|
||||
HAL_SESSION_ABORT_DONE,
|
||||
HAL_SESSION_START_DONE,
|
||||
HAL_SESSION_STOP_DONE,
|
||||
HAL_SESSION_CVP_OPERATION_CONFIG,
|
||||
HAL_SESSION_FLUSH_DONE,
|
||||
HAL_SESSION_SUSPEND_DONE,
|
||||
HAL_SESSION_RESUME_DONE,
|
||||
HAL_SESSION_SET_PROP_DONE,
|
||||
HAL_SESSION_GET_PROP_DONE,
|
||||
HAL_SESSION_RELEASE_BUFFER_DONE,
|
||||
HAL_SESSION_REGISTER_BUFFER_DONE,
|
||||
HAL_SESSION_UNREGISTER_BUFFER_DONE,
|
||||
HAL_SESSION_RELEASE_RESOURCE_DONE,
|
||||
HAL_SESSION_PROPERTY_INFO,
|
||||
HAL_SESSION_DUMP_NOTIFY,
|
||||
HAL_SESSION_ERROR,
|
||||
HAL_RESPONSE_UNUSED = 0x10000000,
|
||||
};
|
||||
|
||||
struct msm_cvp_capability {
|
||||
u32 reserved[183];
|
||||
};
|
||||
|
||||
struct cvp_hal_sys_init_done {
|
||||
u32 dec_codec_supported;
|
||||
u32 enc_codec_supported;
|
||||
u32 codec_count;
|
||||
struct msm_cvp_capability *capabilities;
|
||||
u32 max_sessions_supported;
|
||||
};
|
||||
|
||||
struct cvp_hal_session_init_done {
|
||||
struct msm_cvp_capability capability;
|
||||
};
|
||||
|
||||
struct msm_cvp_cb_cmd_done {
|
||||
u32 device_id;
|
||||
void *session_id;
|
||||
enum cvp_status status;
|
||||
u32 size;
|
||||
union {
|
||||
struct cvp_hfi_msg_session_hdr msg_hdr;
|
||||
struct cvp_resource_hdr resource_hdr;
|
||||
struct cvp_hal_sys_init_done sys_init_done;
|
||||
struct cvp_hal_session_init_done session_init_done;
|
||||
u32 buffer_addr;
|
||||
} data;
|
||||
};
|
||||
|
||||
struct msm_cvp_cb_data_done {
|
||||
u32 device_id;
|
||||
void *session_id;
|
||||
enum cvp_status status;
|
||||
u32 size;
|
||||
u32 client_data;
|
||||
};
|
||||
|
||||
struct msm_cvp_cb_info {
|
||||
enum hal_command_response response_type;
|
||||
union {
|
||||
struct msm_cvp_cb_cmd_done cmd;
|
||||
struct msm_cvp_cb_data_done data;
|
||||
} response;
|
||||
};
|
||||
|
||||
enum msm_cvp_hfi_type {
|
||||
CVP_HFI_IRIS,
|
||||
};
|
||||
|
||||
enum msm_cvp_thermal_level {
|
||||
CVP_THERMAL_NORMAL = 0,
|
||||
CVP_THERMAL_LOW,
|
||||
CVP_THERMAL_HIGH,
|
||||
CVP_THERMAL_CRITICAL
|
||||
};
|
||||
|
||||
struct msm_cvp_gov_data {
|
||||
struct cvp_bus_vote_data *data;
|
||||
u32 data_count;
|
||||
};
|
||||
|
||||
enum msm_cvp_power_mode {
|
||||
CVP_POWER_NORMAL = 0,
|
||||
CVP_POWER_LOW,
|
||||
CVP_POWER_TURBO
|
||||
};
|
||||
|
||||
struct cvp_bus_vote_data {
|
||||
u32 domain;
|
||||
u32 ddr_bw;
|
||||
u32 sys_cache_bw;
|
||||
enum msm_cvp_power_mode power_mode;
|
||||
bool use_sys_cache;
|
||||
};
|
||||
|
||||
struct cvp_hal_cmd_sys_get_property_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
#define call_hfi_op(q, op, args...) \
|
||||
(((q) && (q)->op) ? ((q)->op(args)) : 0)
|
||||
|
||||
#define PKT_NAME_LEN 24
|
||||
#define MAX_PKT_IDX 0x200
|
||||
|
||||
struct msm_cvp_hfi_defs {
|
||||
unsigned int size;
|
||||
unsigned int type;
|
||||
bool is_config_pkt;
|
||||
bool checksum_enabled;
|
||||
enum hal_command_response resp;
|
||||
char name[PKT_NAME_LEN];
|
||||
bool force_kernel_fence;
|
||||
};
|
||||
|
||||
struct cvp_hfi_ops {
|
||||
void *hfi_device_data;
|
||||
/*Add function pointers for all the hfi functions below*/
|
||||
int (*core_init)(void *device);
|
||||
int (*core_release)(void *device);
|
||||
int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type);
|
||||
int (*session_init)(void *device, void *session_id, void **new_session);
|
||||
int (*session_end)(void *session);
|
||||
int (*session_start)(void *session);
|
||||
int (*session_stop)(void *session);
|
||||
int (*session_abort)(void *session);
|
||||
int (*session_set_buffers)(void *sess, u32 iova, u32 size);
|
||||
int (*session_release_buffers)(void *sess);
|
||||
int (*session_send)(void *sess, struct eva_kmd_hfi_packet *in_pkt);
|
||||
int (*session_flush)(void *sess);
|
||||
int (*scale_clocks)(void *dev, u32 freq);
|
||||
int (*vote_bus)(void *dev, struct bus_info *bus, unsigned long bw);
|
||||
int (*get_fw_info)(void *dev, struct cvp_hal_fw_info *fw_info);
|
||||
int (*session_clean)(void *sess);
|
||||
int (*get_core_capabilities)(void *dev);
|
||||
int (*suspend)(void *dev);
|
||||
int (*resume)(void *dev);
|
||||
int (*flush_debug_queue)(void *dev);
|
||||
int (*noc_error_info)(void *dev);
|
||||
int (*validate_session)(void *sess, const char *func);
|
||||
int (*pm_qos_update)(void *device);
|
||||
int (*debug_hook)(void *device);
|
||||
};
|
||||
|
||||
typedef void (*hfi_cmd_response_callback) (enum hal_command_response cmd,
|
||||
void *data);
|
||||
typedef void (*msm_cvp_callback) (enum hal_command_response response,
|
||||
void *callback);
|
||||
struct msm_cvp_fw {
|
||||
int cookie;
|
||||
};
|
||||
|
||||
int cvp_hfi_process_msg_packet(u32 device_id,
|
||||
void *msg_hdr, struct msm_cvp_cb_info *info);
|
||||
|
||||
enum cvp_status cvp_hfi_process_sys_init_done_prop_read(
|
||||
struct cvp_hfi_msg_sys_init_done_packet *pkt,
|
||||
struct cvp_hal_sys_init_done *sys_init_done);
|
||||
|
||||
enum cvp_status hfi_process_session_init_done_prop_read(
|
||||
struct cvp_hfi_msg_sys_session_init_done_packet *pkt,
|
||||
struct cvp_hal_session_init_done *session_init_done);
|
||||
|
||||
struct cvp_hfi_ops *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type,
|
||||
struct msm_cvp_platform_resources *res,
|
||||
hfi_cmd_response_callback callback);
|
||||
void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type,
|
||||
struct cvp_hfi_ops *hdev);
|
||||
|
||||
int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr);
|
||||
int get_pkt_fenceoverride(struct cvp_hal_session_cmd_pkt* hdr);
|
||||
int get_pkt_index_from_type(u32 pkt_type);
|
||||
int get_hfi_version(void);
|
||||
unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr);
|
||||
unsigned int get_msg_session_id(void *msg);
|
||||
unsigned int get_msg_errorcode(void *msg);
|
||||
int get_msg_opconfigs(void *msg, unsigned int *session_id,
|
||||
unsigned int *error_type, unsigned int *config_id);
|
||||
extern const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX];
|
||||
void print_hfi_queue_info(struct cvp_hfi_ops *hdev);
|
||||
#endif /*__CVP_HFI_API_H__ */
|
511
qcom/opensource/eva-kernel/msm/eva/cvp_hfi_helper.h
Normal file
511
qcom/opensource/eva-kernel/msm/eva/cvp_hfi_helper.h
Normal file
@ -0,0 +1,511 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cvp_comm_def.h"
|
||||
#ifndef __H_CVP_HFI_HELPER_H__
|
||||
#define __H_CVP_HFI_HELPER_H__
|
||||
|
||||
#define HFI_COMMON_BASE (0)
|
||||
#define HFI_DOMAIN_BASE_COMMON (HFI_COMMON_BASE + 0)
|
||||
#define HFI_DOMAIN_BASE_CVP (HFI_COMMON_BASE + 0x04000000)
|
||||
|
||||
#define HFI_ARCH_COMMON_OFFSET (0)
|
||||
|
||||
#define HFI_CMD_START_OFFSET (0x00010000)
|
||||
#define HFI_MSG_START_OFFSET (0x00020000)
|
||||
|
||||
#define HFI_ERR_NONE (HFI_COMMON_BASE) /**< Status: No error */
|
||||
#define HFI_ERR_SYS_FATAL (HFI_COMMON_BASE + 0x1) /**< Fatal system error */
|
||||
#define HFI_ERR_SYS_INVALID_PARAMETER (HFI_COMMON_BASE + 0x2) /**< Invalid system parameter encountered */
|
||||
#define HFI_ERR_SYS_VERSION_MISMATCH (HFI_COMMON_BASE + 0x3) /**< Interface version mismatch */
|
||||
#define HFI_ERR_SYS_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x4) /**< Insufficient system resources */
|
||||
#define HFI_ERR_SYS_MAX_SESSIONS_REACHED (HFI_COMMON_BASE + 0x5) /**< Maximum number of sessions reached */
|
||||
#define HFI_ERR_SYS_SESSION_IN_USE (HFI_COMMON_BASE + 0x7) /**< Session ID specified is in use */
|
||||
#define HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE (HFI_COMMON_BASE + 0x8) /**< ID is out of range */
|
||||
#define HFI_ERR_SYS_UNSUPPORTED_TRIGCMD (HFI_COMMON_BASE + 0xA) /**< Unsupported TRIGCMD command*/
|
||||
#define HFI_ERR_SYS_UNSUPPORTED_RESOURCES (HFI_COMMON_BASE + 0xB) /**< Unsupported resource*/
|
||||
#define HFI_ERR_SYS_UNSUPPORT_CMD (HFI_COMMON_BASE + 0xC) /**< Command is not supported*/
|
||||
#define HFI_ERR_SYS_CMDSIZE (HFI_COMMON_BASE + 0xD) /**< command size err*/
|
||||
#define HFI_ERR_SYS_UNSUPPORT_PROPERTY (HFI_COMMON_BASE + 0xE) /**< Unsupported property*/
|
||||
#define HFI_ERR_SYS_INIT_EXPECTED (HFI_COMMON_BASE + 0xF) /**< Upon FW start, first command must be SYS_INIT*/
|
||||
#define HFI_ERR_SYS_INIT_IGNORED (HFI_COMMON_BASE + 0x10) /**< After FW started, SYS_INIT will be ignored*/
|
||||
#define HFI_ERR_SYS_MAX_DME_SESSIONS_REACHED (HFI_COMMON_BASE + 0x11) /**< Maximum DME sessions Reached */
|
||||
#define HFI_ERR_SYS_MAX_FD_SESSIONS_REACHED (HFI_COMMON_BASE + 0x12) /**< Maximum FD sessions Reached */
|
||||
#define HFI_ERR_SYS_MAX_ODT_SESSIONS_REACHED (HFI_COMMON_BASE + 0x13) /**< Maximum ODT sessions Reached*/
|
||||
#define HFI_ERR_SYS_MAX_CV_SESSIONS_REACHED (HFI_COMMON_BASE + 0x14) /**< Maximum CV sessions Reached*/
|
||||
#define HFI_ERR_SYS_INVALID_SESSION_TYPE (HFI_COMMON_BASE + 0x15) /**< Invalid session TYPE. */
|
||||
#define HFI_ERR_SYS_NOC_ERROR (HFI_COMMON_BASE + 0x16) /**< NOC Error encountered */
|
||||
|
||||
/**
|
||||
Level 2 Comment: "Session Level Error types"
|
||||
Common HFI_ERROR_SESSION_X values to be used as session level error/warning
|
||||
for event and messages
|
||||
*/
|
||||
#define HFI_ERR_SESSION_FATAL (HFI_COMMON_BASE + 0x1001) /**< Fatal session error */
|
||||
#define HFI_ERR_SESSION_INVALID_PARAMETER (HFI_COMMON_BASE + 0x1002) /**< Invalid session parameter */
|
||||
#define HFI_ERR_SESSION_BAD_POINTER (HFI_COMMON_BASE + 0x1003) /**< Bad pointer encountered */
|
||||
#define HFI_ERR_SESSION_INVALID_SESSION_ID (HFI_COMMON_BASE + 0x1004) /**< Invalid session ID. eventData2 specifies the session ID. */
|
||||
#define HFI_ERR_SESSION_INVALID_STREAM_ID (HFI_COMMON_BASE + 0x1005) /**< Invalid stream ID. eventData2 specifies the stream ID. */
|
||||
#define HFI_ERR_SESSION_INCORRECT_STATE_OPERATION (HFI_COMMON_BASE + 0x1006) /**< Incorrect state for specified operation */
|
||||
#define HFI_ERR_SESSION_UNSUPPORTED_PROPERTY (HFI_COMMON_BASE + 0x1007) /**< Unsupported property. eventData2 specifies the property index. */
|
||||
#define HFI_ERR_SESSION_UNSUPPORTED_SETTING (HFI_COMMON_BASE + 0x1008) /**< Unsupported property setting. eventData2 specifies the property index. */
|
||||
#define HFI_ERR_SESSION_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x1009) /**< Insufficient resources for session */
|
||||
#define HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED (HFI_COMMON_BASE + 0x100A) /**< Stream is found to be corrupt; processing is stalled */
|
||||
#define HFI_ERR_SESSION_STREAM_CORRUPT (HFI_COMMON_BASE + 0x100B) /**< Stream is found to be corrupt; processing is recoverable */
|
||||
#define HFI_ERR_SESSION_RESERVED (HFI_COMMON_BASE + 0x100C) /**< Reserved */
|
||||
#define HFI_ERR_SESSION_UNSUPPORTED_STREAM (HFI_COMMON_BASE + 0x100D) /**< Unsupported stream */
|
||||
#define HFI_ERR_SESSION_CMDSIZE (HFI_COMMON_BASE + 0x100E) /**< Command packet size err*/
|
||||
#define HFI_ERR_SESSION_UNSUPPORT_CMD (HFI_COMMON_BASE + 0x100F) /**< Command is not supported*/
|
||||
#define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE (HFI_COMMON_BASE + 0x1010) /**< BufferType is not supported*/
|
||||
#define HFI_ERR_SESSION_BUFFERCOUNT_TOOSMALL (HFI_COMMON_BASE + 0x1011) /**< Buffer Count is less than default*/
|
||||
#define HFI_ERR_SESSION_INVALID_SCALE_FACTOR (HFI_COMMON_BASE + 0x1012) /**< Downscaling not possible */
|
||||
#define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED (HFI_COMMON_BASE + 0x1013) /**< Upscaling not possible */
|
||||
#define HFI_ERR_SESSION_CANNOT_KEEP_ASPECT_RATIO (HFI_COMMON_BASE + 0x1014) /**< Cannot maintain aspect ratio */
|
||||
#define HFI_ERR_SESSION_ADDRESS_NOT_ALIGNED (HFI_COMMON_BASE + 0x1016) /**Address is not aligned */
|
||||
#define HFI_ERR_SESSION_BUFFERSIZE_TOOSMALL (HFI_COMMON_BASE + 0x1017) /**< Buffer Count is less than default*/
|
||||
#define HFI_ERR_SESSION_ABORTED (HFI_COMMON_BASE + 0x1018) /**< error caused by session abort*/
|
||||
#define HFI_ERR_SESSION_BUFFER_ALREADY_SET (HFI_COMMON_BASE + 0x1019) /**< Cannot set buffer multiple times without releasing in between. */
|
||||
#define HFI_ERR_SESSION_BUFFER_ALREADY_RELEASED (HFI_COMMON_BASE + 0x101A) /**< Cannot release buffer multiple times without setting in between. */
|
||||
#define HFI_ERR_SESSION_END_BUFFER_NOT_RELEASED (HFI_COMMON_BASE + 0x101B) /**< Session was ended without properly releasing all buffers */
|
||||
#define HFI_ERR_SESSION_FLUSHED (HFI_COMMON_BASE + 0x101C) /**< Cannot set buffer multiple times without releasing in between. */
|
||||
#define HFI_ERR_SESSION_KERNEL_MAX_STREAMS_REACHED (HFI_COMMON_BASE + 0x101D) /*Maximum Streams per Kernel reached in a session*/
|
||||
#define HFI_ERR_SESSION_MAX_STREAMS_REACHED (HFI_COMMON_BASE + 0x101E) /*Maximum Streams Reached in a session*/
|
||||
#define HFI_ERR_SESSION_HW_HANG_DETECTED (HFI_COMMON_BASE + 0x101F) /*HW hang was detected in one of the HW blocks for a frame*/
|
||||
|
||||
#define HFI_EVENT_SYS_ERROR (HFI_COMMON_BASE + 0x1)
|
||||
#define HFI_EVENT_SESSION_ERROR (HFI_COMMON_BASE + 0x2)
|
||||
|
||||
#define HFI_TME_PROFILE_DEFAULT 0x00000001
|
||||
#define HFI_TME_PROFILE_FRC 0x00000002
|
||||
#define HFI_TME_PROFILE_ASW 0x00000004
|
||||
#define HFI_TME_PROFILE_DFS_BOKEH 0x00000008
|
||||
|
||||
#define HFI_TME_LEVEL_INTEGER 0x00000001
|
||||
|
||||
#define HFI_BUFFER_INPUT (HFI_COMMON_BASE + 0x1)
|
||||
#define HFI_BUFFER_OUTPUT (HFI_COMMON_BASE + 0x2)
|
||||
#define HFI_BUFFER_OUTPUT2 (HFI_COMMON_BASE + 0x3)
|
||||
#define HFI_BUFFER_INTERNAL_PERSIST (HFI_COMMON_BASE + 0x4)
|
||||
#define HFI_BUFFER_INTERNAL_PERSIST_1 (HFI_COMMON_BASE + 0x5)
|
||||
#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH (HFI_COMMON_BASE + 0x6)
|
||||
#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1 (HFI_COMMON_BASE + 0x7)
|
||||
#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2 (HFI_COMMON_BASE + 0x8)
|
||||
#define HFI_BUFFER_COMMON_INTERNAL_RECON (HFI_COMMON_BASE + 0x9)
|
||||
#define HFI_BUFFER_EXTRADATA_OUTPUT (HFI_COMMON_BASE + 0xA)
|
||||
#define HFI_BUFFER_EXTRADATA_OUTPUT2 (HFI_COMMON_BASE + 0xB)
|
||||
#define HFI_BUFFER_EXTRADATA_INPUT (HFI_COMMON_BASE + 0xC)
|
||||
|
||||
|
||||
#define HFI_PROPERTY_SYS_COMMON_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x0000)
|
||||
#define HFI_PROPERTY_SYS_DEBUG_CONFIG \
|
||||
(HFI_PROPERTY_SYS_COMMON_START + 0x001)
|
||||
#define HFI_PROPERTY_SYS_RESOURCE_OCMEM_REQUIREMENT_INFO \
|
||||
(HFI_PROPERTY_SYS_COMMON_START + 0x002)
|
||||
#define HFI_PROPERTY_SYS_CONFIG_VCODEC_CLKFREQ \
|
||||
(HFI_PROPERTY_SYS_COMMON_START + 0x003)
|
||||
#define HFI_PROPERTY_SYS_IDLE_INDICATOR \
|
||||
(HFI_PROPERTY_SYS_COMMON_START + 0x004)
|
||||
#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL \
|
||||
(HFI_PROPERTY_SYS_COMMON_START + 0x005)
|
||||
#define HFI_PROPERTY_SYS_IMAGE_VERSION \
|
||||
(HFI_PROPERTY_SYS_COMMON_START + 0x006)
|
||||
#define HFI_PROPERTY_SYS_CONFIG_COVERAGE \
|
||||
(HFI_PROPERTY_SYS_COMMON_START + 0x007)
|
||||
#define HFI_PROPERTY_SYS_UBWC_CONFIG \
|
||||
(HFI_PROPERTY_SYS_COMMON_START + 0x008)
|
||||
|
||||
#define HFI_DEBUG_MSG_LOW 0x00000001
|
||||
#define HFI_DEBUG_MSG_MEDIUM 0x00000002
|
||||
#define HFI_DEBUG_MSG_HIGH 0x00000004
|
||||
#define HFI_DEBUG_MSG_ERROR 0x00000008
|
||||
#define HFI_DEBUG_MSG_FATAL 0x00000010
|
||||
#define HFI_DEBUG_MSG_PERF 0x00000020
|
||||
|
||||
#define HFI_DEBUG_MODE_QUEUE 0x00000001
|
||||
#define HFI_DEBUG_MODE_QDSS 0x00000002
|
||||
|
||||
struct cvp_hfi_debug_config {
|
||||
u32 debug_config;
|
||||
u32 debug_mode;
|
||||
};
|
||||
|
||||
struct cvp_hfi_enable {
|
||||
u32 enable;
|
||||
};
|
||||
|
||||
#define HFI_RESOURCE_SYSCACHE 0x00000002
|
||||
|
||||
struct cvp_hfi_resource_subcache_type {
|
||||
u32 size;
|
||||
u32 sc_id;
|
||||
};
|
||||
|
||||
struct cvp_hfi_resource_syscache_info_type {
|
||||
u32 num_entries;
|
||||
struct cvp_hfi_resource_subcache_type rg_subcache_entries[1];
|
||||
};
|
||||
|
||||
#define HFI_CMD_SYS_COMMON_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + HFI_CMD_START_OFFSET \
|
||||
+ 0x0000)
|
||||
#define HFI_CMD_SYS_INIT (HFI_CMD_SYS_COMMON_START + 0x001)
|
||||
#define HFI_CMD_SYS_PC_PREP (HFI_CMD_SYS_COMMON_START + 0x002)
|
||||
#define HFI_CMD_SYS_SET_RESOURCE (HFI_CMD_SYS_COMMON_START + 0x003)
|
||||
#define HFI_CMD_SYS_RELEASE_RESOURCE (HFI_CMD_SYS_COMMON_START + 0x004)
|
||||
#define HFI_CMD_SYS_SET_PROPERTY (HFI_CMD_SYS_COMMON_START + 0x005)
|
||||
#define HFI_CMD_SYS_GET_PROPERTY (HFI_CMD_SYS_COMMON_START + 0x006)
|
||||
#define HFI_CMD_SYS_SESSION_INIT (HFI_CMD_SYS_COMMON_START + 0x007)
|
||||
#define HFI_CMD_SYS_SESSION_END (HFI_CMD_SYS_COMMON_START + 0x008)
|
||||
#define HFI_CMD_SYS_SET_BUFFERS (HFI_CMD_SYS_COMMON_START + 0x009)
|
||||
#define HFI_CMD_SYS_SESSION_ABORT (HFI_CMD_SYS_COMMON_START + 0x00A)
|
||||
#define HFI_CMD_SYS_TEST_START (HFI_CMD_SYS_COMMON_START + 0x100)
|
||||
|
||||
#define HFI_MSG_SYS_COMMON_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + \
|
||||
HFI_MSG_START_OFFSET + 0x0000)
|
||||
#define HFI_MSG_SYS_INIT_DONE (HFI_MSG_SYS_COMMON_START + 0x1)
|
||||
#define HFI_MSG_SYS_PC_PREP_DONE (HFI_MSG_SYS_COMMON_START + 0x2)
|
||||
#define HFI_MSG_SYS_RELEASE_RESOURCE (HFI_MSG_SYS_COMMON_START + 0x3)
|
||||
#define HFI_MSG_SYS_DEBUG (HFI_MSG_SYS_COMMON_START + 0x4)
|
||||
#define HFI_MSG_SYS_SESSION_INIT_DONE (HFI_MSG_SYS_COMMON_START + 0x6)
|
||||
#define HFI_MSG_SYS_SESSION_END_DONE (HFI_MSG_SYS_COMMON_START + 0x7)
|
||||
#define HFI_MSG_SYS_IDLE (HFI_MSG_SYS_COMMON_START + 0x8)
|
||||
#define HFI_MSG_SYS_COV (HFI_MSG_SYS_COMMON_START + 0x9)
|
||||
#define HFI_MSG_SYS_PROPERTY_INFO (HFI_MSG_SYS_COMMON_START + 0xA)
|
||||
#define HFI_MSG_SYS_SESSION_ABORT_DONE (HFI_MSG_SYS_COMMON_START + 0xC)
|
||||
#define HFI_MSG_SESSION_SYNC_DONE (HFI_MSG_SESSION_OX_START + 0xD)
|
||||
|
||||
#define HFI_MSG_SESSION_COMMON_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + \
|
||||
HFI_MSG_START_OFFSET + 0x1000)
|
||||
#define HFI_MSG_EVENT_NOTIFY (HFI_MSG_SESSION_COMMON_START + 0x1)
|
||||
#define HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE \
|
||||
(HFI_MSG_SESSION_COMMON_START + 0x2)
|
||||
|
||||
#define HFI_CMD_SYS_TEST_SSR (HFI_CMD_SYS_TEST_START + 0x1)
|
||||
#define HFI_TEST_SSR_SW_ERR_FATAL 0x1
|
||||
#define HFI_TEST_SSR_SW_DIV_BY_ZERO 0x2
|
||||
#define HFI_TEST_SSR_HW_WDOG_IRQ 0x3
|
||||
|
||||
struct cvp_hal_cmd_pkt_hdr {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
};
|
||||
|
||||
struct cvp_hal_msg_pkt_hdr {
|
||||
u32 size;
|
||||
u32 packet;
|
||||
};
|
||||
|
||||
struct cvp_hal_session_cmd_pkt {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_init_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 arch_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_pc_prep_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_set_resource_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 resource_handle;
|
||||
u32 resource_type;
|
||||
u32 rg_resource_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_release_resource_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 resource_type;
|
||||
u32 resource_handle;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_set_property_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_get_property_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_session_init_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 session_type;
|
||||
u32 session_kmask;
|
||||
u32 session_prio;
|
||||
u32 is_secure;
|
||||
u32 dsp_ac_mask;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_session_end_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_set_buffers_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 buffer_type;
|
||||
u32 buffer_size;
|
||||
u32 num_buffers;
|
||||
u32 rg_buffer_addr[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
struct {
|
||||
u32 max_channel_override : 1;
|
||||
u32 mal_length_override : 1;
|
||||
u32 hb_override : 1;
|
||||
u32 bank_swzl_level_override : 1;
|
||||
u32 bank_spreading_override : 1;
|
||||
u32 reserved : 27;
|
||||
} override_bit_info;
|
||||
u32 max_channels;
|
||||
u32 mal_length;
|
||||
u32 highest_bank_bit;
|
||||
u32 bank_swzl_level;
|
||||
u32 bank_spreading;
|
||||
u32 reserved[2];
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_session_set_property_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_client {
|
||||
u32 transaction_id;
|
||||
u32 data1;
|
||||
u32 data2;
|
||||
u64 kdata;
|
||||
u32 reserved1;
|
||||
u32 reserved2;
|
||||
} __packed;
|
||||
|
||||
struct cvp_hfi_buf_type {
|
||||
u32 iova;
|
||||
u32 size;
|
||||
u32 offset;
|
||||
u32 flags;
|
||||
u32 reserved1;
|
||||
u32 reserved2;
|
||||
u32 fence_type;
|
||||
u32 input_handle;
|
||||
u32 output_handle;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_session_set_buffers_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
struct cvp_hfi_client client_data;
|
||||
struct cvp_hfi_buf_type buf_type;
|
||||
} __packed;
|
||||
|
||||
struct cvp_session_release_buffers_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
struct cvp_hfi_client client_data;
|
||||
u32 kernel_type;
|
||||
u32 buffer_type;
|
||||
u32 num_buffers;
|
||||
u32 buffer_idx;
|
||||
} __packed;
|
||||
|
||||
struct cvp_hfi_cmd_session_hdr {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
struct cvp_hfi_client client_data;
|
||||
u32 stream_idx;
|
||||
} __packed;
|
||||
|
||||
struct cvp_hfi_msg_session_hdr {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
struct cvp_hfi_client client_data;
|
||||
u32 stream_idx;
|
||||
} __packed;
|
||||
|
||||
struct cvp_hfi_dumpmsg_session_hdr {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
struct cvp_hfi_client client_data;
|
||||
u32 dump_offset;
|
||||
u32 dump_size;
|
||||
} __packed;
|
||||
|
||||
#define HFI_MAX_HW_ACTIVATIONS_PER_FRAME (6)
|
||||
|
||||
enum hfi_hw_thread {
|
||||
HFI_HW_FDU,
|
||||
HFI_HW_MPU,
|
||||
HFI_HW_OD,
|
||||
HFI_HW_ICA,
|
||||
HFI_HW_VADL,
|
||||
HFI_HW_TOF,
|
||||
HFI_HW_RGE,
|
||||
HFI_HW_XRA,
|
||||
HFI_HW_LSR,
|
||||
HFI_MAX_HW_THREADS
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_session_hdr_ext {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
struct cvp_hfi_client client_data;
|
||||
u32 stream_idx;
|
||||
u32 busy_cycles;
|
||||
u32 total_cycles;
|
||||
u32 hw_cycles[HFI_MAX_HW_THREADS][HFI_MAX_HW_ACTIVATIONS_PER_FRAME];
|
||||
u32 fw_cycles[HFI_MAX_HW_ACTIVATIONS_PER_FRAME];
|
||||
} __packed;
|
||||
|
||||
struct cvp_hfi_buffer_mapping_type {
|
||||
u32 index;
|
||||
u32 device_addr;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_session_sync_process_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 sync_id;
|
||||
u32 rg_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_event_notify_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 event_id;
|
||||
u32 event_data1;
|
||||
u32 event_data2;
|
||||
u32 rg_ext_event_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_session_op_cfg_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
struct cvp_hfi_client client_data;
|
||||
u32 stream_idx;
|
||||
u32 op_conf_id;
|
||||
} __packed;
|
||||
|
||||
struct cvp_hfi_msg_sys_init_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 error_type;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_sys_pc_prep_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_sys_release_resource_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 resource_handle;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_sys_session_init_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_sys_session_end_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_session_get_sequence_header_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
u32 header_len;
|
||||
u32 sequence_header;
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_sys_debug_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 msg_type;
|
||||
u32 msg_size;
|
||||
u32 time_stamp_hi;
|
||||
u32 time_stamp_lo;
|
||||
u8 rg_msg_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_packet_header {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_sfr_struct {
|
||||
u32 bufSize;
|
||||
u8 rg_data[1];
|
||||
};
|
||||
|
||||
struct cvp_hfi_cmd_sys_test_ssr_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 trigger_type;
|
||||
};
|
||||
|
||||
struct cvp_hfi_msg_sys_session_ctrl_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
struct cvp_hfi_client client_data;
|
||||
};
|
||||
|
||||
#endif
|
311
qcom/opensource/eva-kernel/msm/eva/cvp_hfi_io.h
Normal file
311
qcom/opensource/eva-kernel/msm/eva/cvp_hfi_io.h
Normal file
@ -0,0 +1,311 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __CVP_HFI_IO_H__
|
||||
#define __CVP_HFI_IO_H__
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
#define CVP_TOP_BASE_OFFS 0x00000000
|
||||
#define CVP_SS_IDLE_STATUS (CVP_TOP_BASE_OFFS + 0x50)
|
||||
|
||||
#define CVP_CPU_BASE_OFFS 0x000A0000
|
||||
#define CVP_AON_BASE_OFFS 0x000E0000
|
||||
|
||||
#define CVP_CPU_CS_A2HSOFTINTEN (CVP_CPU_BASE_OFFS + 0x10)
|
||||
#define CVP_CPU_CS_A2HSOFTINTENCLR (CVP_CPU_BASE_OFFS + 0x14)
|
||||
#define CVP_CPU_CS_A2HSOFTINT (CVP_CPU_BASE_OFFS + 0x18)
|
||||
#define CVP_CPU_CS_A2HSOFTINTCLR (CVP_CPU_BASE_OFFS + 0x1C)
|
||||
#define CVP_CPU_CS_VMIMSG (CVP_CPU_BASE_OFFS + 0x34)
|
||||
#define CVP_CPU_CS_VMIMSGAG0 (CVP_CPU_BASE_OFFS + 0x38)
|
||||
#define CVP_CPU_CS_VMIMSGAG1 (CVP_CPU_BASE_OFFS + 0x3C)
|
||||
#define CVP_CPU_CS_VMIMSGAG2 (CVP_CPU_BASE_OFFS + 0x40)
|
||||
#define CVP_CPU_CS_VMIMSGAG3 (CVP_CPU_BASE_OFFS + 0x44)
|
||||
#define CVP_CPU_CS_SCIACMD (CVP_CPU_BASE_OFFS + 0x48)
|
||||
#define CVP_CPU_CS_AXI4_QOS (CVP_CPU_BASE_OFFS + 0x13C)
|
||||
#define CVP_CPU_CS_H2XSOFTINTEN (CVP_CPU_BASE_OFFS + 0x148)
|
||||
|
||||
/* CVP_CTRL_STATUS */
|
||||
#define CVP_CPU_CS_SCIACMDARG0 (CVP_CPU_BASE_OFFS + 0x4C)
|
||||
#define CVP_CPU_CS_SCIACMDARG0_BMSK 0xff
|
||||
#define CVP_CPU_CS_SCIACMDARG0_SHFT 0x0
|
||||
#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK 0xfe
|
||||
#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT 0x1
|
||||
#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK 0x1
|
||||
#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT 0x0
|
||||
#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY 0x100
|
||||
|
||||
/* HFI_QTBL_INFO */
|
||||
#define CVP_CPU_CS_SCIACMDARG1 (CVP_CPU_BASE_OFFS + 0x50)
|
||||
|
||||
/* HFI_QTBL_ADDR */
|
||||
#define CVP_CPU_CS_SCIACMDARG2 (CVP_CPU_BASE_OFFS + 0x54)
|
||||
|
||||
/* HFI_VERSION_INFO */
|
||||
#define CVP_CPU_CS_SCIACMDARG3 (CVP_CPU_BASE_OFFS + 0x58)
|
||||
|
||||
/* CVP_SFR_ADDR */
|
||||
#define CVP_CPU_CS_SCIBCMD (CVP_CPU_BASE_OFFS + 0x5C)
|
||||
|
||||
/* CVP_MMAP_ADDR */
|
||||
#define CVP_CPU_CS_SCIBCMDARG0 (CVP_CPU_BASE_OFFS + 0x60)
|
||||
|
||||
/* CVP_UC_REGION_ADDR */
|
||||
#define CVP_CPU_CS_SCIBARG1 (CVP_CPU_BASE_OFFS + 0x64)
|
||||
|
||||
/* CVP_UC_REGION_ADDR */
|
||||
#define CVP_CPU_CS_SCIBARG2 (CVP_CPU_BASE_OFFS + 0x68)
|
||||
|
||||
#define CVP_CPU_CS_SCIBARG3 (CVP_CPU_BASE_OFFS + 0x6C)
|
||||
|
||||
#define CVP_CPU_CS_H2ASOFTINTEN (CVP_CPU_BASE_OFFS + 0x148)
|
||||
#define CVP_CPU_CS_H2ASOFTINTENCLR (CVP_CPU_BASE_OFFS + 0x14c)
|
||||
#define CVP_CPU_CS_H2ASOFTINT (CVP_CPU_BASE_OFFS + 0x150)
|
||||
#define CVP_CPU_CS_H2ASOFTINTCLR (CVP_CPU_BASE_OFFS + 0x154)
|
||||
|
||||
#define CVP_AHB_BRIDGE_SYNC_RESET (CVP_CPU_BASE_OFFS + 0x160)
|
||||
|
||||
/* FAL10 Feature Control */
|
||||
#define CVP_CPU_CS_X2RPMh (CVP_CPU_BASE_OFFS + 0x168)
|
||||
#define CVP_CPU_CS_X2RPMh_MASK0_BMSK 0x1
|
||||
#define CVP_CPU_CS_X2RPMh_MASK0_SHFT 0x0
|
||||
#define CVP_CPU_CS_X2RPMh_MASK1_BMSK 0x2
|
||||
#define CVP_CPU_CS_X2RPMh_MASK1_SHFT 0x1
|
||||
#define CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK 0x4
|
||||
#define CVP_CPU_CS_X2RPMh_SWOVERRIDE_SHFT 0x3
|
||||
|
||||
#define CVP_CPU_CS_X2RPMh_STATUS (CVP_CPU_BASE_OFFS + 0x170)
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------------
|
||||
* MODULE: cvp_wrapper
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
#define CVP_WRAPPER_BASE_OFFS 0x000B0000
|
||||
|
||||
#define CVP_WRAPPER_HW_VERSION (CVP_WRAPPER_BASE_OFFS + 0x00)
|
||||
#define CVP_WRAPPER_HW_VERSION_MAJOR_VERSION_MASK 0x78000000
|
||||
#define CVP_WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT 28
|
||||
#define CVP_WRAPPER_HW_VERSION_MINOR_VERSION_MASK 0xFFF0000
|
||||
#define CVP_WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT 16
|
||||
#define CVP_WRAPPER_HW_VERSION_STEP_VERSION_MASK 0xFFFF
|
||||
|
||||
#define CVP_WRAPPER_INTR_STATUS (CVP_WRAPPER_BASE_OFFS + 0x0C)
|
||||
#define CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK 0x8
|
||||
#define CVP_WRAPPER_INTR_STATUS_A2H_BMSK 0x4
|
||||
|
||||
#define CVP_SS_IRQ_MASK (CVP_TOP_BASE_OFFS + 0x04)
|
||||
#define CVP_SS_INTR_BMASK (0x100)
|
||||
#define CVP_WRAPPER_INTR_MASK (CVP_WRAPPER_BASE_OFFS + 0x10)
|
||||
#define CVP_FATAL_INTR_BMSK (CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK | \
|
||||
CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK )
|
||||
#define CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK 0x40
|
||||
#define CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK 0x20
|
||||
#define CVP_WRAPPER_INTR_MASK_A2HWD_BMSK 0x8
|
||||
#define CVP_WRAPPER_INTR_MASK_A2HCPU_BMSK 0x4
|
||||
#define CVP_WRAPPER_INTR_MASK_A2HCPU_SHFT 0x2
|
||||
|
||||
#define CVP_WRAPPER_INTR_CLEAR (CVP_WRAPPER_BASE_OFFS + 0x14)
|
||||
|
||||
#define CVP_WRAPPER_TZ_BASE_OFFS 0x000C0000
|
||||
|
||||
#define CVP_WRAPPER_TZ_CPU_CLOCK_CONFIG (CVP_WRAPPER_TZ_BASE_OFFS)
|
||||
#define CVP_WRAPPER_INTR_CLEAR_A2HWD_BMSK 0x10
|
||||
#define CVP_WRAPPER_INTR_CLEAR_A2HWD_SHFT 0x4
|
||||
#define CVP_WRAPPER_INTR_CLEAR_A2H_BMSK 0x4
|
||||
#define CVP_WRAPPER_INTR_CLEAR_A2H_SHFT 0x2
|
||||
#define CVP_WRAPPER_CPU_STATUS (CVP_WRAPPER_TZ_BASE_OFFS + 0x10)
|
||||
#define CVP_WRAPPER_AXI_CLOCK_CONFIG (CVP_WRAPPER_TZ_BASE_OFFS + 0x14)
|
||||
#define CVP_WRAPPER_QNS4PDXFIFO_RESET (CVP_WRAPPER_TZ_BASE_OFFS + 0x18)
|
||||
#define CVP_WRAPPER_CPU_CGC_DIS (CVP_WRAPPER_BASE_OFFS + 0x2010)
|
||||
|
||||
#define CVP_WRAPPER_CPU_CLOCK_CONFIG (CVP_WRAPPER_BASE_OFFS + 0x50)
|
||||
#define CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (CVP_WRAPPER_BASE_OFFS + 0x54)
|
||||
#define CVP_WRAPPER_DEBUG_BRIDGE_LPI_STATUS (CVP_WRAPPER_BASE_OFFS + 0x58)
|
||||
#define CVP_WRAPPER_CPU_NOC_LPI_CONTROL (CVP_WRAPPER_BASE_OFFS + 0x5C)
|
||||
#define CVP_WRAPPER_CPU_NOC_LPI_STATUS (CVP_WRAPPER_BASE_OFFS + 0x60)
|
||||
#define CVP_WRAPPER_CORE_CLOCK_CONFIG (CVP_WRAPPER_BASE_OFFS + 0x88)
|
||||
|
||||
#define CVP_CTRL_INIT CVP_CPU_CS_SCIACMD
|
||||
|
||||
#define CVP_CTRL_STATUS CVP_CPU_CS_SCIACMDARG0
|
||||
#define CVP_CTRL_INIT_STATUS__M \
|
||||
CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK
|
||||
#define CVP_CTRL_ERROR_STATUS__M \
|
||||
CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK
|
||||
#define CVP_CTRL_INIT_IDLE_MSG_BMSK \
|
||||
CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK
|
||||
#define CVP_CTRL_STATUS_PC_READY \
|
||||
CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY
|
||||
|
||||
|
||||
#define CVP_QTBL_INFO CVP_CPU_CS_SCIACMDARG1
|
||||
|
||||
#define CVP_QTBL_ADDR CVP_CPU_CS_SCIACMDARG2
|
||||
|
||||
#define CVP_VERSION_INFO CVP_CPU_CS_SCIACMDARG3
|
||||
|
||||
#define CVP_SFR_ADDR CVP_CPU_CS_SCIBCMD
|
||||
#define CVP_MMAP_ADDR CVP_CPU_CS_SCIBCMDARG0
|
||||
#define CVP_UC_REGION_ADDR CVP_CPU_CS_SCIBARG1
|
||||
#define CVP_UC_REGION_SIZE CVP_CPU_CS_SCIBARG2
|
||||
|
||||
/* HFI_DSP_QTBL_ADDR
|
||||
* 31:3 - HFI_DSP_QTBL_ADDR
|
||||
* 4-byte aligned Address
|
||||
*/
|
||||
#define HFI_DSP_QTBL_ADDR CVP_CPU_CS_VMIMSG
|
||||
|
||||
/* HFI_DSP_UC_REGION_ADDR
|
||||
* 31:20 - HFI_DSP_UC_REGION_ADDR
|
||||
* 1MB aligned address.
|
||||
* Uncached Region start Address. This region covers
|
||||
* HFI DSP QTable,
|
||||
* HFI DSP Queue Headers,
|
||||
* HFI DSP Queues,
|
||||
*/
|
||||
#define HFI_DSP_UC_REGION_ADDR CVP_CPU_CS_VMIMSGAG0
|
||||
|
||||
/* HFI_DSP_UC_REGION_SIZE
|
||||
* 31:20 - HFI_DSP_UC_REGION_SIZE
|
||||
* Multiples of 1MB.
|
||||
* Size of the DSP_UC_REGION Uncached Region
|
||||
*/
|
||||
#define HFI_DSP_UC_REGION_SIZE CVP_CPU_CS_VMIMSGAG1
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------------
|
||||
* MODULE: vcodec noc error log registers
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
#define CVP_NOC_BASE_OFFS 0x000D0000
|
||||
#define CVP_NOC_ERR_SWID_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x0)
|
||||
#define CVP_NOC_ERR_SWID_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x4)
|
||||
#define CVP_NOC_ERR_MAINCTL_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x8)
|
||||
#define CVP_NOC_ERR_ERRVLD_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x10)
|
||||
#define CVP_NOC_ERR_ERRCLR_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x18)
|
||||
#define CVP_NOC_ERR_ERRLOG0_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x20)
|
||||
#define CVP_NOC_ERR_ERRLOG0_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x24)
|
||||
#define CVP_NOC_ERR_ERRLOG1_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x28)
|
||||
#define CVP_NOC_ERR_ERRLOG1_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x2C)
|
||||
#define CVP_NOC_ERR_ERRLOG2_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x30)
|
||||
#define CVP_NOC_ERR_ERRLOG2_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x34)
|
||||
#define CVP_NOC_ERR_ERRLOG3_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x38)
|
||||
#define CVP_NOC_ERR_ERRLOG3_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x3C)
|
||||
#define CVP_NOC_SBM_FAULTINEN0_LOW (CVP_NOC_BASE_OFFS + 0x240)
|
||||
#define CVP_NOC_SBM_FAULTINSTATUS0_LOW (CVP_NOC_BASE_OFFS + 0x248)
|
||||
#define CVP_NOC_SBM_SENSELN0_LOW (CVP_NOC_BASE_OFFS + 0x300)
|
||||
|
||||
#define CVP_NOC_CORE_BASE_OFFS 0x00010000
|
||||
#define CVP_NOC_RGE_NIU_DECCTL_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3108)
|
||||
#define CVP_NOC_RGE_NIU_ENCCTL_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3188)
|
||||
#define CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3508)
|
||||
#define CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3588)
|
||||
#define CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0240)
|
||||
#define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0300)
|
||||
#define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0304)
|
||||
#define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x030C)
|
||||
#define CVP_NOC_CORE_ERR_SWID_LOW_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0000)
|
||||
#define CVP_NOC_CORE_ERR_SWID_HIGH_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0004)
|
||||
#define CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0008)
|
||||
#define CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0010)
|
||||
#define CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0018)
|
||||
#define CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0020)
|
||||
#define CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0024)
|
||||
#define CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0028)
|
||||
#define CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x002C)
|
||||
#define CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0030)
|
||||
#define CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0034)
|
||||
#define CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x0038)
|
||||
#define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x003C)
|
||||
|
||||
#define CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x2018)
|
||||
/* NoC QoS registers */
|
||||
#define CVP_NOC_RGE_PRIORITYLUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3030)
|
||||
#define CVP_NOC_RGE_PRIORITYLUT_HIGH \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3034)
|
||||
#define CVP_NOC_RGE_URGENCY_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3038)
|
||||
#define CVP_NOC_RGE_DANGERLUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3040)
|
||||
#define CVP_NOC_RGE_SAFELUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3048)
|
||||
#define CVP_NOC_GCE_PRIORITYLUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3430)
|
||||
#define CVP_NOC_GCE_PRIORITYLUT_HIGH \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3434)
|
||||
#define CVP_NOC_GCE_URGENCY_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3438)
|
||||
#define CVP_NOC_GCE_DANGERLUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3440)
|
||||
#define CVP_NOC_GCE_SAFELUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3448)
|
||||
#define CVP_NOC_CDM_PRIORITYLUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3830)
|
||||
#define CVP_NOC_CDM_PRIORITYLUT_HIGH \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3834)
|
||||
#define CVP_NOC_CDM_URGENCY_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3838)
|
||||
#define CVP_NOC_CDM_DANGERLUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3840)
|
||||
#define CVP_NOC_CDM_SAFELUT_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0x3848)
|
||||
|
||||
|
||||
/* End of NoC Qos */
|
||||
|
||||
#define CVP_NOC_RCGCONTROLLER_MAINCTL_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0xC008)
|
||||
#define CVP_NOC_RCGCONTROLLER_HYSTERESIS_LOW \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0xC010)
|
||||
#define CVP_NOC_RESET_REQ \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0xf000)
|
||||
#define CVP_NOC_RESET_ACK \
|
||||
(CVP_NOC_CORE_BASE_OFFS + 0xf004)
|
||||
|
||||
|
||||
#define CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL (CVP_AON_BASE_OFFS + 0x8)
|
||||
#define CVP_AON_WRAPPER_CVP_NOC_LPI_STATUS (CVP_AON_BASE_OFFS + 0xC)
|
||||
#define CVP_AON_WRAPPER_CVP_NOC_ARCG_CONTROL (CVP_AON_BASE_OFFS + 0x14)
|
||||
#define CVP_AON_WRAPPER_CVP_NOC_CORE_CLK_CONTROL (CVP_AON_BASE_OFFS + 0x24)
|
||||
#define CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET (CVP_AON_BASE_OFFS + 0x1C)
|
||||
#define CVP_AON_WRAPPER_SPARE (CVP_AON_BASE_OFFS + 0x28)
|
||||
|
||||
#define CVP_CC_BASE_OFFS 0xF8000
|
||||
#define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x78)
|
||||
#define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0x90)
|
||||
#define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xCC)
|
||||
#define CVP_CC_MVS1_CBCR (CVP_CC_BASE_OFFS + 0xE0)
|
||||
#define CVP_CC_AHB_CBCR (CVP_CC_BASE_OFFS + 0xF4)
|
||||
#define CVP_CC_XO_CBCR (CVP_CC_BASE_OFFS + 0x124)
|
||||
#define CVP_CC_SLEEP_CBCR (CVP_CC_BASE_OFFS + 0x150)
|
||||
|
||||
#define CVP_GCC_VIDEO_AXI1_CBCR (0x22024)
|
||||
|
||||
#endif
|
343
qcom/opensource/eva-kernel/msm/eva/cvp_power.c
Normal file
343
qcom/opensource/eva-kernel/msm/eva/cvp_power.c
Normal file
@ -0,0 +1,343 @@
|
||||
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "msm_cvp.h"
|
||||
#include "cvp_power.h"
|
||||
|
||||
static inline int find_max(unsigned long *array, unsigned int num)
|
||||
{
|
||||
int i, max = 0;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
max = array[i] > max ? array[i] : max;
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static bool is_subblock_profile_existed(struct msm_cvp_inst *inst)
|
||||
{
|
||||
return (inst->prop.cycles[HFI_HW_OD] ||
|
||||
inst->prop.cycles[HFI_HW_MPU] ||
|
||||
inst->prop.cycles[HFI_HW_FDU] ||
|
||||
inst->prop.cycles[HFI_HW_ICA] ||
|
||||
inst->prop.cycles[HFI_HW_VADL] ||
|
||||
inst->prop.cycles[HFI_HW_TOF] ||
|
||||
inst->prop.cycles[HFI_HW_RGE] ||
|
||||
inst->prop.cycles[HFI_HW_XRA] ||
|
||||
inst->prop.cycles[HFI_HW_LSR]);
|
||||
}
|
||||
|
||||
static char hw_names[HFI_MAX_HW_THREADS][8] = {{"FDU"}, {"MPU"}, {"OD"}, {"ICA"},
|
||||
{"VADL"}, {"TOF"}, {"RGE"}, {"XRA"},
|
||||
{"LSR"}};
|
||||
static void aggregate_power_update(struct msm_cvp_core *core,
|
||||
struct cvp_power_level *nrt_pwr,
|
||||
struct cvp_power_level *rt_pwr,
|
||||
unsigned int max_clk_rate)
|
||||
{
|
||||
struct msm_cvp_inst *inst;
|
||||
int i, j;
|
||||
unsigned long blocks_sum[2][HFI_MAX_HW_THREADS] = {0};
|
||||
unsigned long fw_sum[2] = {0}, max_cycle[2] = {0}, op_max_cycle[2] = {0};
|
||||
unsigned long op_blocks_max[2][HFI_MAX_HW_THREADS] = {0};
|
||||
unsigned long op_fw_max[2] = {0}, bw_sum[2] = {0}, op_bw_max[2] = {0};
|
||||
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
if (inst->state == MSM_CVP_CORE_INVALID ||
|
||||
inst->state == MSM_CVP_CORE_UNINIT ||
|
||||
!is_subblock_profile_existed(inst))
|
||||
continue;
|
||||
if (inst->prop.priority <= CVP_RT_PRIO_THRESHOLD) {
|
||||
/* Non-realtime session use index 0 */
|
||||
i = 0;
|
||||
} else {
|
||||
i = 1;
|
||||
}
|
||||
for (j = 0; j < HFI_MAX_HW_THREADS; j++)
|
||||
if (inst->prop.cycles[j])
|
||||
dprintk(CVP_PWR, "pwrUpdate %s %u\n",
|
||||
hw_names[j], inst->prop.cycles[j]);
|
||||
|
||||
for (j = 0; j < HFI_MAX_HW_THREADS; j++)
|
||||
if (inst->prop.op_cycles[j])
|
||||
dprintk(CVP_PWR, "pwrUpdate_OP %s %u\n",
|
||||
hw_names[j], inst->prop.op_cycles[j]);
|
||||
|
||||
dprintk(CVP_PWR, " fw %u fw_o %u\n", inst->prop.fw_cycles,
|
||||
inst->prop.fw_op_cycles);
|
||||
|
||||
for (j = 0; j < HFI_MAX_HW_THREADS; j++)
|
||||
blocks_sum[i][j] += inst->prop.cycles[j];
|
||||
|
||||
fw_sum[i] += inst->prop.fw_cycles;
|
||||
|
||||
for (j = 0; j < HFI_MAX_HW_THREADS; j++)
|
||||
op_blocks_max[i][j] =
|
||||
(op_blocks_max[i][j] >= inst->prop.op_cycles[j]) ?
|
||||
op_blocks_max[i][j] : inst->prop.op_cycles[j];
|
||||
|
||||
op_fw_max[i] =
|
||||
(op_fw_max[i] >= inst->prop.fw_op_cycles) ?
|
||||
op_fw_max[i] : inst->prop.fw_op_cycles;
|
||||
|
||||
bw_sum[i] += inst->prop.ddr_bw;
|
||||
|
||||
op_bw_max[i] =
|
||||
(op_bw_max[i] >= inst->prop.ddr_op_bw) ?
|
||||
op_bw_max[i] : inst->prop.ddr_op_bw;
|
||||
|
||||
for (j = 0; j < HFI_MAX_HW_THREADS; j++) {
|
||||
if (inst->prop.fps[j])
|
||||
dprintk(CVP_PWR, "fps %s %d ", hw_names[j],
|
||||
inst->prop.fps[j]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
max_cycle[i] = find_max(&blocks_sum[i][0], HFI_MAX_HW_THREADS);
|
||||
op_max_cycle[i] = find_max(&op_blocks_max[i][0], HFI_MAX_HW_THREADS);
|
||||
|
||||
op_max_cycle[i] =
|
||||
(op_max_cycle[i] > max_clk_rate) ?
|
||||
max_clk_rate : op_max_cycle[i];
|
||||
bw_sum[i] = (bw_sum[i] >= op_bw_max[i]) ?
|
||||
bw_sum[i] : op_bw_max[i];
|
||||
}
|
||||
|
||||
nrt_pwr->core_sum += max_cycle[0];
|
||||
nrt_pwr->op_core_sum = (nrt_pwr->op_core_sum >= op_max_cycle[0]) ?
|
||||
nrt_pwr->op_core_sum : op_max_cycle[0];
|
||||
nrt_pwr->bw_sum += bw_sum[0];
|
||||
rt_pwr->core_sum += max_cycle[1];
|
||||
rt_pwr->op_core_sum = (rt_pwr->op_core_sum >= op_max_cycle[1]) ?
|
||||
rt_pwr->op_core_sum : op_max_cycle[1];
|
||||
rt_pwr->bw_sum += bw_sum[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* adjust_bw_freqs(): calculate CVP clock freq and bw required to sustain
|
||||
* required use case.
|
||||
* Bandwidth vote will be best-effort, not returning error if the request
|
||||
* b/w exceeds max limit.
|
||||
* Clock vote from non-realtime sessions will be best effort, not returning
|
||||
* error if the aggreated session clock request exceeds max limit.
|
||||
* Clock vote from realtime session will be hard request. If aggregated
|
||||
* session clock request exceeds max limit, the function will return
|
||||
* error.
|
||||
*
|
||||
* Ensure caller acquires clk_lock!
|
||||
*/
|
||||
static int adjust_bw_freqs(unsigned int max_bw, unsigned int min_bw)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
struct iris_hfi_device *hdev;
|
||||
struct allowed_clock_rates_table *tbl = NULL;
|
||||
unsigned int tbl_size;
|
||||
unsigned int cvp_min_rate, cvp_max_rate;
|
||||
struct cvp_power_level rt_pwr = {0}, nrt_pwr = {0};
|
||||
unsigned long tmp, core_sum, op_core_sum, bw_sum;
|
||||
int i;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
|
||||
hdev = core->dev_ops->hfi_device_data;
|
||||
tbl = core->resources.allowed_clks_tbl;
|
||||
tbl_size = core->resources.allowed_clks_tbl_size;
|
||||
cvp_min_rate = tbl[0].clock_rate;
|
||||
cvp_max_rate = tbl[tbl_size - 1].clock_rate;
|
||||
|
||||
aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate);
|
||||
dprintk(CVP_PWR, "PwrUpdate nrt %u %u rt %u %u\n",
|
||||
nrt_pwr.core_sum, nrt_pwr.op_core_sum,
|
||||
rt_pwr.core_sum, rt_pwr.op_core_sum);
|
||||
|
||||
if (rt_pwr.core_sum > cvp_max_rate) {
|
||||
dprintk(CVP_WARN, "%s clk vote out of range %lld\n",
|
||||
__func__, rt_pwr.core_sum);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
core_sum = rt_pwr.core_sum + nrt_pwr.core_sum;
|
||||
op_core_sum = (rt_pwr.op_core_sum >= nrt_pwr.op_core_sum) ?
|
||||
rt_pwr.op_core_sum : nrt_pwr.op_core_sum;
|
||||
|
||||
core_sum = (core_sum >= op_core_sum) ?
|
||||
core_sum : op_core_sum;
|
||||
|
||||
if (core_sum > cvp_max_rate) {
|
||||
core_sum = cvp_max_rate;
|
||||
} else if (core_sum <= cvp_min_rate) {
|
||||
core_sum = cvp_min_rate;
|
||||
} else {
|
||||
for (i = 1; i < tbl_size; i++)
|
||||
if (core_sum <= tbl[i].clock_rate)
|
||||
break;
|
||||
core_sum = tbl[i].clock_rate;
|
||||
}
|
||||
|
||||
bw_sum = rt_pwr.bw_sum + nrt_pwr.bw_sum;
|
||||
bw_sum = bw_sum >> 10;
|
||||
bw_sum = (bw_sum > max_bw) ? max_bw : bw_sum;
|
||||
bw_sum = (bw_sum < min_bw) ? min_bw : bw_sum;
|
||||
|
||||
dprintk(CVP_PWR, "%s %lld %lld\n", __func__,
|
||||
core_sum, bw_sum);
|
||||
|
||||
tmp = core->curr_freq;
|
||||
core->curr_freq = core_sum;
|
||||
core->orig_core_sum = tmp;
|
||||
|
||||
hdev->clk_freq = core->curr_freq;
|
||||
core->bw_sum = bw_sum;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_cvp_update_power(struct msm_cvp_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_core *core;
|
||||
struct msm_cvp_inst *s;
|
||||
struct bus_info *bus = NULL;
|
||||
struct clock_set *clocks;
|
||||
struct clock_info *cl;
|
||||
int bus_count = 0;
|
||||
unsigned int max_bw = 0, min_bw = 0;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s = cvp_get_inst_validate(inst->core, inst);
|
||||
if (!s)
|
||||
return -ECONNRESET;
|
||||
|
||||
core = inst->core;
|
||||
if (!core || core->state == CVP_CORE_UNINIT) {
|
||||
rc = -ECONNRESET;
|
||||
goto adjust_exit;
|
||||
}
|
||||
|
||||
clocks = &core->resources.clock_set;
|
||||
cl = &clocks->clock_tbl[clocks->count - 1];
|
||||
if (!cl->has_scaling) {
|
||||
dprintk(CVP_ERR, "Cannot scale CVP clock\n");
|
||||
rc = -EINVAL;
|
||||
goto adjust_exit;
|
||||
}
|
||||
for (bus_count = 0; bus_count < core->resources.bus_set.count; bus_count++) {
|
||||
if (!strcmp(core->resources.bus_set.bus_tbl[bus_count].name, "cvp-ddr")) {
|
||||
bus = &core->resources.bus_set.bus_tbl[bus_count];
|
||||
max_bw = bus->range[1];
|
||||
min_bw = max_bw/10;
|
||||
}
|
||||
}
|
||||
if (!bus) {
|
||||
dprintk(CVP_ERR, "bus node is NULL for cvp-ddr\n");
|
||||
rc = -EINVAL;
|
||||
goto adjust_exit;
|
||||
}
|
||||
mutex_lock(&core->clk_lock);
|
||||
rc = adjust_bw_freqs(max_bw, min_bw);
|
||||
mutex_unlock(&core->clk_lock);
|
||||
if (rc)
|
||||
goto adjust_exit;
|
||||
|
||||
rc = msm_cvp_set_clocks(core);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to set clock rate %u %s: %d %s\n",
|
||||
core->curr_freq, cl->name, rc, __func__);
|
||||
core->curr_freq = core->orig_core_sum;
|
||||
goto adjust_exit;
|
||||
}
|
||||
rc = msm_cvp_set_bw(core, bus, core->bw_sum);
|
||||
|
||||
adjust_exit:
|
||||
cvp_put_inst(s);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
unsigned int msm_cvp_get_hw_aggregate_cycles(enum hfi_hw_thread hwblk)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
struct msm_cvp_inst *inst;
|
||||
unsigned long cycles_sum = 0;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
|
||||
if (!core) {
|
||||
dprintk(CVP_ERR, "%s: invalid core\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&core->clk_lock);
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
if (inst->state == MSM_CVP_CORE_INVALID ||
|
||||
inst->state == MSM_CVP_CORE_UNINIT ||
|
||||
!is_subblock_profile_existed(inst))
|
||||
continue;
|
||||
switch (hwblk) {
|
||||
case HFI_HW_FDU:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_FDU];
|
||||
break;
|
||||
}
|
||||
case HFI_HW_ICA:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_ICA];
|
||||
break;
|
||||
}
|
||||
case HFI_HW_MPU:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_MPU];
|
||||
break;
|
||||
}
|
||||
case HFI_HW_OD:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_OD];
|
||||
break;
|
||||
}
|
||||
case HFI_HW_VADL:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_VADL];
|
||||
break;
|
||||
}
|
||||
case HFI_HW_TOF:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_TOF];
|
||||
break;
|
||||
}
|
||||
case HFI_HW_RGE:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_RGE];
|
||||
break;
|
||||
}
|
||||
case HFI_HW_XRA:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_XRA];
|
||||
break;
|
||||
}
|
||||
case HFI_HW_LSR:
|
||||
{
|
||||
cycles_sum += inst->prop.cycles[HFI_HW_LSR];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "unrecognized hw block %d\n",
|
||||
hwblk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&core->clk_lock);
|
||||
cycles_sum = cycles_sum&0xFFFFFFFF;
|
||||
return (unsigned int)cycles_sum;
|
||||
}
|
||||
|
23
qcom/opensource/eva-kernel/msm/eva/cvp_power.h
Normal file
23
qcom/opensource/eva-kernel/msm/eva/cvp_power.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CVP_POWER_H_
|
||||
#define _CVP_POWER_H_
|
||||
|
||||
#include "msm_cvp_internal.h"
|
||||
#include "msm_cvp_common.h"
|
||||
#include "msm_cvp_clocks.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
|
||||
struct cvp_power_level {
|
||||
unsigned long core_sum;
|
||||
unsigned long op_core_sum;
|
||||
unsigned long bw_sum;
|
||||
};
|
||||
|
||||
int msm_cvp_update_power(struct msm_cvp_inst *inst);
|
||||
unsigned int msm_cvp_get_hw_aggregate_cycles(enum hfi_hw_thread hwblk);
|
||||
#endif
|
18
qcom/opensource/eva-kernel/msm/eva/cvp_private.h
Normal file
18
qcom/opensource/eva-kernel/msm/eva/cvp_private.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_V4L2_PRIVATE_H_
|
||||
#define _MSM_V4L2_PRIVATE_H_
|
||||
|
||||
#include <media/msm_eva_private.h>
|
||||
#include "msm_cvp_debug.h"
|
||||
|
||||
long cvp_unblocked_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
long cvp_compat_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
#endif
|
663
qcom/opensource/eva-kernel/msm/eva/cvp_smem.c
Normal file
663
qcom/opensource/eva-kernel/msm/eva/cvp_smem.c
Normal file
@ -0,0 +1,663 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-heap.h>
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/msm_dma_iommu_mapping.h>
|
||||
#include <soc/qcom/secure_buffer.h>
|
||||
#include <linux/mem-buf.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/qcom-dma-mapping.h>
|
||||
#include <linux/version.h>
|
||||
#include "msm_cvp_core.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "msm_cvp_resources.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
|
||||
static void * __cvp_dma_buf_vmap(struct dma_buf *dbuf)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0))
|
||||
struct dma_buf_map map;
|
||||
#else
|
||||
struct iosys_map map;
|
||||
#endif
|
||||
void *dma_map;
|
||||
int err;
|
||||
|
||||
err = dma_buf_vmap(dbuf, &map);
|
||||
dma_map = err ? NULL : map.vaddr;
|
||||
if (!dma_map)
|
||||
dprintk(CVP_ERR, "map to kvaddr failed\n");
|
||||
|
||||
return dma_map;
|
||||
}
|
||||
|
||||
static void __cvp_dma_buf_vunmap(struct dma_buf *dbuf, void *vaddr)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0))
|
||||
struct dma_buf_map map = { \
|
||||
.vaddr = vaddr, \
|
||||
.is_iomem = false, \
|
||||
};
|
||||
#else
|
||||
struct iosys_map map = { \
|
||||
.vaddr = vaddr, \
|
||||
.is_iomem = false, \
|
||||
};
|
||||
#endif
|
||||
if (vaddr)
|
||||
dma_buf_vunmap(dbuf, &map);
|
||||
}
|
||||
|
||||
static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align,
|
||||
dma_addr_t *iova, u32 flags, struct msm_cvp_platform_resources *res,
|
||||
struct cvp_dma_mapping_info *mapping_info)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dma_buf_attachment *attach;
|
||||
struct sg_table *table = NULL;
|
||||
struct context_bank_info *cb = NULL;
|
||||
|
||||
if (!dbuf || !iova || !mapping_info) {
|
||||
dprintk(CVP_ERR, "Invalid params: %pK, %pK, %pK\n",
|
||||
dbuf, iova, mapping_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_iommu_present(res)) {
|
||||
cb = msm_cvp_smem_get_context_bank(res, flags);
|
||||
if (!cb) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed to get context bank device\n",
|
||||
__func__);
|
||||
rc = -EIO;
|
||||
goto mem_map_failed;
|
||||
}
|
||||
|
||||
/* Prepare a dma buf for dma on the given device */
|
||||
attach = dma_buf_attach(dbuf, cb->dev);
|
||||
if (IS_ERR_OR_NULL(attach)) {
|
||||
rc = PTR_ERR(attach) ?: -ENOMEM;
|
||||
dprintk(CVP_ERR, "Failed to attach dmabuf\n");
|
||||
goto mem_buf_attach_failed;
|
||||
}
|
||||
dprintk(CVP_MEM, "%s: CB dev: %s, attach dev: %s, attach: 0x%lx, dbuf: 0x%lx",
|
||||
__func__, dev_name(cb->dev), dev_name(attach->dev), attach, dbuf);
|
||||
|
||||
/*
|
||||
* Get the scatterlist for the given attachment
|
||||
* Mapping of sg is taken care by map attachment
|
||||
*/
|
||||
/*
|
||||
* We do not need dma_map function to perform cache operations
|
||||
* on the whole buffer size and hence pass skip sync flag.
|
||||
* We do the required cache operations separately for the
|
||||
* required buffer size
|
||||
*/
|
||||
attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
|
||||
if (flags & SMEM_CAMERA)
|
||||
attach->dma_map_attrs |= DMA_ATTR_QTI_SMMU_PROXY_MAP;
|
||||
if (res->sys_cache_present)
|
||||
attach->dma_map_attrs |=
|
||||
DMA_ATTR_IOMMU_USE_UPSTREAM_HINT;
|
||||
|
||||
table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
||||
if (IS_ERR_OR_NULL(table)) {
|
||||
dprintk(CVP_ERR, "Failed to map table %d\n", PTR_ERR(table));
|
||||
dprintk(CVP_ERR,
|
||||
"Mapping detail dma_buf 0x%llx, %s, size %#x\n",
|
||||
dbuf, dbuf->name, dbuf->size);
|
||||
rc = PTR_ERR(table) ?: -ENOMEM;
|
||||
goto mem_map_table_failed;
|
||||
}
|
||||
|
||||
if (table->sgl) {
|
||||
*iova = table->sgl->dma_address;
|
||||
} else {
|
||||
dprintk(CVP_ERR, "sgl is NULL\n");
|
||||
rc = -ENOMEM;
|
||||
goto mem_map_sg_failed;
|
||||
}
|
||||
|
||||
mapping_info->dev = cb->dev;
|
||||
mapping_info->domain = cb->domain;
|
||||
mapping_info->table = table;
|
||||
mapping_info->attach = attach;
|
||||
mapping_info->buf = dbuf;
|
||||
mapping_info->cb_info = (void *)cb;
|
||||
|
||||
dprintk(CVP_MEM, "%s: sg-table: 0x%lx, dbuf: 0x%lx, table->sgl->dma_address: 0x%lx",
|
||||
__func__, table, dbuf, table->sgl->dma_address);
|
||||
} else {
|
||||
dprintk(CVP_MEM, "iommu not present, use phys mem addr\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
mem_map_sg_failed:
|
||||
dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL);
|
||||
mem_map_table_failed:
|
||||
dma_buf_detach(dbuf, attach);
|
||||
mem_buf_attach_failed:
|
||||
mem_map_failed:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_dma_put_device_address(u32 flags,
|
||||
struct cvp_dma_mapping_info *mapping_info)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dma_buf_attachment *attach = NULL;
|
||||
struct sg_table *table = NULL;
|
||||
struct context_bank_info *cb = NULL;
|
||||
struct dma_buf *dbuf = NULL;
|
||||
|
||||
if (!mapping_info) {
|
||||
dprintk(CVP_WARN, "Invalid mapping_info\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!mapping_info->dev || !mapping_info->table ||
|
||||
!mapping_info->buf || !mapping_info->attach ||
|
||||
!mapping_info->cb_info) {
|
||||
dprintk(CVP_WARN, "Invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
attach = mapping_info->attach;
|
||||
table = mapping_info->table;
|
||||
cb = (struct context_bank_info *) mapping_info->cb_info;
|
||||
dbuf = mapping_info->buf;
|
||||
dprintk(CVP_MEM, "%s: CB dev_name: %s, attach dev_name: %s, attach: 0x%lx, dbuf: 0x%lx",
|
||||
__func__, dev_name(cb->dev), dev_name(attach->dev), attach, dbuf);
|
||||
dprintk(CVP_MEM, "%s: sg-table: 0x%lx, table->sgl->dma_address: 0x%lx",
|
||||
__func__, table, dbuf, table->sgl->dma_address);
|
||||
|
||||
dma_buf_unmap_attachment(mapping_info->attach,
|
||||
mapping_info->table, DMA_BIDIRECTIONAL);
|
||||
dma_buf_detach(mapping_info->buf, mapping_info->attach);
|
||||
|
||||
mapping_info->dev = NULL;
|
||||
mapping_info->domain = NULL;
|
||||
mapping_info->table = NULL;
|
||||
mapping_info->attach = NULL;
|
||||
mapping_info->buf = NULL;
|
||||
mapping_info->cb_info = NULL;
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct dma_buf *msm_cvp_smem_get_dma_buf(int fd)
|
||||
{
|
||||
struct dma_buf *dma_buf;
|
||||
|
||||
dma_buf = dma_buf_get(fd);
|
||||
if (IS_ERR_OR_NULL(dma_buf)) {
|
||||
dprintk(CVP_ERR, "Failed to get dma_buf for %d, error %ld\n",
|
||||
fd, PTR_ERR(dma_buf));
|
||||
dma_buf = NULL;
|
||||
}
|
||||
|
||||
return dma_buf;
|
||||
}
|
||||
|
||||
void msm_cvp_smem_put_dma_buf(void *dma_buf)
|
||||
{
|
||||
if (!dma_buf) {
|
||||
dprintk(CVP_ERR, "%s: NULL dma_buf\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dma_heap_buffer_free((struct dma_buf *)dma_buf);
|
||||
}
|
||||
|
||||
int msm_cvp_map_smem(struct msm_cvp_inst *inst,
|
||||
struct msm_cvp_smem *smem,
|
||||
const char *str)
|
||||
{
|
||||
int *vmid_list;
|
||||
int *perms_list;
|
||||
int nelems = 0;
|
||||
int i, rc = 0;
|
||||
|
||||
dma_addr_t iova = 0;
|
||||
u32 temp = 0, checksum = 0;
|
||||
u32 align = SZ_4K;
|
||||
struct dma_buf *dma_buf;
|
||||
bool is_config_pkt = false;
|
||||
|
||||
if (!inst || !smem) {
|
||||
dprintk(CVP_ERR, "%s: Invalid params: %pK %pK\n",
|
||||
__func__, inst, smem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dma_buf = smem->dma_buf;
|
||||
rc = mem_buf_dma_buf_copy_vmperm(dma_buf,
|
||||
&vmid_list, &perms_list, &nelems);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s fail to get vmid and perms %d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (temp = 0; temp < nelems; temp++) {
|
||||
if (vmid_list[temp] == VMID_CP_PIXEL)
|
||||
smem->flags |= (SMEM_SECURE | SMEM_PIXEL);
|
||||
else if (vmid_list[temp] == VMID_CP_NON_PIXEL)
|
||||
smem->flags |= (SMEM_SECURE | SMEM_NON_PIXEL);
|
||||
else if (vmid_list[temp] == VMID_CP_CAMERA ||
|
||||
/* To-do: what if the EVA driver runs in TVM */
|
||||
vmid_list[temp] == VMID_TVM)
|
||||
smem->flags |= (SMEM_SECURE | SMEM_CAMERA);
|
||||
dprintk(CVP_MEM, "inst %pK VM idx %d VM_ID %d fd %d pkt_type %#x\n",
|
||||
inst, temp, vmid_list[temp], smem->fd, smem->pkt_type);
|
||||
}
|
||||
|
||||
rc = msm_dma_get_device_address(dma_buf, align, &iova, smem->flags,
|
||||
&(inst->core->resources), &smem->mapping_info);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "Failed to get device address: %d\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
temp = (u32)iova;
|
||||
if ((dma_addr_t)temp != iova) {
|
||||
dprintk(CVP_ERR, "iova(%pa) truncated to %#x", &iova, temp);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
smem->size = dma_buf->size;
|
||||
smem->device_addr = (u32)iova;
|
||||
i = get_pkt_index_from_type(smem->pkt_type);
|
||||
if (i > 0 && smem->pkt_type != HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS
|
||||
&& smem->pkt_type != HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS
|
||||
&& smem->pkt_type != HFI_CMD_SESSION_EVA_DLFL_CONFIG)
|
||||
/* User persist buffer has no feature config info */
|
||||
is_config_pkt = cvp_hfi_defs[i].is_config_pkt;
|
||||
|
||||
if (i > 0 && cvp_hfi_defs[i].checksum_enabled) {
|
||||
dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
|
||||
smem->kvaddr = __cvp_dma_buf_vmap(dma_buf);
|
||||
if (!smem->kvaddr) {
|
||||
dprintk(CVP_WARN, "%s Fail map into kernel\n",
|
||||
__func__);
|
||||
dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
|
||||
} else {
|
||||
for (i = 0; i < 256; i++)
|
||||
checksum += *(u32 *)(smem->kvaddr + i*sizeof(u32));
|
||||
dprintk(CVP_MEM, "Map checksum %#x fd=%d\n",
|
||||
checksum, smem->fd);
|
||||
}
|
||||
}
|
||||
print_smem(CVP_MEM, str, inst, smem);
|
||||
atomic_inc(&inst->smem_count);
|
||||
goto success;
|
||||
exit:
|
||||
smem->device_addr = 0x0;
|
||||
success:
|
||||
kfree(vmid_list);
|
||||
kfree(perms_list);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_cvp_unmap_smem(struct msm_cvp_inst *inst,
|
||||
struct msm_cvp_smem *smem,
|
||||
const char *str)
|
||||
{
|
||||
int i, rc = 0;
|
||||
u32 checksum = 0;
|
||||
struct dma_buf *dma_buf;
|
||||
|
||||
if (!smem) {
|
||||
dprintk(CVP_ERR, "%s: Invalid params: %pK\n", __func__, smem);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
print_smem(CVP_MEM, str, inst, smem);
|
||||
dma_buf = smem->dma_buf;
|
||||
i = get_pkt_index_from_type(smem->pkt_type);
|
||||
if (i > 0 && cvp_hfi_defs[i].checksum_enabled) {
|
||||
if (!smem->kvaddr) {
|
||||
dprintk(CVP_WARN, "%s DS buf Fail map into kernel\n",
|
||||
__func__);
|
||||
dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
|
||||
} else {
|
||||
for (i = 0; i < 256; i++)
|
||||
checksum += *(u32 *)(smem->kvaddr + i*sizeof(u32));
|
||||
dprintk(CVP_MEM, "Unmap checksum %#x fd=%d\n",
|
||||
checksum, smem->fd);
|
||||
__cvp_dma_buf_vunmap(dma_buf, smem->kvaddr);
|
||||
smem->kvaddr = 0;
|
||||
dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
|
||||
}
|
||||
}
|
||||
rc = msm_dma_put_device_address(smem->flags, &smem->mapping_info);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "Failed to put device address: %d\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
smem->device_addr = 0x0;
|
||||
atomic_dec(&inst->smem_count);
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int alloc_dma_mem(size_t size, u32 align, int map_kernel,
|
||||
struct msm_cvp_platform_resources *res, struct msm_cvp_smem *mem)
|
||||
{
|
||||
dma_addr_t iova = 0;
|
||||
int rc = 0;
|
||||
struct dma_buf *dbuf = NULL;
|
||||
struct dma_heap *heap = NULL;
|
||||
struct mem_buf_lend_kernel_arg arg;
|
||||
int vmids[1];
|
||||
int perms[1];
|
||||
|
||||
if (!res) {
|
||||
dprintk(CVP_ERR, "%s: NULL res\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
align = ALIGN(align, SZ_4K);
|
||||
size = ALIGN(size, SZ_4K);
|
||||
|
||||
if (is_iommu_present(res)) {
|
||||
heap = dma_heap_find("qcom,system");
|
||||
dprintk(CVP_MEM, "%s size %zx align %d flag %d\n",
|
||||
__func__, size, align, mem->flags);
|
||||
} else {
|
||||
dprintk(CVP_ERR,
|
||||
"No IOMMU CB: allocate shared memory heap size %zx align %d\n",
|
||||
size, align);
|
||||
}
|
||||
|
||||
dbuf = dma_heap_buffer_alloc(heap, size, 0, 0);
|
||||
if (IS_ERR_OR_NULL(dbuf)) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to allocate shared memory = %x bytes, %x %x\n",
|
||||
size, mem->flags, PTR_ERR(dbuf));
|
||||
rc = -ENOMEM;
|
||||
goto fail_shared_mem_alloc;
|
||||
}
|
||||
|
||||
perms[0] = PERM_READ | PERM_WRITE;
|
||||
arg.nr_acl_entries = 1;
|
||||
arg.vmids = vmids;
|
||||
arg.perms = perms;
|
||||
|
||||
if (mem->flags & SMEM_NON_PIXEL) {
|
||||
vmids[0] = VMID_CP_NON_PIXEL;
|
||||
rc = mem_buf_lend(dbuf, &arg);
|
||||
} else if (mem->flags & SMEM_PIXEL) {
|
||||
vmids[0] = VMID_CP_PIXEL;
|
||||
rc = mem_buf_lend(dbuf, &arg);
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "Failed to lend dmabuf %d, vmid %d\n",
|
||||
rc, vmids[0]);
|
||||
goto fail_device_address;
|
||||
}
|
||||
|
||||
if (!gfa_cv.dmabuf_f_op)
|
||||
gfa_cv.dmabuf_f_op = (const struct file_operations *)dbuf->file->f_op;
|
||||
|
||||
mem->size = size;
|
||||
mem->dma_buf = dbuf;
|
||||
mem->kvaddr = NULL;
|
||||
|
||||
rc = msm_dma_get_device_address(dbuf, align, &iova, mem->flags,
|
||||
res, &mem->mapping_info);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "Failed to get device address: %d\n",
|
||||
rc);
|
||||
goto fail_device_address;
|
||||
}
|
||||
mem->device_addr = (u32)iova;
|
||||
if ((dma_addr_t)mem->device_addr != iova) {
|
||||
dprintk(CVP_ERR, "iova(%pa) truncated to %#x",
|
||||
&iova, mem->device_addr);
|
||||
goto fail_device_address;
|
||||
}
|
||||
|
||||
if (map_kernel) {
|
||||
dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL);
|
||||
mem->kvaddr = __cvp_dma_buf_vmap(dbuf);
|
||||
if (!mem->kvaddr) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to map shared mem in kernel\n");
|
||||
rc = -EIO;
|
||||
goto fail_map;
|
||||
}
|
||||
}
|
||||
|
||||
dprintk(CVP_MEM,
|
||||
"%s: dma_buf=%pK,iova=%x,size=%d,kvaddr=%pK,flags=%#lx\n",
|
||||
__func__, mem->dma_buf, mem->device_addr, mem->size,
|
||||
mem->kvaddr, mem->flags);
|
||||
return rc;
|
||||
|
||||
fail_map:
|
||||
if (map_kernel)
|
||||
dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL);
|
||||
fail_device_address:
|
||||
dma_heap_buffer_free(dbuf);
|
||||
fail_shared_mem_alloc:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int free_dma_mem(struct msm_cvp_smem *mem)
|
||||
{
|
||||
dprintk(CVP_MEM,
|
||||
"%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK\n",
|
||||
__func__, mem->dma_buf, mem->device_addr, mem->size, mem->kvaddr);
|
||||
|
||||
if (mem->device_addr) {
|
||||
msm_dma_put_device_address(mem->flags, &mem->mapping_info);
|
||||
mem->device_addr = 0x0;
|
||||
}
|
||||
|
||||
if (mem->kvaddr) {
|
||||
__cvp_dma_buf_vunmap(mem->dma_buf, mem->kvaddr);
|
||||
mem->kvaddr = NULL;
|
||||
dma_buf_end_cpu_access(mem->dma_buf, DMA_BIDIRECTIONAL);
|
||||
}
|
||||
|
||||
if (mem->dma_buf) {
|
||||
dma_heap_buffer_free(mem->dma_buf);
|
||||
mem->dma_buf = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_cvp_smem_alloc(size_t size, u32 align, int map_kernel,
|
||||
void *res, struct msm_cvp_smem *smem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!smem || !size) {
|
||||
dprintk(CVP_ERR, "%s: NULL smem or %d size\n",
|
||||
__func__, (u32)size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = alloc_dma_mem(size, align, map_kernel,
|
||||
(struct msm_cvp_platform_resources *)res, smem);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_cvp_smem_free(struct msm_cvp_smem *smem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!smem) {
|
||||
dprintk(CVP_ERR, "NULL smem passed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = free_dma_mem(smem);
|
||||
|
||||
return rc;
|
||||
};
|
||||
|
||||
int msm_cvp_smem_cache_operations(struct dma_buf *dbuf,
|
||||
enum smem_cache_ops cache_op, unsigned long offset, unsigned long size)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!dbuf) {
|
||||
dprintk(CVP_ERR, "%s: Invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (cache_op) {
|
||||
case SMEM_CACHE_CLEAN:
|
||||
case SMEM_CACHE_CLEAN_INVALIDATE:
|
||||
rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_BIDIRECTIONAL,
|
||||
offset, size);
|
||||
if (rc)
|
||||
break;
|
||||
rc = dma_buf_end_cpu_access_partial(dbuf, DMA_BIDIRECTIONAL,
|
||||
offset, size);
|
||||
break;
|
||||
case SMEM_CACHE_INVALIDATE:
|
||||
rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE,
|
||||
offset, size);
|
||||
if (rc)
|
||||
break;
|
||||
rc = dma_buf_end_cpu_access_partial(dbuf, DMA_FROM_DEVICE,
|
||||
offset, size);
|
||||
break;
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: cache (%d) operation not supported\n",
|
||||
__func__, cache_op);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct context_bank_info *msm_cvp_smem_get_context_bank(
|
||||
struct msm_cvp_platform_resources *res,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct context_bank_info *cb = NULL, *match = NULL;
|
||||
char *search_str;
|
||||
char *non_secure_cb = "cvp_hlos";
|
||||
char *secure_nonpixel_cb = "cvp_sec_nonpixel";
|
||||
char *secure_pixel_cb = "cvp_sec_pixel";
|
||||
char *camera_cb = "cvp_camera";
|
||||
char *dsp_cb = "cvp_dsp";
|
||||
bool is_secure = (flags & SMEM_SECURE) ? true : false;
|
||||
|
||||
if (flags & SMEM_PIXEL)
|
||||
search_str = secure_pixel_cb;
|
||||
else if (flags & SMEM_NON_PIXEL)
|
||||
search_str = secure_nonpixel_cb;
|
||||
else if (flags & SMEM_CAMERA)
|
||||
/* Secure Camera pixel buffer */
|
||||
search_str = camera_cb;
|
||||
else if (flags & SMEM_CDSP)
|
||||
search_str = dsp_cb;
|
||||
else
|
||||
search_str = non_secure_cb;
|
||||
|
||||
list_for_each_entry(cb, &res->context_banks, list) {
|
||||
if (cb->is_secure == is_secure &&
|
||||
!strcmp(search_str, cb->name)) {
|
||||
match = cb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cb not found for flags %x, is_secure %d\n",
|
||||
__func__, flags, is_secure);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
int msm_cvp_map_ipcc_regs(u32 *iova)
|
||||
{
|
||||
struct context_bank_info *cb;
|
||||
struct msm_cvp_core *core;
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
struct iris_hfi_device *dev = NULL;
|
||||
phys_addr_t paddr;
|
||||
u32 size;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
if (core) {
|
||||
ops_tbl = core->dev_ops;
|
||||
if (ops_tbl)
|
||||
dev = ops_tbl->hfi_device_data;
|
||||
}
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
paddr = dev->res->ipcc_reg_base;
|
||||
size = dev->res->ipcc_reg_size;
|
||||
|
||||
if (!paddr || !size)
|
||||
return -EINVAL;
|
||||
|
||||
cb = msm_cvp_smem_get_context_bank(dev->res, 0);
|
||||
if (!cb) {
|
||||
dprintk(CVP_ERR, "%s: fail to get context bank\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
*iova = dma_map_resource(cb->dev, paddr, size, DMA_BIDIRECTIONAL, 0);
|
||||
if (*iova == DMA_MAPPING_ERROR) {
|
||||
dprintk(CVP_WARN, "%s: fail to map IPCC regs\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_cvp_unmap_ipcc_regs(u32 iova)
|
||||
{
|
||||
struct context_bank_info *cb;
|
||||
struct msm_cvp_core *core;
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
struct iris_hfi_device *dev = NULL;
|
||||
u32 size;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
if (core) {
|
||||
ops_tbl = core->dev_ops;
|
||||
if (ops_tbl)
|
||||
dev = ops_tbl->hfi_device_data;
|
||||
}
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
size = dev->res->ipcc_reg_size;
|
||||
|
||||
if (!iova || !size)
|
||||
return -EINVAL;
|
||||
|
||||
cb = msm_cvp_smem_get_context_bank(dev->res, 0);
|
||||
if (!cb) {
|
||||
dprintk(CVP_ERR, "%s: fail to get context bank\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
dma_unmap_resource(cb->dev, iova, size, DMA_BIDIRECTIONAL, 0);
|
||||
|
||||
return 0;
|
||||
}
|
86
qcom/opensource/eva-kernel/msm/eva/eva_shared_def.h
Normal file
86
qcom/opensource/eva-kernel/msm/eva/eva_shared_def.h
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file contains definitions that are common to UMD and KMD
|
||||
* but shall not be added to the UAPI to allow for better UAPI
|
||||
* backward compatibility. Identical copies of this file must be
|
||||
* used by both UMD and KMD for desired functioning.
|
||||
*/
|
||||
|
||||
#ifndef _EVA_SHARED_DEF_H_
|
||||
#define _EVA_SHARED_DEF_H_
|
||||
|
||||
/**
|
||||
* Structure corresponding to HFI_CVP_BUFFER_TYPE
|
||||
*/
|
||||
|
||||
struct cvp_buf_type {
|
||||
__s32 fd;
|
||||
__u32 size;
|
||||
__u32 offset;
|
||||
__u32 flags;
|
||||
__u32 reserved1;
|
||||
__u32 reserved2;
|
||||
__u32 fence_type;
|
||||
__u32 input_handle;
|
||||
__u32 output_handle;
|
||||
__u32 debug_flags;
|
||||
__u32 crc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Structures and macros for Warp-NCC Out-of-Band (OOB) buffer
|
||||
*/
|
||||
|
||||
#define EVA_KMD_WNCC_MAX_LAYERS 4
|
||||
#define EVA_KMD_WNCC_MAX_ADDRESSES 4095
|
||||
#define EVA_KMD_WNCC_MAX_SRC_BUFS 2400
|
||||
#define EVA_KMD_WNCC_SRC_BUF_ID_OFFSET 1
|
||||
|
||||
struct eva_kmd_wncc_metadata {
|
||||
__u64 loc_x_dec : 12;
|
||||
__u64 loc_x_frac : 9;
|
||||
__u64 loc_y_dec : 12;
|
||||
__u64 loc_y_frac : 9;
|
||||
__u64 iova_lsb : 22; /* Populated in KMD */
|
||||
__u64 iova_msb : 10; /* Populated in KMD */
|
||||
__u64 scale_idx : 2;
|
||||
__s64 aff_coeff_3 : 13;
|
||||
__s64 aff_coeff_2 : 13;
|
||||
__s64 aff_coeff_1 : 13;
|
||||
__s64 aff_coeff_0 : 13;
|
||||
};
|
||||
|
||||
struct eva_kmd_oob_wncc {
|
||||
__u32 metadata_bufs_offset;
|
||||
__u32 num_layers;
|
||||
struct eva_kmd_wncc_layer {
|
||||
__u32 num_addrs;
|
||||
struct eva_kmd_wncc_addr {
|
||||
__u32 buffer_id;
|
||||
__u32 offset;
|
||||
} addrs[EVA_KMD_WNCC_MAX_ADDRESSES];
|
||||
} layers[EVA_KMD_WNCC_MAX_LAYERS];
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure and macros for Out-of-Band (OOB) buffer
|
||||
* that may accompany HFI packet data
|
||||
*/
|
||||
|
||||
#define EVA_KMD_OOB_INVALID 0
|
||||
#define EVA_KMD_OOB_WNCC 1
|
||||
|
||||
struct eva_kmd_oob_buf {
|
||||
__u32 oob_type;
|
||||
union {
|
||||
struct eva_kmd_oob_wncc wncc;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
463
qcom/opensource/eva-kernel/msm/eva/hfi_packetization.c
Normal file
463
qcom/opensource/eva-kernel/msm/eva/hfi_packetization.c
Normal file
@ -0,0 +1,463 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "hfi_packetization.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
|
||||
/* Set up look-up tables to convert HAL_* to HFI_*.
|
||||
*
|
||||
* The tables below mostly take advantage of the fact that most
|
||||
* HAL_* types are defined bitwise. So if we index them normally
|
||||
* when declaring the tables, we end up with huge arrays with wasted
|
||||
* space. So before indexing them, we apply log2 to use a more
|
||||
* sensible index.
|
||||
*/
|
||||
|
||||
int cvp_create_pkt_cmd_sys_init(struct cvp_hfi_cmd_sys_init_packet *pkt,
|
||||
u32 arch_type)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!pkt)
|
||||
return -EINVAL;
|
||||
|
||||
pkt->packet_type = HFI_CMD_SYS_INIT;
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_init_packet);
|
||||
pkt->arch_type = arch_type;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_sys_pc_prep(struct cvp_hfi_cmd_sys_pc_prep_packet *pkt)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!pkt)
|
||||
return -EINVAL;
|
||||
|
||||
pkt->packet_type = HFI_CMD_SYS_PC_PREP;
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_pc_prep_packet);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_sys_debug_config(
|
||||
struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 mode)
|
||||
{
|
||||
struct cvp_hfi_debug_config *hfi;
|
||||
|
||||
if (!pkt)
|
||||
return -EINVAL;
|
||||
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) +
|
||||
sizeof(struct cvp_hfi_debug_config) + sizeof(u32);
|
||||
pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
|
||||
pkt->num_properties = 1;
|
||||
pkt->rg_property_data[0] = HFI_PROPERTY_SYS_DEBUG_CONFIG;
|
||||
hfi = (struct cvp_hfi_debug_config *) &pkt->rg_property_data[1];
|
||||
hfi->debug_config = mode;
|
||||
hfi->debug_mode = HFI_DEBUG_MODE_QUEUE;
|
||||
if (msm_cvp_fw_debug_mode
|
||||
<= (HFI_DEBUG_MODE_QUEUE | HFI_DEBUG_MODE_QDSS))
|
||||
hfi->debug_mode = msm_cvp_fw_debug_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_sys_coverage_config(
|
||||
struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 mode)
|
||||
{
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "In %s(), No input packet\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) +
|
||||
sizeof(u32);
|
||||
pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
|
||||
pkt->num_properties = 1;
|
||||
pkt->rg_property_data[0] = HFI_PROPERTY_SYS_CONFIG_COVERAGE;
|
||||
pkt->rg_property_data[1] = mode;
|
||||
dprintk(CVP_PKT, "Firmware coverage mode %d\n",
|
||||
pkt->rg_property_data[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_sys_set_idle_indicator(
|
||||
struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 mode)
|
||||
{
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "In %s(), No input packet\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) +
|
||||
sizeof(u32);
|
||||
pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
|
||||
pkt->num_properties = 1;
|
||||
pkt->rg_property_data[0] = HFI_PROPERTY_SYS_IDLE_INDICATOR;
|
||||
pkt->rg_property_data[1] = mode;
|
||||
dprintk(CVP_PKT, "Firmware idle indicator mode %d\n",
|
||||
pkt->rg_property_data[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_sys_set_resource(
|
||||
struct cvp_hfi_cmd_sys_set_resource_packet *pkt,
|
||||
struct cvp_resource_hdr *res_hdr,
|
||||
void *res_value)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 i = 0;
|
||||
|
||||
if (!pkt || !res_hdr || !res_value) {
|
||||
dprintk(CVP_ERR,
|
||||
"Invalid paramas pkt %pK res_hdr %pK res_value %pK\n",
|
||||
pkt, res_hdr, res_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pkt->packet_type = HFI_CMD_SYS_SET_RESOURCE;
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_resource_packet);
|
||||
pkt->resource_handle = hash32_ptr(res_hdr->resource_handle);
|
||||
|
||||
switch (res_hdr->resource_id) {
|
||||
case CVP_RESOURCE_SYSCACHE:
|
||||
{
|
||||
struct cvp_hfi_resource_syscache_info_type *res_sc_info =
|
||||
(struct cvp_hfi_resource_syscache_info_type *)res_value;
|
||||
struct cvp_hfi_resource_subcache_type *res_sc =
|
||||
(struct cvp_hfi_resource_subcache_type *)
|
||||
&(res_sc_info->rg_subcache_entries[0]);
|
||||
|
||||
struct cvp_hfi_resource_syscache_info_type *hfi_sc_info =
|
||||
(struct cvp_hfi_resource_syscache_info_type *)
|
||||
&pkt->rg_resource_data[0];
|
||||
|
||||
struct cvp_hfi_resource_subcache_type *hfi_sc =
|
||||
(struct cvp_hfi_resource_subcache_type *)
|
||||
&(hfi_sc_info->rg_subcache_entries[0]);
|
||||
|
||||
pkt->resource_type = HFI_RESOURCE_SYSCACHE;
|
||||
hfi_sc_info->num_entries = res_sc_info->num_entries;
|
||||
|
||||
pkt->size += (sizeof(struct cvp_hfi_resource_subcache_type))
|
||||
* hfi_sc_info->num_entries;
|
||||
|
||||
for (i = 0; i < hfi_sc_info->num_entries; i++) {
|
||||
hfi_sc[i] = res_sc[i];
|
||||
dprintk(CVP_PKT, "entry hfi#%d, sc_id %d, size %d\n",
|
||||
i, hfi_sc[i].sc_id, hfi_sc[i].size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR,
|
||||
"Invalid resource_id %d\n", res_hdr->resource_id);
|
||||
rc = -ENOTSUPP;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_sys_release_resource(
|
||||
struct cvp_hfi_cmd_sys_release_resource_packet *pkt,
|
||||
struct cvp_resource_hdr *res_hdr)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!pkt || !res_hdr) {
|
||||
dprintk(CVP_ERR,
|
||||
"Invalid paramas pkt %pK res_hdr %pK\n",
|
||||
pkt, res_hdr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_release_resource_packet);
|
||||
pkt->packet_type = HFI_CMD_SYS_RELEASE_RESOURCE;
|
||||
pkt->resource_handle = hash32_ptr(res_hdr->resource_handle);
|
||||
|
||||
switch (res_hdr->resource_id) {
|
||||
case CVP_RESOURCE_SYSCACHE:
|
||||
pkt->resource_type = HFI_RESOURCE_SYSCACHE;
|
||||
break;
|
||||
default:
|
||||
dprintk(CVP_ERR,
|
||||
"Invalid resource_id %d\n", res_hdr->resource_id);
|
||||
rc = -ENOTSUPP;
|
||||
}
|
||||
|
||||
dprintk(CVP_PKT,
|
||||
"rel_res: pkt_type 0x%x res_type 0x%x prepared\n",
|
||||
pkt->packet_type, pkt->resource_type);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
inline int cvp_create_pkt_cmd_sys_session_init(
|
||||
struct cvp_hfi_cmd_sys_session_init_packet *pkt,
|
||||
struct cvp_hal_session *session)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_inst *inst = session->session_id;
|
||||
|
||||
if (!pkt || !inst)
|
||||
return -EINVAL;
|
||||
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_session_init_packet);
|
||||
pkt->packet_type = HFI_CMD_SYS_SESSION_INIT;
|
||||
pkt->session_id = hash32_ptr(session);
|
||||
pkt->session_type = inst->prop.type;
|
||||
pkt->session_kmask = inst->prop.kernel_mask;
|
||||
pkt->session_prio = inst->prop.priority;
|
||||
pkt->is_secure = inst->prop.is_secure;
|
||||
pkt->dsp_ac_mask = inst->prop.dsp_mask;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int create_pkt_cmd_sys_ubwc_config(
|
||||
struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
struct msm_cvp_ubwc_config_data *ubwc_config)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type *hfi;
|
||||
|
||||
if (!pkt)
|
||||
return -EINVAL;
|
||||
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) +
|
||||
sizeof(struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type)
|
||||
+ sizeof(u32);
|
||||
|
||||
pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
|
||||
pkt->num_properties = 1;
|
||||
pkt->rg_property_data[0] = HFI_PROPERTY_SYS_UBWC_CONFIG;
|
||||
hfi = (struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type *)
|
||||
&pkt->rg_property_data[1];
|
||||
|
||||
hfi->max_channels = ubwc_config->max_channels;
|
||||
hfi->override_bit_info.max_channel_override =
|
||||
ubwc_config->override_bit_info.max_channel_override;
|
||||
|
||||
hfi->mal_length = ubwc_config->mal_length;
|
||||
hfi->override_bit_info.mal_length_override =
|
||||
ubwc_config->override_bit_info.mal_length_override;
|
||||
|
||||
hfi->highest_bank_bit = ubwc_config->highest_bank_bit;
|
||||
hfi->override_bit_info.hb_override =
|
||||
ubwc_config->override_bit_info.hb_override;
|
||||
|
||||
hfi->bank_swzl_level = ubwc_config->bank_swzl_level;
|
||||
hfi->override_bit_info.bank_swzl_level_override =
|
||||
ubwc_config->override_bit_info.bank_swzl_level_override;
|
||||
|
||||
hfi->bank_spreading = ubwc_config->bank_spreading;
|
||||
hfi->override_bit_info.bank_spreading_override =
|
||||
ubwc_config->override_bit_info.bank_spreading_override;
|
||||
hfi->size = sizeof(struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_session_cmd(struct cvp_hal_session_cmd_pkt *pkt,
|
||||
int pkt_type, struct cvp_hal_session *session)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!pkt)
|
||||
return -EINVAL;
|
||||
|
||||
pkt->size = sizeof(struct cvp_hal_session_cmd_pkt);
|
||||
pkt->packet_type = pkt_type;
|
||||
pkt->session_id = hash32_ptr(session);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_sys_power_control(
|
||||
struct cvp_hfi_cmd_sys_set_property_packet *pkt, u32 enable)
|
||||
{
|
||||
struct cvp_hfi_enable *hfi;
|
||||
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "No input packet\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) +
|
||||
sizeof(struct cvp_hfi_enable) + sizeof(u32);
|
||||
pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY;
|
||||
pkt->num_properties = 1;
|
||||
pkt->rg_property_data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL;
|
||||
hfi = (struct cvp_hfi_enable *) &pkt->rg_property_data[1];
|
||||
hfi->enable = enable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_session_set_buffers(
|
||||
void *cmd,
|
||||
struct cvp_hal_session *session,
|
||||
u32 iova,
|
||||
u32 size)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cvp_hfi_cmd_session_set_buffers_packet *pkt;
|
||||
|
||||
if (!cmd || !session)
|
||||
return -EINVAL;
|
||||
|
||||
pkt = (struct cvp_hfi_cmd_session_set_buffers_packet *)cmd;
|
||||
pkt->packet_type = HFI_CMD_SESSION_CVP_SET_BUFFERS;
|
||||
pkt->session_id = hash32_ptr(session);
|
||||
pkt->buf_type.iova = iova;
|
||||
pkt->buf_type.size = size;
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_session_set_buffers_packet);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_session_release_buffers(
|
||||
void *cmd,
|
||||
struct cvp_hal_session *session)
|
||||
{
|
||||
struct cvp_session_release_buffers_packet *pkt;
|
||||
|
||||
if (!cmd || !session || session == (void *)0xdeadbeef)
|
||||
return -EINVAL;
|
||||
|
||||
pkt = (struct cvp_session_release_buffers_packet *)cmd;
|
||||
pkt->packet_type = HFI_CMD_SESSION_CVP_RELEASE_BUFFERS;
|
||||
pkt->session_id = hash32_ptr(session);
|
||||
pkt->num_buffers = 1;
|
||||
pkt->buffer_type = 0;
|
||||
pkt->size = sizeof(struct cvp_session_release_buffers_packet) +
|
||||
((pkt->num_buffers - 1) * sizeof(u32));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_session_send(
|
||||
struct eva_kmd_hfi_packet *out_pkt,
|
||||
struct cvp_hal_session *session,
|
||||
struct eva_kmd_hfi_packet *in_pkt)
|
||||
{
|
||||
int def_idx;
|
||||
struct cvp_hal_session_cmd_pkt *ptr =
|
||||
(struct cvp_hal_session_cmd_pkt *)in_pkt;
|
||||
|
||||
if (!out_pkt || !in_pkt || !session)
|
||||
return -EINVAL;
|
||||
|
||||
if (ptr->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int))
|
||||
goto error_hfi_packet;
|
||||
|
||||
if (ptr->session_id != hash32_ptr(session))
|
||||
goto error_hfi_packet;
|
||||
|
||||
def_idx = get_pkt_index(ptr);
|
||||
if (def_idx < 0) {
|
||||
memcpy(out_pkt, in_pkt, ptr->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cvp_hfi_defs[def_idx].type != ptr->packet_type)
|
||||
goto error_hfi_packet;
|
||||
|
||||
memcpy(out_pkt, in_pkt, ptr->size);
|
||||
|
||||
return 0;
|
||||
|
||||
error_hfi_packet:
|
||||
dprintk(CVP_ERR, "%s incorrect packet: size=%d type=%d sessionid=%d\n",
|
||||
__func__, ptr->size, ptr->packet_type, ptr->session_id);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int get_hfi_ssr_type(enum hal_ssr_trigger_type type)
|
||||
{
|
||||
int rc = HFI_TEST_SSR_HW_WDOG_IRQ;
|
||||
|
||||
switch (type) {
|
||||
case SSR_ERR_FATAL:
|
||||
rc = HFI_TEST_SSR_SW_ERR_FATAL;
|
||||
break;
|
||||
case SSR_SW_DIV_BY_ZERO:
|
||||
rc = HFI_TEST_SSR_SW_DIV_BY_ZERO;
|
||||
break;
|
||||
case SSR_HW_WDOG_IRQ:
|
||||
rc = HFI_TEST_SSR_HW_WDOG_IRQ;
|
||||
break;
|
||||
default:
|
||||
dprintk(CVP_WARN,
|
||||
"SSR trigger type not recognized, using WDOG.\n");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_ssr_cmd(enum hal_ssr_trigger_type type,
|
||||
struct cvp_hfi_cmd_sys_test_ssr_packet *pkt)
|
||||
{
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "Invalid params, device: %pK\n", pkt);
|
||||
return -EINVAL;
|
||||
}
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_test_ssr_packet);
|
||||
pkt->packet_type = HFI_CMD_SYS_TEST_SSR;
|
||||
pkt->trigger_type = get_hfi_ssr_type(type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cvp_create_pkt_cmd_sys_image_version(
|
||||
struct cvp_hfi_cmd_sys_get_property_packet *pkt)
|
||||
{
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "%s invalid param :%pK\n", __func__, pkt);
|
||||
return -EINVAL;
|
||||
}
|
||||
pkt->size = sizeof(struct cvp_hfi_cmd_sys_get_property_packet);
|
||||
pkt->packet_type = HFI_CMD_SYS_GET_PROPERTY;
|
||||
pkt->num_properties = 1;
|
||||
pkt->rg_property_data[0] = HFI_PROPERTY_SYS_IMAGE_VERSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cvp_hfi_packetization_ops hfi_default = {
|
||||
.sys_init = cvp_create_pkt_cmd_sys_init,
|
||||
.sys_pc_prep = cvp_create_pkt_cmd_sys_pc_prep,
|
||||
.sys_power_control = cvp_create_pkt_cmd_sys_power_control,
|
||||
.sys_set_resource = cvp_create_pkt_cmd_sys_set_resource,
|
||||
.sys_debug_config = cvp_create_pkt_cmd_sys_debug_config,
|
||||
.sys_coverage_config = cvp_create_pkt_cmd_sys_coverage_config,
|
||||
.sys_set_idle_indicator = cvp_create_pkt_cmd_sys_set_idle_indicator,
|
||||
.sys_release_resource = cvp_create_pkt_cmd_sys_release_resource,
|
||||
.sys_image_version = cvp_create_pkt_cmd_sys_image_version,
|
||||
.sys_ubwc_config = create_pkt_cmd_sys_ubwc_config,
|
||||
.ssr_cmd = cvp_create_pkt_ssr_cmd,
|
||||
.session_init = cvp_create_pkt_cmd_sys_session_init,
|
||||
.session_cmd = cvp_create_pkt_cmd_session_cmd,
|
||||
.session_set_buffers =
|
||||
cvp_create_pkt_cmd_session_set_buffers,
|
||||
.session_release_buffers =
|
||||
cvp_create_pkt_cmd_session_release_buffers,
|
||||
.session_send = cvp_create_pkt_cmd_session_send,
|
||||
};
|
||||
|
||||
struct cvp_hfi_packetization_ops *cvp_hfi_get_pkt_ops_handle(
|
||||
enum hfi_packetization_type type)
|
||||
{
|
||||
dprintk(CVP_HFI, "%s selected\n",
|
||||
type == HFI_PACKETIZATION_4XX ?
|
||||
"4xx packetization" : "Unknown hfi");
|
||||
|
||||
switch (type) {
|
||||
case HFI_PACKETIZATION_4XX:
|
||||
return &hfi_default;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
75
qcom/opensource/eva-kernel/msm/eva/hfi_packetization.h
Normal file
75
qcom/opensource/eva-kernel/msm/eva/hfi_packetization.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef __HFI_PACKETIZATION__
|
||||
#define __HFI_PACKETIZATION__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "cvp_hfi_helper.h"
|
||||
#include "cvp_hfi.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
|
||||
#define call_hfi_pkt_op(q, op, ...) \
|
||||
(((q) && (q)->pkt_ops && (q)->pkt_ops->op) ? \
|
||||
((q)->pkt_ops->op(__VA_ARGS__)) : 0)
|
||||
|
||||
enum hfi_packetization_type {
|
||||
HFI_PACKETIZATION_4XX,
|
||||
};
|
||||
|
||||
struct cvp_hfi_packetization_ops {
|
||||
int (*sys_init)(struct cvp_hfi_cmd_sys_init_packet *pkt, u32 arch_type);
|
||||
int (*sys_pc_prep)(struct cvp_hfi_cmd_sys_pc_prep_packet *pkt);
|
||||
int (*sys_power_control)(
|
||||
struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 enable);
|
||||
int (*sys_set_resource)(
|
||||
struct cvp_hfi_cmd_sys_set_resource_packet *pkt,
|
||||
struct cvp_resource_hdr *resource_hdr,
|
||||
void *resource_value);
|
||||
int (*sys_debug_config)(struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 mode);
|
||||
int (*sys_coverage_config)(
|
||||
struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 mode);
|
||||
int (*sys_set_idle_indicator)(
|
||||
struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 mode);
|
||||
int (*sys_release_resource)(
|
||||
struct cvp_hfi_cmd_sys_release_resource_packet *pkt,
|
||||
struct cvp_resource_hdr *resource_hdr);
|
||||
int (*sys_image_version)(
|
||||
struct cvp_hfi_cmd_sys_get_property_packet *pkt);
|
||||
int (*sys_ubwc_config)(struct cvp_hfi_cmd_sys_set_property_packet *pkt,
|
||||
struct msm_cvp_ubwc_config_data *ubwc_config);
|
||||
int (*ssr_cmd)(enum hal_ssr_trigger_type type,
|
||||
struct cvp_hfi_cmd_sys_test_ssr_packet *pkt);
|
||||
int (*session_init)(
|
||||
struct cvp_hfi_cmd_sys_session_init_packet *pkt,
|
||||
struct cvp_hal_session *session);
|
||||
int (*session_cmd)(struct cvp_hal_session_cmd_pkt *pkt,
|
||||
int pkt_type, struct cvp_hal_session *session);
|
||||
int (*session_set_buffers)(
|
||||
void *pkt,
|
||||
struct cvp_hal_session *session,
|
||||
u32 iova,
|
||||
u32 size);
|
||||
int (*session_release_buffers)(
|
||||
void *pkt,
|
||||
struct cvp_hal_session *session);
|
||||
int (*session_get_buf_req)(
|
||||
struct cvp_hfi_cmd_session_get_property_packet *pkt,
|
||||
struct cvp_hal_session *session);
|
||||
int (*session_sync_process)(
|
||||
struct cvp_hfi_cmd_session_sync_process_packet *pkt,
|
||||
struct cvp_hal_session *session);
|
||||
int (*session_send)(
|
||||
struct eva_kmd_hfi_packet *out_pkt,
|
||||
struct cvp_hal_session *session,
|
||||
struct eva_kmd_hfi_packet *in_pkt);
|
||||
};
|
||||
|
||||
struct cvp_hfi_packetization_ops *cvp_hfi_get_pkt_ops_handle(
|
||||
enum hfi_packetization_type);
|
||||
#endif
|
748
qcom/opensource/eva-kernel/msm/eva/hfi_response_handler.c
Normal file
748
qcom/opensource/eva-kernel/msm/eva/hfi_response_handler.c
Normal file
@ -0,0 +1,748 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/hash.h>
|
||||
#include <linux/soc/qcom/smem.h>
|
||||
#include "cvp_hfi_helper.h"
|
||||
#include "cvp_hfi_io.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "cvp_hfi.h"
|
||||
#include "msm_cvp_common.h"
|
||||
|
||||
extern struct msm_cvp_drv *cvp_driver;
|
||||
|
||||
static enum cvp_status hfi_map_err_status(u32 hfi_err)
|
||||
{
|
||||
enum cvp_status cvp_err;
|
||||
|
||||
switch (hfi_err) {
|
||||
case HFI_ERR_NONE:
|
||||
cvp_err = CVP_ERR_NONE;
|
||||
break;
|
||||
case HFI_ERR_SYS_FATAL:
|
||||
cvp_err = CVP_ERR_HW_FATAL;
|
||||
break;
|
||||
case HFI_ERR_SYS_NOC_ERROR:
|
||||
cvp_err = CVP_ERR_NOC_ERROR;
|
||||
break;
|
||||
case HFI_ERR_SYS_VERSION_MISMATCH:
|
||||
case HFI_ERR_SYS_INVALID_PARAMETER:
|
||||
case HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE:
|
||||
case HFI_ERR_SESSION_INVALID_PARAMETER:
|
||||
case HFI_ERR_SESSION_INVALID_SESSION_ID:
|
||||
case HFI_ERR_SESSION_INVALID_STREAM_ID:
|
||||
cvp_err = CVP_ERR_BAD_PARAM;
|
||||
break;
|
||||
case HFI_ERR_SYS_INSUFFICIENT_RESOURCES:
|
||||
case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY:
|
||||
case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
|
||||
case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES:
|
||||
case HFI_ERR_SESSION_UNSUPPORTED_STREAM:
|
||||
cvp_err = CVP_ERR_NOT_SUPPORTED;
|
||||
break;
|
||||
case HFI_ERR_SYS_MAX_SESSIONS_REACHED:
|
||||
cvp_err = CVP_ERR_MAX_CLIENTS;
|
||||
break;
|
||||
case HFI_ERR_SYS_SESSION_IN_USE:
|
||||
cvp_err = CVP_ERR_CLIENT_PRESENT;
|
||||
break;
|
||||
case HFI_ERR_SESSION_FATAL:
|
||||
cvp_err = CVP_ERR_CLIENT_FATAL;
|
||||
break;
|
||||
case HFI_ERR_SESSION_BAD_POINTER:
|
||||
cvp_err = CVP_ERR_BAD_PARAM;
|
||||
break;
|
||||
case HFI_ERR_SESSION_INCORRECT_STATE_OPERATION:
|
||||
cvp_err = CVP_ERR_BAD_STATE;
|
||||
break;
|
||||
default:
|
||||
cvp_err = CVP_ERR_FAIL;
|
||||
break;
|
||||
}
|
||||
return cvp_err;
|
||||
}
|
||||
|
||||
static int hfi_process_sys_error(u32 device_id,
|
||||
struct cvp_hfi_msg_event_notify_packet *pkt,
|
||||
struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->event_data1);
|
||||
|
||||
info->response_type = HAL_SYS_ERROR;
|
||||
info->response.cmd = cmd_done;
|
||||
dprintk(CVP_ERR, "Received FW sys error %#x\n", pkt->event_data1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfi_process_session_error(u32 device_id,
|
||||
struct cvp_hfi_msg_event_notify_packet *pkt,
|
||||
struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->event_data1);
|
||||
cmd_done.size = pkt->event_data2;
|
||||
info->response.cmd = cmd_done;
|
||||
dprintk(CVP_WARN, "Received: SESSION_ERROR with event data 1 2: %#x %#x\n",
|
||||
pkt->event_data1, pkt->event_data2);
|
||||
switch (pkt->event_data1) {
|
||||
/* Ignore below errors */
|
||||
case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
|
||||
case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
|
||||
dprintk(CVP_INFO, "Non Fatal: HFI_EVENT_SESSION_ERROR\n");
|
||||
info->response_type = HAL_RESPONSE_UNUSED;
|
||||
break;
|
||||
default:
|
||||
dprintk(CVP_ERR,
|
||||
"%s: session %x id %#x, data1 %#x, data2 %#x\n",
|
||||
__func__, pkt->session_id, pkt->event_id,
|
||||
pkt->event_data1, pkt->event_data2);
|
||||
info->response_type = HAL_SESSION_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfi_process_event_notify(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_event_notify_packet *pkt =
|
||||
(struct cvp_hfi_msg_event_notify_packet *)hdr;
|
||||
|
||||
dprintk(CVP_HFI, "Received: EVENT_NOTIFY\n");
|
||||
|
||||
if (pkt->size < sizeof(struct cvp_hfi_msg_event_notify_packet)) {
|
||||
dprintk(CVP_ERR, "Invalid Params\n");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
switch (pkt->event_id) {
|
||||
case HFI_EVENT_SYS_ERROR:
|
||||
dprintk(CVP_ERR, "HFI_EVENT_SYS_ERROR: %d, %#x\n",
|
||||
pkt->event_data1, pkt->event_data2);
|
||||
return hfi_process_sys_error(device_id, pkt, info);
|
||||
|
||||
case HFI_EVENT_SESSION_ERROR:
|
||||
return hfi_process_session_error(device_id, pkt, info);
|
||||
|
||||
default:
|
||||
*info = (struct msm_cvp_cb_info) {
|
||||
.response_type = HAL_RESPONSE_UNUSED,
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int hfi_process_sys_init_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_sys_init_done_packet *pkt =
|
||||
(struct cvp_hfi_msg_sys_init_done_packet *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
enum cvp_status status = CVP_ERR_NONE;
|
||||
|
||||
dprintk(CVP_CORE, "RECEIVED: SYS_INIT_DONE\n");
|
||||
if (sizeof(struct cvp_hfi_msg_sys_init_done_packet) > pkt->size) {
|
||||
dprintk(CVP_ERR, "%s: bad_pkt_size: %d\n", __func__,
|
||||
pkt->size);
|
||||
return -E2BIG;
|
||||
}
|
||||
if (!pkt->num_properties) {
|
||||
dprintk(CVP_CORE,
|
||||
"hal_process_sys_init_done: no_properties\n");
|
||||
goto err_no_prop;
|
||||
}
|
||||
|
||||
status = hfi_map_err_status(pkt->error_type);
|
||||
if (status) {
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, status, pkt->packet_type, pkt->error_type);
|
||||
goto err_no_prop;
|
||||
}
|
||||
|
||||
err_no_prop:
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = NULL;
|
||||
cmd_done.status = (u32)status;
|
||||
cmd_done.size = sizeof(struct cvp_hal_sys_init_done);
|
||||
|
||||
info->response_type = HAL_SYS_INIT_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum cvp_status cvp_hfi_process_sys_init_done_prop_read(
|
||||
struct cvp_hfi_msg_sys_init_done_packet *pkt,
|
||||
struct cvp_hal_sys_init_done *sys_init_done)
|
||||
{
|
||||
enum cvp_status status = CVP_ERR_NONE;
|
||||
u32 rem_bytes, num_properties;
|
||||
u8 *data_ptr;
|
||||
|
||||
if (!pkt || !sys_init_done) {
|
||||
dprintk(CVP_ERR,
|
||||
"hfi_msg_sys_init_done: Invalid input\n");
|
||||
return CVP_ERR_FAIL;
|
||||
}
|
||||
|
||||
rem_bytes = pkt->size - sizeof(struct
|
||||
cvp_hfi_msg_sys_init_done_packet) + sizeof(u32);
|
||||
|
||||
if (!rem_bytes) {
|
||||
dprintk(CVP_ERR,
|
||||
"hfi_msg_sys_init_done: missing_prop_info\n");
|
||||
return CVP_ERR_FAIL;
|
||||
}
|
||||
|
||||
status = hfi_map_err_status(pkt->error_type);
|
||||
if (status) {
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, status, pkt->packet_type, pkt->error_type);
|
||||
return status;
|
||||
}
|
||||
|
||||
data_ptr = (u8 *) &pkt->rg_property_data[0];
|
||||
num_properties = pkt->num_properties;
|
||||
dprintk(CVP_HFI,
|
||||
"%s: data_start %pK, num_properties %#x\n",
|
||||
__func__, data_ptr, num_properties);
|
||||
|
||||
sys_init_done->capabilities = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
static int hfi_process_session_init_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_sys_session_init_done_packet *pkt =
|
||||
(struct cvp_hfi_msg_sys_session_init_done_packet *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
struct cvp_hal_session_init_done session_init_done = { {0} };
|
||||
|
||||
dprintk(CVP_SESS, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id);
|
||||
|
||||
if (sizeof(struct cvp_hfi_msg_sys_session_init_done_packet)
|
||||
> pkt->size) {
|
||||
dprintk(CVP_ERR,
|
||||
"hal_process_session_init_done: bad_pkt_size\n");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->error_type);
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.data.session_init_done = session_init_done;
|
||||
cmd_done.size = sizeof(struct cvp_hal_session_init_done);
|
||||
|
||||
info->response_type = HAL_SESSION_INIT_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int hfi_process_session_end_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_sys_session_end_done_packet *pkt =
|
||||
(struct cvp_hfi_msg_sys_session_end_done_packet *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
|
||||
dprintk(CVP_SESS, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id);
|
||||
|
||||
if (!pkt || pkt->size !=
|
||||
sizeof(struct cvp_hfi_msg_sys_session_end_done_packet)) {
|
||||
dprintk(CVP_ERR, "%s: bad packet/packet size\n", __func__);
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->error_type);
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.size = 0;
|
||||
|
||||
info->response_type = HAL_SESSION_END_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfi_process_session_abort_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_sys_session_abort_done_packet *pkt =
|
||||
(struct cvp_hfi_msg_sys_session_abort_done_packet *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
|
||||
dprintk(CVP_SESS, "RECEIVED: SESSION_ABORT_DONE[%#x]\n",
|
||||
pkt->session_id);
|
||||
|
||||
if (!pkt || pkt->size !=
|
||||
sizeof(struct cvp_hfi_msg_sys_session_abort_done_packet)) {
|
||||
dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n",
|
||||
__func__, pkt ? pkt->size : 0);
|
||||
return -E2BIG;
|
||||
}
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->error_type);
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.size = 0;
|
||||
|
||||
info->response_type = HAL_SESSION_ABORT_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfi_process_session_set_buf_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_session_hdr *pkt =
|
||||
(struct cvp_hfi_msg_session_hdr *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
unsigned int pkt_size = get_msg_size(pkt);
|
||||
|
||||
if (!pkt || pkt->size < pkt_size) {
|
||||
dprintk(CVP_ERR, "bad packet/packet size %d\n",
|
||||
pkt ? pkt->size : 0);
|
||||
return -E2BIG;
|
||||
}
|
||||
dprintk(CVP_SESS, "RECEIVED:CVP_SET_BUFFER_DONE[%#x]\n",
|
||||
pkt->session_id);
|
||||
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt);
|
||||
cmd_done.status = hfi_map_err_status(get_msg_errorcode(pkt));
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.size = 0;
|
||||
|
||||
info->response_type = HAL_SESSION_SET_BUFFER_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfi_process_session_flush_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt =
|
||||
(struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
|
||||
dprintk(CVP_SESS, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n",
|
||||
pkt->session_id);
|
||||
|
||||
if (!pkt || pkt->size <
|
||||
sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) {
|
||||
dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n",
|
||||
__func__, pkt ? pkt->size : 0);
|
||||
return -E2BIG;
|
||||
}
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->error_type);
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.size = 0;
|
||||
|
||||
info->response_type = HAL_SESSION_FLUSH_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfi_process_session_start_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt =
|
||||
(struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
|
||||
dprintk(CVP_SESS, "RECEIVED: SESSION_START_DONE[%#x]\n",
|
||||
pkt->session_id);
|
||||
|
||||
if (!pkt || pkt->size <
|
||||
sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) {
|
||||
dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n",
|
||||
__func__, pkt ? pkt->size : 0);
|
||||
return -E2BIG;
|
||||
}
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->error_type);
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.size = 0;
|
||||
|
||||
info->response_type = HAL_SESSION_START_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfi_process_session_stop_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt =
|
||||
(struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
|
||||
dprintk(CVP_SESS, "RECEIVED: SESSION_STOP_DONE[%#x]\n",
|
||||
pkt->session_id);
|
||||
|
||||
if (!pkt || pkt->size <
|
||||
sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) {
|
||||
dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n",
|
||||
__func__, pkt ? pkt->size : 0);
|
||||
return -E2BIG;
|
||||
}
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->error_type);
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.size = 0;
|
||||
|
||||
info->response_type = HAL_SESSION_STOP_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int hfi_process_session_rel_buf_done(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_session_hdr *pkt =
|
||||
(struct cvp_hfi_msg_session_hdr *)hdr;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
unsigned int pkt_size = get_msg_size(pkt);
|
||||
|
||||
if (!pkt || pkt->size < pkt_size) {
|
||||
dprintk(CVP_ERR, "bad packet/packet size %d\n",
|
||||
pkt ? pkt->size : 0);
|
||||
return -E2BIG;
|
||||
}
|
||||
dprintk(CVP_SESS, "RECEIVED:CVP_RELEASE_BUFFER_DONE[%#x]\n",
|
||||
pkt->session_id);
|
||||
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt);
|
||||
cmd_done.status = hfi_map_err_status(get_msg_errorcode(pkt));
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.size = 0;
|
||||
|
||||
info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core,
|
||||
unsigned int session_id)
|
||||
{
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
bool match = false;
|
||||
int count = 0;
|
||||
|
||||
if (!core || !session_id)
|
||||
return NULL;
|
||||
|
||||
retry:
|
||||
if (mutex_trylock(&core->lock)) {
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
if (hash32_ptr(inst->session) == session_id) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inst = match && kref_get_unless_zero(&inst->kref) ? inst : NULL;
|
||||
mutex_unlock(&core->lock);
|
||||
} else {
|
||||
if (core->state == CVP_CORE_UNINIT)
|
||||
return NULL;
|
||||
usleep_range(100, 200);
|
||||
count++;
|
||||
if (count < 1000)
|
||||
goto retry;
|
||||
else
|
||||
dprintk(CVP_ERR, "timeout locking core mutex\n");
|
||||
}
|
||||
|
||||
return inst;
|
||||
|
||||
}
|
||||
|
||||
static int hfi_process_session_dump_notify(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
struct msm_cvp_core *core;
|
||||
struct cvp_session_prop *session_prop;
|
||||
unsigned int session_id;
|
||||
struct msm_cvp_cb_cmd_done cmd_done = {0};
|
||||
struct cvp_hfi_dumpmsg_session_hdr *pkt =
|
||||
(struct cvp_hfi_dumpmsg_session_hdr *)hdr;
|
||||
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "%s: invalid param\n", __func__);
|
||||
return -EINVAL;
|
||||
} else if (pkt->size > sizeof(struct cvp_hfi_dumpmsg_session_hdr)) {
|
||||
dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size);
|
||||
return -E2BIG;
|
||||
}
|
||||
session_id = get_msg_session_id(pkt);
|
||||
core = cvp_driver->cvp_core;
|
||||
inst = cvp_get_inst_from_id(core, session_id);
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: invalid session\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
session_prop = &inst->prop;
|
||||
session_prop->dump_offset = pkt->dump_offset;
|
||||
session_prop->dump_size = pkt->dump_size;
|
||||
|
||||
dprintk(CVP_SESS, "RECEIVED: SESSION_DUMP[%x]\n", session_id);
|
||||
|
||||
cmd_done.device_id = device_id;
|
||||
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
|
||||
cmd_done.status = hfi_map_err_status(pkt->error_type);
|
||||
if (cmd_done.status)
|
||||
dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
|
||||
__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
|
||||
cmd_done.size = 0;
|
||||
|
||||
info->response_type = HAL_SESSION_DUMP_NOTIFY;
|
||||
info->response.cmd = cmd_done;
|
||||
|
||||
cvp_put_inst(inst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfi_process_session_cvp_msg(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_session_hdr *pkt =
|
||||
(struct cvp_hfi_msg_session_hdr *)hdr;
|
||||
struct cvp_session_msg *sess_msg;
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
struct msm_cvp_core *core;
|
||||
unsigned int session_id;
|
||||
struct cvp_session_queue *sq;
|
||||
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "%s: invalid param\n", __func__);
|
||||
return -EINVAL;
|
||||
} else if (pkt->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int)) {
|
||||
dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size);
|
||||
return -E2BIG;
|
||||
}
|
||||
session_id = get_msg_session_id(pkt);
|
||||
core = cvp_driver->cvp_core;
|
||||
inst = cvp_get_inst_from_id(core, session_id);
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: invalid session\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pkt->client_data.kdata & FENCE_BIT)
|
||||
sq = &inst->session_queue_fence;
|
||||
else
|
||||
sq = &inst->session_queue;
|
||||
|
||||
sess_msg = cvp_kmem_cache_zalloc(&cvp_driver->msg_cache, GFP_KERNEL);
|
||||
if (sess_msg == NULL) {
|
||||
dprintk(CVP_ERR, "%s runs out msg cache memory\n", __func__);
|
||||
goto error_no_mem;
|
||||
}
|
||||
|
||||
memcpy(&sess_msg->pkt, pkt, get_msg_size(pkt));
|
||||
|
||||
dprintk(CVP_HFI,
|
||||
"%s: Received msg %x cmd_done.status=%d sessionid=%x\n",
|
||||
__func__, pkt->packet_type,
|
||||
hfi_map_err_status(get_msg_errorcode(pkt)), session_id);
|
||||
|
||||
spin_lock(&sq->lock);
|
||||
if (sq->msg_count >= MAX_NUM_MSGS_PER_SESSION) {
|
||||
dprintk(CVP_ERR, "Reached session queue size limit\n");
|
||||
goto error_handle_msg;
|
||||
}
|
||||
list_add_tail(&sess_msg->node, &sq->msgs);
|
||||
sq->msg_count++;
|
||||
spin_unlock(&sq->lock);
|
||||
|
||||
wake_up_all(&sq->wq);
|
||||
|
||||
info->response_type = HAL_NO_RESP;
|
||||
|
||||
cvp_put_inst(inst);
|
||||
return 0;
|
||||
|
||||
error_handle_msg:
|
||||
spin_unlock(&sq->lock);
|
||||
cvp_kmem_cache_free(&cvp_driver->msg_cache, sess_msg);
|
||||
error_no_mem:
|
||||
cvp_put_inst(inst);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void hfi_process_sys_get_prop_image_version(
|
||||
struct cvp_hfi_msg_sys_property_info_packet *pkt)
|
||||
{
|
||||
int i = 0;
|
||||
const u32 version_string_size = 128;
|
||||
u8 *str_image_version;
|
||||
int req_bytes;
|
||||
|
||||
req_bytes = pkt->size - sizeof(*pkt);
|
||||
if (req_bytes < (signed int)version_string_size ||
|
||||
!pkt->rg_property_data[1] ||
|
||||
pkt->num_properties > 1) {
|
||||
dprintk(CVP_ERR, "%s: bad_pkt: %d\n", __func__, req_bytes);
|
||||
return;
|
||||
}
|
||||
str_image_version = (u8 *)&pkt->rg_property_data[1];
|
||||
/*
|
||||
* The version string returned by firmware includes null
|
||||
* characters at the start and in between. Replace the null
|
||||
* characters with space, to print the version info.
|
||||
*/
|
||||
for (i = 0; i < version_string_size; i++) {
|
||||
if (str_image_version[i] != '\0')
|
||||
cvp_driver->fw_version[i] = str_image_version[i];
|
||||
else
|
||||
cvp_driver->fw_version[i] = ' ';
|
||||
}
|
||||
cvp_driver->fw_version[i - 1] = '\0';
|
||||
dprintk(CVP_HFI, "F/W version: %s\n", cvp_driver->fw_version);
|
||||
}
|
||||
|
||||
static int hfi_process_sys_property_info(u32 device_id,
|
||||
void *hdr, struct msm_cvp_cb_info *info)
|
||||
{
|
||||
struct cvp_hfi_msg_sys_property_info_packet *pkt =
|
||||
(struct cvp_hfi_msg_sys_property_info_packet *)hdr;
|
||||
if (!pkt) {
|
||||
dprintk(CVP_ERR, "%s: invalid param\n", __func__);
|
||||
return -EINVAL;
|
||||
} else if (pkt->size > sizeof(*pkt)) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: bad_pkt_size %d\n", __func__, pkt->size);
|
||||
return -E2BIG;
|
||||
} else if (!pkt->num_properties) {
|
||||
dprintk(CVP_WARN,
|
||||
"%s: no_properties\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (pkt->rg_property_data[0]) {
|
||||
case HFI_PROPERTY_SYS_IMAGE_VERSION:
|
||||
hfi_process_sys_get_prop_image_version(pkt);
|
||||
|
||||
*info = (struct msm_cvp_cb_info) {
|
||||
.response_type = HAL_RESPONSE_UNUSED,
|
||||
};
|
||||
return 0;
|
||||
default:
|
||||
dprintk(CVP_WARN,
|
||||
"%s: unknown_prop_id: %x\n",
|
||||
__func__, pkt->rg_property_data[0]);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int cvp_hfi_process_msg_packet(u32 device_id, void *hdr,
|
||||
struct msm_cvp_cb_info *info)
|
||||
{
|
||||
typedef int (*pkt_func_def)(u32, void *, struct msm_cvp_cb_info *info);
|
||||
pkt_func_def pkt_func = NULL;
|
||||
struct cvp_hal_msg_pkt_hdr *msg_hdr = (struct cvp_hal_msg_pkt_hdr *)hdr;
|
||||
|
||||
if (!info || !msg_hdr || msg_hdr->size < CVP_IFACEQ_MIN_PKT_SIZE) {
|
||||
dprintk(CVP_ERR, "%s: bad packet/packet size\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dprintk(CVP_HFI, "Received HFI MSG with type %#x\n", msg_hdr->packet);
|
||||
switch (msg_hdr->packet) {
|
||||
case HFI_MSG_EVENT_NOTIFY:
|
||||
pkt_func = (pkt_func_def)hfi_process_event_notify;
|
||||
break;
|
||||
case HFI_MSG_SYS_INIT_DONE:
|
||||
pkt_func = (pkt_func_def)hfi_process_sys_init_done;
|
||||
break;
|
||||
case HFI_MSG_SYS_SESSION_INIT_DONE:
|
||||
pkt_func = (pkt_func_def)hfi_process_session_init_done;
|
||||
break;
|
||||
case HFI_MSG_SYS_PROPERTY_INFO:
|
||||
pkt_func = (pkt_func_def)hfi_process_sys_property_info;
|
||||
break;
|
||||
case HFI_MSG_SYS_SESSION_END_DONE:
|
||||
pkt_func = (pkt_func_def)hfi_process_session_end_done;
|
||||
break;
|
||||
case HFI_MSG_SESSION_CVP_SET_BUFFERS:
|
||||
pkt_func = (pkt_func_def) hfi_process_session_set_buf_done;
|
||||
break;
|
||||
case HFI_MSG_SESSION_CVP_RELEASE_BUFFERS:
|
||||
pkt_func = (pkt_func_def)hfi_process_session_rel_buf_done;
|
||||
break;
|
||||
case HFI_MSG_SYS_SESSION_ABORT_DONE:
|
||||
pkt_func = (pkt_func_def)hfi_process_session_abort_done;
|
||||
break;
|
||||
case HFI_MSG_SESSION_CVP_FLUSH:
|
||||
pkt_func = (pkt_func_def)hfi_process_session_flush_done;
|
||||
break;
|
||||
case HFI_MSG_SESSION_EVA_START:
|
||||
pkt_func = (pkt_func_def)hfi_process_session_start_done;
|
||||
break;
|
||||
case HFI_MSG_SESSION_EVA_STOP:
|
||||
pkt_func = (pkt_func_def)hfi_process_session_stop_done;
|
||||
break;
|
||||
case HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY:
|
||||
pkt_func = (pkt_func_def)hfi_process_session_dump_notify;
|
||||
break;
|
||||
default:
|
||||
dprintk(CVP_HFI, "Use default msg handler: %#x\n",
|
||||
msg_hdr->packet);
|
||||
pkt_func = (pkt_func_def)hfi_process_session_cvp_msg;
|
||||
break;
|
||||
}
|
||||
|
||||
return pkt_func ?
|
||||
pkt_func(device_id, hdr, info) : -ENOTSUPP;
|
||||
}
|
1708
qcom/opensource/eva-kernel/msm/eva/msm_cvp.c
Normal file
1708
qcom/opensource/eva-kernel/msm/eva/msm_cvp.c
Normal file
File diff suppressed because it is too large
Load Diff
49
qcom/opensource/eva-kernel/msm/eva/msm_cvp.h
Normal file
49
qcom/opensource/eva-kernel/msm/eva/msm_cvp.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_CVP_H_
|
||||
#define _MSM_CVP_H_
|
||||
|
||||
#include "msm_cvp_internal.h"
|
||||
#include "msm_cvp_common.h"
|
||||
#include "msm_cvp_clocks.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
#include "eva_shared_def.h"
|
||||
|
||||
static inline bool is_buf_param_valid(u32 buf_num, u32 offset)
|
||||
{
|
||||
int max_buf_num;
|
||||
|
||||
max_buf_num = sizeof(struct eva_kmd_hfi_packet) /
|
||||
sizeof(struct cvp_buf_type);
|
||||
|
||||
if (buf_num > max_buf_num)
|
||||
return false;
|
||||
if ((offset > U32_MAX/sizeof(u32)) ||
|
||||
(offset*sizeof(u32) > U32_MAX - buf_num * sizeof(struct cvp_buf_type)))
|
||||
return false;
|
||||
if ((offset * sizeof(u32) + buf_num * sizeof(struct cvp_buf_type)) >
|
||||
sizeof(struct eva_kmd_hfi_packet))
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg);
|
||||
int msm_cvp_session_init(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_session_deinit(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_session_create(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_session_delete(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_session_start(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg);
|
||||
int msm_cvp_session_stop(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg);
|
||||
int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session);
|
||||
int msm_cvp_update_power(struct msm_cvp_inst *inst);
|
||||
int cvp_clean_session_queues(struct msm_cvp_inst *inst);
|
||||
#endif
|
2480
qcom/opensource/eva-kernel/msm/eva/msm_cvp_buf.c
Normal file
2480
qcom/opensource/eva-kernel/msm/eva/msm_cvp_buf.c
Normal file
File diff suppressed because it is too large
Load Diff
244
qcom/opensource/eva-kernel/msm/eva/msm_cvp_buf.h
Normal file
244
qcom/opensource/eva-kernel/msm/eva/msm_cvp_buf.h
Normal file
@ -0,0 +1,244 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_CVP_BUF_H_
|
||||
#define _MSM_CVP_BUF_H_
|
||||
|
||||
#include <linux/poll.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-heap.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <media/msm_eva_private.h>
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
#define MAX_FRAME_BUFFER_NUMS 40
|
||||
#define MAX_DMABUF_NUMS 64
|
||||
#define IS_CVP_BUF_VALID(buf, smem) \
|
||||
((buf->size <= smem->size) && \
|
||||
(buf->size <= smem->size - buf->offset))
|
||||
|
||||
struct msm_cvp_inst;
|
||||
struct msm_cvp_platform_resources;
|
||||
struct msm_cvp_list;
|
||||
|
||||
enum smem_cache_ops {
|
||||
SMEM_CACHE_CLEAN,
|
||||
SMEM_CACHE_INVALIDATE,
|
||||
SMEM_CACHE_CLEAN_INVALIDATE,
|
||||
};
|
||||
|
||||
enum smem_prop {
|
||||
SMEM_UNCACHED = 0x1,
|
||||
SMEM_CACHED = 0x2,
|
||||
SMEM_SECURE = 0x4,
|
||||
SMEM_CDSP = 0x8,
|
||||
SMEM_NON_PIXEL = 0x10,
|
||||
SMEM_PIXEL = 0x20,
|
||||
SMEM_CAMERA = 0x40,
|
||||
SMEM_PERSIST = 0x100,
|
||||
};
|
||||
|
||||
struct msm_cvp_list {
|
||||
struct list_head list;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static inline void INIT_MSM_CVP_LIST(struct msm_cvp_list *mlist)
|
||||
{
|
||||
mutex_init(&mlist->lock);
|
||||
INIT_LIST_HEAD(&mlist->list);
|
||||
}
|
||||
|
||||
static inline void DEINIT_MSM_CVP_LIST(struct msm_cvp_list *mlist)
|
||||
{
|
||||
mutex_destroy(&mlist->lock);
|
||||
}
|
||||
|
||||
struct cvp_dma_mapping_info {
|
||||
struct device *dev;
|
||||
struct iommu_domain *domain;
|
||||
struct sg_table *table;
|
||||
struct dma_buf_attachment *attach;
|
||||
struct dma_buf *buf;
|
||||
void *cb_info;
|
||||
};
|
||||
|
||||
struct msm_cvp_smem {
|
||||
struct list_head list;
|
||||
atomic_t refcount;
|
||||
struct dma_buf *dma_buf;
|
||||
void *kvaddr;
|
||||
u32 device_addr;
|
||||
dma_addr_t dma_handle;
|
||||
u32 size;
|
||||
u32 bitmap_index;
|
||||
u32 flags;
|
||||
u32 pkt_type;
|
||||
u32 buf_idx;
|
||||
u32 fd;
|
||||
struct cvp_dma_mapping_info mapping_info;
|
||||
};
|
||||
|
||||
struct msm_cvp_wncc_buffer {
|
||||
u32 fd;
|
||||
u32 iova;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct cvp_dmamap_cache {
|
||||
unsigned long usage_bitmap;
|
||||
struct mutex lock;
|
||||
struct msm_cvp_smem *entries[MAX_DMABUF_NUMS];
|
||||
unsigned int nr;
|
||||
};
|
||||
|
||||
static inline void INIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache)
|
||||
{
|
||||
mutex_init(&cache->lock);
|
||||
cache->usage_bitmap = 0;
|
||||
cache->nr = 0;
|
||||
}
|
||||
|
||||
static inline void DEINIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache)
|
||||
{
|
||||
mutex_destroy(&cache->lock);
|
||||
cache->usage_bitmap = 0;
|
||||
cache->nr = 0;
|
||||
}
|
||||
|
||||
#define INPUT_FENCE_BITMASK 0x1
|
||||
#define OUTPUT_FENCE_BITMASK 0x2
|
||||
|
||||
/* Track source of dma_buf allocator/owner */
|
||||
enum buffer_owner {
|
||||
DRIVER, /* Allocated by KMD, for CPU driver */
|
||||
CLIENT, /* Allocated by Client (DSP or CPU) */
|
||||
DSP, /* Allocated by KMD, for DSP driver */
|
||||
MAX_OWNER
|
||||
};
|
||||
|
||||
struct cvp_internal_buf {
|
||||
struct list_head list;
|
||||
s32 fd;
|
||||
u32 size;
|
||||
u32 offset;
|
||||
u32 type;
|
||||
u32 index;
|
||||
u64 ktid;
|
||||
enum buffer_owner ownership;
|
||||
struct msm_cvp_smem *smem;
|
||||
};
|
||||
|
||||
struct msm_cvp_frame {
|
||||
struct list_head list;
|
||||
struct cvp_internal_buf bufs[MAX_FRAME_BUFFER_NUMS];
|
||||
u32 nr;
|
||||
u64 ktid;
|
||||
u32 pkt_type;
|
||||
};
|
||||
|
||||
struct cvp_frame_bufs {
|
||||
u64 ktid;
|
||||
u32 nr;
|
||||
struct msm_cvp_smem smem[MAX_FRAME_BUFFER_NUMS];
|
||||
};
|
||||
|
||||
struct wncc_oob_buf {
|
||||
u32 bitmap_idx;
|
||||
struct eva_kmd_oob_wncc *buf;
|
||||
};
|
||||
|
||||
#define NUM_WNCC_BUFS 8
|
||||
struct cvp_oob_pool {
|
||||
struct mutex lock;
|
||||
bool allocated;
|
||||
u32 used_bitmap;
|
||||
struct eva_kmd_oob_wncc *bufs[NUM_WNCC_BUFS];
|
||||
};
|
||||
|
||||
extern struct cvp_oob_pool wncc_buf_pool;
|
||||
|
||||
void print_cvp_buffer(u32 tag, const char *str,
|
||||
struct msm_cvp_inst *inst,
|
||||
struct cvp_internal_buf *cbuf);
|
||||
void print_cvp_buffer(u32 tag, const char *str,
|
||||
struct msm_cvp_inst *inst,
|
||||
struct cvp_internal_buf *cbuf);
|
||||
void print_client_buffer(u32 tag, const char *str,
|
||||
struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_buffer *cbuf);
|
||||
int print_smem(u32 tag, const char *str,
|
||||
struct msm_cvp_inst *inst,
|
||||
struct msm_cvp_smem *smem);
|
||||
|
||||
/*Kernel DMA buffer and IOMMU mapping functions*/
|
||||
int msm_cvp_smem_alloc(size_t size, u32 align, int map_kernel,
|
||||
void *res, struct msm_cvp_smem *smem);
|
||||
int msm_cvp_smem_free(struct msm_cvp_smem *smem);
|
||||
struct context_bank_info *msm_cvp_smem_get_context_bank(
|
||||
struct msm_cvp_platform_resources *res,
|
||||
unsigned int flags);
|
||||
int msm_cvp_map_smem(struct msm_cvp_inst *inst,
|
||||
struct msm_cvp_smem *smem,
|
||||
const char *str);
|
||||
int msm_cvp_unmap_smem(struct msm_cvp_inst *inst,
|
||||
struct msm_cvp_smem *smem,
|
||||
const char *str);
|
||||
struct dma_buf *msm_cvp_smem_get_dma_buf(int fd);
|
||||
void msm_cvp_smem_put_dma_buf(void *dma_buf);
|
||||
int msm_cvp_smem_cache_operations(struct dma_buf *dbuf,
|
||||
enum smem_cache_ops cache_op,
|
||||
unsigned long offset,
|
||||
unsigned long size);
|
||||
int msm_cvp_map_ipcc_regs(u32 *iova);
|
||||
int msm_cvp_unmap_ipcc_regs(u32 iova);
|
||||
|
||||
/* CVP driver internal buffer management functions*/
|
||||
struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst,
|
||||
u32 buffer_size);
|
||||
int cvp_release_arp_buffers(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_buffer *buf);
|
||||
int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_buffer *buf);
|
||||
int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_buffer *buf,
|
||||
int32_t pid,
|
||||
uint32_t *iova);
|
||||
int msm_cvp_unmap_buf_dsp_new(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_buffer *buf);
|
||||
int msm_cvp_map_buf_wncc(struct msm_cvp_inst* inst,
|
||||
struct eva_kmd_buffer* buf);
|
||||
int msm_cvp_unmap_buf_wncc(struct msm_cvp_inst* inst,
|
||||
struct eva_kmd_buffer* buf);
|
||||
int msm_cvp_proc_oob(struct msm_cvp_inst* inst,
|
||||
struct eva_kmd_hfi_packet* in_pkt);
|
||||
void msm_cvp_cache_operations(struct msm_cvp_smem *smem,
|
||||
u32 type, u32 offset, u32 size);
|
||||
int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_hfi_packet *in_pkt,
|
||||
unsigned int offset, unsigned int buf_num);
|
||||
int msm_cvp_map_user_persist(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_hfi_packet *in_pkt,
|
||||
unsigned int offset, unsigned int buf_num);
|
||||
int msm_cvp_map_frame(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_hfi_packet *in_pkt,
|
||||
unsigned int offset, unsigned int buf_num);
|
||||
void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid);
|
||||
int msm_cvp_register_buffer(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_buffer *buf);
|
||||
int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst,
|
||||
struct eva_kmd_buffer *buf);
|
||||
int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst);
|
||||
void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log);
|
||||
int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst,
|
||||
struct cvp_internal_buf *buf,
|
||||
u32 buffer_size,
|
||||
u32 secure_type);
|
||||
int cvp_release_dsp_buffers(struct msm_cvp_inst *inst,
|
||||
struct cvp_internal_buf *buf);
|
||||
#endif
|
494
qcom/opensource/eva-kernel/msm/eva/msm_cvp_clocks.c
Normal file
494
qcom/opensource/eva-kernel/msm/eva/msm_cvp_clocks.c
Normal file
@ -0,0 +1,494 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "msm_cvp_common.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "msm_cvp_clocks.h"
|
||||
|
||||
static bool __mmrm_client_check_scaling_supported(
|
||||
struct mmrm_client_desc *client)
|
||||
{
|
||||
#ifdef CVP_MMRM_ENABLED
|
||||
return mmrm_client_check_scaling_supported(
|
||||
client->client_type,
|
||||
client->client_info.desc.client_domain);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct mmrm_client *__mmrm_client_register(
|
||||
struct mmrm_client_desc *client)
|
||||
{
|
||||
#ifdef CVP_MMRM_ENABLED
|
||||
return mmrm_client_register(client);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __mmrm_client_deregister(struct mmrm_client *client)
|
||||
{
|
||||
#ifdef CVP_MMRM_ENABLED
|
||||
return mmrm_client_deregister(client);
|
||||
#else
|
||||
return -ENODEV;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __mmrm_client_set_value_in_range(struct mmrm_client *client,
|
||||
struct mmrm_client_data *data,
|
||||
struct mmrm_client_res_value *val)
|
||||
{
|
||||
#ifdef CVP_MMRM_ENABLED
|
||||
return mmrm_client_set_value_in_range(client, data, val);
|
||||
#else
|
||||
return -ENODEV;
|
||||
#endif
|
||||
}
|
||||
|
||||
int msm_cvp_mmrm_notifier_cb(
|
||||
struct mmrm_client_notifier_data *notifier_data)
|
||||
{
|
||||
if (!notifier_data) {
|
||||
dprintk(CVP_WARN, "%s Invalid notifier data: %pK\n",
|
||||
__func__, notifier_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (notifier_data->cb_type == MMRM_CLIENT_RESOURCE_VALUE_CHANGE) {
|
||||
struct iris_hfi_device *dev = notifier_data->pvt_data;
|
||||
|
||||
dprintk(CVP_PWR,
|
||||
"%s: Clock %s throttled from %ld to %ld \n",
|
||||
__func__, dev->mmrm_desc.client_info.desc.name,
|
||||
notifier_data->cb_data.val_chng.old_val,
|
||||
notifier_data->cb_data.val_chng.new_val);
|
||||
|
||||
/*TODO: if need further handling to notify eva client */
|
||||
} else {
|
||||
dprintk(CVP_WARN, "%s Invalid cb type: %d\n",
|
||||
__func__, notifier_data->cb_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_cvp_set_clocks(struct msm_cvp_core *core)
|
||||
{
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
int rc;
|
||||
|
||||
if (!core || !core->dev_ops) {
|
||||
dprintk(CVP_ERR, "%s Invalid args: %pK\n", __func__, core);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ops_tbl = core->dev_ops;
|
||||
rc = call_hfi_op(ops_tbl, scale_clocks,
|
||||
ops_tbl->hfi_device_data, core->curr_freq);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_cvp_mmrm_register(struct iris_hfi_device *device)
|
||||
{
|
||||
int rc = 0;
|
||||
struct clock_info *cl = NULL;
|
||||
char *name;
|
||||
bool isSupport;
|
||||
|
||||
if (!device) {
|
||||
dprintk(CVP_ERR, "%s invalid device\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
name = (char *)device->mmrm_desc.client_info.desc.name;
|
||||
device->mmrm_cvp=NULL;
|
||||
device->mmrm_desc.client_type=MMRM_CLIENT_CLOCK;
|
||||
device->mmrm_desc.priority=MMRM_CLIENT_PRIOR_LOW;
|
||||
device->mmrm_desc.pvt_data = device;
|
||||
device->mmrm_desc.notifier_callback_fn = msm_cvp_mmrm_notifier_cb;
|
||||
device->mmrm_desc.client_info.desc.client_domain=MMRM_CLIENT_DOMAIN_CVP;
|
||||
|
||||
iris_hfi_for_each_clock(device, cl) {
|
||||
if (cl->has_scaling) { /* only clk source enabled in dtsi */
|
||||
device->mmrm_desc.client_info.desc.clk=cl->clk;
|
||||
device->mmrm_desc.client_info.desc.client_id=cl->clk_id;
|
||||
strlcpy(name, cl->name,
|
||||
sizeof(device->mmrm_desc.client_info.desc.name));
|
||||
}
|
||||
}
|
||||
|
||||
isSupport = __mmrm_client_check_scaling_supported(&(device->mmrm_desc));
|
||||
|
||||
if (!isSupport) {
|
||||
dprintk(CVP_PWR, "%s: mmrm not supported, flag: %d\n",
|
||||
__func__, isSupport);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dprintk(CVP_PWR,
|
||||
"%s: Register for %s, clk_id %d\n",
|
||||
__func__, device->mmrm_desc.client_info.desc.name,
|
||||
device->mmrm_desc.client_info.desc.client_id);
|
||||
|
||||
device->mmrm_cvp = __mmrm_client_register(&(device->mmrm_desc));
|
||||
if (device->mmrm_cvp == NULL) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed mmrm_client_register with mmrm_cvp: %pK\n",
|
||||
__func__, device->mmrm_cvp);
|
||||
rc = -ENOENT;
|
||||
} else {
|
||||
dprintk(CVP_PWR,
|
||||
"%s: mmrm_client_register done: %pK, type:%d, uid:%ld\n",
|
||||
__func__, device->mmrm_cvp,
|
||||
device->mmrm_cvp->client_type,
|
||||
device->mmrm_cvp->client_uid);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_cvp_mmrm_deregister(struct iris_hfi_device *device)
|
||||
{
|
||||
int rc = 0;
|
||||
struct clock_info *cl = NULL;
|
||||
|
||||
if (!device) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s invalid args: device %pK \n",
|
||||
__func__, device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!device->mmrm_cvp) { // when mmrm not supported
|
||||
dprintk(CVP_ERR,
|
||||
"%s device->mmrm_cvp not initialized \n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* set clk value to 0 before deregister */
|
||||
iris_hfi_for_each_clock(device, cl) {
|
||||
if ((cl->has_scaling) && (__clk_is_enabled(cl->clk))){
|
||||
// set min freq and cur freq to 0;
|
||||
rc = msm_cvp_mmrm_set_value_in_range(device,
|
||||
0, 0);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s Failed set clock %s: %d\n",
|
||||
__func__, cl->name, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = __mmrm_client_deregister(device->mmrm_cvp);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed mmrm_client_deregister with rc: %d\n",
|
||||
__func__, rc);
|
||||
}
|
||||
|
||||
device->mmrm_cvp = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device,
|
||||
u32 freq_min, u32 freq_cur)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mmrm_client_res_value val;
|
||||
struct mmrm_client_data data;
|
||||
|
||||
if (!device) {
|
||||
dprintk(CVP_ERR, "%s invalid device\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dprintk(CVP_PWR,
|
||||
"%s: set clock rate for mmrm_cvp: %pK, type :%d, uid: %ld\n",
|
||||
__func__, device->mmrm_cvp,
|
||||
device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid);
|
||||
|
||||
val.min = freq_min;
|
||||
val.cur = freq_cur;
|
||||
data.num_hw_blocks = 1;
|
||||
data.flags = 0; /* Not MMRM_CLIENT_DATA_FLAG_RESERVE_ONLY */
|
||||
|
||||
dprintk(CVP_PWR,
|
||||
"%s: set clock rate to min %u cur %u: %d\n",
|
||||
__func__, val.min, val.cur, rc);
|
||||
|
||||
rc = __mmrm_client_set_value_in_range(device->mmrm_cvp, &data, &val);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed to set clock rate to min %u cur %u: %d\n",
|
||||
__func__, val.min, val.cur, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_cvp_set_clocks_impl(struct iris_hfi_device *device, u32 freq)
|
||||
{
|
||||
struct clock_info *cl;
|
||||
int rc = 0;
|
||||
int fsrc2clk = 3;
|
||||
// ratio factor for clock source : clk
|
||||
u32 freq_min = device->res->allowed_clks_tbl[0].clock_rate * fsrc2clk;
|
||||
|
||||
dprintk(CVP_PWR, "%s: entering with freq : %ld\n", __func__, freq);
|
||||
|
||||
iris_hfi_for_each_clock(device, cl) {
|
||||
if (cl->has_scaling) {/* has_scaling */
|
||||
device->clk_freq = freq;
|
||||
if (msm_cvp_clock_voting)
|
||||
freq = msm_cvp_clock_voting;
|
||||
|
||||
freq = freq * fsrc2clk;
|
||||
dprintk(CVP_PWR,
|
||||
"%s: clock source rate set to: %ld\n",
|
||||
__func__, freq);
|
||||
|
||||
if (device->mmrm_cvp != NULL) {
|
||||
/* min freq : 1st element value in the table */
|
||||
rc = msm_cvp_mmrm_set_value_in_range(device,
|
||||
freq_min, freq);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed set clock %s: %d\n",
|
||||
cl->name, rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dprintk(CVP_PWR,
|
||||
"%s: set clock with clk_set_rate\n",
|
||||
__func__);
|
||||
rc = clk_set_rate(cl->clk, freq);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed set clock %u %s: %d\n",
|
||||
freq, cl->name, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dprintk(CVP_PWR, "Scaling clock %s to %u\n",
|
||||
cl->name, freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_cvp_scale_clocks(struct iris_hfi_device *device)
|
||||
{
|
||||
int rc = 0;
|
||||
struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
|
||||
u32 rate = 0;
|
||||
|
||||
allowed_clks_tbl = device->res->allowed_clks_tbl;
|
||||
|
||||
rate = device->clk_freq ? device->clk_freq :
|
||||
allowed_clks_tbl[0].clock_rate;
|
||||
|
||||
dprintk(CVP_PWR, "%s: scale clock rate %d\n", __func__, rate);
|
||||
rc = msm_cvp_set_clocks_impl(device, rate);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_cvp_prepare_enable_clk(struct iris_hfi_device *device,
|
||||
const char *name)
|
||||
{
|
||||
struct clock_info *cl = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (!device) {
|
||||
dprintk(CVP_ERR, "Invalid params: %pK\n", device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iris_hfi_for_each_clock(device, cl) {
|
||||
if (strcmp(cl->name, name))
|
||||
continue;
|
||||
/*
|
||||
* For the clocks we control, set the rate prior to preparing
|
||||
* them. Since we don't really have a load at this point,
|
||||
* scale it to the lowest frequency possible
|
||||
*/
|
||||
if (!cl->clk) {
|
||||
dprintk(CVP_PWR, "%s %s already enabled by framework",
|
||||
__func__, cl->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cl->has_scaling) {
|
||||
if (device->mmrm_cvp != NULL) {
|
||||
// set min freq and cur freq to 0;
|
||||
rc = msm_cvp_mmrm_set_value_in_range(device,
|
||||
0, 0);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR,
|
||||
"%s Failed set clock %s: %d\n",
|
||||
__func__, cl->name, rc);
|
||||
}
|
||||
else {
|
||||
dprintk(CVP_PWR,
|
||||
"%s: set clock with clk_set_rate\n",
|
||||
__func__);
|
||||
clk_set_rate(cl->clk,
|
||||
clk_round_rate(cl->clk, 0));
|
||||
}
|
||||
}
|
||||
rc = clk_prepare_enable(cl->clk);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "Failed to enable clock %s\n",
|
||||
cl->name);
|
||||
return rc;
|
||||
}
|
||||
if (!__clk_is_enabled(cl->clk)) {
|
||||
dprintk(CVP_ERR, "%s: clock %s not enabled\n",
|
||||
__func__, cl->name);
|
||||
clk_disable_unprepare(cl->clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dprintk(CVP_PWR, "Clock: %s prepared and enabled\n",
|
||||
cl->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dprintk(CVP_ERR, "%s clock %s not found\n", __func__, name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device,
|
||||
const char *name)
|
||||
{
|
||||
struct clock_info *cl;
|
||||
int rc = 0;
|
||||
|
||||
if (!device) {
|
||||
dprintk(CVP_ERR, "Invalid params: %pK\n", device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iris_hfi_for_each_clock_reverse(device, cl) {
|
||||
if (strcmp(cl->name, name))
|
||||
continue;
|
||||
if (!cl->clk) {
|
||||
dprintk(CVP_PWR, "%s %s always enabled by framework",
|
||||
__func__, cl->name);
|
||||
return 0;
|
||||
}
|
||||
clk_disable_unprepare(cl->clk);
|
||||
dprintk(CVP_PWR, "Clock: %s disable and unprepare\n",
|
||||
cl->name);
|
||||
|
||||
if (cl->has_scaling) {
|
||||
if (device->mmrm_cvp != NULL) {
|
||||
// set min freq and cur freq to 0;
|
||||
rc = msm_cvp_mmrm_set_value_in_range(device,
|
||||
0, 0);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR,
|
||||
"%s Failed set clock %s: %d\n",
|
||||
__func__, cl->name, rc);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
dprintk(CVP_ERR, "%s clock %s not found\n", __func__, name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int msm_cvp_init_clocks(struct iris_hfi_device *device)
|
||||
{
|
||||
int rc = 0;
|
||||
struct clock_info *cl = NULL;
|
||||
|
||||
if (!device) {
|
||||
dprintk(CVP_ERR, "Invalid params: %pK\n", device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iris_hfi_for_each_clock(device, cl) {
|
||||
|
||||
dprintk(CVP_PWR, "%s: scalable? %d, count %d\n",
|
||||
cl->name, cl->has_scaling, cl->count);
|
||||
}
|
||||
|
||||
iris_hfi_for_each_clock(device, cl) {
|
||||
if (!cl->clk) {
|
||||
cl->clk = clk_get(&device->res->pdev->dev, cl->name);
|
||||
if (IS_ERR(cl->clk)) {
|
||||
rc = PTR_ERR(cl->clk);
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to get clock: %s, rc %d\n",
|
||||
cl->name, rc);
|
||||
cl->clk = NULL;
|
||||
goto err_clk_get;
|
||||
}
|
||||
}
|
||||
}
|
||||
device->clk_freq = 0;
|
||||
return 0;
|
||||
|
||||
err_clk_get:
|
||||
msm_cvp_deinit_clocks(device);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_cvp_deinit_clocks(struct iris_hfi_device *device)
|
||||
{
|
||||
struct clock_info *cl;
|
||||
|
||||
device->clk_freq = 0;
|
||||
iris_hfi_for_each_clock_reverse(device, cl) {
|
||||
if (cl->clk) {
|
||||
clk_put(cl->clk);
|
||||
cl->clk = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int msm_cvp_set_bw(struct msm_cvp_core *core, struct bus_info *bus, unsigned long bw)
|
||||
{
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
int rc;
|
||||
|
||||
if (!core || !core->dev_ops) {
|
||||
dprintk(CVP_ERR, "%s Invalid args: %pK\n", __func__, core);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ops_tbl = core->dev_ops;
|
||||
rc = call_hfi_op(ops_tbl, vote_bus, ops_tbl->hfi_device_data, bus, bw);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
int cvp_set_bw(struct bus_info *bus, unsigned long bw)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!bus->client)
|
||||
return -EINVAL;
|
||||
dprintk(CVP_PWR, "bus->name = %s to bw = %u\n",
|
||||
bus->name, bw);
|
||||
|
||||
rc = icc_set_bw(bus->client, bw, 0);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR, "Failed voting bus %s to ab %u\n",
|
||||
bus->name, bw);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
28
qcom/opensource/eva-kernel/msm/eva/msm_cvp_clocks.h
Normal file
28
qcom/opensource/eva-kernel/msm/eva/msm_cvp_clocks.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MSM_CVP_CLOCKS_H_
|
||||
#define _MSM_CVP_CLOCKS_H_
|
||||
#include "msm_cvp_internal.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
|
||||
int msm_cvp_set_clocks(struct msm_cvp_core *core);
|
||||
int msm_cvp_mmrm_register(struct iris_hfi_device *device);
|
||||
int msm_cvp_mmrm_deregister(struct iris_hfi_device *device);
|
||||
int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device,
|
||||
u32 freq_min, u32 freq_cur);
|
||||
int msm_cvp_set_clocks_impl(struct iris_hfi_device *device, u32 freq);
|
||||
int msm_cvp_scale_clocks(struct iris_hfi_device *device);
|
||||
int msm_cvp_prepare_enable_clk(struct iris_hfi_device *device,
|
||||
const char *name);
|
||||
int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device,
|
||||
const char *name);
|
||||
int msm_cvp_init_clocks(struct iris_hfi_device *device);
|
||||
void msm_cvp_deinit_clocks(struct iris_hfi_device *device);
|
||||
int msm_cvp_set_bw(struct msm_cvp_core *core, struct bus_info *bus, unsigned long bw);
|
||||
int cvp_set_bw(struct bus_info *bus, unsigned long bw);
|
||||
#endif
|
1431
qcom/opensource/eva-kernel/msm/eva/msm_cvp_common.c
Normal file
1431
qcom/opensource/eva-kernel/msm/eva/msm_cvp_common.c
Normal file
File diff suppressed because it is too large
Load Diff
36
qcom/opensource/eva-kernel/msm/eva/msm_cvp_common.h
Normal file
36
qcom/opensource/eva-kernel/msm/eva/msm_cvp_common.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MSM_CVP_COMMON_H_
|
||||
#define _MSM_CVP_COMMON_H_
|
||||
#include "msm_cvp_internal.h"
|
||||
|
||||
void cvp_put_inst(struct msm_cvp_inst *inst);
|
||||
struct msm_cvp_inst *cvp_get_inst(struct msm_cvp_core *core,
|
||||
void *session_id);
|
||||
struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core,
|
||||
void *session_id);
|
||||
bool is_cvp_inst_valid(struct msm_cvp_inst *inst);
|
||||
void cvp_change_inst_state(struct msm_cvp_inst *inst,
|
||||
enum instance_state state);
|
||||
int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state);
|
||||
int msm_cvp_deinit_core(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_comm_suspend(void);
|
||||
void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst);
|
||||
void msm_cvp_comm_generate_sys_error(struct msm_cvp_inst *inst);
|
||||
void handle_sys_error(enum hal_command_response cmd, void *data);
|
||||
int msm_cvp_comm_smem_cache_operations(struct msm_cvp_inst *inst,
|
||||
struct msm_cvp_smem *mem, enum smem_cache_ops cache_ops);
|
||||
int msm_cvp_comm_check_core_init(struct msm_cvp_core *core);
|
||||
int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst,
|
||||
enum hal_command_response cmd);
|
||||
int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst);
|
||||
int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst);
|
||||
int msm_cvp_noc_error_info(struct msm_cvp_core *core);
|
||||
int cvp_print_inst(u32 tag, struct msm_cvp_inst *inst);
|
||||
unsigned long long get_aon_time(void);
|
||||
#endif
|
544
qcom/opensource/eva-kernel/msm/eva/msm_cvp_core.c
Normal file
544
qcom/opensource/eva-kernel/msm/eva/msm_cvp_core.c
Normal file
@ -0,0 +1,544 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include "msm_cvp_core.h"
|
||||
#include "msm_cvp_internal.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "msm_cvp.h"
|
||||
#include "msm_cvp_common.h"
|
||||
#include <linux/delay.h>
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "msm_cvp_clocks.h"
|
||||
#include <linux/dma-buf.h>
|
||||
|
||||
#define MAX_EVENTS 30
|
||||
#define NUM_CYCLES16X16_HCD_FRAME 95
|
||||
#define NUM_CYCLES16X16_DMM_FRAME 600
|
||||
#define NUM_CYCLES16X16_NCC_FRAME 400
|
||||
#define NUM_CYCLES16X16_DS_FRAME 80
|
||||
#define NUM_CYCLESFW_FRAME 1680000
|
||||
#define NUM_DMM_MAX_FEATURE_POINTS 500
|
||||
#define CYCLES_MARGIN_IN_POWEROF2 3
|
||||
|
||||
static atomic_t nr_insts;
|
||||
|
||||
void *cvp_kmem_cache_zalloc(struct cvp_kmem_cache *k, gfp_t flags)
|
||||
{
|
||||
atomic_inc(&k->nr_objs);
|
||||
return kmem_cache_zalloc(k->cache, flags);
|
||||
}
|
||||
|
||||
void cvp_kmem_cache_free(struct cvp_kmem_cache *k, void *obj)
|
||||
{
|
||||
atomic_dec(&k->nr_objs);
|
||||
kmem_cache_free(k->cache, obj);
|
||||
}
|
||||
|
||||
int msm_cvp_poll(void *instance, struct file *filp,
|
||||
struct poll_table_struct *wait)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(msm_cvp_poll);
|
||||
|
||||
int msm_cvp_private(void *cvp_inst, unsigned int cmd,
|
||||
struct eva_kmd_arg *arg)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_inst *inst = (struct msm_cvp_inst *)cvp_inst;
|
||||
|
||||
if (!inst || !arg) {
|
||||
dprintk(CVP_ERR, "%s: invalid args\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_cvp_handle_syscall(inst, arg);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(msm_cvp_private);
|
||||
|
||||
static bool msm_cvp_check_for_inst_overload(struct msm_cvp_core *core,
|
||||
u32 *instance_count)
|
||||
{
|
||||
u32 secure_instance_count = 0;
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
bool overload = false;
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
(*instance_count)++;
|
||||
/* This flag is not updated yet for the current instance */
|
||||
if (inst->flags & CVP_SECURE)
|
||||
secure_instance_count++;
|
||||
}
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
/* Instance count includes current instance as well. */
|
||||
|
||||
if ((*instance_count >= core->resources.max_inst_count) ||
|
||||
(secure_instance_count >=
|
||||
core->resources.max_secure_inst_count))
|
||||
overload = true;
|
||||
return overload;
|
||||
}
|
||||
|
||||
static int __init_session_queue(struct msm_cvp_inst *inst)
|
||||
{
|
||||
spin_lock_init(&inst->session_queue.lock);
|
||||
INIT_LIST_HEAD(&inst->session_queue.msgs);
|
||||
inst->session_queue.msg_count = 0;
|
||||
init_waitqueue_head(&inst->session_queue.wq);
|
||||
inst->session_queue.state = QUEUE_ACTIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init_fence_queue(struct msm_cvp_inst *inst)
|
||||
{
|
||||
mutex_init(&inst->fence_cmd_queue.lock);
|
||||
INIT_LIST_HEAD(&inst->fence_cmd_queue.wait_list);
|
||||
INIT_LIST_HEAD(&inst->fence_cmd_queue.sched_list);
|
||||
init_waitqueue_head(&inst->fence_cmd_queue.wq);
|
||||
inst->fence_cmd_queue.state = QUEUE_ACTIVE;
|
||||
inst->fence_cmd_queue.mode = OP_NORMAL;
|
||||
|
||||
spin_lock_init(&inst->session_queue_fence.lock);
|
||||
INIT_LIST_HEAD(&inst->session_queue_fence.msgs);
|
||||
inst->session_queue_fence.msg_count = 0;
|
||||
init_waitqueue_head(&inst->session_queue_fence.wq);
|
||||
inst->session_queue_fence.state = QUEUE_ACTIVE;
|
||||
}
|
||||
|
||||
static void __deinit_fence_queue(struct msm_cvp_inst *inst)
|
||||
{
|
||||
mutex_destroy(&inst->fence_cmd_queue.lock);
|
||||
inst->fence_cmd_queue.state = QUEUE_INVALID;
|
||||
inst->fence_cmd_queue.mode = OP_INVALID;
|
||||
}
|
||||
|
||||
static void __deinit_session_queue(struct msm_cvp_inst *inst)
|
||||
{
|
||||
struct cvp_session_msg *msg, *tmpmsg;
|
||||
|
||||
/* free all messages */
|
||||
spin_lock(&inst->session_queue.lock);
|
||||
list_for_each_entry_safe(msg, tmpmsg, &inst->session_queue.msgs, node) {
|
||||
list_del_init(&msg->node);
|
||||
cvp_kmem_cache_free(&cvp_driver->msg_cache, msg);
|
||||
}
|
||||
inst->session_queue.msg_count = 0;
|
||||
inst->session_queue.state = QUEUE_INVALID;
|
||||
spin_unlock(&inst->session_queue.lock);
|
||||
|
||||
wake_up_all(&inst->session_queue.wq);
|
||||
}
|
||||
|
||||
struct msm_cvp_inst *msm_cvp_open(int session_type, struct task_struct *task)
|
||||
{
|
||||
struct msm_cvp_inst *inst = NULL;
|
||||
struct msm_cvp_core *core = NULL;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
u32 instance_count;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
if (!core) {
|
||||
dprintk(CVP_ERR, "%s CVP core not initialized\n", __func__);
|
||||
goto err_invalid_core;
|
||||
}
|
||||
|
||||
if (!msm_cvp_auto_pil && session_type == MSM_CVP_BOOT) {
|
||||
dprintk(CVP_SESS, "Auto PIL disabled, bypass CVP init at boot");
|
||||
goto err_invalid_core;
|
||||
}
|
||||
|
||||
core->resources.max_inst_count = MAX_SUPPORTED_INSTANCES;
|
||||
if (msm_cvp_check_for_inst_overload(core, &instance_count)) {
|
||||
dprintk(CVP_ERR, "Instance num reached Max, rejecting session");
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(inst, &core->instances, list)
|
||||
cvp_print_inst(CVP_ERR, inst);
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "Failed to allocate memory\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_invalid_core;
|
||||
}
|
||||
|
||||
pr_info(CVP_DBG_TAG "%s opening cvp instance: %pK type %d cnt %d\n",
|
||||
"sess", task->comm, inst, session_type, instance_count);
|
||||
mutex_init(&inst->sync_lock);
|
||||
mutex_init(&inst->lock);
|
||||
spin_lock_init(&inst->event_handler.lock);
|
||||
|
||||
INIT_MSM_CVP_LIST(&inst->persistbufs);
|
||||
INIT_DMAMAP_CACHE(&inst->dma_cache);
|
||||
INIT_MSM_CVP_LIST(&inst->cvpdspbufs);
|
||||
INIT_MSM_CVP_LIST(&inst->cvpwnccbufs);
|
||||
INIT_MSM_CVP_LIST(&inst->frames);
|
||||
|
||||
inst->cvpwnccbufs_num = 0;
|
||||
inst->cvpwnccbufs_table = NULL;
|
||||
|
||||
init_waitqueue_head(&inst->event_handler.wq);
|
||||
|
||||
kref_init(&inst->kref);
|
||||
|
||||
inst->session_type = session_type;
|
||||
inst->state = MSM_CVP_CORE_UNINIT_DONE;
|
||||
inst->core = core;
|
||||
inst->clk_data.min_freq = 0;
|
||||
inst->clk_data.curr_freq = 0;
|
||||
inst->clk_data.ddr_bw = 0;
|
||||
inst->clk_data.sys_cache_bw = 0;
|
||||
inst->clk_data.bitrate = 0;
|
||||
|
||||
for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
|
||||
i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
|
||||
init_completion(&inst->completions[i]);
|
||||
}
|
||||
|
||||
msm_cvp_session_init(inst);
|
||||
|
||||
__init_fence_queue(inst);
|
||||
mutex_lock(&core->lock);
|
||||
mutex_lock(&core->clk_lock);
|
||||
list_add_tail(&inst->list, &core->instances);
|
||||
atomic_inc(&nr_insts);
|
||||
mutex_unlock(&core->clk_lock);
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
rc = __init_session_queue(inst);
|
||||
if (rc)
|
||||
goto fail_init;
|
||||
|
||||
rc = msm_cvp_comm_try_state(inst, MSM_CVP_CORE_INIT_DONE);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to move cvp instance to init state\n");
|
||||
goto fail_init;
|
||||
}
|
||||
|
||||
inst->debugfs_root =
|
||||
msm_cvp_debugfs_init_inst(inst, core->debugfs_root);
|
||||
strlcpy(inst->proc_name, task->comm, TASK_COMM_LEN);
|
||||
|
||||
return inst;
|
||||
fail_init:
|
||||
__deinit_session_queue(inst);
|
||||
__deinit_fence_queue(inst);
|
||||
mutex_lock(&core->lock);
|
||||
list_del(&inst->list);
|
||||
mutex_unlock(&core->lock);
|
||||
mutex_destroy(&inst->sync_lock);
|
||||
mutex_destroy(&inst->lock);
|
||||
|
||||
DEINIT_MSM_CVP_LIST(&inst->persistbufs);
|
||||
DEINIT_DMAMAP_CACHE(&inst->dma_cache);
|
||||
DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs);
|
||||
DEINIT_MSM_CVP_LIST(&inst->cvpwnccbufs);
|
||||
DEINIT_MSM_CVP_LIST(&inst->frames);
|
||||
|
||||
kfree(inst);
|
||||
inst = NULL;
|
||||
err_invalid_core:
|
||||
return inst;
|
||||
}
|
||||
EXPORT_SYMBOL(msm_cvp_open);
|
||||
|
||||
static void msm_cvp_clean_sess_queue(struct msm_cvp_inst *inst,
|
||||
struct cvp_session_queue *sq)
|
||||
{
|
||||
struct cvp_session_msg *mptr, *dummy;
|
||||
u64 ktid = 0LL;
|
||||
|
||||
check_again:
|
||||
spin_lock(&sq->lock);
|
||||
if (sq->msg_count && sq->state != QUEUE_ACTIVE) {
|
||||
list_for_each_entry_safe(mptr, dummy, &sq->msgs, node) {
|
||||
ktid = mptr->pkt.client_data.kdata;
|
||||
if (ktid) {
|
||||
list_del_init(&mptr->node);
|
||||
sq->msg_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&sq->lock);
|
||||
|
||||
if (ktid) {
|
||||
msm_cvp_unmap_frame(inst, ktid);
|
||||
cvp_kmem_cache_free(&cvp_driver->msg_cache, mptr);
|
||||
mptr = NULL;
|
||||
ktid = 0LL;
|
||||
goto check_again;
|
||||
}
|
||||
}
|
||||
|
||||
static int msm_cvp_cleanup_instance(struct msm_cvp_inst *inst)
|
||||
{
|
||||
bool empty;
|
||||
int rc, max_retries;
|
||||
struct msm_cvp_frame *frame;
|
||||
struct cvp_session_queue *sq, *sqf;
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
struct msm_cvp_inst *tmp;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sqf = &inst->session_queue_fence;
|
||||
sq = &inst->session_queue;
|
||||
|
||||
max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 5;
|
||||
msm_cvp_session_queue_stop(inst);
|
||||
|
||||
wait_dsp:
|
||||
mutex_lock(&inst->cvpdspbufs.lock);
|
||||
empty = list_empty(&inst->cvpdspbufs.list);
|
||||
if (!empty && max_retries > 0) {
|
||||
mutex_unlock(&inst->cvpdspbufs.lock);
|
||||
usleep_range(2000, 3000);
|
||||
max_retries--;
|
||||
goto wait_dsp;
|
||||
}
|
||||
mutex_unlock(&inst->cvpdspbufs.lock);
|
||||
|
||||
if (!empty) {
|
||||
dprintk(CVP_WARN, "Failed sess %pK DSP frame pending\n", inst);
|
||||
/*
|
||||
* A session is either DSP session or CPU session, cannot have both
|
||||
* DSP and frame buffers
|
||||
*/
|
||||
goto stop_session;
|
||||
}
|
||||
|
||||
max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1;
|
||||
wait_frame:
|
||||
mutex_lock(&inst->frames.lock);
|
||||
empty = list_empty(&inst->frames.list);
|
||||
if (!empty && max_retries > 0) {
|
||||
mutex_unlock(&inst->frames.lock);
|
||||
usleep_range(1000, 2000);
|
||||
msm_cvp_clean_sess_queue(inst, sqf);
|
||||
msm_cvp_clean_sess_queue(inst, sq);
|
||||
max_retries--;
|
||||
goto wait_frame;
|
||||
}
|
||||
mutex_unlock(&inst->frames.lock);
|
||||
|
||||
if (!empty) {
|
||||
dprintk(CVP_WARN,
|
||||
"Failed to process frames before session %pK close\n",
|
||||
inst);
|
||||
mutex_lock(&inst->frames.lock);
|
||||
list_for_each_entry(frame, &inst->frames.list, list)
|
||||
dprintk(CVP_WARN, "Unprocessed frame %08x ktid %llu\n",
|
||||
frame->pkt_type, frame->ktid);
|
||||
mutex_unlock(&inst->frames.lock);
|
||||
inst->core->synx_ftbl->cvp_dump_fence_queue(inst);
|
||||
}
|
||||
|
||||
stop_session:
|
||||
tmp = cvp_get_inst_validate(inst->core, inst);
|
||||
if (!tmp) {
|
||||
dprintk(CVP_ERR, "%s has a invalid session %llx\n",
|
||||
__func__, inst);
|
||||
goto exit;
|
||||
}
|
||||
spin_lock(&sq->lock);
|
||||
if (sq->state == QUEUE_STOP) {
|
||||
spin_unlock(&sq->lock);
|
||||
dprintk(CVP_WARN,
|
||||
"%s: Double stop session - inst %llx, sess %llx, %s of type %d\n",
|
||||
__func__, inst, inst->session, inst->proc_name, inst->session_type);
|
||||
goto release_arp;
|
||||
}
|
||||
spin_unlock(&sq->lock);
|
||||
|
||||
if (!empty) {
|
||||
/* STOP SESSION to avoid SMMU fault after releasing ARP */
|
||||
ops_tbl = inst->core->dev_ops;
|
||||
rc = call_hfi_op(ops_tbl, session_stop, (void *)inst->session);
|
||||
if (rc) {
|
||||
dprintk(CVP_WARN, "%s: cannot stop session rc %d\n",
|
||||
__func__, rc);
|
||||
goto release_arp;
|
||||
}
|
||||
|
||||
/*Fail stop session, release arp later may cause smmu fault*/
|
||||
rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_STOP_DONE);
|
||||
if (rc) {
|
||||
dprintk(CVP_WARN, "%s: wait for sess_stop fail, rc %d\n",
|
||||
__func__, rc);
|
||||
} else {
|
||||
spin_lock(&sq->lock);
|
||||
sq->state = QUEUE_STOP;
|
||||
spin_unlock(&sq->lock);
|
||||
}
|
||||
/* Continue to release ARP anyway */
|
||||
}
|
||||
release_arp:
|
||||
cvp_put_inst(tmp);
|
||||
exit:
|
||||
if (cvp_release_arp_buffers(inst))
|
||||
dprintk_rl(CVP_WARN,
|
||||
"Failed to release persist buffers\n");
|
||||
|
||||
if (inst->prop.type == HFI_SESSION_FD
|
||||
|| inst->prop.type == HFI_SESSION_DMM) {
|
||||
spin_lock(&inst->core->resources.pm_qos.lock);
|
||||
if (inst->core->resources.pm_qos.off_vote_cnt > 0)
|
||||
inst->core->resources.pm_qos.off_vote_cnt--;
|
||||
else
|
||||
dprintk(CVP_INFO, "%s Unexpected pm_qos off vote %d\n",
|
||||
__func__,
|
||||
inst->core->resources.pm_qos.off_vote_cnt);
|
||||
spin_unlock(&inst->core->resources.pm_qos.lock);
|
||||
ops_tbl = inst->core->dev_ops;
|
||||
call_hfi_op(ops_tbl, pm_qos_update, ops_tbl->hfi_device_data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_cvp_destroy(struct msm_cvp_inst *inst)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = inst->core;
|
||||
|
||||
if (inst->session_type == MSM_CVP_DSP) {
|
||||
cvp_dsp_del_sess(inst->dsp_handle, inst);
|
||||
inst->task = NULL;
|
||||
}
|
||||
|
||||
/* Ensure no path has core->clk_lock and core->lock sequence */
|
||||
mutex_lock(&core->lock);
|
||||
mutex_lock(&core->clk_lock);
|
||||
/* inst->list lives in core->instances */
|
||||
list_del(&inst->list);
|
||||
atomic_dec(&nr_insts);
|
||||
mutex_unlock(&core->clk_lock);
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
DEINIT_MSM_CVP_LIST(&inst->persistbufs);
|
||||
DEINIT_DMAMAP_CACHE(&inst->dma_cache);
|
||||
DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs);
|
||||
DEINIT_MSM_CVP_LIST(&inst->cvpwnccbufs);
|
||||
DEINIT_MSM_CVP_LIST(&inst->frames);
|
||||
|
||||
kfree(inst->cvpwnccbufs_table);
|
||||
inst->cvpwnccbufs_table = NULL;
|
||||
|
||||
mutex_destroy(&inst->sync_lock);
|
||||
mutex_destroy(&inst->lock);
|
||||
|
||||
msm_cvp_debugfs_deinit_inst(inst);
|
||||
|
||||
__deinit_session_queue(inst);
|
||||
__deinit_fence_queue(inst);
|
||||
core->synx_ftbl->cvp_sess_deinit_synx(inst);
|
||||
|
||||
pr_info(CVP_DBG_TAG
|
||||
"closed cvp instance: %pK session_id = %d type %d %d\n",
|
||||
inst->proc_name, inst, hash32_ptr(inst->session),
|
||||
inst->session_type, core->smem_leak_count);
|
||||
inst->session = (void *)0xdeadbeef;
|
||||
if (atomic_read(&inst->smem_count) > 0) {
|
||||
dprintk(CVP_WARN, "Session closed with %d unmapped smems\n",
|
||||
atomic_read(&inst->smem_count));
|
||||
core->smem_leak_count += atomic_read(&inst->smem_count);
|
||||
}
|
||||
kfree(inst);
|
||||
inst = NULL;
|
||||
dprintk(CVP_SESS,
|
||||
"sys-stat: nr_insts %d msgs %d, frames %d, bufs %d, smems %d\n",
|
||||
atomic_read(&nr_insts),
|
||||
atomic_read(&cvp_driver->msg_cache.nr_objs),
|
||||
atomic_read(&cvp_driver->frame_cache.nr_objs),
|
||||
atomic_read(&cvp_driver->buf_cache.nr_objs),
|
||||
atomic_read(&cvp_driver->smem_cache.nr_objs));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void close_helper(struct kref *kref)
|
||||
{
|
||||
struct msm_cvp_inst *inst;
|
||||
|
||||
if (!kref)
|
||||
return;
|
||||
inst = container_of(kref, struct msm_cvp_inst, kref);
|
||||
|
||||
msm_cvp_destroy(inst);
|
||||
}
|
||||
|
||||
int msm_cvp_close(void *instance)
|
||||
{
|
||||
struct msm_cvp_inst *inst = instance;
|
||||
int rc = 0;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk_rl(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_info(CVP_DBG_TAG
|
||||
"to close instance: %pK session_id = %d type %d state %d\n",
|
||||
inst->proc_name, inst, hash32_ptr(inst->session),
|
||||
inst->session_type, inst->state);
|
||||
|
||||
if (inst->session == 0) {
|
||||
if (inst->state >= MSM_CVP_CORE_INIT_DONE &&
|
||||
inst->state < MSM_CVP_OPEN_DONE) {
|
||||
/* Session is not created, no ARP */
|
||||
inst->state = MSM_CVP_CORE_UNINIT;
|
||||
goto exit;
|
||||
}
|
||||
if (inst->state == MSM_CVP_CORE_UNINIT)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (inst->session_type != MSM_CVP_BOOT) {
|
||||
rc = msm_cvp_cleanup_instance(inst);
|
||||
if (rc)
|
||||
return -EINVAL;
|
||||
msm_cvp_session_deinit(inst);
|
||||
}
|
||||
|
||||
rc = msm_cvp_comm_try_state(inst, MSM_CVP_CORE_UNINIT);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to move inst %pK to uninit state\n", inst);
|
||||
rc = msm_cvp_deinit_core(inst);
|
||||
}
|
||||
|
||||
msm_cvp_comm_session_clean(inst);
|
||||
exit:
|
||||
kref_put(&inst->kref, close_helper);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(msm_cvp_close);
|
||||
|
||||
int msm_cvp_suspend(void)
|
||||
{
|
||||
return msm_cvp_comm_suspend();
|
||||
}
|
||||
EXPORT_SYMBOL(msm_cvp_suspend);
|
40
qcom/opensource/eva-kernel/msm/eva/msm_cvp_core.h
Normal file
40
qcom/opensource/eva-kernel/msm/eva/msm_cvp_core.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_CVP_CORE_H_
|
||||
#define _MSM_CVP_CORE_H_
|
||||
|
||||
#include <linux/poll.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <media/msm_eva_private.h>
|
||||
#include "msm_cvp_buf.h"
|
||||
#include "msm_cvp_synx.h"
|
||||
|
||||
#define DDR_TYPE_LPDDR4 0x6
|
||||
#define DDR_TYPE_LPDDR4X 0x7
|
||||
#define DDR_TYPE_LPDDR4Y 0x8
|
||||
#define DDR_TYPE_LPDDR5 0x9
|
||||
|
||||
enum session_type {
|
||||
MSM_CVP_USER = 1,
|
||||
MSM_CVP_KERNEL,
|
||||
MSM_CVP_BOOT,
|
||||
MSM_CVP_DSP,
|
||||
MSM_CVP_UNKNOWN,
|
||||
MSM_CVP_MAX_DEVICES = MSM_CVP_UNKNOWN,
|
||||
};
|
||||
|
||||
struct msm_cvp_inst *msm_cvp_open(int session_type, struct task_struct *task);
|
||||
int msm_cvp_close(void *instance);
|
||||
int msm_cvp_suspend(void);
|
||||
int msm_cvp_poll(void *instance, struct file *filp,
|
||||
struct poll_table_struct *pt);
|
||||
int msm_cvp_private(void *cvp_inst, unsigned int cmd,
|
||||
struct eva_kmd_arg *arg);
|
||||
|
||||
#endif
|
630
qcom/opensource/eva-kernel/msm/eva/msm_cvp_debug.c
Normal file
630
qcom/opensource/eva-kernel/msm/eva/msm_cvp_debug.c
Normal file
@ -0,0 +1,630 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "msm_cvp_common.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
|
||||
#define MAX_SSR_STRING_LEN 10
|
||||
int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW;
|
||||
EXPORT_SYMBOL(msm_cvp_debug);
|
||||
|
||||
int msm_cvp_debug_out = CVP_OUT_PRINTK;
|
||||
EXPORT_SYMBOL(msm_cvp_debug_out);
|
||||
|
||||
int msm_cvp_fw_debug = 0x18;
|
||||
int msm_cvp_fw_debug_mode = 1;
|
||||
int msm_cvp_fw_low_power_mode = 1;
|
||||
bool msm_cvp_fw_coverage = !true;
|
||||
bool msm_cvp_auto_pil = true;
|
||||
bool msm_cvp_cacheop_enabled = true;
|
||||
bool msm_cvp_thermal_mitigation_disabled = !true;
|
||||
bool msm_cvp_cacheop_disabled = !true;
|
||||
int msm_cvp_clock_voting = !1;
|
||||
bool msm_cvp_syscache_disable = !true;
|
||||
bool msm_cvp_dsp_disable = !true;
|
||||
#ifdef CVP_MMRM_ENABLED
|
||||
bool msm_cvp_mmrm_enabled = true;
|
||||
#else
|
||||
bool msm_cvp_mmrm_enabled = !true;
|
||||
#endif
|
||||
bool msm_cvp_dcvs_disable = !true;
|
||||
int msm_cvp_minidump_enable = !1;
|
||||
int cvp_kernel_fence_enabled = 2;
|
||||
int msm_cvp_hw_wd_recovery = 1;
|
||||
|
||||
#define MAX_DBG_BUF_SIZE 4096
|
||||
|
||||
struct cvp_core_inst_pair {
|
||||
struct msm_cvp_core *core;
|
||||
struct msm_cvp_inst *inst;
|
||||
};
|
||||
|
||||
static int core_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
dprintk(CVP_INFO, "%s: Enter\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 write_str(char *buffer,
|
||||
size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
u32 len;
|
||||
|
||||
va_start(args, fmt);
|
||||
len = vscnprintf(buffer, size, fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t core_info_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct msm_cvp_core *core = file->private_data;
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
struct cvp_hal_fw_info fw_info = { {0} };
|
||||
char *dbuf, *cur, *end;
|
||||
int i = 0, rc = 0;
|
||||
ssize_t len = 0;
|
||||
|
||||
if (!core || !core->dev_ops) {
|
||||
dprintk(CVP_ERR, "Invalid params, core: %pK\n", core);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL);
|
||||
if (!dbuf) {
|
||||
dprintk(CVP_ERR, "%s: Allocation failed!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cur = dbuf;
|
||||
end = cur + MAX_DBG_BUF_SIZE;
|
||||
ops_tbl = core->dev_ops;
|
||||
|
||||
cur += write_str(cur, end - cur, "===============================\n");
|
||||
cur += write_str(cur, end - cur, "CORE %d: %pK\n", 0, core);
|
||||
cur += write_str(cur, end - cur, "===============================\n");
|
||||
cur += write_str(cur, end - cur, "Core state: %d\n", core->state);
|
||||
rc = call_hfi_op(ops_tbl, get_fw_info, ops_tbl->hfi_device_data, &fw_info);
|
||||
if (rc) {
|
||||
dprintk(CVP_WARN, "Failed to read FW info\n");
|
||||
goto err_fw_info;
|
||||
}
|
||||
|
||||
cur += write_str(cur, end - cur,
|
||||
"FW version : %s\n", &fw_info.version);
|
||||
cur += write_str(cur, end - cur,
|
||||
"base addr: 0x%x\n", fw_info.base_addr);
|
||||
cur += write_str(cur, end - cur,
|
||||
"register_base: 0x%x\n", fw_info.register_base);
|
||||
cur += write_str(cur, end - cur,
|
||||
"register_size: %u\n", fw_info.register_size);
|
||||
cur += write_str(cur, end - cur, "irq: %u\n", fw_info.irq);
|
||||
|
||||
err_fw_info:
|
||||
for (i = SYS_MSG_START; i < SYS_MSG_END; i++) {
|
||||
cur += write_str(cur, end - cur, "completions[%d]: %s\n", i,
|
||||
completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
|
||||
"pending" : "done");
|
||||
}
|
||||
len = simple_read_from_buffer(buf, count, ppos,
|
||||
dbuf, cur - dbuf);
|
||||
|
||||
kfree(dbuf);
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations core_info_fops = {
|
||||
.open = core_info_open,
|
||||
.read = core_info_read,
|
||||
};
|
||||
|
||||
static int trigger_ssr_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
dprintk(CVP_INFO, "%s: Enter\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
unsigned long ssr_trigger_val = 0;
|
||||
int rc = 0;
|
||||
struct msm_cvp_core *core = filp->private_data;
|
||||
size_t size = MAX_SSR_STRING_LEN;
|
||||
char kbuf[MAX_SSR_STRING_LEN + 1] = {0};
|
||||
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (!count)
|
||||
goto exit;
|
||||
|
||||
if (count < size)
|
||||
size = count;
|
||||
|
||||
if (copy_from_user(kbuf, buf, size)) {
|
||||
dprintk(CVP_WARN, "%s User memory fault\n", __func__);
|
||||
rc = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = kstrtoul(kbuf, 0, &ssr_trigger_val);
|
||||
if (rc) {
|
||||
dprintk(CVP_WARN, "returning error err %d\n", rc);
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
msm_cvp_trigger_ssr(core, ssr_trigger_val);
|
||||
rc = count;
|
||||
}
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct file_operations ssr_fops = {
|
||||
.open = trigger_ssr_open,
|
||||
.write = trigger_ssr_write,
|
||||
};
|
||||
|
||||
static int cvp_power_get(void *data, u64 *val)
|
||||
{
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
struct msm_cvp_core *core;
|
||||
struct iris_hfi_device *hfi_device;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
if (!core)
|
||||
return 0;
|
||||
ops_tbl = core->dev_ops;
|
||||
if (!ops_tbl)
|
||||
return 0;
|
||||
|
||||
hfi_device = ops_tbl->hfi_device_data;
|
||||
if (!hfi_device)
|
||||
return 0;
|
||||
|
||||
*val = hfi_device->power_enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MIN_PC_INTERVAL 1000
|
||||
#define MAX_PC_INTERVAL 1000000
|
||||
|
||||
static int cvp_power_set(void *data, u64 val)
|
||||
{
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
struct msm_cvp_core *core;
|
||||
struct iris_hfi_device *hfi_device;
|
||||
int rc = 0;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
if (!core)
|
||||
return -EINVAL;
|
||||
|
||||
ops_tbl = core->dev_ops;
|
||||
if (!ops_tbl)
|
||||
return -EINVAL;
|
||||
|
||||
hfi_device = ops_tbl->hfi_device_data;
|
||||
if (!hfi_device)
|
||||
return -EINVAL;
|
||||
|
||||
if (val >= MAX_PC_INTERVAL) {
|
||||
hfi_device->res->sw_power_collapsible = 0;
|
||||
} else if (val > MIN_PC_INTERVAL) {
|
||||
hfi_device->res->sw_power_collapsible = 1;
|
||||
hfi_device->res->msm_cvp_pwr_collapse_delay =
|
||||
(unsigned int)val;
|
||||
}
|
||||
|
||||
if (core->state == CVP_CORE_UNINIT)
|
||||
return -EINVAL;
|
||||
|
||||
if (val > 0) {
|
||||
rc = call_hfi_op(ops_tbl, resume, ops_tbl->hfi_device_data);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR, "debugfs fail to power on cvp\n");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(cvp_pwr_fops, cvp_power_get, cvp_power_set, "%llu\n");
|
||||
|
||||
struct dentry *msm_cvp_debugfs_init_drv(void)
|
||||
{
|
||||
struct dentry *dir = NULL;
|
||||
|
||||
dir = debugfs_create_dir("msm_cvp", NULL);
|
||||
if (IS_ERR_OR_NULL(dir)) {
|
||||
dir = NULL;
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
debugfs_create_x32("debug_level", 0644, dir, &msm_cvp_debug);
|
||||
debugfs_create_x32("fw_level", 0644, dir, &msm_cvp_fw_debug);
|
||||
debugfs_create_u32("fw_debug_mode", 0644, dir, &msm_cvp_fw_debug_mode);
|
||||
debugfs_create_u32("fw_low_power_mode", 0644, dir,
|
||||
&msm_cvp_fw_low_power_mode);
|
||||
debugfs_create_u32("debug_output", 0644, dir, &msm_cvp_debug_out);
|
||||
debugfs_create_u32("minidump_enable", 0644, dir,
|
||||
&msm_cvp_minidump_enable);
|
||||
debugfs_create_bool("fw_coverage", 0644, dir, &msm_cvp_fw_coverage);
|
||||
debugfs_create_bool("auto_pil", 0644, dir, &msm_cvp_auto_pil);
|
||||
debugfs_create_u32("kernel_fence", 0644, dir, &cvp_kernel_fence_enabled);
|
||||
debugfs_create_bool("disable_thermal_mitigation", 0644, dir,
|
||||
&msm_cvp_thermal_mitigation_disabled);
|
||||
debugfs_create_bool("enable_cacheop", 0644, dir,
|
||||
&msm_cvp_cacheop_enabled);
|
||||
debugfs_create_bool("disable_cvp_syscache", 0644, dir,
|
||||
&msm_cvp_syscache_disable);
|
||||
debugfs_create_bool("disable_dcvs", 0644, dir,
|
||||
&msm_cvp_dcvs_disable);
|
||||
|
||||
debugfs_create_file("cvp_power", 0644, dir, NULL, &cvp_pwr_fops);
|
||||
|
||||
return dir;
|
||||
|
||||
failed_create_dir:
|
||||
if (dir)
|
||||
debugfs_remove_recursive(cvp_driver->debugfs_root);
|
||||
|
||||
dprintk(CVP_WARN, "Failed to create debugfs\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _clk_rate_set(void *data, u64 val)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
struct cvp_hfi_ops *ops_tbl;
|
||||
struct allowed_clock_rates_table *tbl = NULL;
|
||||
unsigned int tbl_size, i;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
ops_tbl = core->dev_ops;
|
||||
tbl = core->resources.allowed_clks_tbl;
|
||||
tbl_size = core->resources.allowed_clks_tbl_size;
|
||||
|
||||
if (val == 0) {
|
||||
struct iris_hfi_device *hdev = ops_tbl->hfi_device_data;
|
||||
|
||||
msm_cvp_clock_voting = 0;
|
||||
call_hfi_op(ops_tbl, scale_clocks, hdev, hdev->clk_freq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < tbl_size; i++)
|
||||
if (val <= tbl[i].clock_rate)
|
||||
break;
|
||||
|
||||
if (i == tbl_size)
|
||||
msm_cvp_clock_voting = tbl[tbl_size-1].clock_rate;
|
||||
else
|
||||
msm_cvp_clock_voting = tbl[i].clock_rate;
|
||||
|
||||
dprintk(CVP_WARN, "Override cvp_clk_rate with %d\n",
|
||||
msm_cvp_clock_voting);
|
||||
|
||||
call_hfi_op(ops_tbl, scale_clocks, ops_tbl->hfi_device_data,
|
||||
msm_cvp_clock_voting);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _clk_rate_get(void *data, u64 *val)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
struct iris_hfi_device *hdev;
|
||||
|
||||
core = cvp_driver->cvp_core;
|
||||
hdev = core->dev_ops->hfi_device_data;
|
||||
if (msm_cvp_clock_voting)
|
||||
*val = msm_cvp_clock_voting;
|
||||
else
|
||||
*val = hdev->clk_freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, _clk_rate_get, _clk_rate_set, "%llu\n");
|
||||
|
||||
static int _dsp_dbg_set(void *data, u64 val)
|
||||
{
|
||||
gfa_cv.debug_mask = (uint32_t)val;
|
||||
|
||||
cvp_dsp_send_debug_mask();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dsp_dbg_get(void *data, u64 *val)
|
||||
{
|
||||
*val = gfa_cv.debug_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(dsp_debug_fops, _dsp_dbg_get, _dsp_dbg_set, "%llu\n");
|
||||
|
||||
static int _max_ssr_set(void *data, u64 val)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
core = cvp_driver->cvp_core;
|
||||
if (core) {
|
||||
if (val < 1) {
|
||||
dprintk(CVP_WARN,
|
||||
"Invalid max_ssr_allowed value %llx\n", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
core->resources.max_ssr_allowed = (unsigned int)val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _max_ssr_get(void *data, u64 *val)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
core = cvp_driver->cvp_core;
|
||||
if (core)
|
||||
*val = core->resources.max_ssr_allowed;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(max_ssr_fops, _max_ssr_get, _max_ssr_set, "%llu\n");
|
||||
|
||||
static int _ssr_stall_set(void *data, u64 val)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
core = cvp_driver->cvp_core;
|
||||
if (core)
|
||||
core->resources.fatal_ssr = (val >= 1) ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ssr_stall_get(void *data, u64 *val)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
core = cvp_driver->cvp_core;
|
||||
if (core)
|
||||
*val = core->resources.fatal_ssr ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(ssr_stall_fops, _ssr_stall_get, _ssr_stall_set, "%llu\n");
|
||||
|
||||
|
||||
struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core,
|
||||
struct dentry *parent)
|
||||
{
|
||||
struct dentry *dir = NULL;
|
||||
char debugfs_name[MAX_DEBUGFS_NAME];
|
||||
|
||||
if (!core) {
|
||||
dprintk(CVP_ERR, "Invalid params, core: %pK\n", core);
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", 0);
|
||||
dir = debugfs_create_dir(debugfs_name, parent);
|
||||
if (IS_ERR_OR_NULL(dir)) {
|
||||
dir = NULL;
|
||||
dprintk(CVP_ERR, "Failed to create debugfs for msm_cvp\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
if (!debugfs_create_file("info", 0444, dir, core, &core_info_fops)) {
|
||||
dprintk(CVP_ERR, "debugfs_create_file: fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
if (!debugfs_create_file("trigger_ssr", 0200,
|
||||
dir, core, &ssr_fops)) {
|
||||
dprintk(CVP_ERR, "debugfs_create_file: fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
if (!debugfs_create_file("clock_rate", 0644, dir,
|
||||
NULL, &clk_rate_fops)) {
|
||||
dprintk(CVP_ERR, "debugfs_create_file: clock_rate fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
if (!debugfs_create_file("dsp_debug_level", 0644, dir,
|
||||
NULL, &dsp_debug_fops)) {
|
||||
dprintk(CVP_ERR, "debugfs_create: dsp_debug_level fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
if (!debugfs_create_file("max_ssr_allowed", 0644, dir,
|
||||
NULL, &max_ssr_fops)) {
|
||||
dprintk(CVP_ERR, "debugfs_create: max_ssr_allowed fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
if (!debugfs_create_file("ssr_stall", 0644, dir,
|
||||
NULL, &ssr_stall_fops)) {
|
||||
dprintk(CVP_ERR, "debugfs_create: ssr_stall fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
debugfs_create_u32("hw_wd_recovery", 0644, dir,
|
||||
&msm_cvp_hw_wd_recovery);
|
||||
failed_create_dir:
|
||||
return dir;
|
||||
}
|
||||
|
||||
static int inst_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
dprintk(CVP_INFO, "Open inode ptr: %pK\n", inode->i_private);
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int publish_unreleased_reference(struct msm_cvp_inst *inst,
|
||||
char **dbuf, char *end)
|
||||
{
|
||||
dprintk(CVP_SESS, "%s deprecated function\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void put_inst_helper(struct kref *kref)
|
||||
{
|
||||
struct msm_cvp_inst *inst;
|
||||
|
||||
if (!kref)
|
||||
return;
|
||||
inst = container_of(kref, struct msm_cvp_inst, kref);
|
||||
|
||||
msm_cvp_destroy(inst);
|
||||
}
|
||||
|
||||
static ssize_t inst_info_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct cvp_core_inst_pair *idata = file->private_data;
|
||||
struct msm_cvp_core *core;
|
||||
struct msm_cvp_inst *inst, *temp = NULL;
|
||||
char *dbuf, *cur, *end;
|
||||
int i;
|
||||
ssize_t len = 0;
|
||||
|
||||
if (!idata || !idata->core || !idata->inst) {
|
||||
dprintk(CVP_ERR, "%s: Invalid params\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
core = idata->core;
|
||||
inst = idata->inst;
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(temp, &core->instances, list) {
|
||||
if (temp == inst)
|
||||
break;
|
||||
}
|
||||
inst = ((temp == inst) && kref_get_unless_zero(&inst->kref)) ?
|
||||
inst : NULL;
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: Instance has become obsolete", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL);
|
||||
if (!dbuf) {
|
||||
dprintk(CVP_ERR, "%s: Allocation failed!\n", __func__);
|
||||
len = -ENOMEM;
|
||||
goto failed_alloc;
|
||||
}
|
||||
cur = dbuf;
|
||||
end = cur + MAX_DBG_BUF_SIZE;
|
||||
|
||||
cur += write_str(cur, end - cur, "==============================\n");
|
||||
cur += write_str(cur, end - cur, "INSTANCE: %pK (%s)\n", inst,
|
||||
inst->session_type == MSM_CVP_USER ? "User" : "Kernel");
|
||||
cur += write_str(cur, end - cur, "==============================\n");
|
||||
cur += write_str(cur, end - cur, "core: %pK\n", inst->core);
|
||||
cur += write_str(cur, end - cur, "state: %d\n", inst->state);
|
||||
cur += write_str(cur, end - cur, "secure: %d\n",
|
||||
!!(inst->flags & CVP_SECURE));
|
||||
for (i = SESSION_MSG_START; i < SESSION_MSG_END; i++) {
|
||||
cur += write_str(cur, end - cur, "completions[%d]: %s\n", i,
|
||||
completion_done(&inst->completions[SESSION_MSG_INDEX(i)]) ?
|
||||
"pending" : "done");
|
||||
}
|
||||
|
||||
publish_unreleased_reference(inst, &cur, end);
|
||||
len = simple_read_from_buffer(buf, count, ppos,
|
||||
dbuf, cur - dbuf);
|
||||
|
||||
kfree(dbuf);
|
||||
failed_alloc:
|
||||
kref_put(&inst->kref, put_inst_helper);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int inst_info_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
dprintk(CVP_INFO, "Release inode ptr: %pK\n", inode->i_private);
|
||||
file->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations inst_info_fops = {
|
||||
.open = inst_info_open,
|
||||
.read = inst_info_read,
|
||||
.release = inst_info_release,
|
||||
};
|
||||
|
||||
struct dentry *msm_cvp_debugfs_init_inst(struct msm_cvp_inst *inst,
|
||||
struct dentry *parent)
|
||||
{
|
||||
struct dentry *dir = NULL, *info = NULL;
|
||||
char debugfs_name[MAX_DEBUGFS_NAME];
|
||||
struct cvp_core_inst_pair *idata = NULL;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "Invalid params, inst: %pK\n", inst);
|
||||
goto exit;
|
||||
}
|
||||
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst);
|
||||
|
||||
idata = kzalloc(sizeof(*idata), GFP_KERNEL);
|
||||
if (!idata) {
|
||||
dprintk(CVP_ERR, "%s: Allocation failed!\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
idata->core = inst->core;
|
||||
idata->inst = inst;
|
||||
|
||||
dir = debugfs_create_dir(debugfs_name, parent);
|
||||
if (IS_ERR_OR_NULL(dir)) {
|
||||
dir = NULL;
|
||||
dprintk(CVP_ERR, "Failed to create debugfs for msm_cvp\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
info = debugfs_create_file("info", 0444, dir,
|
||||
idata, &inst_info_fops);
|
||||
if (!info) {
|
||||
dprintk(CVP_ERR, "debugfs_create_file: info fail\n");
|
||||
goto failed_create_file;
|
||||
}
|
||||
|
||||
dir->d_inode->i_private = info->d_inode->i_private;
|
||||
inst->debug.pdata[FRAME_PROCESSING].sampling = true;
|
||||
return dir;
|
||||
|
||||
failed_create_file:
|
||||
debugfs_remove_recursive(dir);
|
||||
dir = NULL;
|
||||
failed_create_dir:
|
||||
kfree(idata);
|
||||
exit:
|
||||
return dir;
|
||||
}
|
||||
|
||||
void msm_cvp_debugfs_deinit_inst(struct msm_cvp_inst *inst)
|
||||
{
|
||||
struct dentry *dentry = NULL;
|
||||
|
||||
if (!inst || !inst->debugfs_root)
|
||||
return;
|
||||
|
||||
dentry = inst->debugfs_root;
|
||||
if (dentry->d_inode) {
|
||||
dprintk(CVP_INFO, "Destroy %pK\n", dentry->d_inode->i_private);
|
||||
kfree(dentry->d_inode->i_private);
|
||||
dentry->d_inode->i_private = NULL;
|
||||
}
|
||||
debugfs_remove_recursive(dentry);
|
||||
inst->debugfs_root = NULL;
|
||||
}
|
205
qcom/opensource/eva-kernel/msm/eva/msm_cvp_debug.h
Normal file
205
qcom/opensource/eva-kernel/msm/eva/msm_cvp_debug.h
Normal file
@ -0,0 +1,205 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __MSM_CVP_DEBUG__
|
||||
#define __MSM_CVP_DEBUG__
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include "msm_cvp_internal.h"
|
||||
#include "msm_cvp_events.h"
|
||||
|
||||
#ifndef CVP_DBG_LABEL
|
||||
#define CVP_DBG_LABEL "msm_cvp"
|
||||
#endif
|
||||
|
||||
#define CVP_DBG_TAG CVP_DBG_LABEL ": %4s: "
|
||||
|
||||
/* To enable messages OR these values and
|
||||
* echo the result to debugfs file.
|
||||
*
|
||||
* To enable all messages set debug_level = 0x101F
|
||||
*/
|
||||
|
||||
enum cvp_msg_prio {
|
||||
CVP_ERR = 0x000001,
|
||||
CVP_WARN = 0x000002,
|
||||
CVP_INFO = 0x000004,
|
||||
CVP_CMD = 0x000008,
|
||||
CVP_PROF = 0x000010,
|
||||
CVP_PKT = 0x000020,
|
||||
CVP_MEM = 0x000040,
|
||||
CVP_SYNX = 0x000080,
|
||||
CVP_CORE = 0x000100,
|
||||
CVP_REG = 0x000200,
|
||||
CVP_PWR = 0x000400,
|
||||
CVP_DSP = 0x000800,
|
||||
CVP_FW = 0x001000,
|
||||
CVP_SESS = 0x002000,
|
||||
CVP_HFI = 0x004000,
|
||||
CVP_VM = 0x008000,
|
||||
CVP_DBG = CVP_MEM | CVP_SYNX | CVP_CORE | CVP_REG | CVP_CMD |
|
||||
CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI | CVP_PKT | CVP_VM,
|
||||
};
|
||||
|
||||
enum cvp_msg_out {
|
||||
CVP_OUT_PRINTK = 0,
|
||||
};
|
||||
|
||||
enum msm_cvp_debugfs_event {
|
||||
MSM_CVP_DEBUGFS_EVENT_ETB,
|
||||
MSM_CVP_DEBUGFS_EVENT_EBD,
|
||||
MSM_CVP_DEBUGFS_EVENT_FTB,
|
||||
MSM_CVP_DEBUGFS_EVENT_FBD,
|
||||
};
|
||||
|
||||
extern int msm_cvp_debug;
|
||||
extern int msm_cvp_debug_out;
|
||||
extern int msm_cvp_fw_debug;
|
||||
extern int msm_cvp_fw_debug_mode;
|
||||
extern int msm_cvp_fw_low_power_mode;
|
||||
extern bool msm_cvp_fw_coverage;
|
||||
extern bool msm_cvp_auto_pil;
|
||||
extern bool msm_cvp_thermal_mitigation_disabled;
|
||||
extern bool msm_cvp_cacheop_disabled;
|
||||
extern int msm_cvp_clock_voting;
|
||||
extern bool msm_cvp_syscache_disable;
|
||||
extern bool msm_cvp_dsp_disable;
|
||||
extern bool msm_cvp_mmrm_enabled;
|
||||
extern bool msm_cvp_dcvs_disable;
|
||||
extern int msm_cvp_minidump_enable;
|
||||
extern int cvp_kernel_fence_enabled;
|
||||
extern int msm_cvp_hw_wd_recovery;
|
||||
|
||||
#define dprintk(__level, __fmt, arg...) \
|
||||
do { \
|
||||
if (msm_cvp_debug & __level) { \
|
||||
if (msm_cvp_debug_out == CVP_OUT_PRINTK) { \
|
||||
pr_info(CVP_DBG_TAG __fmt, \
|
||||
get_debug_level_str(__level), \
|
||||
## arg); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* dprintk_rl is designed for printing frequent recurring errors */
|
||||
#define dprintk_rl(__level, __fmt, arg...) \
|
||||
do { \
|
||||
if (msm_cvp_debug & __level) { \
|
||||
if (msm_cvp_debug_out == CVP_OUT_PRINTK) { \
|
||||
pr_info_ratelimited(CVP_DBG_TAG __fmt, \
|
||||
get_debug_level_str(__level), \
|
||||
## arg); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MSM_CVP_ERROR(value) \
|
||||
do { if (value) \
|
||||
dprintk(CVP_ERR, "BugOn"); \
|
||||
WARN_ON(value); \
|
||||
} while (0)
|
||||
|
||||
|
||||
struct dentry *msm_cvp_debugfs_init_drv(void);
|
||||
struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core,
|
||||
struct dentry *parent);
|
||||
struct dentry *msm_cvp_debugfs_init_inst(struct msm_cvp_inst *inst,
|
||||
struct dentry *parent);
|
||||
void msm_cvp_debugfs_deinit_inst(struct msm_cvp_inst *inst);
|
||||
|
||||
static inline char *get_debug_level_str(int level)
|
||||
{
|
||||
switch (level) {
|
||||
case CVP_ERR:
|
||||
return "err";
|
||||
case CVP_WARN:
|
||||
return "warn";
|
||||
case CVP_INFO:
|
||||
return "info";
|
||||
case CVP_CMD:
|
||||
return "cmd";
|
||||
case CVP_DBG:
|
||||
return "dbg";
|
||||
case CVP_PROF:
|
||||
return "prof";
|
||||
case CVP_PKT:
|
||||
return "pkt";
|
||||
case CVP_MEM:
|
||||
return "mem";
|
||||
case CVP_SYNX:
|
||||
return "synx";
|
||||
case CVP_CORE:
|
||||
return "core";
|
||||
case CVP_REG:
|
||||
return "reg";
|
||||
case CVP_PWR:
|
||||
return "pwr";
|
||||
case CVP_DSP:
|
||||
return "dsp";
|
||||
case CVP_FW:
|
||||
return "fw";
|
||||
case CVP_SESS:
|
||||
return "sess";
|
||||
case CVP_HFI:
|
||||
return "hfi";
|
||||
case CVP_VM:
|
||||
return "vm";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
static inline void show_stats(struct msm_cvp_inst *i)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; x < MAX_PROFILING_POINTS; x++) {
|
||||
if (i->debug.pdata[x].name[0] &&
|
||||
(msm_cvp_debug & CVP_PROF)) {
|
||||
if (i->debug.samples) {
|
||||
dprintk(CVP_PROF, "%s averaged %d ms/sample\n",
|
||||
i->debug.pdata[x].name,
|
||||
i->debug.pdata[x].cumulative /
|
||||
i->debug.samples);
|
||||
}
|
||||
|
||||
dprintk(CVP_PROF, "%s Samples: %d\n",
|
||||
i->debug.pdata[x].name,
|
||||
i->debug.samples);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void msm_cvp_res_handle_fatal_hw_error(
|
||||
struct msm_cvp_platform_resources *resources,
|
||||
bool enable_fatal)
|
||||
{
|
||||
enable_fatal &= resources->debug_timeout;
|
||||
MSM_CVP_ERROR(enable_fatal);
|
||||
}
|
||||
|
||||
static inline void msm_cvp_handle_hw_error(struct msm_cvp_core *core)
|
||||
{
|
||||
bool enable_fatal = true;
|
||||
|
||||
/*
|
||||
* In current implementation user-initiated SSR triggers
|
||||
* a fatal error from hardware. However, there is no way
|
||||
* to know if fatal error is due to SSR or not. Handle
|
||||
* user SSR as non-fatal.
|
||||
*/
|
||||
if (core->trigger_ssr) {
|
||||
core->trigger_ssr = false;
|
||||
enable_fatal = false;
|
||||
}
|
||||
|
||||
/* CVP driver can decide FATAL handling of HW errors
|
||||
* based on multiple factors. This condition check will
|
||||
* be enhanced later.
|
||||
*/
|
||||
msm_cvp_res_handle_fatal_hw_error(&core->resources, enable_fatal);
|
||||
}
|
||||
|
||||
#endif
|
2234
qcom/opensource/eva-kernel/msm/eva/msm_cvp_dsp.c
Normal file
2234
qcom/opensource/eva-kernel/msm/eva/msm_cvp_dsp.c
Normal file
File diff suppressed because it is too large
Load Diff
315
qcom/opensource/eva-kernel/msm/eva/msm_cvp_dsp.h
Normal file
315
qcom/opensource/eva-kernel/msm/eva/msm_cvp_dsp.h
Normal file
@ -0,0 +1,315 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef MSM_CVP_DSP_H
|
||||
#define MSM_CVP_DSP_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/refcount.h>
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
|
||||
#include <linux/pid.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#ifdef CVP_FASTRPC_ENABLED
|
||||
#include <fastrpc.h>
|
||||
#else
|
||||
struct fastrpc_device {
|
||||
int handle;
|
||||
};
|
||||
|
||||
enum fastrpc_driver_status {
|
||||
FASTRPC_CVP_B,
|
||||
};
|
||||
|
||||
enum fastrpc_driver_invoke_nums {
|
||||
FASTRPC_DEV_MAP_DMA = 1,
|
||||
FASTRPC_DEV_UNMAP_DMA,
|
||||
FASTRPC_DEV_GET_HLOS_PID,
|
||||
};
|
||||
|
||||
struct fastrpc_driver {
|
||||
struct device_driver driver;
|
||||
int handle;
|
||||
int (*probe)(struct fastrpc_device *dev);
|
||||
int (*callback)(struct fastrpc_device *dev,
|
||||
enum fastrpc_driver_status status);
|
||||
};
|
||||
#endif /* End of CVP_FASTRPC_ENABLED */
|
||||
|
||||
#define CVP_APPS_DSP_GLINK_GUID "cvp-glink-apps-dsp"
|
||||
#define CVP_APPS_DSP_SMD_GUID "cvp-smd-apps-dsp"
|
||||
|
||||
#define VMID_CDSP_Q6 (30)
|
||||
#define HLOS_VM_NUM 1
|
||||
#define DSP_VM_NUM 2
|
||||
#define CVP_DSP_MAX_RESERVED 5
|
||||
#define CVP_DSP2CPU_RESERVED 8
|
||||
#define CVP_DSP_RESPONSE_TIMEOUT 1000
|
||||
#define CVP_INVALID_RPMSG_TYPE 0xBADDFACE
|
||||
#define MAX_FRAME_BUF_NUM 16
|
||||
|
||||
#define BITPTRSIZE32 (4)
|
||||
#define BITPTRSIZE64 (8)
|
||||
#define HIGH32 (0xFFFFFFFF00000000LL)
|
||||
#define LOW32 (0xFFFFFFFFLL)
|
||||
|
||||
#define CVP_FASTRPC_DRIVER_NAME_SIZE 16
|
||||
|
||||
/* Supports up to 8 DSP sessions in 8 processes */
|
||||
#define MAX_DSP_SESSION_NUM (8)
|
||||
#define MAX_FASTRPC_DRIVER_NUM (MAX_DSP_SESSION_NUM)
|
||||
|
||||
int cvp_dsp_device_init(void);
|
||||
void cvp_dsp_device_exit(void);
|
||||
void cvp_dsp_send_hfi_queue(void);
|
||||
void cvp_dsp_init_hfi_queue_hdr(struct iris_hfi_device *device);
|
||||
|
||||
enum CPU2DSP_STATUS {
|
||||
CPU2DSP_SUCCESS = 0,
|
||||
CPU2DSP_EFAIL = 1,
|
||||
CPU2DSP_EFATAL = 2,
|
||||
CPU2DSP_EUNAVAILABLE = 3,
|
||||
CPU2DSP_EINVALSTATE = 4,
|
||||
CPU2DSP_EUNSUPPORTED = 5,
|
||||
};
|
||||
|
||||
enum CVP_DSP_COMMAND {
|
||||
CPU2DSP_SEND_HFI_QUEUE = 0,
|
||||
CPU2DSP_SUSPEND = 1,
|
||||
CPU2DSP_RESUME = 2,
|
||||
CPU2DSP_SHUTDOWN = 3,
|
||||
CPU2DSP_REGISTER_BUFFER = 4,
|
||||
CPU2DSP_DEREGISTER_BUFFER = 5,
|
||||
CPU2DSP_INIT = 6,
|
||||
CPU2DSP_SET_DEBUG_LEVEL = 7,
|
||||
CPU2DSP_MAX_CMD = 8,
|
||||
DSP2CPU_POWERON = 11,
|
||||
DSP2CPU_POWEROFF = 12,
|
||||
DSP2CPU_CREATE_SESSION = 13,
|
||||
DSP2CPU_DETELE_SESSION = 14,
|
||||
DSP2CPU_POWER_REQUEST = 15,
|
||||
DSP2CPU_POWER_CANCEL = 16,
|
||||
DSP2CPU_REGISTER_BUFFER = 17,
|
||||
DSP2CPU_DEREGISTER_BUFFER = 18,
|
||||
DSP2CPU_MEM_ALLOC = 19,
|
||||
DSP2CPU_MEM_FREE = 20,
|
||||
DSP2CPU_START_SESSION = 21,
|
||||
DSP2CPU_STOP_SESSION = 22,
|
||||
CVP_DSP_MAX_CMD = 23,
|
||||
};
|
||||
|
||||
struct eva_power_req {
|
||||
uint32_t clock_fdu;
|
||||
uint32_t clock_ica;
|
||||
uint32_t clock_od;
|
||||
uint32_t clock_mpu;
|
||||
uint32_t clock_fw;
|
||||
uint32_t bw_ddr;
|
||||
uint32_t bw_sys_cache;
|
||||
uint32_t op_clock_fdu;
|
||||
uint32_t op_clock_ica;
|
||||
uint32_t op_clock_od;
|
||||
uint32_t op_clock_mpu;
|
||||
uint32_t op_clock_fw;
|
||||
uint32_t op_bw_ddr;
|
||||
uint32_t op_bw_sys_cache;
|
||||
};
|
||||
|
||||
struct eva_mem_remote {
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t fd;
|
||||
uint32_t offset;
|
||||
uint32_t index;
|
||||
uint32_t iova;
|
||||
uint32_t dsp_remote_map;
|
||||
uint64_t v_dsp_addr;
|
||||
};
|
||||
|
||||
/*
|
||||
* command: defined as a packet initiated from one party.
|
||||
* message: defined as a packet sent as response to a command
|
||||
*/
|
||||
|
||||
/*
|
||||
* cvp_dsp_cmd_msg contains
|
||||
* the message sent from CPU to DSP
|
||||
* or
|
||||
* the command sent from CPU to DSP
|
||||
*/
|
||||
struct cvp_dsp_cmd_msg {
|
||||
uint32_t type;
|
||||
int32_t ret;
|
||||
uint64_t msg_ptr;
|
||||
uint32_t msg_ptr_len;
|
||||
uint32_t buff_fd_iova;
|
||||
uint32_t buff_index;
|
||||
uint32_t buff_size;
|
||||
uint32_t session_id;
|
||||
int32_t ddr_type;
|
||||
uint32_t buff_fd;
|
||||
uint32_t buff_offset;
|
||||
uint32_t buff_fd_size;
|
||||
|
||||
uint32_t eva_dsp_debug_mask;
|
||||
|
||||
/* Create Session */
|
||||
uint32_t session_cpu_low;
|
||||
uint32_t session_cpu_high;
|
||||
|
||||
struct eva_mem_remote sbuf;
|
||||
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
};
|
||||
|
||||
/* cvp_dsp_rsp_msg contains the message sent from DSP to CPU */
|
||||
struct cvp_dsp_rsp_msg {
|
||||
uint32_t type;
|
||||
int32_t ret;
|
||||
uint32_t dsp_state;
|
||||
uint32_t reserved[CVP_DSP_MAX_RESERVED - 1];
|
||||
};
|
||||
|
||||
/* cvp_dsp2cpu_cmd contains the command sent from DSP to cpu*/
|
||||
struct cvp_dsp2cpu_cmd {
|
||||
uint32_t type;
|
||||
uint32_t ver;
|
||||
uint32_t len;
|
||||
|
||||
/* Create Session */
|
||||
uint32_t session_type;
|
||||
uint32_t kernel_mask;
|
||||
uint32_t session_prio;
|
||||
uint32_t is_secure;
|
||||
uint32_t dsp_access_mask;
|
||||
|
||||
uint32_t session_id;
|
||||
uint32_t session_cpu_low;
|
||||
uint32_t session_cpu_high;
|
||||
int32_t pid;
|
||||
struct eva_power_req power_req;
|
||||
struct eva_mem_remote sbuf;
|
||||
|
||||
uint32_t data[CVP_DSP2CPU_RESERVED];
|
||||
};
|
||||
|
||||
struct driver_name {
|
||||
uint32_t status;
|
||||
char name[CVP_FASTRPC_DRIVER_NAME_SIZE];
|
||||
};
|
||||
|
||||
enum DRIVER_NAME_STATUS {
|
||||
DRIVER_NAME_INVALID = 0,
|
||||
DRIVER_NAME_AVAILABLE = 1,
|
||||
DRIVER_NAME_USED = 2,
|
||||
};
|
||||
|
||||
struct cvp_dsp_fastrpc_driver_entry {
|
||||
struct list_head list;
|
||||
uint32_t handle; /*handle is not PID*/
|
||||
uint32_t session_cnt;
|
||||
uint32_t driver_name_idx;
|
||||
atomic_t refcount;
|
||||
struct fastrpc_driver cvp_fastrpc_driver;
|
||||
struct fastrpc_device *cvp_fastrpc_device;
|
||||
struct completion fastrpc_probe_completion;
|
||||
/* all dsp sessions list */
|
||||
struct msm_cvp_list dsp_sessions;
|
||||
};
|
||||
|
||||
struct cvp_dsp_apps {
|
||||
/*
|
||||
* tx_lock for sending CPU2DSP cmds or msgs
|
||||
* and dsp state change
|
||||
*/
|
||||
struct mutex tx_lock;
|
||||
/* rx_lock for receiving DSP2CPU cmds or msgs */
|
||||
struct mutex rx_lock;
|
||||
struct mutex driver_name_lock;
|
||||
struct rpmsg_device *chan;
|
||||
uint32_t state;
|
||||
uint32_t debug_mask;
|
||||
bool hyp_assigned;
|
||||
uint64_t addr;
|
||||
uint32_t size;
|
||||
struct completion completions[CPU2DSP_MAX_CMD + 1];
|
||||
struct cvp_dsp2cpu_cmd pending_dsp2cpu_cmd;
|
||||
struct cvp_dsp_rsp_msg pending_dsp2cpu_rsp;
|
||||
struct task_struct *dsp_thread;
|
||||
/* dsp buffer mapping, set of dma function pointer */
|
||||
const struct file_operations *dmabuf_f_op;
|
||||
uint32_t buf_num;
|
||||
struct msm_cvp_list fastrpc_driver_list;
|
||||
struct driver_name cvp_fastrpc_name[MAX_FASTRPC_DRIVER_NUM];
|
||||
};
|
||||
|
||||
#define EVA_TRACE_MAX_SESSION_NUM 16
|
||||
#define EVA_TRACE_MAX_INSTANCE_NUM 6
|
||||
#define EVA_TRACE_MAX_BUF_NUM 256
|
||||
|
||||
#define CONFIG_SIZE_IN_BYTES 2048
|
||||
#define CONFIG_SIZE_IN_WORDS (CONFIG_SIZE_IN_BYTES >> 2)
|
||||
|
||||
// iova is eva_dsp_buf->iova
|
||||
// pkt_type is frame packet type using the buffer
|
||||
// buf_idx is the index of the buffer in a frame packet
|
||||
// transaction_id is the transaction id of frame packet
|
||||
struct cvp_dsp_trace_buf {
|
||||
u32 iova;
|
||||
u32 pkt_type;
|
||||
u32 buf_idx;
|
||||
u32 transaction_id;
|
||||
u32 fd;
|
||||
};
|
||||
|
||||
// Saving config packet for each intance
|
||||
struct cvp_dsp_trace_instance {
|
||||
u32 feature_type;
|
||||
u32 config_pkt[CONFIG_SIZE_IN_WORDS];
|
||||
};
|
||||
|
||||
struct cvp_dsp_trace_session {
|
||||
u32 session_id;
|
||||
u32 buf_cnt;
|
||||
u32 inst_cnt;
|
||||
struct cvp_dsp_trace_instance instance[EVA_TRACE_MAX_INSTANCE_NUM];
|
||||
struct cvp_dsp_trace_buf buf[EVA_TRACE_MAX_BUF_NUM];
|
||||
};
|
||||
|
||||
struct cvp_dsp_trace {
|
||||
struct cvp_dsp_trace_session sessions[EVA_TRACE_MAX_SESSION_NUM];
|
||||
};
|
||||
|
||||
extern struct cvp_dsp_apps gfa_cv;
|
||||
/*
|
||||
* API for CVP driver to suspend CVP session during
|
||||
* power collapse
|
||||
*/
|
||||
int cvp_dsp_suspend(bool force);
|
||||
|
||||
/*
|
||||
* API for CVP driver to resume CVP session during
|
||||
* power collapse
|
||||
*/
|
||||
int cvp_dsp_resume(void);
|
||||
|
||||
/*
|
||||
* API for CVP driver to shutdown CVP session during
|
||||
* cvp subsystem error.
|
||||
*/
|
||||
int cvp_dsp_shutdown(void);
|
||||
|
||||
int cvp_dsp_fastrpc_unmap(uint32_t handle, struct cvp_internal_buf *buf);
|
||||
|
||||
int cvp_dsp_del_sess(uint32_t handle, struct msm_cvp_inst *inst);
|
||||
|
||||
void cvp_dsp_send_debug_mask(void);
|
||||
|
||||
#endif // MSM_CVP_DSP_H
|
||||
|
375
qcom/opensource/eva-kernel/msm/eva/msm_cvp_events.h
Normal file
375
qcom/opensource/eva-kernel/msm/eva/msm_cvp_events.h
Normal file
@ -0,0 +1,375 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#if !defined(_MSM_CVP_EVENTS_H_) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _MSM_CVP_EVENTS_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM msm_cvp
|
||||
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE msm_cvp_events
|
||||
|
||||
// Since Chrome supports to parse the event “tracing_mark_write” by default
|
||||
// so we can re-use this to display your own events in Chrome
|
||||
// enable command as below:
|
||||
// adb shell "echo 1 > /sys/kernel/tracing/events/msm_cvp/tracing_mark_write/enable"
|
||||
TRACE_EVENT(tracing_mark_write,
|
||||
TP_PROTO(int pid, const char *name, bool trace_begin),
|
||||
TP_ARGS(pid, name, trace_begin),
|
||||
TP_STRUCT__entry(
|
||||
__field(int, pid)
|
||||
__string(trace_name, name)
|
||||
__field(bool, trace_begin)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->pid = pid;
|
||||
__assign_str(trace_name, name);
|
||||
__entry->trace_begin = trace_begin;
|
||||
),
|
||||
TP_printk("%s|%d|%s", __entry->trace_begin ? "B" : "E",
|
||||
__entry->pid, __get_str(trace_name))
|
||||
)
|
||||
#define CVPKERNEL_ATRACE_END(name) \
|
||||
trace_tracing_mark_write(current->tgid, name, 0)
|
||||
#define CVPKERNEL_ATRACE_BEGIN(name) \
|
||||
trace_tracing_mark_write(current->tgid, name, 1)
|
||||
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_v4l2_cvp,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(char *, dummy)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dummy = dummy;
|
||||
),
|
||||
|
||||
TP_printk("%s", __entry->dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_open_start,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_open_end,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_close_start,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_close_end,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_fw_load_start,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_fw_load_end,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_cvp_common,
|
||||
|
||||
TP_PROTO(void *instp, int old_state, int new_state),
|
||||
|
||||
TP_ARGS(instp, old_state, new_state),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(void *, instp)
|
||||
__field(int, old_state)
|
||||
__field(int, new_state)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->instp = instp;
|
||||
__entry->old_state = old_state;
|
||||
__entry->new_state = new_state;
|
||||
),
|
||||
|
||||
TP_printk("Moved inst: %p from 0x%x to 0x%x",
|
||||
__entry->instp,
|
||||
__entry->old_state,
|
||||
__entry->new_state)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_cvp_common, msm_cvp_common_state_change,
|
||||
|
||||
TP_PROTO(void *instp, int old_state, int new_state),
|
||||
|
||||
TP_ARGS(instp, old_state, new_state)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(cvp_venus_hfi_var,
|
||||
|
||||
TP_PROTO(u32 cp_start, u32 cp_size,
|
||||
u32 cp_nonpixel_start, u32 cp_nonpixel_size),
|
||||
|
||||
TP_ARGS(cp_start, cp_size, cp_nonpixel_start, cp_nonpixel_size),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(u32, cp_start)
|
||||
__field(u32, cp_size)
|
||||
__field(u32, cp_nonpixel_start)
|
||||
__field(u32, cp_nonpixel_size)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->cp_start = cp_start;
|
||||
__entry->cp_size = cp_size;
|
||||
__entry->cp_nonpixel_start = cp_nonpixel_start;
|
||||
__entry->cp_nonpixel_size = cp_nonpixel_size;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"TZBSP_MEM_PROTECT_VIDEO_VAR done, cp_start : 0x%x, cp_size : 0x%x, cp_nonpixel_start : 0x%x, cp_nonpixel_size : 0x%x",
|
||||
__entry->cp_start,
|
||||
__entry->cp_size,
|
||||
__entry->cp_nonpixel_start,
|
||||
__entry->cp_nonpixel_size)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(cvp_venus_hfi_var, cvp_venus_hfi_var_done,
|
||||
|
||||
TP_PROTO(u32 cp_start, u32 cp_size,
|
||||
u32 cp_nonpixel_start, u32 cp_nonpixel_size),
|
||||
|
||||
TP_ARGS(cp_start, cp_size, cp_nonpixel_start, cp_nonpixel_size)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_v4l2_cvp_buffer_events,
|
||||
|
||||
TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp,
|
||||
u32 alloc_len, u32 filled_len, u32 offset),
|
||||
|
||||
TP_ARGS(event_type, device_addr, timestamp, alloc_len,
|
||||
filled_len, offset),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(char *, event_type)
|
||||
__field(u32, device_addr)
|
||||
__field(int64_t, timestamp)
|
||||
__field(u32, alloc_len)
|
||||
__field(u32, filled_len)
|
||||
__field(u32, offset)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->event_type = event_type;
|
||||
__entry->device_addr = device_addr;
|
||||
__entry->timestamp = timestamp;
|
||||
__entry->alloc_len = alloc_len;
|
||||
__entry->filled_len = filled_len;
|
||||
__entry->offset = offset;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s, device_addr : 0x%x, timestamp : %lld, alloc_len : 0x%x, filled_len : 0x%x, offset : 0x%x",
|
||||
__entry->event_type,
|
||||
__entry->device_addr,
|
||||
__entry->timestamp,
|
||||
__entry->alloc_len,
|
||||
__entry->filled_len,
|
||||
__entry->offset)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_cvp_buffer_events, msm_v4l2_cvp_buffer_event_start,
|
||||
|
||||
TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp,
|
||||
u32 alloc_len, u32 filled_len, u32 offset),
|
||||
|
||||
TP_ARGS(event_type, device_addr, timestamp, alloc_len,
|
||||
filled_len, offset)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_cvp_buffer_events, msm_v4l2_cvp_buffer_event_end,
|
||||
|
||||
TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp,
|
||||
u32 alloc_len, u32 filled_len, u32 offset),
|
||||
|
||||
TP_ARGS(event_type, device_addr, timestamp, alloc_len,
|
||||
filled_len, offset)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_cvp_smem_buffer_dma_ops,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(char *, buffer_op)
|
||||
__field(u32, buffer_type)
|
||||
__field(u32, heap_mask)
|
||||
__field(u32, size)
|
||||
__field(u32, align)
|
||||
__field(u32, flags)
|
||||
__field(int, map_kernel)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->buffer_op = buffer_op;
|
||||
__entry->buffer_type = buffer_type;
|
||||
__entry->heap_mask = heap_mask;
|
||||
__entry->size = size;
|
||||
__entry->align = align;
|
||||
__entry->flags = flags;
|
||||
__entry->map_kernel = map_kernel;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s, buffer_type : 0x%x, heap_mask : 0x%x, size : 0x%x, align : 0x%x, flags : 0x%x, map_kernel : %d",
|
||||
__entry->buffer_op,
|
||||
__entry->buffer_type,
|
||||
__entry->heap_mask,
|
||||
__entry->size,
|
||||
__entry->align,
|
||||
__entry->flags,
|
||||
__entry->map_kernel)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_cvp_smem_buffer_dma_ops, msm_cvp_smem_buffer_dma_op_start,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_cvp_smem_buffer_dma_ops, msm_cvp_smem_buffer_dma_op_end,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_cvp_smem_buffer_iommu_ops,
|
||||
|
||||
TP_PROTO(char *buffer_op, int domain_num, int partition_num,
|
||||
unsigned long align, unsigned long iova,
|
||||
unsigned long buffer_size),
|
||||
|
||||
TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(char *, buffer_op)
|
||||
__field(int, domain_num)
|
||||
__field(int, partition_num)
|
||||
__field(unsigned long, align)
|
||||
__field(unsigned long, iova)
|
||||
__field(unsigned long, buffer_size)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->buffer_op = buffer_op;
|
||||
__entry->domain_num = domain_num;
|
||||
__entry->partition_num = partition_num;
|
||||
__entry->align = align;
|
||||
__entry->iova = iova;
|
||||
__entry->buffer_size = buffer_size;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s, domain : %d, partition : %d, align : %lx, iova : 0x%lx, buffer_size=%lx",
|
||||
__entry->buffer_op,
|
||||
__entry->domain_num,
|
||||
__entry->partition_num,
|
||||
__entry->align,
|
||||
__entry->iova,
|
||||
__entry->buffer_size)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_cvp_smem_buffer_iommu_ops, msm_cvp_smem_buffer_iommu_op_start,
|
||||
|
||||
TP_PROTO(char *buffer_op, int domain_num, int partition_num,
|
||||
unsigned long align, unsigned long iova,
|
||||
unsigned long buffer_size),
|
||||
|
||||
TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_cvp_smem_buffer_iommu_ops, msm_cvp_smem_buffer_iommu_op_end,
|
||||
|
||||
TP_PROTO(char *buffer_op, int domain_num, int partition_num,
|
||||
unsigned long align, unsigned long iova,
|
||||
unsigned long buffer_size),
|
||||
|
||||
TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_cvp_perf,
|
||||
|
||||
TP_PROTO(const char *name, unsigned long value),
|
||||
|
||||
TP_ARGS(name, value),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const char *, name)
|
||||
__field(unsigned long, value)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->name = name;
|
||||
__entry->value = value;
|
||||
),
|
||||
|
||||
TP_printk("%s %lu", __entry->name, __entry->value)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_cvp_perf, msm_cvp_perf_clock_scale,
|
||||
|
||||
TP_PROTO(const char *clock_name, unsigned long frequency),
|
||||
|
||||
TP_ARGS(clock_name, frequency)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_cvp_perf, msm_cvp_perf_bus_vote,
|
||||
|
||||
TP_PROTO(const char *governor_mode, unsigned long ab),
|
||||
|
||||
TP_ARGS(governor_mode, ab)
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
|
||||
#include <trace/define_trace.h>
|
408
qcom/opensource/eva-kernel/msm/eva/msm_cvp_internal.h
Normal file
408
qcom/opensource/eva-kernel/msm/eva/msm_cvp_internal.h
Normal file
@ -0,0 +1,408 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_CVP_INTERNAL_H_
|
||||
#define _MSM_CVP_INTERNAL_H_
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/interconnect.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include "msm_cvp_core.h"
|
||||
#include <media/msm_eva_private.h>
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "cvp_hfi_helper.h"
|
||||
|
||||
#define MAX_SUPPORTED_INSTANCES 16
|
||||
#define MAX_DEBUGFS_NAME 50
|
||||
#define MAX_DSP_INIT_ATTEMPTS 16
|
||||
#define FENCE_WAIT_SIGNAL_TIMEOUT 100
|
||||
#define FENCE_WAIT_SIGNAL_RETRY_TIMES 20
|
||||
#define FENCE_BIT (1ULL << 63)
|
||||
|
||||
#define FENCE_DMM_ICA_ENABLED_IDX 0
|
||||
#define FENCE_DMM_DS_IDX 1
|
||||
#define FENCE_DMM_OUTPUT_IDX 7
|
||||
|
||||
#define SYS_MSG_START HAL_SYS_INIT_DONE
|
||||
#define SYS_MSG_END HAL_SYS_ERROR
|
||||
#define SESSION_MSG_START HAL_SESSION_EVENT_CHANGE
|
||||
#define SESSION_MSG_END HAL_SESSION_ERROR
|
||||
#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START)
|
||||
#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
|
||||
|
||||
#define ARP_BUF_SIZE 0x300000
|
||||
|
||||
#define CVP_RT_PRIO_THRESHOLD 1
|
||||
|
||||
struct msm_cvp_inst;
|
||||
|
||||
enum cvp_core_state {
|
||||
CVP_CORE_UNINIT = 0,
|
||||
CVP_CORE_INIT,
|
||||
CVP_CORE_INIT_DONE,
|
||||
};
|
||||
|
||||
enum instance_state {
|
||||
MSM_CVP_CORE_UNINIT_DONE = 0x0001,
|
||||
MSM_CVP_CORE_INIT,
|
||||
MSM_CVP_CORE_INIT_DONE,
|
||||
MSM_CVP_OPEN,
|
||||
MSM_CVP_OPEN_DONE,
|
||||
MSM_CVP_CLOSE,
|
||||
MSM_CVP_CLOSE_DONE,
|
||||
MSM_CVP_CORE_UNINIT,
|
||||
MSM_CVP_CORE_INVALID
|
||||
};
|
||||
|
||||
enum dsp_state {
|
||||
DSP_INVALID,
|
||||
DSP_UNINIT,
|
||||
DSP_PROBED,
|
||||
DSP_READY,
|
||||
DSP_SUSPEND,
|
||||
DSP_INACTIVE,
|
||||
};
|
||||
|
||||
struct msm_cvp_common_data {
|
||||
char key[128];
|
||||
int value;
|
||||
};
|
||||
|
||||
enum sku_version {
|
||||
SKU_VERSION_0 = 0,
|
||||
SKU_VERSION_1,
|
||||
SKU_VERSION_2,
|
||||
};
|
||||
|
||||
enum vpu_version {
|
||||
VPU_VERSION_4 = 1,
|
||||
VPU_VERSION_5,
|
||||
};
|
||||
|
||||
struct msm_cvp_ubwc_config_data {
|
||||
struct {
|
||||
u32 max_channel_override : 1;
|
||||
u32 mal_length_override : 1;
|
||||
u32 hb_override : 1;
|
||||
u32 bank_swzl_level_override : 1;
|
||||
u32 bank_spreading_override : 1;
|
||||
u32 reserved : 27;
|
||||
} override_bit_info;
|
||||
|
||||
u32 max_channels;
|
||||
u32 mal_length;
|
||||
u32 highest_bank_bit;
|
||||
u32 bank_swzl_level;
|
||||
u32 bank_spreading;
|
||||
};
|
||||
|
||||
struct msm_cvp_qos_setting {
|
||||
u32 axi_qos;
|
||||
u32 prioritylut_low;
|
||||
u32 prioritylut_high;
|
||||
u32 urgency_low;
|
||||
u32 urgency_low_ro;
|
||||
u32 dangerlut_low;
|
||||
u32 safelut_low;
|
||||
};
|
||||
|
||||
struct msm_cvp_platform_data {
|
||||
struct msm_cvp_common_data *common_data;
|
||||
unsigned int common_data_length;
|
||||
unsigned int sku_version;
|
||||
uint32_t vpu_ver;
|
||||
unsigned int vm_id; /* pvm: 1; tvm: 2 */
|
||||
struct msm_cvp_ubwc_config_data *ubwc_config;
|
||||
struct msm_cvp_qos_setting *noc_qos;
|
||||
};
|
||||
|
||||
struct cvp_kmem_cache {
|
||||
struct kmem_cache *cache;
|
||||
atomic_t nr_objs;
|
||||
};
|
||||
|
||||
struct msm_cvp_drv {
|
||||
struct mutex lock;
|
||||
struct msm_cvp_core *cvp_core;
|
||||
struct dentry *debugfs_root;
|
||||
int thermal_level;
|
||||
u32 sku_version;
|
||||
struct cvp_kmem_cache msg_cache;
|
||||
struct cvp_kmem_cache frame_cache;
|
||||
struct cvp_kmem_cache buf_cache;
|
||||
struct cvp_kmem_cache smem_cache;
|
||||
char fw_version[CVP_VERSION_LENGTH];
|
||||
};
|
||||
|
||||
enum profiling_points {
|
||||
SYS_INIT = 0,
|
||||
SESSION_INIT,
|
||||
LOAD_RESOURCES,
|
||||
FRAME_PROCESSING,
|
||||
FW_IDLE,
|
||||
MAX_PROFILING_POINTS,
|
||||
};
|
||||
|
||||
struct cvp_clock_data {
|
||||
int buffer_counter;
|
||||
int load;
|
||||
int load_low;
|
||||
int load_norm;
|
||||
int load_high;
|
||||
int min_threshold;
|
||||
int max_threshold;
|
||||
unsigned long bitrate;
|
||||
unsigned long min_freq;
|
||||
unsigned long curr_freq;
|
||||
u32 ddr_bw;
|
||||
u32 sys_cache_bw;
|
||||
u32 operating_rate;
|
||||
bool low_latency_mode;
|
||||
bool turbo_mode;
|
||||
};
|
||||
|
||||
struct cvp_profile_data {
|
||||
int start;
|
||||
int stop;
|
||||
int cumulative;
|
||||
char name[64];
|
||||
int sampling;
|
||||
int average;
|
||||
};
|
||||
|
||||
struct msm_cvp_debug {
|
||||
struct cvp_profile_data pdata[MAX_PROFILING_POINTS];
|
||||
int profile;
|
||||
int samples;
|
||||
};
|
||||
|
||||
enum msm_cvp_modes {
|
||||
CVP_SECURE = BIT(0),
|
||||
CVP_TURBO = BIT(1),
|
||||
CVP_THUMBNAIL = BIT(2),
|
||||
CVP_LOW_POWER = BIT(3),
|
||||
CVP_REALTIME = BIT(4),
|
||||
};
|
||||
|
||||
#define MAX_NUM_MSGS_PER_SESSION 128
|
||||
|
||||
struct cvp_session_msg {
|
||||
struct list_head node;
|
||||
struct cvp_hfi_msg_session_hdr_ext pkt;
|
||||
};
|
||||
|
||||
struct cvp_session_queue {
|
||||
spinlock_t lock;
|
||||
enum queue_state state;
|
||||
unsigned int msg_count;
|
||||
struct list_head msgs;
|
||||
wait_queue_head_t wq;
|
||||
};
|
||||
|
||||
struct cvp_session_prop {
|
||||
u32 type;
|
||||
u32 kernel_mask;
|
||||
u32 priority;
|
||||
u32 is_secure;
|
||||
u32 dsp_mask;
|
||||
u32 fthread_nr;
|
||||
u32 cycles[HFI_MAX_HW_THREADS];
|
||||
u32 fw_cycles;
|
||||
u32 op_cycles[HFI_MAX_HW_THREADS];
|
||||
u32 fw_op_cycles;
|
||||
u32 ddr_bw;
|
||||
u32 ddr_op_bw;
|
||||
u32 ddr_cache;
|
||||
u32 ddr_op_cache;
|
||||
u32 fps[HFI_MAX_HW_THREADS];
|
||||
u32 dump_offset;
|
||||
u32 dump_size;
|
||||
};
|
||||
|
||||
enum cvp_event_t {
|
||||
CVP_NO_EVENT,
|
||||
CVP_SSR_EVENT = 1,
|
||||
CVP_SYS_ERROR_EVENT,
|
||||
CVP_MAX_CLIENTS_EVENT,
|
||||
CVP_HW_UNSUPPORTED_EVENT,
|
||||
CVP_INVALID_EVENT,
|
||||
CVP_DUMP_EVENT,
|
||||
};
|
||||
|
||||
struct cvp_session_event {
|
||||
spinlock_t lock;
|
||||
enum cvp_event_t event;
|
||||
wait_queue_head_t wq;
|
||||
};
|
||||
|
||||
#define MAX_ENTRIES 64
|
||||
|
||||
struct smem_data {
|
||||
u32 size;
|
||||
u32 flags;
|
||||
u32 device_addr;
|
||||
u32 bitmap_index;
|
||||
u32 refcount;
|
||||
u32 pkt_type;
|
||||
u32 buf_idx;
|
||||
};
|
||||
|
||||
struct cvp_buf_data {
|
||||
u32 device_addr;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct inst_snapshot {
|
||||
void *session;
|
||||
u32 smem_index;
|
||||
u32 dsp_index;
|
||||
u32 persist_index;
|
||||
struct smem_data smem_log[MAX_ENTRIES];
|
||||
struct cvp_buf_data dsp_buf_log[MAX_ENTRIES];
|
||||
struct cvp_buf_data persist_buf_log[MAX_ENTRIES];
|
||||
};
|
||||
|
||||
struct cvp_noc_log {
|
||||
u32 used;
|
||||
u32 err_ctrl_swid_low;
|
||||
u32 err_ctrl_swid_high;
|
||||
u32 err_ctrl_mainctl_low;
|
||||
u32 err_ctrl_errvld_low;
|
||||
u32 err_ctrl_errclr_low;
|
||||
u32 err_ctrl_errlog0_low;
|
||||
u32 err_ctrl_errlog0_high;
|
||||
u32 err_ctrl_errlog1_low;
|
||||
u32 err_ctrl_errlog1_high;
|
||||
u32 err_ctrl_errlog2_low;
|
||||
u32 err_ctrl_errlog2_high;
|
||||
u32 err_ctrl_errlog3_low;
|
||||
u32 err_ctrl_errlog3_high;
|
||||
u32 err_core_swid_low;
|
||||
u32 err_core_swid_high;
|
||||
u32 err_core_mainctl_low;
|
||||
u32 err_core_errvld_low;
|
||||
u32 err_core_errclr_low;
|
||||
u32 err_core_errlog0_low;
|
||||
u32 err_core_errlog0_high;
|
||||
u32 err_core_errlog1_low;
|
||||
u32 err_core_errlog1_high;
|
||||
u32 err_core_errlog2_low;
|
||||
u32 err_core_errlog2_high;
|
||||
u32 err_core_errlog3_low;
|
||||
u32 err_core_errlog3_high;
|
||||
u32 arp_test_bus[16];
|
||||
u32 dma_test_bus[512];
|
||||
};
|
||||
|
||||
struct cvp_debug_log {
|
||||
struct cvp_noc_log noc_log;
|
||||
u32 snapshot_index;
|
||||
struct inst_snapshot snapshot[16];
|
||||
};
|
||||
|
||||
struct msm_cvp_core {
|
||||
struct mutex lock;
|
||||
struct mutex clk_lock;
|
||||
dev_t dev_num;
|
||||
struct cdev cdev;
|
||||
struct class *class;
|
||||
struct device *dev;
|
||||
struct cvp_hfi_ops *dev_ops;
|
||||
struct msm_cvp_platform_data *platform_data;
|
||||
struct msm_cvp_synx_ops *synx_ftbl;
|
||||
struct list_head instances;
|
||||
struct dentry *debugfs_root;
|
||||
enum cvp_core_state state;
|
||||
struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
|
||||
enum msm_cvp_hfi_type hfi_type;
|
||||
struct msm_cvp_platform_resources resources;
|
||||
struct msm_cvp_capability *capabilities;
|
||||
struct delayed_work fw_unload_work;
|
||||
struct work_struct ssr_work;
|
||||
enum hal_ssr_trigger_type ssr_type;
|
||||
u32 smmu_fault_count;
|
||||
u32 last_fault_addr;
|
||||
u32 ssr_count;
|
||||
u32 smem_leak_count;
|
||||
bool trigger_ssr;
|
||||
unsigned long curr_freq;
|
||||
unsigned long orig_core_sum;
|
||||
unsigned long bw_sum;
|
||||
atomic64_t kernel_trans_id;
|
||||
struct cvp_debug_log log;
|
||||
};
|
||||
|
||||
struct msm_cvp_inst {
|
||||
struct list_head list;
|
||||
struct list_head dsp_list;
|
||||
struct mutex sync_lock, lock;
|
||||
struct msm_cvp_core *core;
|
||||
enum session_type session_type;
|
||||
u32 dsp_handle;
|
||||
struct task_struct *task;
|
||||
atomic_t smem_count;
|
||||
struct cvp_session_queue session_queue;
|
||||
struct cvp_session_queue session_queue_fence;
|
||||
struct cvp_session_event event_handler;
|
||||
void *session;
|
||||
enum instance_state state;
|
||||
struct msm_cvp_list freqs;
|
||||
struct msm_cvp_list persistbufs;
|
||||
struct cvp_dmamap_cache dma_cache;
|
||||
struct msm_cvp_list cvpdspbufs;
|
||||
struct msm_cvp_list cvpwnccbufs;
|
||||
struct msm_cvp_list frames;
|
||||
struct cvp_frame_bufs last_frame;
|
||||
struct cvp_frame_bufs unused_dsp_bufs;
|
||||
struct cvp_frame_bufs unused_wncc_bufs;
|
||||
u32 cvpwnccbufs_num;
|
||||
struct msm_cvp_wncc_buffer* cvpwnccbufs_table;
|
||||
struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
|
||||
struct dentry *debugfs_root;
|
||||
struct msm_cvp_debug debug;
|
||||
struct cvp_clock_data clk_data;
|
||||
enum msm_cvp_modes flags;
|
||||
struct msm_cvp_capability capability;
|
||||
struct kref kref;
|
||||
struct cvp_session_prop prop;
|
||||
/* error_code will be cleared after being returned to user mode */
|
||||
u32 error_code;
|
||||
/* prev_error_code saves value of error_code before it's cleared */
|
||||
u32 prev_error_code;
|
||||
struct synx_session *synx_session_id;
|
||||
struct cvp_fence_queue fence_cmd_queue;
|
||||
char proc_name[TASK_COMM_LEN];
|
||||
};
|
||||
|
||||
extern struct msm_cvp_drv *cvp_driver;
|
||||
|
||||
void cvp_handle_cmd_response(enum hal_command_response cmd, void *data);
|
||||
int msm_cvp_trigger_ssr(struct msm_cvp_core *core,
|
||||
enum hal_ssr_trigger_type type);
|
||||
int msm_cvp_noc_error_info(struct msm_cvp_core *core);
|
||||
void msm_cvp_comm_handle_thermal_event(void);
|
||||
|
||||
void msm_cvp_ssr_handler(struct work_struct *work);
|
||||
/*
|
||||
* XXX: normally should be in msm_cvp_core.h, but that's meant for public APIs,
|
||||
* whereas this is private
|
||||
*/
|
||||
int msm_cvp_destroy(struct msm_cvp_inst *inst);
|
||||
void *cvp_get_drv_data(struct device *dev);
|
||||
void *cvp_kmem_cache_zalloc(struct cvp_kmem_cache *k, gfp_t flags);
|
||||
void cvp_kmem_cache_free(struct cvp_kmem_cache *k, void *obj);
|
||||
#endif
|
670
qcom/opensource/eva-kernel/msm/eva/msm_cvp_ioctl.c
Normal file
670
qcom/opensource/eva-kernel/msm/eva/msm_cvp_ioctl.c
Normal file
@ -0,0 +1,670 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include "cvp_private.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
|
||||
static int _get_pkt_hdr_from_user(struct eva_kmd_arg __user *up,
|
||||
struct cvp_hal_session_cmd_pkt *pkt_hdr)
|
||||
{
|
||||
struct eva_kmd_hfi_packet *u;
|
||||
struct cvp_hfi_msg_session_hdr *hdr;
|
||||
|
||||
hdr = (struct cvp_hfi_msg_session_hdr *)pkt_hdr;
|
||||
|
||||
u = &up->data.hfi_pkt;
|
||||
|
||||
if (get_user(pkt_hdr->size, &u->pkt_data[0]))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(pkt_hdr->packet_type, &u->pkt_data[1]))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_pkt_index(pkt_hdr) < 0) {
|
||||
dprintk(CVP_ERR, "user mode provides incorrect hfi\n");
|
||||
goto set_default_pkt_hdr;
|
||||
}
|
||||
|
||||
if (pkt_hdr->size > MAX_HFI_PKT_SIZE*sizeof(unsigned int)) {
|
||||
dprintk(CVP_ERR, "user HFI packet too large %x\n",
|
||||
pkt_hdr->size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
set_default_pkt_hdr:
|
||||
pkt_hdr->size = get_msg_size(hdr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _get_fence_pkt_hdr_from_user(struct eva_kmd_arg __user *up,
|
||||
struct cvp_hal_session_cmd_pkt *pkt_hdr)
|
||||
{
|
||||
struct eva_kmd_hfi_synx_packet __user *u;
|
||||
|
||||
u = &up->data.hfi_synx_pkt;
|
||||
|
||||
if (get_user(pkt_hdr->size, &u->pkt_data[0]))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(pkt_hdr->packet_type, &u->pkt_data[1]))
|
||||
return -EFAULT;
|
||||
|
||||
if (pkt_hdr->size > (MAX_HFI_PKT_SIZE*sizeof(unsigned int)))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Size is in unit of u32 */
|
||||
static int _copy_pkt_from_user(struct eva_kmd_arg *kp,
|
||||
struct eva_kmd_arg __user *up,
|
||||
unsigned int start, unsigned int size)
|
||||
{
|
||||
struct eva_kmd_hfi_packet *k, *u;
|
||||
int i;
|
||||
|
||||
k = &kp->data.hfi_pkt;
|
||||
u = &up->data.hfi_pkt;
|
||||
for (i = start; i < start + size; i++)
|
||||
if (get_user(k->pkt_data[i], &u->pkt_data[i]))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(k->oob_buf, &u->oob_buf))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _copy_synx_data_from_user(
|
||||
struct eva_kmd_hfi_synx_packet *k,
|
||||
struct eva_kmd_hfi_synx_packet __user *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_FENCE_DATA_SIZE; i++) {
|
||||
if (get_user(k->fence_data[i], &u->fence_data[i]))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (get_user(k->oob_buf, &u->oob_buf))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Size is in unit of u32 */
|
||||
static int _copy_fence_data_from_user_deprecate(
|
||||
struct eva_kmd_hfi_fence_packet *k,
|
||||
struct eva_kmd_hfi_fence_packet __user *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_HFI_FENCE_SIZE; i++) {
|
||||
if (get_user(k->fence_data[i], &u->fence_data[i]))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (get_user(k->frame_id, &u->frame_id)) {
|
||||
dprintk(CVP_ERR, "Failed to get frame id from fence pkt\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _copy_fence_pkt_from_user(struct eva_kmd_arg *kp,
|
||||
struct eva_kmd_arg __user *up)
|
||||
{ struct eva_kmd_hfi_synx_packet *k;
|
||||
struct eva_kmd_hfi_synx_packet __user *u;
|
||||
struct eva_kmd_hfi_fence_packet __user *u1;
|
||||
int i;
|
||||
|
||||
k = &kp->data.hfi_synx_pkt;
|
||||
u = &up->data.hfi_synx_pkt;
|
||||
u1 = &up->data.hfi_fence_pkt;
|
||||
|
||||
for (i = 0; i < MAX_HFI_PKT_SIZE; i++)
|
||||
if (get_user(k->pkt_data[i], &u->pkt_data[i]))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(k->fence_data[0], &u->fence_data[0]))
|
||||
return -EFAULT;
|
||||
|
||||
if (k->fence_data[0] == 0xFEEDFACE)
|
||||
return _copy_synx_data_from_user(k, u);
|
||||
else
|
||||
return _copy_fence_data_from_user_deprecate(
|
||||
(struct eva_kmd_hfi_fence_packet *)k, u1);
|
||||
}
|
||||
|
||||
static int _copy_frameid_from_user(struct eva_kmd_arg *kp,
|
||||
struct eva_kmd_arg __user *up)
|
||||
{
|
||||
if (get_user(kp->data.frame_id, &up->data.frame_id)) {
|
||||
dprintk(CVP_ERR, "Failed to get frame id from user\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _copy_sysprop_from_user(struct eva_kmd_arg *kp,
|
||||
struct eva_kmd_arg __user *up)
|
||||
{
|
||||
struct eva_kmd_sys_properties *k, *u;
|
||||
|
||||
k = &kp->data.sys_properties;
|
||||
u = &up->data.sys_properties;
|
||||
|
||||
if (get_user(k->prop_num, &u->prop_num))
|
||||
return -EFAULT;
|
||||
|
||||
if (k->prop_num < 1 || k->prop_num > MAX_KMD_PROP_NUM_PER_PACKET) {
|
||||
dprintk(CVP_ERR, "Num of prop out of range %d\n", k->prop_num);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return _copy_pkt_from_user(kp, up, 1,
|
||||
(k->prop_num * (sizeof(struct eva_kmd_sys_property) >> 2)));
|
||||
}
|
||||
|
||||
static int _copy_pkt_to_user(struct eva_kmd_arg *kp,
|
||||
struct eva_kmd_arg __user *up,
|
||||
unsigned int size)
|
||||
{
|
||||
struct eva_kmd_hfi_packet *k, *u;
|
||||
int i;
|
||||
|
||||
k = &kp->data.hfi_pkt;
|
||||
u = &up->data.hfi_pkt;
|
||||
for (i = 0; i < size; i++)
|
||||
if (put_user(k->pkt_data[i], &u->pkt_data[i]))
|
||||
return -EFAULT;
|
||||
|
||||
if (put_user(k->oob_buf, &u->oob_buf))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _copy_fence_pkt_to_user(struct eva_kmd_arg *kp,
|
||||
struct eva_kmd_arg __user *up)
|
||||
{
|
||||
struct eva_kmd_hfi_synx_packet *k;
|
||||
struct eva_kmd_hfi_synx_packet __user *u;
|
||||
int i;
|
||||
|
||||
k = &kp->data.hfi_synx_pkt;
|
||||
u = &up->data.hfi_synx_pkt;
|
||||
for (i = 0; i < MAX_HFI_PKT_SIZE; i++) {
|
||||
if (put_user(k->pkt_data[i], &u->pkt_data[i]))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (put_user(k->oob_buf, &u->oob_buf))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _copy_sysprop_to_user(struct eva_kmd_arg *kp,
|
||||
struct eva_kmd_arg __user *up)
|
||||
{
|
||||
struct eva_kmd_sys_properties *k;
|
||||
struct eva_kmd_sys_properties __user *u;
|
||||
int i;
|
||||
|
||||
k = &kp->data.sys_properties;
|
||||
u = &up->data.sys_properties;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (put_user(k->prop_data[i].data, &u->prop_data[i].data))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void print_hfi_short(struct eva_kmd_arg __user *up)
|
||||
{
|
||||
struct eva_kmd_hfi_packet *pkt;
|
||||
unsigned int words[5];
|
||||
|
||||
pkt = &up->data.hfi_pkt;
|
||||
if (get_user(words[0], &up->type) ||
|
||||
get_user(words[1], &up->buf_offset) ||
|
||||
get_user(words[2], &up->buf_num) ||
|
||||
get_user(words[3], &pkt->pkt_data[0]) ||
|
||||
get_user(words[4], &pkt->pkt_data[1]))
|
||||
dprintk(CVP_ERR, "Failed to print ioctl cmd\n");
|
||||
|
||||
dprintk(CVP_HFI, "IOCTL cmd type %#x, offset %d, num %d, pkt %d %#x\n",
|
||||
words[0], words[1], words[2], words[3], words[4]);
|
||||
}
|
||||
|
||||
static int _copy_session_ctrl_to_user(
|
||||
struct eva_kmd_session_control *k,
|
||||
struct eva_kmd_session_control *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (put_user(k->ctrl_type, &u->ctrl_type))
|
||||
return -EFAULT;
|
||||
for (i = 0; i < 8; i++)
|
||||
if (put_user(k->ctrl_data[i], &u->ctrl_data[i]))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _get_session_ctrl_from_user(
|
||||
struct eva_kmd_session_control *k,
|
||||
struct eva_kmd_session_control *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (get_user(k->ctrl_type, &u->ctrl_type))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (get_user(k->ctrl_data[i], &u->ctrl_data[i]))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _get_session_info_from_user(
|
||||
struct eva_kmd_session_info *k,
|
||||
struct eva_kmd_session_info __user *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (get_user(k->session_id, &u->session_id))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
if (get_user(k->reserved[i], &u->reserved[i]))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int convert_from_user(struct eva_kmd_arg *kp,
|
||||
unsigned long arg,
|
||||
struct msm_cvp_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
struct eva_kmd_arg __user *up = (struct eva_kmd_arg *)arg;
|
||||
struct cvp_hal_session_cmd_pkt pkt_hdr;
|
||||
int pkt_idx;
|
||||
|
||||
if (!kp || !up) {
|
||||
dprintk_rl(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
print_hfi_short(up);
|
||||
|
||||
if (get_user(kp->type, &up->type))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(kp->buf_offset, &up->buf_offset) ||
|
||||
get_user(kp->buf_num, &up->buf_num))
|
||||
return -EFAULT;
|
||||
|
||||
switch (kp->type) {
|
||||
case EVA_KMD_GET_SESSION_INFO:
|
||||
{
|
||||
struct eva_kmd_session_info *k;
|
||||
struct eva_kmd_session_info __user *u;
|
||||
|
||||
k = &kp->data.session;
|
||||
u = &up->data.session;
|
||||
if (_get_session_info_from_user(k, u)) {
|
||||
dprintk(CVP_ERR, "fail to get sess info\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_REGISTER_BUFFER:
|
||||
{
|
||||
struct eva_kmd_buffer *k, *u;
|
||||
|
||||
k = &kp->data.regbuf;
|
||||
u = &up->data.regbuf;
|
||||
if (get_user(k->type, &u->type) ||
|
||||
get_user(k->index, &u->index) ||
|
||||
get_user(k->fd, &u->fd) ||
|
||||
get_user(k->size, &u->size) ||
|
||||
get_user(k->offset, &u->offset) ||
|
||||
get_user(k->pixelformat, &u->pixelformat) ||
|
||||
get_user(k->flags, &u->flags))
|
||||
return -EFAULT;
|
||||
for (i = 0; i < 5; i++)
|
||||
if (get_user(k->reserved[i], &u->reserved[i]))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_UNREGISTER_BUFFER:
|
||||
{
|
||||
struct eva_kmd_buffer *k, *u;
|
||||
|
||||
k = &kp->data.unregbuf;
|
||||
u = &up->data.unregbuf;
|
||||
if (get_user(k->type, &u->type) ||
|
||||
get_user(k->index, &u->index) ||
|
||||
get_user(k->fd, &u->fd) ||
|
||||
get_user(k->size, &u->size) ||
|
||||
get_user(k->offset, &u->offset) ||
|
||||
get_user(k->pixelformat, &u->pixelformat) ||
|
||||
get_user(k->flags, &u->flags))
|
||||
return -EFAULT;
|
||||
for (i = 0; i < 5; i++)
|
||||
if (get_user(k->reserved[i], &u->reserved[i]))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_SEND_CMD_PKT:
|
||||
{
|
||||
if (_get_pkt_hdr_from_user(up, &pkt_hdr)) {
|
||||
dprintk(CVP_ERR, "Invalid syscall: %x, %x, %x\n",
|
||||
kp->type, pkt_hdr.size, pkt_hdr.packet_type);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
rc = _copy_pkt_from_user(kp, up, 0, (pkt_hdr.size >> 2));
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_SEND_FENCE_CMD_PKT:
|
||||
{
|
||||
if (_get_fence_pkt_hdr_from_user(up, &pkt_hdr)) {
|
||||
dprintk(CVP_ERR, "Invalid syscall: %x, %x, %x\n",
|
||||
kp->type, pkt_hdr.size, pkt_hdr.packet_type);
|
||||
return -EFAULT;
|
||||
}
|
||||
dprintk(CVP_HFI, "system call cmd pkt: %d 0x%x\n",
|
||||
pkt_hdr.size, pkt_hdr.packet_type);
|
||||
|
||||
pkt_idx = get_pkt_index(&pkt_hdr);
|
||||
if (pkt_idx < 0) {
|
||||
dprintk(CVP_ERR, "%s incorrect packet %d, %x\n",
|
||||
__func__,
|
||||
pkt_hdr.size,
|
||||
pkt_hdr.packet_type);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
rc = _copy_fence_pkt_from_user(kp, up);
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_RECEIVE_MSG_PKT:
|
||||
break;
|
||||
case EVA_KMD_SESSION_CONTROL:
|
||||
{
|
||||
struct eva_kmd_session_control *k, *u;
|
||||
|
||||
k = &kp->data.session_ctrl;
|
||||
u = &up->data.session_ctrl;
|
||||
|
||||
rc = _get_session_ctrl_from_user(k, u);
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_GET_SYS_PROPERTY:
|
||||
{
|
||||
if (_copy_sysprop_from_user(kp, up)) {
|
||||
dprintk(CVP_ERR, "Failed to get sysprop from user\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_SET_SYS_PROPERTY:
|
||||
{
|
||||
if (_copy_sysprop_from_user(kp, up)) {
|
||||
dprintk(CVP_ERR, "Failed to set sysprop from user\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_FLUSH_ALL:
|
||||
case EVA_KMD_UPDATE_POWER:
|
||||
break;
|
||||
case EVA_KMD_FLUSH_FRAME:
|
||||
{
|
||||
if (_copy_frameid_from_user(kp, up))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk_rl(CVP_ERR, "%s: unknown cmd type 0x%x\n",
|
||||
__func__, kp->type);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _put_user_session_info(
|
||||
struct eva_kmd_session_info *k,
|
||||
struct eva_kmd_session_info __user *u)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (put_user(k->session_id, &u->session_id))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
if (put_user(k->reserved[i], &u->reserved[i]))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int convert_to_user(struct eva_kmd_arg *kp, unsigned long arg)
|
||||
{
|
||||
int rc = 0;
|
||||
int i, size;
|
||||
struct eva_kmd_arg __user *up = (struct eva_kmd_arg *)arg;
|
||||
struct cvp_hal_session_cmd_pkt pkt_hdr;
|
||||
|
||||
if (!kp || !up) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (put_user(kp->type, &up->type))
|
||||
return -EFAULT;
|
||||
|
||||
switch (kp->type) {
|
||||
case EVA_KMD_RECEIVE_MSG_PKT:
|
||||
{
|
||||
struct eva_kmd_hfi_packet *k, *u;
|
||||
struct cvp_hfi_msg_session_hdr *hdr;
|
||||
|
||||
k = &kp->data.hfi_pkt;
|
||||
u = &up->data.hfi_pkt;
|
||||
hdr = (struct cvp_hfi_msg_session_hdr *)k;
|
||||
size = get_msg_size(hdr) >> 2;
|
||||
for (i = 0; i < size; i++)
|
||||
if (put_user(k->pkt_data[i], &u->pkt_data[i]))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_GET_SESSION_INFO:
|
||||
{
|
||||
struct eva_kmd_session_info *k;
|
||||
struct eva_kmd_session_info __user *u;
|
||||
|
||||
k = &kp->data.session;
|
||||
u = &up->data.session;
|
||||
if (_put_user_session_info(k, u)) {
|
||||
dprintk(CVP_ERR, "fail to copy sess info to user\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_REGISTER_BUFFER:
|
||||
{
|
||||
struct eva_kmd_buffer *k, *u;
|
||||
|
||||
k = &kp->data.regbuf;
|
||||
u = &up->data.regbuf;
|
||||
if (put_user(k->type, &u->type) ||
|
||||
put_user(k->index, &u->index) ||
|
||||
put_user(k->fd, &u->fd) ||
|
||||
put_user(k->size, &u->size) ||
|
||||
put_user(k->offset, &u->offset) ||
|
||||
put_user(k->pixelformat, &u->pixelformat) ||
|
||||
put_user(k->flags, &u->flags))
|
||||
return -EFAULT;
|
||||
for (i = 0; i < 5; i++)
|
||||
if (put_user(k->reserved[i], &u->reserved[i]))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_UNREGISTER_BUFFER:
|
||||
{
|
||||
struct eva_kmd_buffer *k, *u;
|
||||
|
||||
k = &kp->data.unregbuf;
|
||||
u = &up->data.unregbuf;
|
||||
if (put_user(k->type, &u->type) ||
|
||||
put_user(k->index, &u->index) ||
|
||||
put_user(k->fd, &u->fd) ||
|
||||
put_user(k->size, &u->size) ||
|
||||
put_user(k->offset, &u->offset) ||
|
||||
put_user(k->pixelformat, &u->pixelformat) ||
|
||||
put_user(k->flags, &u->flags))
|
||||
return -EFAULT;
|
||||
for (i = 0; i < 5; i++)
|
||||
if (put_user(k->reserved[i], &u->reserved[i]))
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_SEND_CMD_PKT:
|
||||
{
|
||||
if (_get_pkt_hdr_from_user(up, &pkt_hdr))
|
||||
return -EFAULT;
|
||||
|
||||
dprintk(CVP_HFI, "Send user cmd pkt: %d %d\n",
|
||||
pkt_hdr.size, pkt_hdr.packet_type);
|
||||
rc = _copy_pkt_to_user(kp, up, (pkt_hdr.size >> 2));
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_SEND_FENCE_CMD_PKT:
|
||||
{
|
||||
if (_get_fence_pkt_hdr_from_user(up, &pkt_hdr))
|
||||
return -EFAULT;
|
||||
|
||||
dprintk(CVP_HFI, "Send user cmd pkt: %d %d\n",
|
||||
pkt_hdr.size, pkt_hdr.packet_type);
|
||||
|
||||
rc = _copy_fence_pkt_to_user(kp, up);
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_SESSION_CONTROL:
|
||||
{
|
||||
struct eva_kmd_session_control *k, *u;
|
||||
|
||||
k = &kp->data.session_ctrl;
|
||||
u = &up->data.session_ctrl;
|
||||
rc = _copy_session_ctrl_to_user(k, u);
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_GET_SYS_PROPERTY:
|
||||
{
|
||||
if (_copy_sysprop_to_user(kp, up)) {
|
||||
dprintk(CVP_ERR, "Fail to copy sysprop to user\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVA_KMD_FLUSH_ALL:
|
||||
case EVA_KMD_FLUSH_FRAME:
|
||||
case EVA_KMD_SET_SYS_PROPERTY:
|
||||
case EVA_KMD_UPDATE_POWER:
|
||||
break;
|
||||
default:
|
||||
dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n",
|
||||
__func__, kp->type);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long cvp_ioctl(struct msm_cvp_inst *inst,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int rc;
|
||||
struct eva_kmd_arg *karg;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
karg = kzalloc(sizeof(*karg), GFP_KERNEL);
|
||||
if (!karg)
|
||||
return -ENOMEM;
|
||||
|
||||
if (convert_from_user(karg, arg, inst)) {
|
||||
dprintk_rl(CVP_ERR, "%s: failed to get from user cmd %x\n",
|
||||
__func__, karg->type);
|
||||
kfree(karg);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
rc = msm_cvp_private((void *)inst, cmd, karg);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: failed cmd type %x %d\n",
|
||||
__func__, karg->type, rc);
|
||||
kfree(karg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (convert_to_user(karg, arg)) {
|
||||
dprintk(CVP_ERR, "%s: failed to copy to user cmd %x\n",
|
||||
__func__, karg->type);
|
||||
kfree(karg);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
kfree(karg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
long cvp_unblocked_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct msm_cvp_inst *inst;
|
||||
|
||||
if (!filp || !filp->private_data) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
inst = filp->private_data;
|
||||
return cvp_ioctl(inst, cmd, arg);
|
||||
}
|
||||
|
||||
long cvp_compat_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct msm_cvp_inst *inst;
|
||||
|
||||
if (!filp || !filp->private_data) {
|
||||
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
inst = filp->private_data;
|
||||
return cvp_ioctl(inst, cmd, (unsigned long)compat_ptr(arg));
|
||||
}
|
1042
qcom/opensource/eva-kernel/msm/eva/msm_cvp_platform.c
Normal file
1042
qcom/opensource/eva-kernel/msm/eva/msm_cvp_platform.c
Normal file
File diff suppressed because it is too large
Load Diff
1265
qcom/opensource/eva-kernel/msm/eva/msm_cvp_res_parse.c
Normal file
1265
qcom/opensource/eva-kernel/msm/eva/msm_cvp_res_parse.c
Normal file
File diff suppressed because it is too large
Load Diff
30
qcom/opensource/eva-kernel/msm/eva/msm_cvp_res_parse.h
Normal file
30
qcom/opensource/eva-kernel/msm/eva/msm_cvp_res_parse.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __MSM_CVP_RES_PARSE_H__
|
||||
#define __MSM_CVP_RES_PARSE_H__
|
||||
#include <linux/of.h>
|
||||
#include "msm_cvp_resources.h"
|
||||
#include "msm_cvp_common.h"
|
||||
void msm_cvp_free_platform_resources(
|
||||
struct msm_cvp_platform_resources *res);
|
||||
|
||||
int read_hfi_type(struct platform_device *pdev);
|
||||
|
||||
int cvp_read_platform_resources_from_drv_data(
|
||||
struct msm_cvp_core *core);
|
||||
int cvp_read_platform_resources_from_dt(
|
||||
struct msm_cvp_platform_resources *res);
|
||||
|
||||
int cvp_read_context_bank_resources_from_dt(struct platform_device *pdev);
|
||||
|
||||
int cvp_read_bus_resources_from_dt(struct platform_device *pdev);
|
||||
int cvp_read_mem_cdsp_resources_from_dt(struct platform_device *pdev);
|
||||
|
||||
int msm_cvp_load_u32_table(struct platform_device *pdev,
|
||||
struct device_node *of_node, char *table_name, int struct_size,
|
||||
u32 **table, u32 *num_elements);
|
||||
|
||||
#endif
|
232
qcom/opensource/eva-kernel/msm/eva/msm_cvp_resources.h
Normal file
232
qcom/opensource/eva-kernel/msm/eva/msm_cvp_resources.h
Normal file
@ -0,0 +1,232 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __MSM_CVP_RESOURCES_H__
|
||||
#define __MSM_CVP_RESOURCES_H__
|
||||
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include "msm_cvp_core.h"
|
||||
#include <linux/soc/qcom/llcc-qcom.h>
|
||||
|
||||
struct reg_value_pair {
|
||||
u32 reg;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct reg_set {
|
||||
struct reg_value_pair *reg_tbl;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct addr_range {
|
||||
u32 start;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct addr_set {
|
||||
struct addr_range *addr_tbl;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct context_bank_info {
|
||||
struct list_head list;
|
||||
const char *name;
|
||||
u32 buffer_type;
|
||||
bool is_secure;
|
||||
struct addr_range addr_range;
|
||||
struct device *dev;
|
||||
struct iommu_domain *domain;
|
||||
};
|
||||
|
||||
struct regulator_info {
|
||||
struct regulator *regulator;
|
||||
bool has_hw_power_collapse;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct regulator_set {
|
||||
struct regulator_info *regulator_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct clock_info {
|
||||
const char *name;
|
||||
u32 clk_id;
|
||||
struct clk *clk;
|
||||
u32 count;
|
||||
bool has_scaling;
|
||||
bool has_mem_retention;
|
||||
};
|
||||
|
||||
struct clock_set {
|
||||
struct clock_info *clock_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct bus_info {
|
||||
char *name;
|
||||
int master;
|
||||
int slave;
|
||||
unsigned int range[2];
|
||||
const char *governor;
|
||||
struct device *dev;
|
||||
struct devfreq_dev_profile devfreq_prof;
|
||||
struct devfreq *devfreq;
|
||||
struct icc_path *client;
|
||||
bool is_prfm_gov_used;
|
||||
};
|
||||
|
||||
struct bus_set {
|
||||
struct bus_info *bus_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
enum action_stage {
|
||||
CVP_ON_INIT,
|
||||
CVP_ON_USE,
|
||||
CVP_ON_INVALID,
|
||||
};
|
||||
enum reset_clk_state {
|
||||
RESET_INIT,
|
||||
RESET_ACQUIRED,
|
||||
RESET_RELEASED,
|
||||
};
|
||||
|
||||
struct reset_info {
|
||||
struct reset_control *rst;
|
||||
enum action_stage required_stage;
|
||||
enum reset_clk_state state;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct reset_set {
|
||||
struct reset_info *reset_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct allowed_clock_rates_table {
|
||||
u32 clock_rate;
|
||||
};
|
||||
|
||||
struct clock_profile_entry {
|
||||
u32 codec_mask;
|
||||
u32 vpp_cycles;
|
||||
u32 vsp_cycles;
|
||||
u32 low_power_cycles;
|
||||
};
|
||||
|
||||
struct clock_freq_table {
|
||||
struct clock_profile_entry *clk_prof_entries;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct subcache_info {
|
||||
const char *name;
|
||||
bool isactive;
|
||||
bool isset;
|
||||
struct llcc_slice_desc *subcache;
|
||||
};
|
||||
|
||||
struct subcache_set {
|
||||
struct subcache_info *subcache_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct msm_cvp_mem_cdsp {
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
#define MAX_SILVER_CORE_NUM 8
|
||||
#define HFI_SESSION_FD 4
|
||||
#define HFI_SESSION_DMM 2
|
||||
|
||||
struct cvp_pm_qos {
|
||||
u32 silver_count;
|
||||
u32 latency_us;
|
||||
u32 off_vote_cnt;
|
||||
spinlock_t lock;
|
||||
int silver_cores[MAX_SILVER_CORE_NUM];
|
||||
struct dev_pm_qos_request *pm_qos_hdls;
|
||||
};
|
||||
|
||||
struct cvp_fw_reg_mappings {
|
||||
phys_addr_t ipclite_iova;
|
||||
phys_addr_t ipclite_phyaddr;
|
||||
uint32_t ipclite_size;
|
||||
phys_addr_t hwmutex_iova;
|
||||
phys_addr_t hwmutex_phyaddr;
|
||||
uint32_t hwmutex_size;
|
||||
phys_addr_t aon_iova;
|
||||
phys_addr_t aon_phyaddr;
|
||||
uint32_t aon_size;
|
||||
phys_addr_t timer_iova;
|
||||
phys_addr_t timer_phyaddr;
|
||||
uint32_t timer_size;
|
||||
};
|
||||
|
||||
struct msm_cvp_platform_resources {
|
||||
phys_addr_t firmware_base;
|
||||
phys_addr_t register_base;
|
||||
phys_addr_t ipcc_reg_base;
|
||||
phys_addr_t gcc_reg_base;
|
||||
uint32_t register_size;
|
||||
uint32_t ipcc_reg_size;
|
||||
uint32_t gcc_reg_size;
|
||||
struct cvp_fw_reg_mappings reg_mappings;
|
||||
uint32_t irq;
|
||||
uint32_t irq_wd;
|
||||
uint32_t sku_version;
|
||||
struct allowed_clock_rates_table *allowed_clks_tbl;
|
||||
u32 allowed_clks_tbl_size;
|
||||
struct clock_freq_table clock_freq_tbl;
|
||||
bool sys_cache_present;
|
||||
bool sys_cache_res_set;
|
||||
struct subcache_set subcache_set;
|
||||
struct reg_set reg_set;
|
||||
struct addr_set qdss_addr_set;
|
||||
uint32_t max_ssr_allowed;
|
||||
struct platform_device *pdev;
|
||||
struct regulator_set regulator_set;
|
||||
struct clock_set clock_set;
|
||||
struct bus_set bus_set;
|
||||
struct reset_set reset_set;
|
||||
bool use_non_secure_pil;
|
||||
bool sw_power_collapsible;
|
||||
bool dsp_enabled;
|
||||
struct list_head context_banks;
|
||||
bool thermal_mitigable;
|
||||
const char *fw_name;
|
||||
const char *hfi_version;
|
||||
bool debug_timeout;
|
||||
struct cvp_pm_qos pm_qos;
|
||||
uint32_t max_inst_count;
|
||||
uint32_t max_secure_inst_count;
|
||||
int msm_cvp_hw_rsp_timeout;
|
||||
int msm_cvp_dsp_rsp_timeout;
|
||||
uint32_t msm_cvp_pwr_collapse_delay;
|
||||
bool non_fatal_pagefaults;
|
||||
bool fatal_ssr;
|
||||
struct msm_cvp_mem_cdsp mem_cdsp;
|
||||
uint32_t vpu_ver;
|
||||
uint32_t fw_cycles;
|
||||
struct msm_cvp_ubwc_config_data *ubwc_config;
|
||||
uint32_t qos_noc_rge_niu_offset;
|
||||
uint32_t qos_noc_gce_vadl_tof_niu_offset;
|
||||
uint32_t qos_noc_cdm_niu_offset;
|
||||
uint32_t noc_core_err_offset;
|
||||
uint32_t noc_main_sidebandmanager_offset;
|
||||
};
|
||||
|
||||
static inline bool is_iommu_present(struct msm_cvp_platform_resources *res)
|
||||
{
|
||||
return !list_empty(&res->context_banks);
|
||||
}
|
||||
|
||||
int cvp_of_fdt_get_ddrtype(void);
|
||||
#endif
|
||||
|
344
qcom/opensource/eva-kernel/msm/eva/msm_cvp_synx.c
Normal file
344
qcom/opensource/eva-kernel/msm/eva/msm_cvp_synx.c
Normal file
@ -0,0 +1,344 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "msm_cvp_common.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "msm_cvp_core.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
#ifdef CVP_SYNX_ENABLED
|
||||
|
||||
static int cvp_sess_init_synx_v2(struct msm_cvp_inst *inst)
|
||||
{
|
||||
|
||||
struct synx_initialization_params params = { 0 };
|
||||
|
||||
params.name = "cvp-kernel-client";
|
||||
params.id = SYNX_CLIENT_EVA_CTX0;
|
||||
inst->synx_session_id = synx_initialize(¶ms);
|
||||
if (IS_ERR_OR_NULL(&inst->synx_session_id)) {
|
||||
dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_sess_deinit_synx_v2(struct msm_cvp_inst *inst)
|
||||
{
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
synx_uninitialize(inst->synx_session_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cvp_dump_fence_queue_v2(struct msm_cvp_inst *inst)
|
||||
{
|
||||
struct cvp_fence_queue *q;
|
||||
struct cvp_fence_command *f;
|
||||
struct synx_session *ssid;
|
||||
int i;
|
||||
|
||||
q = &inst->fence_cmd_queue;
|
||||
ssid = inst->synx_session_id;
|
||||
mutex_lock(&q->lock);
|
||||
dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %pK\n",
|
||||
hash32_ptr(inst->session), q->mode, ssid);
|
||||
|
||||
dprintk(CVP_WARN, "fence cmdq wait list:\n");
|
||||
list_for_each_entry(f, &q->wait_list, list) {
|
||||
dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type);
|
||||
for (i = 0; i < f->output_index; i++)
|
||||
dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n",
|
||||
i, f->synx[i],
|
||||
synx_get_status(ssid, f->synx[i]));
|
||||
|
||||
}
|
||||
|
||||
dprintk(CVP_WARN, "fence cmdq schedule list:\n");
|
||||
list_for_each_entry(f, &q->sched_list, list) {
|
||||
dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type);
|
||||
for (i = 0; i < f->output_index; i++)
|
||||
dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n",
|
||||
i, f->synx[i],
|
||||
synx_get_status(ssid, f->synx[i]));
|
||||
|
||||
}
|
||||
mutex_unlock(&q->lock);
|
||||
}
|
||||
|
||||
static int cvp_import_synx_v2(struct msm_cvp_inst *inst,
|
||||
struct cvp_fence_command *fc,
|
||||
u32 *fence)
|
||||
{
|
||||
int rc = 0, rr = 0;
|
||||
int i;
|
||||
struct eva_kmd_fence *fs;
|
||||
struct synx_import_params params = {0};
|
||||
u32 h_synx;
|
||||
struct synx_session *ssid;
|
||||
|
||||
fs = (struct eva_kmd_fence *)fence;
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
for (i = 0; i < fc->num_fences; ++i) {
|
||||
h_synx = fs[i].h_synx;
|
||||
|
||||
if (h_synx) {
|
||||
params.type = SYNX_IMPORT_INDV_PARAMS;
|
||||
params.indv.fence = &h_synx;
|
||||
params.indv.flags = SYNX_IMPORT_SYNX_FENCE
|
||||
| SYNX_IMPORT_LOCAL_FENCE;
|
||||
params.indv.new_h_synx = &fc->synx[i];
|
||||
|
||||
rc = synx_import(ssid, ¶ms);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: %u synx_import failed\n",
|
||||
__func__, h_synx);
|
||||
rr = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rr;
|
||||
}
|
||||
|
||||
static int cvp_release_synx_v2(struct msm_cvp_inst *inst,
|
||||
struct cvp_fence_command *fc)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
u32 h_synx;
|
||||
struct synx_session *ssid;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
for (i = 0; i < fc->num_fences; ++i) {
|
||||
h_synx = fc->synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_release(ssid, h_synx);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_release %d, %d failed\n",
|
||||
__func__, h_synx, i);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst,
|
||||
enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc,
|
||||
int synx_state)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
u32 h_synx;
|
||||
struct synx_session *ssid;
|
||||
int start = 0, end = 0;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
if (type == CVP_INPUT_SYNX) {
|
||||
start = 0;
|
||||
end = fc->output_index;
|
||||
} else if (type == CVP_OUTPUT_SYNX) {
|
||||
start = fc->output_index;
|
||||
end = fc->num_fences;
|
||||
} else {
|
||||
dprintk(CVP_ERR, "%s Incorrect synx type\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = start; i < end; ++i) {
|
||||
h_synx = fc->synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
dprintk(CVP_SYNX, "Cancel synx %d session %llx\n",
|
||||
h_synx, inst);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_signal %d %d %d failed\n",
|
||||
__func__, h_synx, i, synx_state);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int cvp_cancel_synx_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc, int synx_state)
|
||||
{
|
||||
return cvp_cancel_synx_impl(inst, type, fc, synx_state);
|
||||
}
|
||||
|
||||
static int cvp_wait_synx(struct synx_session *ssid, u32 *synx, u32 num_synx,
|
||||
u32 *synx_state)
|
||||
{
|
||||
int i = 0, rc = 0;
|
||||
unsigned long timeout_ms = 2000;
|
||||
u32 h_synx;
|
||||
|
||||
while (i < num_synx) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_wait(ssid, h_synx, timeout_ms);
|
||||
if (rc) {
|
||||
*synx_state = synx_get_status(ssid, h_synx);
|
||||
if(*synx_state == SYNX_STATE_SIGNALED_SUCCESS)
|
||||
{
|
||||
dprintk(CVP_SYNX, "%s: SYNX SIGNAl STATE SUCCESS \n", __func__);
|
||||
rc=0;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) {
|
||||
dprintk(CVP_SYNX,
|
||||
"%s: synx_wait %d cancel %d state %d\n",
|
||||
current->comm, i, rc, *synx_state);
|
||||
} else {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_wait %d failed %d state %d\n",
|
||||
current->comm, i, rc, *synx_state);
|
||||
*synx_state = SYNX_STATE_SIGNALED_CANCEL;
|
||||
}
|
||||
return rc;
|
||||
} else {
|
||||
rc = 0; /* SYNX_STATE_SIGNALED_SUCCESS = 2 */
|
||||
}
|
||||
|
||||
dprintk(CVP_SYNX, "Wait synx %u returned succes\n",
|
||||
h_synx);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_signal_synx(struct synx_session *ssid, u32 *synx, u32 num_synx,
|
||||
u32 synx_state)
|
||||
{
|
||||
int i = 0, rc = 0;
|
||||
u32 h_synx;
|
||||
|
||||
while (i < num_synx) {
|
||||
h_synx = synx[i];
|
||||
if (h_synx) {
|
||||
rc = synx_signal(ssid, h_synx, synx_state);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: synx_signal %u %d failed\n",
|
||||
current->comm, h_synx, i);
|
||||
synx_state = SYNX_STATE_SIGNALED_CANCEL;
|
||||
}
|
||||
dprintk(CVP_SYNX, "Signaled synx %u state %d\n",
|
||||
h_synx, synx_state);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_synx_ops_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc, u32 *synx_state)
|
||||
{
|
||||
struct synx_session *ssid;
|
||||
|
||||
if (fc->signature == 0xB0BABABE)
|
||||
return 0;
|
||||
|
||||
ssid = inst->synx_session_id;
|
||||
|
||||
if (type == CVP_INPUT_SYNX) {
|
||||
return cvp_wait_synx(ssid, fc->synx, fc->output_index,
|
||||
synx_state);
|
||||
} else if (type == CVP_OUTPUT_SYNX) {
|
||||
return cvp_signal_synx(ssid, &fc->synx[fc->output_index],
|
||||
(fc->num_fences - fc->output_index),
|
||||
*synx_state);
|
||||
} else {
|
||||
dprintk(CVP_ERR, "%s Incorrect SYNX type\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct msm_cvp_synx_ops cvp_synx = {
|
||||
.cvp_sess_init_synx = cvp_sess_init_synx_v2,
|
||||
.cvp_sess_deinit_synx = cvp_sess_deinit_synx_v2,
|
||||
.cvp_release_synx = cvp_release_synx_v2,
|
||||
.cvp_import_synx = cvp_import_synx_v2,
|
||||
.cvp_synx_ops = cvp_synx_ops_v2,
|
||||
.cvp_cancel_synx = cvp_cancel_synx_v2,
|
||||
.cvp_dump_fence_queue = cvp_dump_fence_queue_v2,
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
static int cvp_sess_init_synx_stub(struct msm_cvp_inst *inst)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_sess_deinit_synx_stub(struct msm_cvp_inst *inst)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_release_synx_stub(struct msm_cvp_inst *inst,
|
||||
struct cvp_fence_command *fc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_import_synx_stub(struct msm_cvp_inst *inst,
|
||||
struct cvp_fence_command *fc,
|
||||
u32 *fence)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_synx_ops_stub(struct msm_cvp_inst *inst, enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc, u32 *synx_state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_cancel_synx_stub(struct msm_cvp_inst *inst, enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc, int synx_state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cvp_dump_fence_queue_stub(struct msm_cvp_inst *inst)
|
||||
{
|
||||
}
|
||||
|
||||
static struct msm_cvp_synx_ops cvp_synx = {
|
||||
.cvp_sess_init_synx = cvp_sess_init_synx_stub,
|
||||
.cvp_sess_deinit_synx = cvp_sess_deinit_synx_stub,
|
||||
.cvp_release_synx = cvp_release_synx_stub,
|
||||
.cvp_import_synx = cvp_import_synx_stub,
|
||||
.cvp_synx_ops = cvp_synx_ops_stub,
|
||||
.cvp_cancel_synx = cvp_cancel_synx_stub,
|
||||
.cvp_dump_fence_queue = cvp_dump_fence_queue_stub,
|
||||
};
|
||||
|
||||
|
||||
#endif /* End of CVP_SYNX_ENABLED */
|
||||
|
||||
void cvp_synx_ftbl_init(struct msm_cvp_core *core)
|
||||
{
|
||||
if (!core)
|
||||
return;
|
||||
|
||||
/* Synx API version check below if needed */
|
||||
core->synx_ftbl = &cvp_synx;
|
||||
}
|
74
qcom/opensource/eva-kernel/msm/eva/msm_cvp_synx.h
Normal file
74
qcom/opensource/eva-kernel/msm/eva/msm_cvp_synx.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
//#ifndef _MSM_CVP_SYNX_H_
|
||||
#define _MSM_CVP_SYNX_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <media/msm_eva_private.h>
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
#ifdef CVP_SYNX_ENABLED
|
||||
#include <synx_api.h>
|
||||
#else
|
||||
#define SYNX_STATE_SIGNALED_SUCCESS 0
|
||||
#define SYNX_STATE_SIGNALED_ERROR 0
|
||||
#define SYNX_STATE_SIGNALED_CANCEL 0
|
||||
struct synx_session {
|
||||
u32 client_id;
|
||||
};
|
||||
#endif /* end of CVP_SYNX_ENABLED */
|
||||
|
||||
struct msm_cvp_core;
|
||||
|
||||
struct cvp_fence_queue {
|
||||
struct mutex lock;
|
||||
enum queue_state state;
|
||||
enum op_mode mode;
|
||||
struct list_head wait_list;
|
||||
wait_queue_head_t wq;
|
||||
struct list_head sched_list;
|
||||
};
|
||||
|
||||
struct cvp_fence_command {
|
||||
struct list_head list;
|
||||
u64 frame_id;
|
||||
enum op_mode mode;
|
||||
u32 signature;
|
||||
u32 num_fences;
|
||||
u32 output_index;
|
||||
u32 type;
|
||||
u32 synx[MAX_HFI_FENCE_SIZE];
|
||||
struct cvp_hfi_cmd_session_hdr *pkt;
|
||||
};
|
||||
|
||||
enum cvp_synx_type {
|
||||
CVP_UINIT_SYNX,
|
||||
CVP_INPUT_SYNX,
|
||||
CVP_OUTPUT_SYNX,
|
||||
CVP_INVALID_SYNX,
|
||||
};
|
||||
|
||||
struct msm_cvp_synx_ops {
|
||||
int (*cvp_sess_init_synx)(struct msm_cvp_inst *inst);
|
||||
int (*cvp_sess_deinit_synx)(struct msm_cvp_inst *inst);
|
||||
int (*cvp_release_synx)(struct msm_cvp_inst *inst,
|
||||
struct cvp_fence_command *fc);
|
||||
int (*cvp_import_synx)(struct msm_cvp_inst *inst,
|
||||
struct cvp_fence_command *fc,
|
||||
u32 *fence);
|
||||
int (*cvp_synx_ops)(struct msm_cvp_inst *inst,
|
||||
enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc,
|
||||
u32 *synx_state);
|
||||
int (*cvp_cancel_synx)(struct msm_cvp_inst *inst,
|
||||
enum cvp_synx_type type,
|
||||
struct cvp_fence_command *fc,
|
||||
int synx_state);
|
||||
void (*cvp_dump_fence_queue)(struct msm_cvp_inst *inst);
|
||||
};
|
||||
|
||||
void cvp_synx_ftbl_init(struct msm_cvp_core *core);
|
||||
//#endif
|
45
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm.h
Normal file
45
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CVP_VM_H_
|
||||
#define _CVP_VM_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "cvp_comm_def.h"
|
||||
#include "msm_cvp_core.h"
|
||||
#include "msm_cvp_internal.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
#include "cvp_vm_msgq.h"
|
||||
#include "cvp_vm_resource.h"
|
||||
|
||||
enum cvp_vm_id {
|
||||
VM_PRIMARY = 1,
|
||||
VM_TRUSTED = 2,
|
||||
VM_INVALID = 3,
|
||||
};
|
||||
|
||||
enum cvp_vm_state {
|
||||
VM_STATE_INIT = 1,
|
||||
VM_STATE_ACTIVE = 2,
|
||||
VM_STATE_ERROR = 3,
|
||||
VM_STATE_INVALID = 4,
|
||||
};
|
||||
|
||||
struct msm_cvp_vm_ops {
|
||||
int (*vm_start)(struct msm_cvp_core *core);
|
||||
int (*vm_init_reg_and_irq)(struct iris_hfi_device *device,
|
||||
struct msm_cvp_platform_resources *res);
|
||||
};
|
||||
|
||||
struct msm_cvp_vm_manager {
|
||||
enum cvp_vm_state vm_state;
|
||||
enum cvp_vm_id vm_id;
|
||||
struct cvp_msgq_drv *msgq_drv;
|
||||
struct cvp_vm_resource *vm_rm;
|
||||
struct msm_cvp_vm_ops *vm_ops;
|
||||
};
|
||||
|
||||
extern struct msm_cvp_vm_manager vm_manager;
|
||||
#endif
|
181
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_main.c
Normal file
181
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_main.c
Normal file
@ -0,0 +1,181 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
#include <asm/memory.h>
|
||||
#include <linux/coresight-stm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/hash.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/soc/qcom/llcc-qcom.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/soc/qcom/smem.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/pm_wakeup.h>
|
||||
#include "hfi_packetization.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
#include "cvp_hfi_helper.h"
|
||||
#include "cvp_hfi_io.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
#include "msm_cvp_clocks.h"
|
||||
#include "cvp_dump.h"
|
||||
#include "cvp_vm.h"
|
||||
|
||||
#define FIRMWARE_SIZE 0X00A00000
|
||||
|
||||
static int msm_cvp_vm_start(struct msm_cvp_core *core);
|
||||
static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device,
|
||||
struct msm_cvp_platform_resources *res);
|
||||
|
||||
static struct msm_cvp_vm_ops vm_ops = {
|
||||
.vm_start = msm_cvp_vm_start,
|
||||
.vm_init_reg_and_irq = msm_cvp_vm_init_reg_and_irq,
|
||||
};
|
||||
|
||||
struct msm_cvp_vm_manager vm_manager = {
|
||||
.msgq_drv = &cvp_ipc_msgq,
|
||||
.vm_rm = &cvp_vm_rm,
|
||||
.vm_ops = &vm_ops,
|
||||
};
|
||||
|
||||
static int msm_cvp_vm_start(struct msm_cvp_core *core)
|
||||
{
|
||||
if (!core || !core->platform_data) {
|
||||
dprintk(CVP_ERR, "%s: Invalid params %pK %pK\n",
|
||||
__func__, core,
|
||||
(core == NULL)? NULL: core->platform_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vm_manager.vm_id = core->platform_data->vm_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __check_core_registered(struct iris_hfi_device *device,
|
||||
phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size,
|
||||
phys_addr_t irq)
|
||||
{
|
||||
struct cvp_hal_data *cvp_hal_data;
|
||||
|
||||
if (!device) {
|
||||
dprintk(CVP_INFO, "no device Registered\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cvp_hal_data = device->cvp_hal_data;
|
||||
if (!cvp_hal_data)
|
||||
return -EINVAL;
|
||||
|
||||
if (cvp_hal_data->irq == irq &&
|
||||
(CONTAINS(cvp_hal_data->firmware_base,
|
||||
FIRMWARE_SIZE, fw_addr) ||
|
||||
CONTAINS(fw_addr, FIRMWARE_SIZE,
|
||||
cvp_hal_data->firmware_base) ||
|
||||
CONTAINS(cvp_hal_data->register_base,
|
||||
reg_size, reg_addr) ||
|
||||
CONTAINS(reg_addr, reg_size,
|
||||
cvp_hal_data->register_base) ||
|
||||
OVERLAPS(cvp_hal_data->register_base,
|
||||
reg_size, reg_addr, reg_size) ||
|
||||
OVERLAPS(reg_addr, reg_size,
|
||||
cvp_hal_data->register_base,
|
||||
reg_size) ||
|
||||
OVERLAPS(cvp_hal_data->firmware_base,
|
||||
FIRMWARE_SIZE, fw_addr,
|
||||
FIRMWARE_SIZE) ||
|
||||
OVERLAPS(fw_addr, FIRMWARE_SIZE,
|
||||
cvp_hal_data->firmware_base,
|
||||
FIRMWARE_SIZE))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dprintk(CVP_INFO, "Device not registered\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device,
|
||||
struct msm_cvp_platform_resources *res)
|
||||
{
|
||||
struct cvp_hal_data *hal = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (vm_manager.vm_id == VM_TRUSTED)
|
||||
return 0;
|
||||
|
||||
rc = __check_core_registered(device, res->firmware_base,
|
||||
(u8 *)(uintptr_t)res->register_base,
|
||||
res->register_size, res->irq);
|
||||
if (!rc) {
|
||||
dprintk(CVP_ERR, "Core present/Already added\n");
|
||||
rc = -EEXIST;
|
||||
goto err_core_init;
|
||||
}
|
||||
|
||||
hal = kzalloc(sizeof(*hal), GFP_KERNEL);
|
||||
if (!hal) {
|
||||
dprintk(CVP_ERR, "Failed to alloc\n");
|
||||
rc = -ENOMEM;
|
||||
goto err_core_init;
|
||||
}
|
||||
|
||||
hal->irq = res->irq;
|
||||
hal->irq_wd = res->irq_wd;
|
||||
hal->firmware_base = res->firmware_base;
|
||||
hal->register_base = devm_ioremap(&res->pdev->dev,
|
||||
res->register_base, res->register_size);
|
||||
hal->register_size = res->register_size;
|
||||
if (!hal->register_base) {
|
||||
dprintk(CVP_ERR,
|
||||
"could not map reg addr %pa of size %d\n",
|
||||
&res->register_base, res->register_size);
|
||||
goto error_irq_fail;
|
||||
}
|
||||
|
||||
if (res->gcc_reg_base) {
|
||||
hal->gcc_reg_base = devm_ioremap(&res->pdev->dev,
|
||||
res->gcc_reg_base, res->gcc_reg_size);
|
||||
hal->gcc_reg_size = res->gcc_reg_size;
|
||||
if (!hal->gcc_reg_base)
|
||||
dprintk(CVP_ERR,
|
||||
"could not map gcc reg addr %pa of size %d\n",
|
||||
&res->gcc_reg_base, res->gcc_reg_size);
|
||||
}
|
||||
|
||||
device->cvp_hal_data = hal;
|
||||
rc = request_threaded_irq(res->irq, cvp_hfi_isr, iris_hfi_core_work_handler,
|
||||
IRQF_TRIGGER_HIGH, "msm_cvp", device);
|
||||
if (unlikely(rc)) {
|
||||
dprintk(CVP_ERR, "%s: request_irq failed rc: %d\n", __func__, rc);
|
||||
goto error_irq_fail;
|
||||
}
|
||||
|
||||
rc = request_irq(res->irq_wd, iris_hfi_isr_wd, IRQF_TRIGGER_HIGH,
|
||||
"msm_cvp", device);
|
||||
if (unlikely(rc)) {
|
||||
dprintk(CVP_ERR, "() :request_irq for WD failed\n");
|
||||
goto error_irq_fail;
|
||||
}
|
||||
|
||||
disable_irq_nosync(res->irq);
|
||||
dprintk(CVP_INFO,
|
||||
"firmware_base = %pa, register_base = %pa, register_size = %d\n",
|
||||
&res->firmware_base, &res->register_base,
|
||||
res->register_size);
|
||||
return rc;
|
||||
|
||||
error_irq_fail:
|
||||
kfree(hal);
|
||||
err_core_init:
|
||||
return rc;
|
||||
}
|
341
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_msgq.c
Normal file
341
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_msgq.c
Normal file
@ -0,0 +1,341 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kthread.h>
|
||||
#include "cvp_vm_msgq.h"
|
||||
#include "msm_cvp_debug.h"
|
||||
|
||||
/**
|
||||
* cvp_msgq_receiver - thread function that receive msg from gunyah msgq
|
||||
* data: cvp_msgq_drv pointer
|
||||
*
|
||||
* Note: single thread. If the sub-function or global data used in this
|
||||
* function is also used somehwere else, please add rx_lock.
|
||||
*/
|
||||
static int cvp_msgq_receiver(void *data)
|
||||
{
|
||||
struct cvp_msgq_drv *msgq_drv = data;
|
||||
|
||||
struct cvp_ipc_msg *msg_ptr;
|
||||
size_t size;
|
||||
bool is_resp;
|
||||
/**
|
||||
* true: response received from remote VM, cmd initiated from LOCAL VM;
|
||||
* false: cmd initiated from REMOTE VM;
|
||||
*/
|
||||
int rc = -1;
|
||||
if (IS_ERR_OR_NULL(msgq_drv))
|
||||
return -EINVAL;
|
||||
|
||||
msg_ptr = kzalloc(sizeof(*msg_ptr), GFP_KERNEL);
|
||||
if (!msg_ptr) {
|
||||
dprintk(CVP_ERR, "%s: fail to allocate mem\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
rc = gh_msgq_recv(msgq_drv->config.handle, msg_ptr,
|
||||
sizeof(*msg_ptr), &size, 0);
|
||||
|
||||
if (rc != 0 ) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: gh_msgq_recv fail rc=%d handle=%#x msg_ptr=%#x\n",
|
||||
__func__, rc, msgq_drv->config.handle, msg_ptr);
|
||||
|
||||
if (rc != -EAGAIN) {
|
||||
kfree(msg_ptr);
|
||||
return rc;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
is_resp = (msg_ptr->type &
|
||||
CVP_IPC_MSG_TYPE_DIR_CHECK) ? true : false;
|
||||
|
||||
if (is_resp == false) {
|
||||
dprintk(CVP_VM,
|
||||
"%s: gh_msgq_recv cmd from remote VM\n",
|
||||
__func__);
|
||||
|
||||
if (msgq_drv->pending_local_cmd.type == 0) {
|
||||
|
||||
/* copy ipc message to local cmd */
|
||||
memcpy(&msgq_drv->pending_local_cmd,
|
||||
msg_ptr, sizeof(struct cvp_ipc_msg));
|
||||
|
||||
/* toggle the direction bit*/
|
||||
msgq_drv->pending_local_cmd.type ^=
|
||||
CVP_IPC_MSG_TYPE_DIR_CHECK;
|
||||
|
||||
/* TODO: call client function ptr to process */
|
||||
|
||||
memcpy(msg_ptr, &msgq_drv->pending_local_cmd,
|
||||
sizeof(struct cvp_ipc_msg));
|
||||
|
||||
/* 4: elements before actual data in cvp_ipc_msg*/
|
||||
size = (4 + msgq_drv->pending_local_cmd.len)<<2;
|
||||
|
||||
/* sanity check on size information */
|
||||
if (size > GH_MSGQ_MAX_MSG_SIZE_BYTES) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: msg size %d exceed max size supported %d \n",
|
||||
__func__, size, GH_MSGQ_MAX_MSG_SIZE_BYTES);
|
||||
rc = -E2BIG;
|
||||
msgq_drv->pending_local_cmd.type = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* send it back to the remote VM as response */
|
||||
rc = gh_msgq_send(msgq_drv->config.handle,
|
||||
msg_ptr, size, GH_MSGQ_TX_PUSH);
|
||||
|
||||
if (rc < 0) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: failed gh_msgq_send rc %d \n",
|
||||
__func__, rc);
|
||||
}
|
||||
|
||||
/* flag the source is released */
|
||||
msgq_drv->pending_local_cmd.type = 0;
|
||||
}
|
||||
else {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Msg rejected, local cmd in use type %d\n",
|
||||
__func__, msgq_drv->pending_local_cmd.type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dprintk(CVP_VM,
|
||||
"%s: gh_msgq_recv respond type from remote VM\n",
|
||||
__func__);
|
||||
|
||||
if ((msg_ptr->type & CVP_IPC_MSG_TYPE_ACT_CHECK) !=
|
||||
msgq_drv->pending_remote_rsp.type) {
|
||||
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Msg disgard,recv type %d, pend local %d\n",
|
||||
__func__, msg_ptr->type,
|
||||
msgq_drv->pending_remote_rsp.type);
|
||||
}
|
||||
else {
|
||||
/* memcpy received data to pending_remote_rsp */
|
||||
memcpy(&msgq_drv->pending_remote_rsp, msg_ptr,
|
||||
sizeof(struct cvp_ipc_msg));
|
||||
|
||||
/* clear direction bit of pending_remote_rsp */
|
||||
msgq_drv->pending_remote_rsp.type &=
|
||||
(~CVP_IPC_MSG_TYPE_DIR_CHECK);
|
||||
|
||||
/* complete for cmd initiated from local VM */
|
||||
complete(&msgq_drv->completions[
|
||||
msgq_drv->pending_remote_rsp.type - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_complete_msgq_init(struct cvp_msgq_drv *msgq_drv)
|
||||
{
|
||||
int i;
|
||||
|
||||
msgq_drv->receiver_thread = kthread_run(
|
||||
cvp_msgq_receiver,
|
||||
(void *)msgq_drv,
|
||||
"CVP msgq receiver");
|
||||
if (IS_ERR_OR_NULL(msgq_drv->receiver_thread)) {
|
||||
dprintk(CVP_ERR, "Failed to start msgq receiver thread\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_init(&msgq_drv->ipc_lock);
|
||||
|
||||
for (i = 0; i <= (CVP_MAX_IPC_CMD - 1); i++)
|
||||
init_completion(&msgq_drv->completions[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_EVA_TVM
|
||||
static int cvp_msgq_cb(struct notifier_block *nb,
|
||||
unsigned long cmd, void *data)
|
||||
{
|
||||
struct gh_rm_notif_vm_status_payload *vm_status_payload;
|
||||
struct cvp_gh_msgq_config *msgq_config;
|
||||
struct cvp_msgq_drv *msgq_drv;
|
||||
gh_vmid_t peer_vmid;
|
||||
gh_vmid_t self_vmid;
|
||||
int rc;
|
||||
|
||||
if (IS_ERR_OR_NULL(nb))
|
||||
return -EINVAL;
|
||||
|
||||
msgq_config = container_of(nb, struct cvp_gh_msgq_config, rm_nb);
|
||||
msgq_drv = container_of(msgq_config, struct cvp_msgq_drv, config);
|
||||
|
||||
if (cmd != GH_RM_NOTIF_VM_STATUS)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/**
|
||||
* Check VM status, only GH_TRUSTED_VM notification activate
|
||||
* Gunyah msgq registration
|
||||
*/
|
||||
vm_status_payload = (struct gh_rm_notif_vm_status_payload *)data;
|
||||
|
||||
if (vm_status_payload->vm_status != GH_RM_VM_STATUS_READY)
|
||||
return -12;
|
||||
|
||||
if (ghd_rm_get_vmid(msgq_config->peer_id, &peer_vmid))
|
||||
return -13;
|
||||
|
||||
if (ghd_rm_get_vmid(GH_PRIMARY_VM, &self_vmid))
|
||||
return -14;
|
||||
|
||||
if (peer_vmid != vm_status_payload->vmid)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
dprintk(CVP_VM, "%s: vmid=%d, peer_vmid=%d\n",
|
||||
__func__, vm_status_payload->vmid, peer_vmid);
|
||||
|
||||
if (msgq_config->handle)
|
||||
return -15;
|
||||
|
||||
msgq_config->handle = gh_msgq_register(GH_MSGQ_LABEL_EVA);
|
||||
if (IS_ERR(msgq_config->handle)) {
|
||||
rc = PTR_ERR(msgq_drv->config.handle);
|
||||
dprintk(CVP_ERR, "PVM failed to register msgq %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
dprintk(CVP_VM, "%s: gh_msgq_register handle: %x\n",
|
||||
__func__, msgq_config->handle);
|
||||
|
||||
rc = cvp_complete_msgq_init(msgq_drv);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cvp_msgq_init(struct cvp_msgq_drv *msgq_drv)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
msgq_drv->config.label = GH_MSGQ_LABEL_EVA;
|
||||
msgq_drv->config.handle = NULL;
|
||||
#ifndef CONFIG_EVA_TVM
|
||||
/* PVM init */
|
||||
msgq_drv->config.peer_id = GH_TRUSTED_VM;
|
||||
msgq_drv->config.rm_nb.notifier_call = cvp_msgq_cb;
|
||||
|
||||
rc = gh_rm_register_notifier(&msgq_drv->config.rm_nb);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "PVM Fail register msgq notifier %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
dprintk(CVP_VM, "%s: gh_rm_register_notifier\n", __func__);
|
||||
#else
|
||||
/* TVM init */
|
||||
msgq_drv->config.handle = gh_msgq_register(GH_MSGQ_LABEL_EVA);
|
||||
if (IS_ERR(msgq_drv->config.handle)) {
|
||||
rc = PTR_ERR(msgq_drv->config.handle);
|
||||
dprintk(CVP_ERR, "TVM failed to register msgq %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
rc = cvp_complete_msgq_init(msgq_drv);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_msgq_deinit(struct cvp_msgq_drv *msgq_drv)
|
||||
{
|
||||
if (msgq_drv->receiver_thread)
|
||||
kthread_stop(msgq_drv->receiver_thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cvp_msgq_send_cmd(struct cvp_msgq_drv *msgq_drv,
|
||||
void *msg, size_t msg_size)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
struct cvp_ipc_msg *msg_ptr = msg;
|
||||
|
||||
if (!msgq_drv->config.handle) {
|
||||
dprintk(CVP_ERR, "%s: Invalid msgq handle\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto err_param_check;
|
||||
}
|
||||
|
||||
if (msg_size > GH_MSGQ_MAX_MSG_SIZE_BYTES) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: msg size %d exceed max size supported %d \n",
|
||||
__func__, msg_size, GH_MSGQ_MAX_MSG_SIZE_BYTES);
|
||||
rc = -E2BIG;
|
||||
goto err_param_check;
|
||||
}
|
||||
|
||||
mutex_lock(&msgq_drv->ipc_lock);
|
||||
|
||||
/* init case: only allow sending msg sequentially */
|
||||
if (msgq_drv->pending_remote_rsp.type &
|
||||
CVP_IPC_MSG_TYPE_ACT_CHECK) {
|
||||
rc = -EPERM;
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Msg rejected, local rsp occupied.\n",
|
||||
__func__);
|
||||
|
||||
goto err_valid_check;
|
||||
}
|
||||
|
||||
/* book keeping type bits in pending_remote_rsp */
|
||||
msgq_drv->pending_remote_rsp.type = msg_ptr->type;
|
||||
|
||||
rc = gh_msgq_send(msgq_drv->config.handle,
|
||||
msg_ptr, msg_size, GH_MSGQ_TX_PUSH);
|
||||
if (rc < 0) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: failed with gh_msgq_send with rc %d \n",
|
||||
__func__, rc);
|
||||
goto err_gh_send;
|
||||
}
|
||||
|
||||
/* wait for completion */
|
||||
if (!wait_for_completion_timeout(
|
||||
&msgq_drv->completions[msgq_drv->pending_remote_rsp.type - 1],
|
||||
msecs_to_jiffies(CVP_VM_RESPONSE_TIMEOUT))) {
|
||||
dprintk(CVP_ERR, "%s cvp ipc msg type %d timeout\n",
|
||||
__func__, msgq_drv->pending_remote_rsp.type-1);
|
||||
rc = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* copy pending_remote_rsp content to msg (inout param)*/
|
||||
memcpy(msg, &msgq_drv->pending_remote_rsp,
|
||||
sizeof(struct cvp_ipc_msg));
|
||||
|
||||
/* clear type bits to indicate resource is avaialbel */
|
||||
msgq_drv->pending_remote_rsp.type = 0;
|
||||
|
||||
mutex_unlock(&msgq_drv->ipc_lock);
|
||||
|
||||
return rc;
|
||||
|
||||
err_gh_send:
|
||||
err_valid_check:
|
||||
mutex_unlock(&msgq_drv->ipc_lock);
|
||||
err_param_check:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct cvp_msgq_ops msgq_ops = {
|
||||
.msgq_init = cvp_msgq_init,
|
||||
.msgq_deinit = cvp_msgq_deinit,
|
||||
.msgq_send = cvp_msgq_send_cmd,
|
||||
.msgq_receive = NULL,
|
||||
};
|
||||
|
||||
struct cvp_msgq_drv cvp_ipc_msgq = {
|
||||
.ops = &msgq_ops,
|
||||
};
|
77
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_msgq.h
Normal file
77
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_msgq.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CVP_VM_MSGQ_H_
|
||||
#define _CVP_VM_MSGQ_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/gunyah/gh_msgq.h>
|
||||
#include <linux/gunyah/gh_rm_drv.h>
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
#define MAX_CVP_IPC_LEN 16
|
||||
|
||||
#define CVP_VM_RESPONSE_TIMEOUT 300
|
||||
|
||||
#define CVP_IPC_MSG_TYPE_DIR_CHECK 0x10000000 /* direction check */
|
||||
#define CVP_IPC_MSG_TYPE_ACT_CHECK 0x00000011 /* action check */
|
||||
|
||||
enum CVP_IPC_MSG_TYPE {
|
||||
REQUEST_SESS_CTRL = 1,
|
||||
RELEASE_SESS_CTRL = 2,
|
||||
REQUEST_EVA_RESET = 3,
|
||||
RECLAIM_SESS_CTRL = 4, /* Only PVM can reclaim sesession control */
|
||||
CVP_MAX_IPC_CMD = 5,
|
||||
};
|
||||
|
||||
struct cvp_ipc_msg {
|
||||
/* type format:
|
||||
* bit 31: 0->Initiated command; 1->Response to remote command
|
||||
* bit 2~0: CVP_IPC_MSG_TYPE
|
||||
*/
|
||||
uint32_t type;
|
||||
uint32_t ver;
|
||||
uint32_t len;
|
||||
uint32_t resv;
|
||||
uint32_t data[MAX_CVP_IPC_LEN];
|
||||
};
|
||||
|
||||
struct cvp_gh_msgq_config {
|
||||
int peer_id;
|
||||
int label;
|
||||
void *handle;
|
||||
struct notifier_block rm_nb;
|
||||
};
|
||||
|
||||
struct cvp_msgq_ops;
|
||||
|
||||
struct cvp_msgq_drv {
|
||||
struct mutex ipc_lock; /* Mutex for sending MSG */
|
||||
struct cvp_gh_msgq_config config;
|
||||
struct task_struct *receiver_thread;
|
||||
struct completion completions[CVP_MAX_IPC_CMD + 1];
|
||||
/*
|
||||
* pending_local_cmd: the command is being processed locally.
|
||||
* The command is a request sent from remote VM
|
||||
*/
|
||||
struct cvp_ipc_msg pending_local_cmd;
|
||||
/*
|
||||
* pending_remote_rsp: the command is being processing remotely.
|
||||
* The command is a request sent by local VM
|
||||
*/
|
||||
struct cvp_ipc_msg pending_remote_rsp;
|
||||
struct cvp_msgq_ops *ops;
|
||||
};
|
||||
|
||||
struct cvp_msgq_ops {
|
||||
int (*msgq_init)(struct cvp_msgq_drv *msgq_drv);
|
||||
int (*msgq_send)(struct cvp_msgq_drv *msgq_drv, void *msg,
|
||||
size_t msg_size);
|
||||
int (*msgq_receive)(struct cvp_msgq_drv *msgq_drv);
|
||||
int (*msgq_deinit)(struct cvp_msgq_drv *msgq_drv);
|
||||
};
|
||||
|
||||
extern struct cvp_msgq_drv cvp_ipc_msgq;
|
||||
#endif
|
8
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_resource.c
Normal file
8
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_resource.c
Normal file
@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cvp_vm_resource.h"
|
||||
|
||||
struct cvp_vm_resource cvp_vm_rm;
|
17
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_resource.h
Normal file
17
qcom/opensource/eva-kernel/msm/eva/vm/cvp_vm_resource.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CVP_VM_RESOURCE_H_
|
||||
#define _CVP_VM_RESOURCE_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
struct cvp_vm_resource {
|
||||
int reserved;
|
||||
};
|
||||
|
||||
extern struct cvp_vm_resource cvp_vm_rm;
|
||||
#endif
|
17
qcom/opensource/eva-kernel/pineapple.bzl
Normal file
17
qcom/opensource/eva-kernel/pineapple.bzl
Normal file
@ -0,0 +1,17 @@
|
||||
load(":eva_modules.bzl", "eva_modules")
|
||||
load(":eva_module_build.bzl", "define_consolidate_gki_modules")
|
||||
|
||||
def define_pineapple():
|
||||
define_consolidate_gki_modules(
|
||||
target = "pineapple",
|
||||
registry = eva_modules,
|
||||
modules = [
|
||||
"msm-eva",
|
||||
],
|
||||
config_options = [
|
||||
#"CONFIG_TARGET_SYNX_ENABLE",
|
||||
"TARGET_SYNX_ENABLE",
|
||||
"TARGET_DSP_ENABLE",
|
||||
"CONFIG_EVA_PINEAPPLE"
|
||||
],
|
||||
)
|
Loading…
Reference in New Issue
Block a user