blob: 2e7224fd93074745c94dcf906f82c0c30b30dcf1 [file] [log] [blame]
/*
* Samsung Exynos SoC series NPU driver
*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/atomic.h>
#include <linux/mutex.h>
#define NPU_LOG_TAG "if-protodrv-mbox2"
#include "npu-if-protodrv-mbox2.h"
#include "npu-log.h"
#include "interface/hardware/npu-interface.h"
struct npu_if_protodrv_mbox_ops npu_if_protodrv_mbox_ops = {
.frame_result_available = fr_rslt_available,
.frame_post_request = fr_req_manager,
.frame_get_result = fr_rslt_manager,
.nw_result_available = nw_rslt_available,
.nw_post_request = nw_req_manager,
.nw_get_result = nw_rslt_manager,
.register_notifier = register_rslt_notifier,
.register_msgid_type_getter = register_msgid_get_type,
};
int npu_mbox_op_register_notifier(protodrv_notifier sig_func)
{
if (npu_if_protodrv_mbox_ops.register_notifier)
return npu_if_protodrv_mbox_ops.register_notifier(sig_func);
npu_warn("not defined: register_notifier()\n");
return 0;
}
/* nw_mbox_ops -> Use npu-if-protodrv-mbox object stored in npu_proto_drv */
int npu_nw_mbox_op_is_available(void)
{
if (npu_if_protodrv_mbox_ops.nw_result_available)
return npu_if_protodrv_mbox_ops.nw_result_available();
npu_warn("not defined: nw_result_available()\n");
return 0;
}
int npu_nw_mbox_ops_get(struct msgid_pool *pool, struct proto_req_nw **target)
{
int msgid = 0;
struct npu_nw nw;
int ret = 0;
if (npu_if_protodrv_mbox_ops.nw_get_result)
ret = npu_if_protodrv_mbox_ops.nw_get_result(&msgid, &nw);
else {
npu_warn("not defined: nw_get_result()\n");
*target = NULL;
return 0;
}
if (ret <= 0) {
/* No message */
*target = NULL;
return ret;
} else {
/* Message available */
*target = msgid_claim_get_ref(pool, msgid, PROTO_DRV_REQ_TYPE_NW);
if (*target != NULL) {
npu_uinfo("mbox->protodrv : NW msgid(%d)\n", &(*target)->nw, msgid);
(*target)->nw.msgid = -1;
(*target)->nw.result_code = nw.result_code;
return 1;
} else {
npu_err("failed to find request mapped with msgid[%d]\n", msgid);
return 0;
}
}
}
int npu_nw_mbox_ops_put(struct msgid_pool *pool, struct proto_req_nw *src)
{
int msgid = 0;
int ret;
msgid = msgid_issue_save_ref(pool, PROTO_DRV_REQ_TYPE_NW, src);
src->nw.msgid = msgid;
npu_uinfo("protodrv-> : NW msgid(%d)\n", &src->nw, msgid);
if (msgid < 0) {
npu_uwarn("no message ID available. Posting message is not temporally available.\n", &src->nw);
return 0;
}
/* Generate mailbox message with given msgid and post it */
if (npu_if_protodrv_mbox_ops.nw_post_request)
ret = npu_if_protodrv_mbox_ops.nw_post_request(msgid, &src->nw);
else {
npu_warn("not defined: nw_post_request()\n");
return 0;
}
if (ret <= 0) {
/* Push failed -> return msgid */
npu_utrace("nw_post_request failed. Reclaiming msgid(%d)\n", &src->nw, msgid);
msgid_claim(pool, msgid);
}
return ret;
}
/* frame_mbox_ops -> Use npu-if-protodrv-mbox object stored in npu_proto_drv */
int npu_frame_mbox_op_is_available(void)
{
if (npu_if_protodrv_mbox_ops.frame_result_available)
return npu_if_protodrv_mbox_ops.frame_result_available();
npu_warn("not defined: frame_result_available()\n");
return 0;
}
int npu_frame_mbox_ops_get(struct msgid_pool *pool, struct proto_req_frame **target)
{
int msgid = 0;
struct npu_frame frame;
int ret = 0;
if (npu_if_protodrv_mbox_ops.frame_get_result)
ret = npu_if_protodrv_mbox_ops.frame_get_result(&msgid, &frame);
else {
npu_warn("not defined: frame_get_result()\n");
*target = NULL;
return 0;
}
if (ret <= 0) {
/* No message */
*target = NULL;
return ret;
} else {
*target = msgid_claim_get_ref(pool, msgid, PROTO_DRV_REQ_TYPE_FRAME);
if (*target != NULL) {
npu_ufinfo("mbox->protodrv : frame msgid(%d)\n", &(*target)->frame, msgid);
(*target)->frame.msgid = -1;
(*target)->frame.result_code = frame.result_code;
return 1;
} else {
npu_err("failed to find request mapped with msgid[%d]\n", msgid);
return 0;
}
}
}
int npu_frame_mbox_ops_put(struct msgid_pool *pool, struct proto_req_frame *src)
{
int msgid = 0;
int ret;
msgid = msgid_issue_save_ref(pool, PROTO_DRV_REQ_TYPE_FRAME, src);
src->frame.msgid = msgid;
npu_ufinfo("protodrv-> : FRAME msgid(%d)\n", &src->frame, msgid);
if (msgid < 0) {
npu_ufwarn("no message ID available. Posting message is not temporally available.\n", &src->frame);
return 0;
}
/* Generate mailbox message with given msgid and post it */
if (npu_if_protodrv_mbox_ops.frame_post_request)
ret = npu_if_protodrv_mbox_ops.frame_post_request(msgid, &src->frame);
else {
npu_warn("not defined: frame_post_request()\n");
return 0;
}
if (ret <= 0) {
/* Push failed -> return msgid */
npu_uftrace("frame_post_request failed. Reclaiming msgid(%d)\n", &src->frame, msgid);
msgid_claim(pool, msgid);
}
return ret;
}
int npu_mbox_op_register_msgid_type_getter(int (*msgid_get_type_func)(int))
{
if (npu_if_protodrv_mbox_ops.register_msgid_type_getter)
return npu_if_protodrv_mbox_ops.register_msgid_type_getter(msgid_get_type_func);
npu_warn("not defined: register_msgid_type_getter()\n");
return 0;
}