blob: 99329af4360a110e3f36f36ddabd31c392a4b716 [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.
*/
#ifndef _NPU_PROTODRV_H_
#define _NPU_PROTODRV_H_
#include <linux/list.h>
#include <linux/time.h>
#include <linux/types.h>
#include <linux/atomic.h>
#include "vs4l.h"
#include "vision-buffer.h"
#include "npu-util-liststatemgr.h"
#include "npu-common.h"
#include "npu-if-session-protodrv.h"
#include "npu-util-msgidgen.h"
#define PROTO_DRV_MAGIC_HEAD 0x50524F4F40484452L /* "PROT@HDR" */
#define PROTO_DRV_MAGIC_TAIL 0x5441494050524F4FL /* "TAI@PROT" */
/* Constants for Session ref look-up hash table */
#define SESS_REF_HASH_TABLE_SIZE 64
#define SESS_REF_HASH_MAGIC 7
#define SESS_REF_INVALID_HASH_ID 0xFFFFFFFF
enum proto_drv_open_steps {
PROTO_DRV_OPEN_SETUP_MBOX_MOCK = 0,
PROTO_DRV_OPEN_SESSION_REF,
PROTO_DRV_OPEN_IF_SESSION_CTX,
PROTO_DRV_OPEN_REGISTER_CB,
PROTO_DRV_OPEN_REGISTER_NOTIFIER,
PROTO_DRV_OPEN_MSGID_POOL,
PROTO_DRV_OPEN_FRAME_LSM,
PROTO_DRV_OPEN_NW_LSM,
PROTO_DRV_OPEN_AST_CREATE,
PROTO_DRV_OPEN_AST_START,
PROTO_DRV_OPEN_COMPLETE
};
typedef enum {
PROTO_DRV_REQ_TYPE_FRAME = 1,
PROTO_DRV_REQ_TYPE_NW,
PROTO_DRV_REQ_TYPE_INVALID,
} proto_drv_req_type_e;
#define LSM_ELEM_STATUS_TRACK_LEN 8
/* All times are ns scale */
struct npu_timestamp_entry {
lsm_list_type_e state;
s64 enter;
s64 leave;
};
struct npu_timestamp {
atomic_t curr_entry;
s64 init;
struct npu_timestamp_entry hist[LSM_ELEM_STATUS_TRACK_LEN];
};
struct proto_req_frame {
lsm_list_type_e state;
struct npu_timestamp ts;
/* Session reference list */
struct list_head sess_ref_list;
struct npu_frame frame;
};
struct proto_req_nw {
lsm_list_type_e state;
struct npu_timestamp ts;
/* Session reference list */
struct list_head sess_ref_list;
struct npu_nw nw;
};
/*
* Return value
* isAvailable() : 0 if the queue is empty. > 0 if one or more entries are available.
* get(..) : 0 if the queue is empty. 1 if a element is fetched.
* put(..) : 0 if the queue is full. 1 if the enqueue was successful.
*/
struct session_nw_ops {
int (*is_available)(void);
int (*get_request)(struct proto_req_nw *target);
int (*put_result)(const struct proto_req_nw *src);
};
struct session_frame_ops {
int (*is_available)(void);
int (*get_request_pair)(struct proto_req_frame *target);
int (*put_result)(const struct proto_req_frame *src);
};
struct mbox_nw_ops {
int (*is_available)(void);
int (*put)(struct proto_req_nw *src);
int (*get)(struct proto_req_nw **target);
};
struct mbox_frame_ops {
int (*is_available)(void);
int (*put)(struct proto_req_frame *src);
int (*get)(struct proto_req_frame **target);
};
enum protodrv_session_state_e {
SESSION_REF_STATE_INVALID = 0,
SESSION_REF_STATE_INACTIVE,
SESSION_REF_STATE_ACTIVE,
SESSION_REF_STATE_STOPPING,
};
struct session_ref_entry {
u32 hash_id;
enum protodrv_session_state_e s_state;
npu_uid_t uid;
const struct npu_session *session;
struct list_head list;
struct list_head frame_list;
struct list_head nw_list;
};
struct session_ref {
struct session_ref_entry *hash_table[SESS_REF_HASH_TABLE_SIZE];
struct list_head entry_list;
};
/* Top-level singleton object of proto-drv */
LSM_DECLARE_REF(proto_frame_lsm);
LSM_DECLARE_REF(proto_nw_lsm);
struct npu_proto_drv {
/* Magic number identifier */
const u64 magic_head;
/* Reference to LSM */
LSM_TYPE(proto_frame_lsm) * frame_lsm;
LSM_TYPE(proto_nw_lsm) * nw_lsm;
/* AST to manage LSM */
struct auto_sleep_thread ast;
struct auto_sleep_thread_param ast_param;
/* State of proto-drv */
atomic_t state;
/* Request ID generator */
atomic_t req_id_gen;
/* MSG ID pool */
struct msgid_pool msgid_pool;
/* Q structures between session (for debugging purpose) */
const struct npu_if_session_protodrv_ctx *if_session_ctx;
/* Reference of npu_device */
struct npu_device *npu_device;
/* Reference of mbox interface */
struct npu_if_protodrv_mbox_ctx *if_mbox_ctx;
/* Session reference */
struct session_ref session_ref;
/* Open status (Bitfield of proto_drv_open_steps) */
unsigned long open_steps;
/* Magic number identifier */
const u64 magic_tail;
};
/*
* Defining parameters for request ID generation.
* INITIAL : Initial value of request ID
* ROLLOVER : Maximum value of request ID. After issuing this ID,
* next ID will be INITIAL.
*/
#define NPU_REQ_ID_ROLLOVER ((npu_req_id_t)((1<<20) - 1))
#define NPU_REQ_ID_INITIAL 1
/* Exported functions */
int proto_drv_probe(struct npu_device *npu_device);
int proto_drv_release(void);
int proto_drv_open(struct npu_device *npu_device);
int proto_drv_close(struct npu_device *npu_device);
int proto_drv_start(struct npu_device *npu_device);
int proto_drv_stop(struct npu_device *npu_device);
int proto_req_fault_listener(void);
int session_fault_listener(void);
#endif /* _NPU_PROTODRV_H_ */