blob: d269ec289baba41ae8f42ef3e77e67fb274047d0 [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/delay.h>
#include "npu-common.h"
#include "npu-log.h"
#include "npu-if-protodrv-mbox.h"
#include "npu-config.h"
#include "npu-util-autosleepthr.h"
#include "npu-device.h"
#include "npu-mailbox-mgr-mock.h"
#define MBOX_MOCK_KEEP_FRAME_ID 3624
#define MBOX_MOCK_RESUME_FRAME_ID 3824
struct mailbox_mgr_mock {
struct npu_if_protodrv_mbox_ctx *if_protodrv_ctx;
struct auto_sleep_thread thr;
struct auto_sleep_thread_param thr_param;
} mailbox_mgr_mock;
static int mailbox_mgr_mock_do_task(struct auto_sleep_thread_param *data)
{
struct npu_nw nw_request;
struct npu_frame frame_request;
int ret = 0;
static int is_keeping;
static struct npu_frame frame_keeping;
/* Frame request */
while (LLQ_GET(mailbox_mgr_mock.if_protodrv_ctx->mbox_frame_req, &frame_request) > 0) {
/* Set result and put it back to result */
frame_request.result_code = 0;
npu_dbg("processed frame at mbox_mock: uid=%u, frame_id=%u, req_id=%u, IO=(%p,%p)",
frame_request.uid, frame_request.frame_id,
frame_request.npu_req_id, frame_request.input, frame_request.output);
if (frame_request.frame_id == MBOX_MOCK_KEEP_FRAME_ID) {
/* Keep the frame, until got the RESUME ID */
is_keeping = 1;
frame_keeping = frame_request;
} else {
while (LLQ_PUT(mailbox_mgr_mock.if_protodrv_ctx->mbox_frame_resp, frame_request) == 0) {
/* Wait until the output queue is available */
msleep(1);
}
}
if (frame_request.frame_id == MBOX_MOCK_RESUME_FRAME_ID) {
/* Return kept frame */
if (is_keeping) {
while (LLQ_PUT(mailbox_mgr_mock.if_protodrv_ctx->mbox_frame_resp, frame_keeping) == 0) {
/* Wait until the output queue is available */
msleep(1);
}
} else {
npu_warn("No kept frame");
}
}
ret++;
}
/* Network request */
while (LLQ_GET(mailbox_mgr_mock.if_protodrv_ctx->mbox_nw_req, &nw_request) > 0) {
/* Set result and put it back to result */
nw_request.result_code = 0;
npu_dbg("processed NW at mbox_mock: uid=%u, frame_id=%u, req_id=%u, ncp_hdr@=%p",
nw_request.uid, nw_request.frame_id,
nw_request.npu_req_id, nw_request.ncp_info.kvaddr);
while (LLQ_PUT(mailbox_mgr_mock.if_protodrv_ctx->mbox_nw_resp, nw_request) == 0) {
/* Wait until the output queue is available */
msleep(1);
}
ret++;
}
return ret;
}
int mailbox_mgr_mock_check_work(struct auto_sleep_thread_param *data)
{
return !LLQ_IS_EMPTY(mailbox_mgr_mock.if_protodrv_ctx->mbox_nw_req)
|| !LLQ_IS_EMPTY(mailbox_mgr_mock.if_protodrv_ctx->mbox_frame_req);
}
static void mailbox_mgr_mock_signal(void)
{
auto_sleep_thread_signal(&mailbox_mgr_mock.thr);
}
int mailbox_mgr_mock_probe(struct npu_device *npu_device)
{
probe_info("start in mailbox_mgr_mock_probe\n");
probe_info("complete in mailbox_mgr_mock_probe\n");
return 0;
}
int mailbox_mgr_mock_release(void)
{
probe_info("start in mailbox_mgr_mock_release\n");
probe_info("complete in mailbox_mgr_mock_release\n");
return 0;
}
int mailbox_mgr_mock_open(struct npu_device *npu_device)
{
int ret = 0;
npu_info("start in mailbox_mgr_mock_open\n");
/* Initialize interface with mailbox manager */
mailbox_mgr_mock.if_protodrv_ctx = npu_if_protodrv_mbox_ctx_open();
if (!mailbox_mgr_mock.if_protodrv_ctx) {
npu_err("init failed in npu_if_protodrv_mbox_ctx ");
ret = -EFAULT;
goto err_exit;
}
LLQ_REGISTER_TASK(mailbox_mgr_mock.if_protodrv_ctx->mbox_nw_req,
mailbox_mgr_mock_signal);
LLQ_REGISTER_TASK(mailbox_mgr_mock.if_protodrv_ctx->mbox_frame_req,
mailbox_mgr_mock_signal);
/* Initialize and run the mbox mock */
ret = auto_sleep_thread_create(&mailbox_mgr_mock.thr, "mailbox_mgr_mock"
, mailbox_mgr_mock_do_task, mailbox_mgr_mock_check_work);
if (ret) {
return -1;
}
ret = auto_sleep_thread_start(&mailbox_mgr_mock.thr, mailbox_mgr_mock.thr_param);
if (ret) {
return -2;
}
npu_info("complete in mailbox_mgr_mock_open\n");
return 0;
err_exit:
return ret;
}
int mailbox_mgr_mock_close(struct npu_device *npu_device)
{
npu_info("start in mailbox_mgr_mock_close\n");
npu_info("stop AST in mailbox_mgr_mock_close\n");
auto_sleep_thread_terminate(&mailbox_mgr_mock.thr);
npu_info("closing npu_if_protodrv_mbox in mailbox_mgr_mock_close.\n");
npu_if_protodrv_mbox_ctx_close();
mailbox_mgr_mock.if_protodrv_ctx = NULL;
npu_info("complete in mailbox_mgr_mock_close\n");
return 0;
}
int mailbox_mgr_mock_start(struct npu_device *npu_device)
{
npu_info("start in mailbox_mgr_mock_start\n");
npu_info("complete in mailbox_mgr_mock_start\n");
return 0;
}
int mailbox_mgr_mock_stop(struct npu_device *npu_device)
{
npu_info("start in mailbox_mgr_mock_stop\n");
npu_info("complete in mailbox_mgr_mock_stop\n");
return 0;
}