From 9265e4209386389707eb6ba8a73d6b2b7ee84c73 Mon Sep 17 00:00:00 2001 From: Sudeep Surendra Date: Thu, 16 Jun 2022 16:46:07 -0700 Subject: [PATCH] misc: mods: add ioctl to communicate with SP JIRA TM-617 Change-Id: I9c786048cf9bec07233bbed38edbf11fe6c555c0 Signed-off-by: Sudeep Surendra Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2730674 Tested-by: Carl Dong Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: Chris Dragan Reviewed-by: Sachin Nikam GVS: Gerrit_Virtual_Submit --- drivers/misc/mods/Makefile | 1 + drivers/misc/mods/mods_arm_ffa.c | 144 ++++++++++++++++++++++++++++++ drivers/misc/mods/mods_internal.h | 14 ++- drivers/misc/mods/mods_krnl.c | 18 ++++ include/uapi/misc/mods.h | 18 ++++ 5 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 drivers/misc/mods/mods_arm_ffa.c diff --git a/drivers/misc/mods/Makefile b/drivers/misc/mods/Makefile index 9e61b417..a37c0aa0 100644 --- a/drivers/misc/mods/Makefile +++ b/drivers/misc/mods/Makefile @@ -15,6 +15,7 @@ mods-y += mods_mem.o mods-$(CONFIG_ACPI) += mods_acpi.o mods-$(CONFIG_TEGRA_NVADSP) += mods_adsp.o +mods-$(CONFIG_ARM_FFA_TRANSPORT) += mods_arm_ffa.o mods-$(CONFIG_COMMON_CLK) += mods_clock.o mods-$(CONFIG_DEBUG_FS) += mods_debugfs.o mods-$(CONFIG_DMA_ENGINE) += mods_dma.o diff --git a/drivers/misc/mods/mods_arm_ffa.c b/drivers/misc/mods/mods_arm_ffa.c new file mode 100644 index 00000000..798c5f18 --- /dev/null +++ b/drivers/misc/mods/mods_arm_ffa.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "mods_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct ffa_device_id mods_ffa_device_id[] = { + { UUID_INIT(0x1f4bfeb9, 0x0f48, 0xdd1e, + 0x11, 0x9c, 0x2c, 0x86, 0xc9, 0x14, 0x03, 0x22) }, + {} +}; + +struct mods_ffa_ctx { + struct ffa_device *ffa_dev; + const struct ffa_dev_ops *ffa_ops; +}; + +static struct mods_ffa_ctx mods_ffa_info; + +static int ffa_probe(struct ffa_device *ffa_dev) +{ + int ret = 0; + const struct ffa_dev_ops *ffa_ops; + + ffa_ops = ffa_dev_ops_get(ffa_dev); + if (!ffa_ops) { + mods_error_printk("failed \"method\" init: ffa\n"); + return -ENOENT; + } + mods_ffa_info.ffa_dev = ffa_dev; + mods_ffa_info.ffa_ops = ffa_ops; + + mods_debug_printk(DEBUG_TEGRADMA, "mods ffa driver registered\n"); + + return ret; +} + +static void ffa_remove(struct ffa_device *ffa_dev) +{ + mods_ffa_info.ffa_dev = NULL; + mods_ffa_info.ffa_ops = NULL; +} + +static struct ffa_driver mods_ffa_driver = { + .name = "mods_arm_ffa", + .probe = ffa_probe, + .remove = ffa_remove, + .id_table = mods_ffa_device_id, +}; + +int mods_ffa_abi_register(void) +{ + mods_debug_printk(DEBUG_TEGRADMA, "registering MODS FFA driver\n"); + return ffa_register(&mods_ffa_driver); +} + +void mods_ffa_abi_unregister(void) +{ + ffa_unregister(&mods_ffa_driver); +} + +int esc_mods_arm_ffa_cmd(struct mods_client *client, + struct MODS_FFA_PARAMS *p) +{ + int err = -EINVAL; + struct ffa_send_direct_data data = { 0 }; + + // Fill the reg TX command parameters + data.data0 = p->cmd; + // 64 bit of the physical address + data.data1 = p->indata[0]; + // 32 bit of the reg value + data.data2 = p->indata[1]; + + if (!mods_ffa_info.ffa_ops) { + cl_error("mods ffa cmd error, device not found\n"); + return -ENODEV; + } + + switch (p->cmd) { + case MODS_FFA_CMD_READ_REG: + // Read command + cl_debug(DEBUG_TEGRADMA, "sending data to SP :read cmd 0x%llx, addr:0x%llx\n", + (unsigned long long)data.data0, + (unsigned long long)data.data1); + break; + case MODS_FFA_CMD_WRITE_REG: + // Write command + cl_debug(DEBUG_TEGRADMA, "sending data to SP :write cmd 0x%llx,addr:0x%llx,write_val:0x%llx\n", + (unsigned long long)data.data0, + (unsigned long long)data.data1, + (unsigned long long)data.data2); + break; + case MODS_FFA_CMD_READ_VER: + cl_debug(DEBUG_TEGRADMA, "sending cmd MODS_FFA_CMD_READ_VER to SP\n"); + break; + default: + cl_error("Unexpected command from SP 0x%llx\n", (unsigned long long)p->cmd); + return err; + } + + err = mods_ffa_info.ffa_ops->sync_send_receive(mods_ffa_info.ffa_dev, &data); + + switch (p->cmd) { + case MODS_FFA_CMD_READ_REG: + // Read command + cl_debug(DEBUG_TEGRADMA, "received read reg status from SP status:%d,read_val:0x%llx\n", + err, (unsigned long long)data.data1); + p->outdata[0] = data.data1; + break; + case MODS_FFA_CMD_WRITE_REG: + // write command + cl_debug(DEBUG_TEGRADMA, "received write reg status from SP status: %d\n", + err); + break; + case MODS_FFA_CMD_READ_VER: + cl_debug(DEBUG_TEGRADMA, "received version from SP : 0x%llx\n", + (unsigned long long)data.data1); + p->outdata[0] = data.data1; + break; + } + + if (err) + cl_error("unexpected error from SP: %d\n", err); + return err; +} diff --git a/drivers/misc/mods/mods_internal.h b/drivers/misc/mods/mods_internal.h index f9252dba..76290b98 100644 --- a/drivers/misc/mods/mods_internal.h +++ b/drivers/misc/mods/mods_internal.h @@ -261,7 +261,7 @@ struct NVL_TRAINED { #define DEBUG_TEGRADMA 0x400 #define DEBUG_ISR_DETAILED (DEBUG_ISR | DEBUG_DETAILED) #define DEBUG_MEM_DETAILED (DEBUG_MEM | DEBUG_DETAILED) -#define DEBUG_ALL (DEBUG_IOCTL | DEBUG_PCI | DEBUG_ACPI | \ +#define DEBUG_ALL (DEBUG_IOCTL | DEBUG_PCI | DEBUG_ACPI | \ DEBUG_ISR | DEBUG_MEM | DEBUG_FUNC | DEBUG_CLOCK | DEBUG_DETAILED | \ DEBUG_TEGRADC | DEBUG_TEGRADMA) @@ -711,6 +711,13 @@ int esc_mods_send_trustzone_msg(struct mods_client *client, int esc_mods_invoke_optee_ta(struct mods_client *client, struct MODS_OPTEE_PARAMS *p); #endif + +#endif + +/* MODS SP call */ +#if defined(CONFIG_ARM_FFA_TRANSPORT) +int esc_mods_arm_ffa_cmd(struct mods_client *client, + struct MODS_FFA_PARAMS *p); #endif #ifdef CONFIG_DEBUG_FS @@ -743,4 +750,9 @@ void smmu_driver_exit(void); int esc_mods_send_ipi(struct mods_client *client, struct MODS_SEND_IPI *p); #endif +#if defined(CONFIG_ARM_FFA_TRANSPORT) +int mods_ffa_abi_register(void); +void mods_ffa_abi_unregister(void); +#endif + #endif /* _MODS_INTERNAL_H_ */ diff --git a/drivers/misc/mods/mods_krnl.c b/drivers/misc/mods/mods_krnl.c index 7b2ef9fc..0ca658f8 100644 --- a/drivers/misc/mods/mods_krnl.c +++ b/drivers/misc/mods/mods_krnl.c @@ -485,6 +485,13 @@ static int __init mods_init_module(void) if (rc < 0) return rc; #endif + +#endif + +#if defined(CONFIG_ARM_FFA_TRANSPORT) + rc = mods_ffa_abi_register(); + if (rc < 0) + mods_warning_printk("error on mods_ffa_abi_register returned %d\n", rc); #endif mods_info_printk("*** WARNING: DIAGNOSTIC DRIVER LOADED ***\n"); @@ -527,6 +534,10 @@ static void __exit mods_exit_module(void) mods_shutdown_clock_api(); #endif +#if defined(CONFIG_ARM_FFA_TRANSPORT) + mods_ffa_abi_unregister(); +#endif + mods_info_printk("driver unloaded\n"); LOG_EXT(); } @@ -2625,6 +2636,13 @@ static long mods_krnl_ioctl(struct file *fp, MODS_IOCTL(MODS_ESC_MODS_SEND_IPI, esc_mods_send_ipi, MODS_SEND_IPI); break; + +#endif + +#if defined(CONFIG_ARM_FFA_TRANSPORT) + case MODS_ESC_FFA_CMD: + MODS_IOCTL(MODS_ESC_FFA_CMD, esc_mods_arm_ffa_cmd, MODS_FFA_PARAMS); + break; #endif case MODS_ESC_ACQUIRE_ACCESS_TOKEN: diff --git a/include/uapi/misc/mods.h b/include/uapi/misc/mods.h index 671e6a98..dc140810 100644 --- a/include/uapi/misc/mods.h +++ b/include/uapi/misc/mods.h @@ -1875,6 +1875,23 @@ struct MODS_SEND_IPI { __u32 num_loops; }; +/* Used by MODS_ESC_FFA_CMD ioctl. + */ +struct MODS_FFA_PARAMS { + /* IN */ + __u64 cmd; + __u64 indata[4]; + /* OUT */ + __u64 outdata[4]; +}; + +enum MODS_SP_FFA_CMD_TYPE { + MODS_FFA_CMD_READ_REG, + MODS_FFA_CMD_WRITE_REG, + MODS_FFA_CMD_READ_VER, + MODS_FFA_CMD_TYPE_END +}; + #define MODS_IOMMU_MAP_CONTIGUOUS 1 #define MODS_MAX_PROP_NAME_LEN 64 @@ -2115,5 +2132,6 @@ struct MODS_PROXIMITY_TO_NUMA_NODE { #define MODS_ESC_READ_DEV_PROPERTY MODSIO(WR, 142, MODS_READ_DEV_PROPERTY) #define MODS_ESC_PROXIMITY_TO_NUMA_NODE MODSIO(WR, 143, MODS_PROXIMITY_TO_NUMA_NODE) #define MODS_ESC_MODS_SEND_IPI MODSIO(W, 144, MODS_SEND_IPI) +#define MODS_ESC_FFA_CMD MODSIO(WR, 145, MODS_FFA_PARAMS) #endif /* _UAPI_MODS_H_ */