Loading drivers/char/fastcvpd.c +89 −13 Original line number Diff line number Diff line Loading @@ -14,8 +14,12 @@ #include <linux/module.h> #include <linux/rpmsg.h> #include <linux/of_platform.h> #include <soc/qcom/secure_buffer.h> #include "linux/fastcvpd.h" #define VMID_CDSP_Q6 (30) #define SRC_VM_NUM 1 #define DEST_VM_NUM 2 #define FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE 0 #define FASTCVPD_VIDEO_SUSPEND 1 #define FASTCVPD_VIDEO_RESUME 2 Loading @@ -28,14 +32,25 @@ struct fastcvpd_cmd_msg { uint32_t msg_ptr_len; }; struct fastcvpd_cmd_msg_rsp { int ret_val; }; struct fastcvpd_apps { struct rpmsg_device *chan; struct mutex smd_mutex; int rpmsg_register; spinlock_t hlock; }; static struct completion work; static struct fastcvpd_apps gfa_cv; static struct fastcvpd_cmd_msg cmd_msg; static struct fastcvpd_cmd_msg_rsp cmd_msg_rsp; static int fastcvpd_send_cmd(void *msg, uint32_t len) { struct fastcvpd_apps *me = &gfa_cv; Loading Loading @@ -82,6 +97,14 @@ static void fastcvpd_rpmsg_remove(struct rpmsg_device *rpdev) static int fastcvpd_rpmsg_callback(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 addr) { int *rpmsg_resp = (int *)data; struct fastcvpd_apps *me = &gfa_cv; spin_lock(&me->hlock); cmd_msg_rsp.ret_val = *rpmsg_resp; spin_unlock(&me->hlock); complete(&work); return 0; } Loading @@ -89,17 +112,39 @@ int fastcvpd_video_send_cmd_hfi_queue(phys_addr_t *phys_addr, uint32_t size_in_bytes) { int err; struct fastcvpd_cmd_msg cmd_msg; struct fastcvpd_cmd_msg local_cmd_msg; struct fastcvpd_apps *me = &gfa_cv; int srcVM[SRC_VM_NUM] = {VMID_HLOS}; int destVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; int destVMperm[DEST_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC, PERM_READ | PERM_WRITE | PERM_EXEC }; cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE; local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE; local_cmd_msg.msg_ptr = (uint64_t)phys_addr; local_cmd_msg.msg_ptr_len = size_in_bytes; mutex_lock(&me->smd_mutex); cmd_msg.msg_ptr = (uint64_t)phys_addr; cmd_msg.msg_ptr_len = size_in_bytes; cmd_msg.msg_ptr_len = (size_in_bytes); mutex_unlock(&me->smd_mutex); pr_debug("%s :: address of buffer, PA=0x%pK size_buff=%d\n", __func__, phys_addr, size_in_bytes); err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr, local_cmd_msg.msg_ptr_len, srcVM, SRC_VM_NUM, destVM, destVMperm, DEST_VM_NUM); if (err) { pr_err("%s: Failed in hyp_assign. err=%d\n", __func__, err); return err; } err = fastcvpd_send_cmd (&cmd_msg, sizeof(struct fastcvpd_cmd_msg)); (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg)); if (err != 0) pr_err("%s: fastcvpd_send_cmd failed with err=%d\n", __func__, err); return err; } EXPORT_SYMBOL(fastcvpd_video_send_cmd_hfi_queue); Loading @@ -107,14 +152,15 @@ EXPORT_SYMBOL(fastcvpd_video_send_cmd_hfi_queue); int fastcvpd_video_suspend(uint32_t session_flag) { int err = 0; struct fastcvpd_cmd_msg cmd_msg; struct fastcvpd_cmd_msg local_cmd_msg; cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SUSPEND; local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SUSPEND; err = fastcvpd_send_cmd (&cmd_msg, sizeof(struct fastcvpd_cmd_msg)); (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg)); if (err != 0) pr_err("%s: fastcvpd_send_cmd failed with err=%d\n", __func__, err); return err; } EXPORT_SYMBOL(fastcvpd_video_suspend); Loading @@ -122,29 +168,56 @@ EXPORT_SYMBOL(fastcvpd_video_suspend); int fastcvpd_video_resume(uint32_t session_flag) { int err; struct fastcvpd_cmd_msg cmd_msg; struct fastcvpd_cmd_msg local_cmd_msg; cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_RESUME; local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_RESUME; err = fastcvpd_send_cmd (&cmd_msg, sizeof(struct fastcvpd_cmd_msg)); (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg)); if (err != 0) pr_err("%s: fastcvpd_send_cmd failed with err=%d\n", __func__, err); return err; } EXPORT_SYMBOL(fastcvpd_video_resume); int fastcvpd_video_shutdown(uint32_t session_flag) { struct fastcvpd_apps *me = &gfa_cv; int err; struct fastcvpd_cmd_msg cmd_msg; struct fastcvpd_cmd_msg local_cmd_msg; int srcVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; int destVM[SRC_VM_NUM] = {VMID_HLOS}; int destVMperm[SRC_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC }; cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SHUTDOWN; local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SHUTDOWN; err = fastcvpd_send_cmd (&cmd_msg, sizeof(struct fastcvpd_cmd_msg)); (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg)); if (err != 0) pr_err("%s: fastcvpd_send_cmd failed with err=%d\n", __func__, err); wait_for_completion(&work); spin_lock(&me->hlock); local_cmd_msg.msg_ptr = cmd_msg.msg_ptr; local_cmd_msg.msg_ptr_len = cmd_msg.msg_ptr_len; if (cmd_msg_rsp.ret_val == 0) { err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr, local_cmd_msg.msg_ptr_len, srcVM, DEST_VM_NUM, destVM, destVMperm, SRC_VM_NUM); if (err) { pr_err("%s: Failed to hyp_assign. err=%d\n", __func__, err); spin_unlock(&me->hlock); return err; } } else { pr_err("%s: Skipping hyp_assign as CDSP sent invalid response=%d\n", __func__, cmd_msg_rsp.ret_val); } spin_unlock(&me->hlock); return err; } EXPORT_SYMBOL(fastcvpd_video_shutdown); Loading @@ -169,7 +242,9 @@ static int __init fastcvpd_device_init(void) struct fastcvpd_apps *me = &gfa_cv; int err; init_completion(&work); mutex_init(&me->smd_mutex); spin_lock_init(&me->hlock); err = register_rpmsg_driver(&fastcvpd_rpmsg_client); if (err) { pr_err("%s : register_rpmsg_driver failed with err %d\n", Loading @@ -187,6 +262,7 @@ static void __exit fastcvpd_device_exit(void) { struct fastcvpd_apps *me = &gfa_cv; mutex_destroy(&me->smd_mutex); if (me->rpmsg_register == 1) unregister_rpmsg_driver(&fastcvpd_rpmsg_client); } Loading Loading
drivers/char/fastcvpd.c +89 −13 Original line number Diff line number Diff line Loading @@ -14,8 +14,12 @@ #include <linux/module.h> #include <linux/rpmsg.h> #include <linux/of_platform.h> #include <soc/qcom/secure_buffer.h> #include "linux/fastcvpd.h" #define VMID_CDSP_Q6 (30) #define SRC_VM_NUM 1 #define DEST_VM_NUM 2 #define FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE 0 #define FASTCVPD_VIDEO_SUSPEND 1 #define FASTCVPD_VIDEO_RESUME 2 Loading @@ -28,14 +32,25 @@ struct fastcvpd_cmd_msg { uint32_t msg_ptr_len; }; struct fastcvpd_cmd_msg_rsp { int ret_val; }; struct fastcvpd_apps { struct rpmsg_device *chan; struct mutex smd_mutex; int rpmsg_register; spinlock_t hlock; }; static struct completion work; static struct fastcvpd_apps gfa_cv; static struct fastcvpd_cmd_msg cmd_msg; static struct fastcvpd_cmd_msg_rsp cmd_msg_rsp; static int fastcvpd_send_cmd(void *msg, uint32_t len) { struct fastcvpd_apps *me = &gfa_cv; Loading Loading @@ -82,6 +97,14 @@ static void fastcvpd_rpmsg_remove(struct rpmsg_device *rpdev) static int fastcvpd_rpmsg_callback(struct rpmsg_device *rpdev, void *data, int len, void *priv, u32 addr) { int *rpmsg_resp = (int *)data; struct fastcvpd_apps *me = &gfa_cv; spin_lock(&me->hlock); cmd_msg_rsp.ret_val = *rpmsg_resp; spin_unlock(&me->hlock); complete(&work); return 0; } Loading @@ -89,17 +112,39 @@ int fastcvpd_video_send_cmd_hfi_queue(phys_addr_t *phys_addr, uint32_t size_in_bytes) { int err; struct fastcvpd_cmd_msg cmd_msg; struct fastcvpd_cmd_msg local_cmd_msg; struct fastcvpd_apps *me = &gfa_cv; int srcVM[SRC_VM_NUM] = {VMID_HLOS}; int destVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; int destVMperm[DEST_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC, PERM_READ | PERM_WRITE | PERM_EXEC }; cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE; local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SEND_HFI_CMD_QUEUE; local_cmd_msg.msg_ptr = (uint64_t)phys_addr; local_cmd_msg.msg_ptr_len = size_in_bytes; mutex_lock(&me->smd_mutex); cmd_msg.msg_ptr = (uint64_t)phys_addr; cmd_msg.msg_ptr_len = size_in_bytes; cmd_msg.msg_ptr_len = (size_in_bytes); mutex_unlock(&me->smd_mutex); pr_debug("%s :: address of buffer, PA=0x%pK size_buff=%d\n", __func__, phys_addr, size_in_bytes); err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr, local_cmd_msg.msg_ptr_len, srcVM, SRC_VM_NUM, destVM, destVMperm, DEST_VM_NUM); if (err) { pr_err("%s: Failed in hyp_assign. err=%d\n", __func__, err); return err; } err = fastcvpd_send_cmd (&cmd_msg, sizeof(struct fastcvpd_cmd_msg)); (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg)); if (err != 0) pr_err("%s: fastcvpd_send_cmd failed with err=%d\n", __func__, err); return err; } EXPORT_SYMBOL(fastcvpd_video_send_cmd_hfi_queue); Loading @@ -107,14 +152,15 @@ EXPORT_SYMBOL(fastcvpd_video_send_cmd_hfi_queue); int fastcvpd_video_suspend(uint32_t session_flag) { int err = 0; struct fastcvpd_cmd_msg cmd_msg; struct fastcvpd_cmd_msg local_cmd_msg; cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SUSPEND; local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SUSPEND; err = fastcvpd_send_cmd (&cmd_msg, sizeof(struct fastcvpd_cmd_msg)); (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg)); if (err != 0) pr_err("%s: fastcvpd_send_cmd failed with err=%d\n", __func__, err); return err; } EXPORT_SYMBOL(fastcvpd_video_suspend); Loading @@ -122,29 +168,56 @@ EXPORT_SYMBOL(fastcvpd_video_suspend); int fastcvpd_video_resume(uint32_t session_flag) { int err; struct fastcvpd_cmd_msg cmd_msg; struct fastcvpd_cmd_msg local_cmd_msg; cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_RESUME; local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_RESUME; err = fastcvpd_send_cmd (&cmd_msg, sizeof(struct fastcvpd_cmd_msg)); (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg)); if (err != 0) pr_err("%s: fastcvpd_send_cmd failed with err=%d\n", __func__, err); return err; } EXPORT_SYMBOL(fastcvpd_video_resume); int fastcvpd_video_shutdown(uint32_t session_flag) { struct fastcvpd_apps *me = &gfa_cv; int err; struct fastcvpd_cmd_msg cmd_msg; struct fastcvpd_cmd_msg local_cmd_msg; int srcVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; int destVM[SRC_VM_NUM] = {VMID_HLOS}; int destVMperm[SRC_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC }; cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SHUTDOWN; local_cmd_msg.cmd_msg_type = FASTCVPD_VIDEO_SHUTDOWN; err = fastcvpd_send_cmd (&cmd_msg, sizeof(struct fastcvpd_cmd_msg)); (&local_cmd_msg, sizeof(struct fastcvpd_cmd_msg)); if (err != 0) pr_err("%s: fastcvpd_send_cmd failed with err=%d\n", __func__, err); wait_for_completion(&work); spin_lock(&me->hlock); local_cmd_msg.msg_ptr = cmd_msg.msg_ptr; local_cmd_msg.msg_ptr_len = cmd_msg.msg_ptr_len; if (cmd_msg_rsp.ret_val == 0) { err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr, local_cmd_msg.msg_ptr_len, srcVM, DEST_VM_NUM, destVM, destVMperm, SRC_VM_NUM); if (err) { pr_err("%s: Failed to hyp_assign. err=%d\n", __func__, err); spin_unlock(&me->hlock); return err; } } else { pr_err("%s: Skipping hyp_assign as CDSP sent invalid response=%d\n", __func__, cmd_msg_rsp.ret_val); } spin_unlock(&me->hlock); return err; } EXPORT_SYMBOL(fastcvpd_video_shutdown); Loading @@ -169,7 +242,9 @@ static int __init fastcvpd_device_init(void) struct fastcvpd_apps *me = &gfa_cv; int err; init_completion(&work); mutex_init(&me->smd_mutex); spin_lock_init(&me->hlock); err = register_rpmsg_driver(&fastcvpd_rpmsg_client); if (err) { pr_err("%s : register_rpmsg_driver failed with err %d\n", Loading @@ -187,6 +262,7 @@ static void __exit fastcvpd_device_exit(void) { struct fastcvpd_apps *me = &gfa_cv; mutex_destroy(&me->smd_mutex); if (me->rpmsg_register == 1) unregister_rpmsg_driver(&fastcvpd_rpmsg_client); } Loading