1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka */
5*437bfbebSnyanmisaka
6*437bfbebSnyanmisaka #define MODULE_TAG "mpp_server"
7*437bfbebSnyanmisaka
8*437bfbebSnyanmisaka #include <sys/ioctl.h>
9*437bfbebSnyanmisaka #include <fcntl.h>
10*437bfbebSnyanmisaka #include <errno.h>
11*437bfbebSnyanmisaka #include <string.h>
12*437bfbebSnyanmisaka
13*437bfbebSnyanmisaka #include "mpp_env.h"
14*437bfbebSnyanmisaka #include "mpp_list.h"
15*437bfbebSnyanmisaka #include "mpp_time.h"
16*437bfbebSnyanmisaka #include "osal_2str.h"
17*437bfbebSnyanmisaka #include "mpp_common.h"
18*437bfbebSnyanmisaka #include "mpp_thread.h"
19*437bfbebSnyanmisaka #include "mpp_mem_pool.h"
20*437bfbebSnyanmisaka #include "mpp_singleton.h"
21*437bfbebSnyanmisaka
22*437bfbebSnyanmisaka #include "mpp_server.h"
23*437bfbebSnyanmisaka #include "mpp_device_debug.h"
24*437bfbebSnyanmisaka #include "mpp_service_impl.h"
25*437bfbebSnyanmisaka
26*437bfbebSnyanmisaka #define MAX_BATCH_TASK 8
27*437bfbebSnyanmisaka #define MAX_SESSION_TASK 4
28*437bfbebSnyanmisaka #define MAX_REQ_SEND_CNT MAX_REQ_NUM
29*437bfbebSnyanmisaka #define MAX_REQ_WAIT_CNT 2
30*437bfbebSnyanmisaka
31*437bfbebSnyanmisaka #define MPP_SERVER_DBG_FLOW (0x00000001)
32*437bfbebSnyanmisaka
33*437bfbebSnyanmisaka #define mpp_serv_dbg(flag, fmt, ...) _mpp_dbg(mpp_server_debug, flag, fmt, ## __VA_ARGS__)
34*437bfbebSnyanmisaka #define mpp_serv_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_server_debug, flag, fmt, ## __VA_ARGS__)
35*437bfbebSnyanmisaka
36*437bfbebSnyanmisaka #define mpp_serv_dbg_flow(fmt, ...) mpp_serv_dbg(MPP_SERVER_DBG_FLOW, fmt, ## __VA_ARGS__)
37*437bfbebSnyanmisaka
38*437bfbebSnyanmisaka #define FIFO_WRITE(size, count, wr, rd) \
39*437bfbebSnyanmisaka do { \
40*437bfbebSnyanmisaka wr++; \
41*437bfbebSnyanmisaka if (wr >= size) wr = 0; \
42*437bfbebSnyanmisaka count++; \
43*437bfbebSnyanmisaka mpp_assert(count <= size); \
44*437bfbebSnyanmisaka } while (0)
45*437bfbebSnyanmisaka
46*437bfbebSnyanmisaka #define FIFO_READ(size, count, wr, rd) \
47*437bfbebSnyanmisaka do { \
48*437bfbebSnyanmisaka rd++; \
49*437bfbebSnyanmisaka if (rd >= size) rd = 0; \
50*437bfbebSnyanmisaka count--; \
51*437bfbebSnyanmisaka mpp_assert(count >= 0); \
52*437bfbebSnyanmisaka } while (0)
53*437bfbebSnyanmisaka
54*437bfbebSnyanmisaka #define get_srv_server() \
55*437bfbebSnyanmisaka ({ \
56*437bfbebSnyanmisaka MppDevServer *__tmp; \
57*437bfbebSnyanmisaka if (!srv_server) { \
58*437bfbebSnyanmisaka mpp_server_init(); \
59*437bfbebSnyanmisaka } \
60*437bfbebSnyanmisaka __tmp = srv_server; \
61*437bfbebSnyanmisaka if (!__tmp || !__tmp->inited) { \
62*437bfbebSnyanmisaka mpp_err("mpp server srv not init for %s at %s\n", \
63*437bfbebSnyanmisaka __tmp ? __tmp->server_error : "invalid server", __FUNCTION__); \
64*437bfbebSnyanmisaka __tmp = NULL; \
65*437bfbebSnyanmisaka } \
66*437bfbebSnyanmisaka __tmp; \
67*437bfbebSnyanmisaka })
68*437bfbebSnyanmisaka
69*437bfbebSnyanmisaka typedef struct MppDevTask_t MppDevTask;
70*437bfbebSnyanmisaka typedef struct MppDevBatTask_t MppDevBatTask;
71*437bfbebSnyanmisaka typedef struct MppDevSession_t MppDevSession;
72*437bfbebSnyanmisaka typedef struct MppDevBatServ_t MppDevBatServ;
73*437bfbebSnyanmisaka
74*437bfbebSnyanmisaka struct MppDevTask_t {
75*437bfbebSnyanmisaka /* link to server */
76*437bfbebSnyanmisaka struct list_head link_server;
77*437bfbebSnyanmisaka /* link to session tasks */
78*437bfbebSnyanmisaka struct list_head link_session;
79*437bfbebSnyanmisaka /* link to batch tasks */
80*437bfbebSnyanmisaka struct list_head link_batch;
81*437bfbebSnyanmisaka
82*437bfbebSnyanmisaka MppDevSession *session;
83*437bfbebSnyanmisaka MppDevBatTask *batch;
84*437bfbebSnyanmisaka
85*437bfbebSnyanmisaka rk_s32 slot_idx;
86*437bfbebSnyanmisaka
87*437bfbebSnyanmisaka /* lock by server */
88*437bfbebSnyanmisaka rk_s32 task_id;
89*437bfbebSnyanmisaka /* lock by batch */
90*437bfbebSnyanmisaka rk_s32 batch_slot_id;
91*437bfbebSnyanmisaka
92*437bfbebSnyanmisaka MppReqV1 *req;
93*437bfbebSnyanmisaka rk_s32 req_cnt;
94*437bfbebSnyanmisaka };
95*437bfbebSnyanmisaka
96*437bfbebSnyanmisaka struct MppDevBatTask_t {
97*437bfbebSnyanmisaka MppMutexCond cond;
98*437bfbebSnyanmisaka
99*437bfbebSnyanmisaka /* link to server */
100*437bfbebSnyanmisaka struct list_head link_server;
101*437bfbebSnyanmisaka /* link to session tasks */
102*437bfbebSnyanmisaka struct list_head link_tasks;
103*437bfbebSnyanmisaka
104*437bfbebSnyanmisaka rk_u32 batch_id;
105*437bfbebSnyanmisaka
106*437bfbebSnyanmisaka MppDevBatCmd *bat_cmd;
107*437bfbebSnyanmisaka MppReqV1 *send_reqs;
108*437bfbebSnyanmisaka MppReqV1 *wait_reqs;
109*437bfbebSnyanmisaka
110*437bfbebSnyanmisaka /* lock and clean by server */
111*437bfbebSnyanmisaka rk_s32 send_req_cnt;
112*437bfbebSnyanmisaka rk_s32 wait_req_cnt;
113*437bfbebSnyanmisaka
114*437bfbebSnyanmisaka /* lock by server */
115*437bfbebSnyanmisaka rk_s32 fill_cnt;
116*437bfbebSnyanmisaka rk_s32 fill_full;
117*437bfbebSnyanmisaka rk_s32 fill_timeout;
118*437bfbebSnyanmisaka rk_s32 poll_cnt;
119*437bfbebSnyanmisaka };
120*437bfbebSnyanmisaka
121*437bfbebSnyanmisaka struct MppDevSession_t {
122*437bfbebSnyanmisaka MppMutexCond cond_lock;
123*437bfbebSnyanmisaka
124*437bfbebSnyanmisaka /* hash table to server */
125*437bfbebSnyanmisaka struct list_head list_server;
126*437bfbebSnyanmisaka /* link to session waiting tasks */
127*437bfbebSnyanmisaka struct list_head list_wait;
128*437bfbebSnyanmisaka /* link to session free tasks */
129*437bfbebSnyanmisaka struct list_head list_done;
130*437bfbebSnyanmisaka
131*437bfbebSnyanmisaka MppDevMppService *ctx;
132*437bfbebSnyanmisaka MppDevBatServ *server;
133*437bfbebSnyanmisaka
134*437bfbebSnyanmisaka rk_s32 client;
135*437bfbebSnyanmisaka
136*437bfbebSnyanmisaka rk_s32 task_wait;
137*437bfbebSnyanmisaka rk_s32 task_done;
138*437bfbebSnyanmisaka
139*437bfbebSnyanmisaka MppDevTask tasks[MAX_SESSION_TASK];
140*437bfbebSnyanmisaka };
141*437bfbebSnyanmisaka
142*437bfbebSnyanmisaka struct MppDevBatServ_t {
143*437bfbebSnyanmisaka MppMutex lock;
144*437bfbebSnyanmisaka
145*437bfbebSnyanmisaka rk_s32 server_fd;
146*437bfbebSnyanmisaka rk_u32 batch_id;
147*437bfbebSnyanmisaka rk_u32 task_id;
148*437bfbebSnyanmisaka
149*437bfbebSnyanmisaka /* timer for serializing process */
150*437bfbebSnyanmisaka MppTimer timer;
151*437bfbebSnyanmisaka
152*437bfbebSnyanmisaka /* session register */
153*437bfbebSnyanmisaka struct list_head session_list;
154*437bfbebSnyanmisaka rk_s32 session_count;
155*437bfbebSnyanmisaka
156*437bfbebSnyanmisaka /* batch task queue */
157*437bfbebSnyanmisaka struct list_head list_batch;
158*437bfbebSnyanmisaka struct list_head list_batch_free;
159*437bfbebSnyanmisaka MppMemPool batch_pool;
160*437bfbebSnyanmisaka rk_s32 batch_max_count;
161*437bfbebSnyanmisaka rk_s32 batch_task_size;
162*437bfbebSnyanmisaka rk_s32 batch_run;
163*437bfbebSnyanmisaka rk_s32 batch_free;
164*437bfbebSnyanmisaka rk_s32 max_task_in_batch;
165*437bfbebSnyanmisaka
166*437bfbebSnyanmisaka /* link to all pending tasks */
167*437bfbebSnyanmisaka struct list_head pending_task;
168*437bfbebSnyanmisaka rk_s32 pending_count;
169*437bfbebSnyanmisaka };
170*437bfbebSnyanmisaka
171*437bfbebSnyanmisaka typedef struct MppDevServer_t {
172*437bfbebSnyanmisaka const char *server_error;
173*437bfbebSnyanmisaka const char *server_name;
174*437bfbebSnyanmisaka rk_s32 inited;
175*437bfbebSnyanmisaka rk_u32 enable;
176*437bfbebSnyanmisaka MppMutex lock;
177*437bfbebSnyanmisaka MppDevBatServ *bat_server[VPU_CLIENT_BUTT];
178*437bfbebSnyanmisaka
179*437bfbebSnyanmisaka MppMemPool session_pool;
180*437bfbebSnyanmisaka MppMemPool batch_pool;
181*437bfbebSnyanmisaka
182*437bfbebSnyanmisaka rk_s32 max_task_in_batch;
183*437bfbebSnyanmisaka
184*437bfbebSnyanmisaka const MppServiceCmdCap *cmd_cap;
185*437bfbebSnyanmisaka } MppDevServer;
186*437bfbebSnyanmisaka
187*437bfbebSnyanmisaka static MppDevServer *srv_server = NULL;
188*437bfbebSnyanmisaka static rk_u32 mpp_server_debug = 0;
189*437bfbebSnyanmisaka
batch_reset(MppDevBatTask * batch)190*437bfbebSnyanmisaka static void batch_reset(MppDevBatTask *batch)
191*437bfbebSnyanmisaka {
192*437bfbebSnyanmisaka mpp_assert(list_empty(&batch->link_tasks));
193*437bfbebSnyanmisaka
194*437bfbebSnyanmisaka batch->fill_cnt = 0;
195*437bfbebSnyanmisaka batch->fill_full = 0;
196*437bfbebSnyanmisaka batch->fill_timeout = 0;
197*437bfbebSnyanmisaka batch->poll_cnt = 0;
198*437bfbebSnyanmisaka batch->send_req_cnt = 0;
199*437bfbebSnyanmisaka batch->wait_req_cnt = 0;
200*437bfbebSnyanmisaka }
201*437bfbebSnyanmisaka
batch_add(MppDevBatServ * server)202*437bfbebSnyanmisaka MppDevBatTask *batch_add(MppDevBatServ *server)
203*437bfbebSnyanmisaka {
204*437bfbebSnyanmisaka MppDevBatTask *batch = (MppDevBatTask *)mpp_mem_pool_get_f(server->batch_pool);
205*437bfbebSnyanmisaka
206*437bfbebSnyanmisaka mpp_assert(batch);
207*437bfbebSnyanmisaka if (!batch)
208*437bfbebSnyanmisaka return batch;
209*437bfbebSnyanmisaka
210*437bfbebSnyanmisaka INIT_LIST_HEAD(&batch->link_server);
211*437bfbebSnyanmisaka INIT_LIST_HEAD(&batch->link_tasks);
212*437bfbebSnyanmisaka
213*437bfbebSnyanmisaka batch->send_reqs = (MppReqV1 *)(batch + 1);
214*437bfbebSnyanmisaka batch->wait_reqs = batch->send_reqs +
215*437bfbebSnyanmisaka (server->max_task_in_batch * MAX_REQ_SEND_CNT);
216*437bfbebSnyanmisaka batch->bat_cmd = (MppDevBatCmd *)(batch->wait_reqs +
217*437bfbebSnyanmisaka (server->max_task_in_batch * MAX_REQ_WAIT_CNT));
218*437bfbebSnyanmisaka
219*437bfbebSnyanmisaka batch_reset(batch);
220*437bfbebSnyanmisaka list_add_tail(&batch->link_server, &server->list_batch_free);
221*437bfbebSnyanmisaka server->batch_free++;
222*437bfbebSnyanmisaka
223*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch add free count %d:%d\n", server->batch_run, server->batch_free);
224*437bfbebSnyanmisaka return batch;
225*437bfbebSnyanmisaka }
226*437bfbebSnyanmisaka
batch_del(MppDevBatServ * server,MppDevBatTask * batch)227*437bfbebSnyanmisaka void batch_del(MppDevBatServ *server, MppDevBatTask *batch)
228*437bfbebSnyanmisaka {
229*437bfbebSnyanmisaka mpp_assert(batch);
230*437bfbebSnyanmisaka mpp_assert(batch->fill_cnt == 0);
231*437bfbebSnyanmisaka mpp_assert(list_empty(&batch->link_tasks));
232*437bfbebSnyanmisaka
233*437bfbebSnyanmisaka list_del_init(&batch->link_server);
234*437bfbebSnyanmisaka
235*437bfbebSnyanmisaka mpp_mem_pool_put_f(server->batch_pool, batch);
236*437bfbebSnyanmisaka server->batch_free--;
237*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch del free count %d:%d\n", server->batch_run, server->batch_free);
238*437bfbebSnyanmisaka }
239*437bfbebSnyanmisaka
batch_send(MppDevBatServ * server,MppDevBatTask * batch)240*437bfbebSnyanmisaka void batch_send(MppDevBatServ *server, MppDevBatTask *batch)
241*437bfbebSnyanmisaka {
242*437bfbebSnyanmisaka rk_s32 ret = 0;
243*437bfbebSnyanmisaka
244*437bfbebSnyanmisaka mpp_assert(batch->send_req_cnt);
245*437bfbebSnyanmisaka
246*437bfbebSnyanmisaka ret = mpp_service_ioctl_request(server->server_fd, batch->send_reqs);
247*437bfbebSnyanmisaka if (ret) {
248*437bfbebSnyanmisaka mpp_err_f("ioctl batch cmd failed ret %d errno %d %s\n",
249*437bfbebSnyanmisaka ret, errno, strerror(errno));
250*437bfbebSnyanmisaka ret = errno;
251*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch %d -> send failed\n", batch->batch_id);
252*437bfbebSnyanmisaka }
253*437bfbebSnyanmisaka
254*437bfbebSnyanmisaka list_del_init(&batch->link_server);
255*437bfbebSnyanmisaka list_add_tail(&batch->link_server, &server->list_batch);
256*437bfbebSnyanmisaka server->batch_free--;
257*437bfbebSnyanmisaka server->batch_run++;
258*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch %d -> send %d for %s\n", batch->batch_id,
259*437bfbebSnyanmisaka batch->fill_cnt, batch->fill_timeout ? "timeout" : "ready");
260*437bfbebSnyanmisaka }
261*437bfbebSnyanmisaka
process_task(void * p)262*437bfbebSnyanmisaka void process_task(void *p)
263*437bfbebSnyanmisaka {
264*437bfbebSnyanmisaka MppDevBatServ *server = (MppDevBatServ *)p;
265*437bfbebSnyanmisaka MppMutex *lock = &server->lock;
266*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
267*437bfbebSnyanmisaka MppDevTask *task;
268*437bfbebSnyanmisaka MppDevBatTask *batch;
269*437bfbebSnyanmisaka MppDevSession *session = NULL;
270*437bfbebSnyanmisaka MppDevBatCmd *bat_cmd;
271*437bfbebSnyanmisaka MppReqV1 *req = NULL;
272*437bfbebSnyanmisaka rk_s32 pending = 0;
273*437bfbebSnyanmisaka
274*437bfbebSnyanmisaka mpp_serv_dbg_flow("process task start\n");
275*437bfbebSnyanmisaka
276*437bfbebSnyanmisaka /* 1. try poll and get finished task */
277*437bfbebSnyanmisaka do {
278*437bfbebSnyanmisaka batch = list_first_entry_or_null(&server->list_batch, MppDevBatTask, link_server);
279*437bfbebSnyanmisaka if (!batch)
280*437bfbebSnyanmisaka break;
281*437bfbebSnyanmisaka
282*437bfbebSnyanmisaka mpp_assert(batch->wait_req_cnt);
283*437bfbebSnyanmisaka ret = mpp_service_ioctl_request(server->server_fd, batch->wait_reqs);
284*437bfbebSnyanmisaka if (!ret) {
285*437bfbebSnyanmisaka MppDevTask *n;
286*437bfbebSnyanmisaka
287*437bfbebSnyanmisaka list_for_each_entry_safe(task, n, &batch->link_tasks, MppDevTask, link_batch) {
288*437bfbebSnyanmisaka rk_s32 batch_slot_id = task->batch_slot_id;
289*437bfbebSnyanmisaka MppDevBatCmd *cmd = batch->bat_cmd + batch_slot_id;
290*437bfbebSnyanmisaka
291*437bfbebSnyanmisaka mpp_assert(batch_slot_id < server->max_task_in_batch);
292*437bfbebSnyanmisaka session = task->session;
293*437bfbebSnyanmisaka
294*437bfbebSnyanmisaka ret = cmd->ret;
295*437bfbebSnyanmisaka if (ret == EAGAIN)
296*437bfbebSnyanmisaka continue;
297*437bfbebSnyanmisaka
298*437bfbebSnyanmisaka if (ret == -EIO) {
299*437bfbebSnyanmisaka mpp_err_f("batch %d:%d task %d poll error found\n",
300*437bfbebSnyanmisaka batch->batch_id, task->batch_slot_id, task->task_id);
301*437bfbebSnyanmisaka cmd->flag |= 1;
302*437bfbebSnyanmisaka continue;
303*437bfbebSnyanmisaka }
304*437bfbebSnyanmisaka if (ret == 0) {
305*437bfbebSnyanmisaka list_del_init(&task->link_batch);
306*437bfbebSnyanmisaka task->batch = NULL;
307*437bfbebSnyanmisaka
308*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch %d:%d session %d ready and remove\n",
309*437bfbebSnyanmisaka batch->batch_id, task->batch_slot_id, session->client);
310*437bfbebSnyanmisaka mpp_mutex_cond_lock(&session->cond_lock);
311*437bfbebSnyanmisaka session->task_done++;
312*437bfbebSnyanmisaka mpp_mutex_cond_signal(&session->cond_lock);
313*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&session->cond_lock);
314*437bfbebSnyanmisaka if (session->ctx && session->ctx->dev_cb)
315*437bfbebSnyanmisaka mpp_callback(session->ctx->dev_cb, NULL);
316*437bfbebSnyanmisaka
317*437bfbebSnyanmisaka batch->poll_cnt++;
318*437bfbebSnyanmisaka cmd->flag |= 1;
319*437bfbebSnyanmisaka }
320*437bfbebSnyanmisaka }
321*437bfbebSnyanmisaka
322*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch %d fill %d poll %d\n", batch->batch_id,
323*437bfbebSnyanmisaka batch->fill_cnt, batch->poll_cnt);
324*437bfbebSnyanmisaka
325*437bfbebSnyanmisaka if (batch->poll_cnt == batch->fill_cnt) {
326*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch %d poll done\n", batch->batch_id);
327*437bfbebSnyanmisaka list_del_init(&batch->link_server);
328*437bfbebSnyanmisaka list_add_tail(&batch->link_server, &server->list_batch_free);
329*437bfbebSnyanmisaka server->batch_run--;
330*437bfbebSnyanmisaka server->batch_free++;
331*437bfbebSnyanmisaka
332*437bfbebSnyanmisaka batch_reset(batch);
333*437bfbebSnyanmisaka batch = NULL;
334*437bfbebSnyanmisaka continue;
335*437bfbebSnyanmisaka }
336*437bfbebSnyanmisaka } else {
337*437bfbebSnyanmisaka mpp_log_f("batch %d poll ret %d errno %d %s", batch->batch_id,
338*437bfbebSnyanmisaka ret, errno, strerror(errno));
339*437bfbebSnyanmisaka mpp_log_f("stop timer\n");
340*437bfbebSnyanmisaka mpp_timer_set_enable(server->timer, 0);
341*437bfbebSnyanmisaka }
342*437bfbebSnyanmisaka break;
343*437bfbebSnyanmisaka } while (1);
344*437bfbebSnyanmisaka
345*437bfbebSnyanmisaka /* 2. get prending task to fill */
346*437bfbebSnyanmisaka mpp_mutex_lock(lock);
347*437bfbebSnyanmisaka pending = server->pending_count;
348*437bfbebSnyanmisaka if (!pending && !server->batch_run && !server->session_count) {
349*437bfbebSnyanmisaka mpp_timer_set_enable(server->timer, 0);
350*437bfbebSnyanmisaka mpp_serv_dbg_flow("stop timer\n");
351*437bfbebSnyanmisaka }
352*437bfbebSnyanmisaka mpp_mutex_unlock(lock);
353*437bfbebSnyanmisaka
354*437bfbebSnyanmisaka mpp_serv_dbg_flow("pending %d running %d free %d max %d process start\n",
355*437bfbebSnyanmisaka pending, server->batch_run, server->batch_free, server->batch_max_count);
356*437bfbebSnyanmisaka
357*437bfbebSnyanmisaka try_proc_pending_task:
358*437bfbebSnyanmisaka /* 3. try get batch task*/
359*437bfbebSnyanmisaka if (!server->batch_free) {
360*437bfbebSnyanmisaka /* if not enough and max count does not reached create new batch */
361*437bfbebSnyanmisaka if (server->batch_free + server->batch_run >= server->batch_max_count) {
362*437bfbebSnyanmisaka mpp_serv_dbg_flow("finish for not batch slot\n");
363*437bfbebSnyanmisaka return ;
364*437bfbebSnyanmisaka }
365*437bfbebSnyanmisaka
366*437bfbebSnyanmisaka batch_add(server);
367*437bfbebSnyanmisaka }
368*437bfbebSnyanmisaka mpp_assert(server->batch_free);
369*437bfbebSnyanmisaka
370*437bfbebSnyanmisaka /* 4. if no pending task to send check timeout batch and send it */
371*437bfbebSnyanmisaka if (!pending) {
372*437bfbebSnyanmisaka if (!server->batch_free) {
373*437bfbebSnyanmisaka /* no pending and no free batch just done */
374*437bfbebSnyanmisaka return;
375*437bfbebSnyanmisaka }
376*437bfbebSnyanmisaka
377*437bfbebSnyanmisaka batch = list_first_entry_or_null(&server->list_batch_free, MppDevBatTask, link_server);
378*437bfbebSnyanmisaka mpp_assert(batch);
379*437bfbebSnyanmisaka if (!batch) {
380*437bfbebSnyanmisaka mpp_log_f("batch run %d free %d\n", server->batch_run, server->batch_free);
381*437bfbebSnyanmisaka return;
382*437bfbebSnyanmisaka }
383*437bfbebSnyanmisaka
384*437bfbebSnyanmisaka /* send one timeout task */
385*437bfbebSnyanmisaka if (batch->fill_cnt)
386*437bfbebSnyanmisaka batch_send(server, batch);
387*437bfbebSnyanmisaka
388*437bfbebSnyanmisaka mpp_serv_dbg_flow("finish for no pending task\n");
389*437bfbebSnyanmisaka return;
390*437bfbebSnyanmisaka }
391*437bfbebSnyanmisaka
392*437bfbebSnyanmisaka mpp_serv_dbg_flow("pending task %d left to process\n", pending);
393*437bfbebSnyanmisaka
394*437bfbebSnyanmisaka /* 5. add task to add batch and try send batch */
395*437bfbebSnyanmisaka if (!server->batch_free) {
396*437bfbebSnyanmisaka /* no pending and no free batch just done */
397*437bfbebSnyanmisaka return;
398*437bfbebSnyanmisaka }
399*437bfbebSnyanmisaka
400*437bfbebSnyanmisaka batch = list_first_entry_or_null(&server->list_batch_free, MppDevBatTask, link_server);
401*437bfbebSnyanmisaka mpp_assert(batch);
402*437bfbebSnyanmisaka mpp_assert(pending);
403*437bfbebSnyanmisaka
404*437bfbebSnyanmisaka task = NULL;
405*437bfbebSnyanmisaka mpp_mutex_lock(lock);
406*437bfbebSnyanmisaka task = list_first_entry_or_null(&server->pending_task, MppDevTask, link_server);
407*437bfbebSnyanmisaka list_del_init(&task->link_server);
408*437bfbebSnyanmisaka server->pending_count--;
409*437bfbebSnyanmisaka mpp_mutex_unlock(lock);
410*437bfbebSnyanmisaka pending--;
411*437bfbebSnyanmisaka
412*437bfbebSnyanmisaka /* first task and setup new batch id */
413*437bfbebSnyanmisaka if (!batch->fill_cnt)
414*437bfbebSnyanmisaka batch->batch_id = server->batch_id++;
415*437bfbebSnyanmisaka
416*437bfbebSnyanmisaka task->batch = batch;
417*437bfbebSnyanmisaka task->batch_slot_id = batch->fill_cnt++;
418*437bfbebSnyanmisaka mpp_assert(task->batch_slot_id < server->max_task_in_batch);
419*437bfbebSnyanmisaka list_add_tail(&task->link_batch, &batch->link_tasks);
420*437bfbebSnyanmisaka if (batch->fill_cnt >= server->max_task_in_batch)
421*437bfbebSnyanmisaka batch->fill_full = 1;
422*437bfbebSnyanmisaka
423*437bfbebSnyanmisaka session = task->session;
424*437bfbebSnyanmisaka mpp_assert(session);
425*437bfbebSnyanmisaka mpp_assert(session->ctx);
426*437bfbebSnyanmisaka
427*437bfbebSnyanmisaka bat_cmd = batch->bat_cmd + task->batch_slot_id;
428*437bfbebSnyanmisaka bat_cmd->flag = 0;
429*437bfbebSnyanmisaka bat_cmd->client = session->client;
430*437bfbebSnyanmisaka bat_cmd->ret = 0;
431*437bfbebSnyanmisaka
432*437bfbebSnyanmisaka /* fill task to batch */
433*437bfbebSnyanmisaka /* add session info before each session task and then copy session request */
434*437bfbebSnyanmisaka req = &batch->send_reqs[batch->send_req_cnt++];
435*437bfbebSnyanmisaka req->cmd = MPP_CMD_SET_SESSION_FD;
436*437bfbebSnyanmisaka req->flag = MPP_FLAGS_MULTI_MSG;
437*437bfbebSnyanmisaka req->offset = 0;
438*437bfbebSnyanmisaka req->size = sizeof(*bat_cmd);
439*437bfbebSnyanmisaka req->data_ptr = REQ_DATA_PTR(bat_cmd);
440*437bfbebSnyanmisaka
441*437bfbebSnyanmisaka {
442*437bfbebSnyanmisaka rk_s32 i;
443*437bfbebSnyanmisaka
444*437bfbebSnyanmisaka for (i = 0; i < task->req_cnt; i++)
445*437bfbebSnyanmisaka batch->send_reqs[batch->send_req_cnt++] = task->req[i];
446*437bfbebSnyanmisaka }
447*437bfbebSnyanmisaka
448*437bfbebSnyanmisaka mpp_assert(batch->send_req_cnt <= server->max_task_in_batch * MAX_REQ_NUM);
449*437bfbebSnyanmisaka
450*437bfbebSnyanmisaka /* setup poll request */
451*437bfbebSnyanmisaka req = &batch->wait_reqs[batch->wait_req_cnt++];
452*437bfbebSnyanmisaka req->cmd = MPP_CMD_SET_SESSION_FD;
453*437bfbebSnyanmisaka req->flag = MPP_FLAGS_MULTI_MSG;
454*437bfbebSnyanmisaka req->offset = 0;
455*437bfbebSnyanmisaka req->size = sizeof(*bat_cmd);
456*437bfbebSnyanmisaka req->data_ptr = REQ_DATA_PTR(bat_cmd);
457*437bfbebSnyanmisaka
458*437bfbebSnyanmisaka req = &batch->wait_reqs[batch->wait_req_cnt++];
459*437bfbebSnyanmisaka req->cmd = MPP_CMD_POLL_HW_FINISH;
460*437bfbebSnyanmisaka req->flag = MPP_FLAGS_POLL_NON_BLOCK | MPP_FLAGS_MULTI_MSG | MPP_FLAGS_LAST_MSG;
461*437bfbebSnyanmisaka req->offset = 0;
462*437bfbebSnyanmisaka req->size = 0;
463*437bfbebSnyanmisaka req->data_ptr = 0;
464*437bfbebSnyanmisaka
465*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch %d:%d add task %d:%d:%d\n",
466*437bfbebSnyanmisaka batch->batch_id, task->batch_slot_id, session->client,
467*437bfbebSnyanmisaka task->slot_idx, task->task_id);
468*437bfbebSnyanmisaka
469*437bfbebSnyanmisaka if (batch->fill_full) {
470*437bfbebSnyanmisaka list_del_init(&batch->link_server);
471*437bfbebSnyanmisaka list_add_tail(&batch->link_server, &server->list_batch);
472*437bfbebSnyanmisaka mpp_serv_dbg_flow("batch %d -> fill_nb %d fill ready\n",
473*437bfbebSnyanmisaka batch->batch_id, batch->fill_cnt);
474*437bfbebSnyanmisaka batch_send(server, batch);
475*437bfbebSnyanmisaka batch = NULL;
476*437bfbebSnyanmisaka }
477*437bfbebSnyanmisaka goto try_proc_pending_task;
478*437bfbebSnyanmisaka }
479*437bfbebSnyanmisaka
mpp_server_thread(void * ctx)480*437bfbebSnyanmisaka static void *mpp_server_thread(void *ctx)
481*437bfbebSnyanmisaka {
482*437bfbebSnyanmisaka process_task((MppDevBatServ *)ctx);
483*437bfbebSnyanmisaka return NULL;
484*437bfbebSnyanmisaka }
485*437bfbebSnyanmisaka
send_task(MppDevMppService * ctx)486*437bfbebSnyanmisaka rk_s32 send_task(MppDevMppService *ctx)
487*437bfbebSnyanmisaka {
488*437bfbebSnyanmisaka MppDevTask *task = NULL;
489*437bfbebSnyanmisaka MppDevSession *session = (MppDevSession *)ctx->serv_ctx;
490*437bfbebSnyanmisaka
491*437bfbebSnyanmisaka if (!session || !session->server) {
492*437bfbebSnyanmisaka mpp_err_f("invalid ctx %p session %p send task\n", ctx, session);
493*437bfbebSnyanmisaka return rk_nok;
494*437bfbebSnyanmisaka }
495*437bfbebSnyanmisaka
496*437bfbebSnyanmisaka MppDevBatServ *server = session->server;
497*437bfbebSnyanmisaka
498*437bfbebSnyanmisaka /* get free task from session and add to run list */
499*437bfbebSnyanmisaka mpp_mutex_cond_lock(&session->cond_lock);
500*437bfbebSnyanmisaka /* get a free task and setup */
501*437bfbebSnyanmisaka task = list_first_entry_or_null(&session->list_done, MppDevTask, link_session);
502*437bfbebSnyanmisaka mpp_assert(task);
503*437bfbebSnyanmisaka
504*437bfbebSnyanmisaka task->req = ctx->reqs;
505*437bfbebSnyanmisaka task->req_cnt = ctx->req_cnt;
506*437bfbebSnyanmisaka
507*437bfbebSnyanmisaka list_del_init(&task->link_session);
508*437bfbebSnyanmisaka list_add_tail(&task->link_session, &session->list_wait);
509*437bfbebSnyanmisaka
510*437bfbebSnyanmisaka session->task_wait++;
511*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&session->cond_lock);
512*437bfbebSnyanmisaka
513*437bfbebSnyanmisaka mpp_mutex_lock(&server->lock);
514*437bfbebSnyanmisaka task->task_id = server->task_id++;
515*437bfbebSnyanmisaka list_del_init(&task->link_server);
516*437bfbebSnyanmisaka list_add_tail(&task->link_server, &server->pending_task);
517*437bfbebSnyanmisaka server->pending_count++;
518*437bfbebSnyanmisaka mpp_serv_dbg_flow("session %d:%d add pending %d\n",
519*437bfbebSnyanmisaka session->client, task->slot_idx, server->pending_count);
520*437bfbebSnyanmisaka
521*437bfbebSnyanmisaka mpp_timer_set_enable(server->timer, 1);
522*437bfbebSnyanmisaka mpp_mutex_unlock(&server->lock);
523*437bfbebSnyanmisaka
524*437bfbebSnyanmisaka return rk_ok;
525*437bfbebSnyanmisaka }
526*437bfbebSnyanmisaka
wait_task(MppDevMppService * ctx,rk_s64 timeout)527*437bfbebSnyanmisaka rk_s32 wait_task(MppDevMppService *ctx, rk_s64 timeout)
528*437bfbebSnyanmisaka {
529*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
530*437bfbebSnyanmisaka MppDevTask *task = NULL;
531*437bfbebSnyanmisaka MppDevSession *session = (MppDevSession *)ctx->serv_ctx;
532*437bfbebSnyanmisaka (void) timeout;
533*437bfbebSnyanmisaka
534*437bfbebSnyanmisaka if (!session) {
535*437bfbebSnyanmisaka mpp_err_f("invalid ctx %p send task\n", ctx);
536*437bfbebSnyanmisaka return rk_nok;
537*437bfbebSnyanmisaka }
538*437bfbebSnyanmisaka
539*437bfbebSnyanmisaka task = list_first_entry_or_null(&session->list_wait, MppDevTask, link_session);
540*437bfbebSnyanmisaka mpp_assert(task);
541*437bfbebSnyanmisaka
542*437bfbebSnyanmisaka mpp_mutex_cond_lock(&session->cond_lock);
543*437bfbebSnyanmisaka if (session->task_wait != session->task_done) {
544*437bfbebSnyanmisaka mpp_serv_dbg_flow("session %d wait %d start %d:%d\n", session->client,
545*437bfbebSnyanmisaka task->task_id, session->task_wait, session->task_done);
546*437bfbebSnyanmisaka mpp_mutex_cond_wait(&session->cond_lock);
547*437bfbebSnyanmisaka }
548*437bfbebSnyanmisaka mpp_serv_dbg_flow("session %d wait %d done %d:%d\n", session->client,
549*437bfbebSnyanmisaka task->task_id, session->task_wait, session->task_done);
550*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&session->cond_lock);
551*437bfbebSnyanmisaka
552*437bfbebSnyanmisaka list_del_init(&task->link_session);
553*437bfbebSnyanmisaka list_add_tail(&task->link_session, &session->list_done);
554*437bfbebSnyanmisaka
555*437bfbebSnyanmisaka return ret;
556*437bfbebSnyanmisaka }
557*437bfbebSnyanmisaka
bat_server_get(MppDevServer * srv,MppClientType client_type)558*437bfbebSnyanmisaka static MppDevBatServ *bat_server_get(MppDevServer *srv, MppClientType client_type)
559*437bfbebSnyanmisaka {
560*437bfbebSnyanmisaka MppDevBatServ *server = NULL;
561*437bfbebSnyanmisaka char timer_name[32];
562*437bfbebSnyanmisaka
563*437bfbebSnyanmisaka mpp_mutex_lock(&srv->lock);
564*437bfbebSnyanmisaka
565*437bfbebSnyanmisaka server = srv->bat_server[client_type];
566*437bfbebSnyanmisaka if (server) {
567*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
568*437bfbebSnyanmisaka return server;
569*437bfbebSnyanmisaka }
570*437bfbebSnyanmisaka
571*437bfbebSnyanmisaka server = mpp_calloc(MppDevBatServ, 1);
572*437bfbebSnyanmisaka if (!server) {
573*437bfbebSnyanmisaka mpp_err("mpp server failed to get bat server\n");
574*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
575*437bfbebSnyanmisaka return NULL;
576*437bfbebSnyanmisaka }
577*437bfbebSnyanmisaka
578*437bfbebSnyanmisaka server->server_fd = open(srv->server_name, O_RDWR | O_CLOEXEC);
579*437bfbebSnyanmisaka if (server->server_fd < 0) {
580*437bfbebSnyanmisaka mpp_err("mpp server get bat server failed to open device\n");
581*437bfbebSnyanmisaka goto failed;
582*437bfbebSnyanmisaka }
583*437bfbebSnyanmisaka
584*437bfbebSnyanmisaka snprintf(timer_name, sizeof(timer_name) - 1, "%s_bat",
585*437bfbebSnyanmisaka strof_client_type(client_type));
586*437bfbebSnyanmisaka
587*437bfbebSnyanmisaka server->timer = mpp_timer_get(timer_name);
588*437bfbebSnyanmisaka if (!server->timer) {
589*437bfbebSnyanmisaka mpp_err("mpp server get bat server failed to create timer\n");
590*437bfbebSnyanmisaka goto failed;
591*437bfbebSnyanmisaka }
592*437bfbebSnyanmisaka
593*437bfbebSnyanmisaka mpp_mutex_init(&server->lock);
594*437bfbebSnyanmisaka
595*437bfbebSnyanmisaka mpp_timer_set_callback(server->timer, mpp_server_thread, server);
596*437bfbebSnyanmisaka /* 10ms */
597*437bfbebSnyanmisaka mpp_timer_set_timing(server->timer, 10, 10);
598*437bfbebSnyanmisaka
599*437bfbebSnyanmisaka INIT_LIST_HEAD(&server->session_list);
600*437bfbebSnyanmisaka INIT_LIST_HEAD(&server->list_batch);
601*437bfbebSnyanmisaka INIT_LIST_HEAD(&server->list_batch_free);
602*437bfbebSnyanmisaka INIT_LIST_HEAD(&server->pending_task);
603*437bfbebSnyanmisaka
604*437bfbebSnyanmisaka server->batch_pool = srv->batch_pool;
605*437bfbebSnyanmisaka server->max_task_in_batch = srv->max_task_in_batch;
606*437bfbebSnyanmisaka
607*437bfbebSnyanmisaka srv->bat_server[client_type] = server;
608*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
609*437bfbebSnyanmisaka
610*437bfbebSnyanmisaka return server;
611*437bfbebSnyanmisaka
612*437bfbebSnyanmisaka failed:
613*437bfbebSnyanmisaka if (server) {
614*437bfbebSnyanmisaka if (server->timer) {
615*437bfbebSnyanmisaka mpp_timer_put(server->timer);
616*437bfbebSnyanmisaka server->timer = NULL;
617*437bfbebSnyanmisaka }
618*437bfbebSnyanmisaka
619*437bfbebSnyanmisaka if (server->server_fd >= 0) {
620*437bfbebSnyanmisaka close(server->server_fd);
621*437bfbebSnyanmisaka server->server_fd = -1;
622*437bfbebSnyanmisaka }
623*437bfbebSnyanmisaka mpp_mutex_destroy(&server->lock);
624*437bfbebSnyanmisaka }
625*437bfbebSnyanmisaka MPP_FREE(server);
626*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
627*437bfbebSnyanmisaka
628*437bfbebSnyanmisaka return NULL;
629*437bfbebSnyanmisaka }
630*437bfbebSnyanmisaka
bat_server_put(MppDevServer * srv,MppClientType client_type)631*437bfbebSnyanmisaka static rk_s32 bat_server_put(MppDevServer *srv, MppClientType client_type)
632*437bfbebSnyanmisaka {
633*437bfbebSnyanmisaka MppDevBatServ *server = NULL;
634*437bfbebSnyanmisaka MppDevBatTask *batch, *n;
635*437bfbebSnyanmisaka
636*437bfbebSnyanmisaka mpp_mutex_lock(&srv->lock);
637*437bfbebSnyanmisaka
638*437bfbebSnyanmisaka if (!srv->bat_server[client_type]) {
639*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
640*437bfbebSnyanmisaka return rk_ok;
641*437bfbebSnyanmisaka }
642*437bfbebSnyanmisaka
643*437bfbebSnyanmisaka server = srv->bat_server[client_type];
644*437bfbebSnyanmisaka srv->bat_server[client_type] = NULL;
645*437bfbebSnyanmisaka
646*437bfbebSnyanmisaka mpp_assert(server->batch_run == 0);
647*437bfbebSnyanmisaka mpp_assert(list_empty(&server->list_batch));
648*437bfbebSnyanmisaka mpp_assert(server->pending_count == 0);
649*437bfbebSnyanmisaka
650*437bfbebSnyanmisaka /* stop thread first */
651*437bfbebSnyanmisaka if (server->timer) {
652*437bfbebSnyanmisaka mpp_timer_put(server->timer);
653*437bfbebSnyanmisaka server->timer = NULL;
654*437bfbebSnyanmisaka }
655*437bfbebSnyanmisaka
656*437bfbebSnyanmisaka if (server->batch_free) {
657*437bfbebSnyanmisaka list_for_each_entry_safe(batch, n, &server->list_batch_free, MppDevBatTask, link_server) {
658*437bfbebSnyanmisaka batch_del(server, batch);
659*437bfbebSnyanmisaka }
660*437bfbebSnyanmisaka } else {
661*437bfbebSnyanmisaka mpp_assert(list_empty(&server->list_batch_free));
662*437bfbebSnyanmisaka }
663*437bfbebSnyanmisaka
664*437bfbebSnyanmisaka if (server->server_fd >= 0) {
665*437bfbebSnyanmisaka close(server->server_fd);
666*437bfbebSnyanmisaka server->server_fd = -1;
667*437bfbebSnyanmisaka }
668*437bfbebSnyanmisaka mpp_mutex_destroy(&server->lock);
669*437bfbebSnyanmisaka MPP_FREE(server);
670*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
671*437bfbebSnyanmisaka
672*437bfbebSnyanmisaka return rk_ok;
673*437bfbebSnyanmisaka }
674*437bfbebSnyanmisaka
server_attach(MppDevServer * srv,MppDevMppService * ctx)675*437bfbebSnyanmisaka static rk_s32 server_attach(MppDevServer *srv, MppDevMppService *ctx)
676*437bfbebSnyanmisaka {
677*437bfbebSnyanmisaka MppClientType client_type = (MppClientType)ctx->client_type;
678*437bfbebSnyanmisaka MppDevBatServ *server;
679*437bfbebSnyanmisaka MppDevSession *session;
680*437bfbebSnyanmisaka rk_u32 i;
681*437bfbebSnyanmisaka
682*437bfbebSnyanmisaka if (client_type < 0 || client_type >= VPU_CLIENT_BUTT) {
683*437bfbebSnyanmisaka mpp_err("mpp server attach failed with invalid client type %d\n", client_type);
684*437bfbebSnyanmisaka return rk_nok;
685*437bfbebSnyanmisaka }
686*437bfbebSnyanmisaka
687*437bfbebSnyanmisaka /* if client type server is not created create it first */
688*437bfbebSnyanmisaka server = bat_server_get(srv, client_type);
689*437bfbebSnyanmisaka if (!server) {
690*437bfbebSnyanmisaka mpp_err("mpp server get bat server with client type %d failed\n", client_type);
691*437bfbebSnyanmisaka return rk_nok;
692*437bfbebSnyanmisaka }
693*437bfbebSnyanmisaka
694*437bfbebSnyanmisaka mpp_mutex_lock(&srv->lock);
695*437bfbebSnyanmisaka if (ctx->serv_ctx) {
696*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
697*437bfbebSnyanmisaka return rk_ok;
698*437bfbebSnyanmisaka }
699*437bfbebSnyanmisaka
700*437bfbebSnyanmisaka session = (MppDevSession *)mpp_mem_pool_get_f(srv->session_pool);
701*437bfbebSnyanmisaka
702*437bfbebSnyanmisaka INIT_LIST_HEAD(&session->list_server);
703*437bfbebSnyanmisaka INIT_LIST_HEAD(&session->list_wait);
704*437bfbebSnyanmisaka INIT_LIST_HEAD(&session->list_done);
705*437bfbebSnyanmisaka
706*437bfbebSnyanmisaka session->ctx = ctx;
707*437bfbebSnyanmisaka session->server = server;
708*437bfbebSnyanmisaka session->client = ctx->client;
709*437bfbebSnyanmisaka mpp_mutex_cond_init(&session->cond_lock);
710*437bfbebSnyanmisaka session->task_wait = 0;
711*437bfbebSnyanmisaka session->task_done = 0;
712*437bfbebSnyanmisaka
713*437bfbebSnyanmisaka for (i = 0; i < MPP_ARRAY_ELEMS(session->tasks); i++) {
714*437bfbebSnyanmisaka MppDevTask *task = &session->tasks[i];
715*437bfbebSnyanmisaka
716*437bfbebSnyanmisaka INIT_LIST_HEAD(&task->link_server);
717*437bfbebSnyanmisaka INIT_LIST_HEAD(&task->link_session);
718*437bfbebSnyanmisaka INIT_LIST_HEAD(&task->link_batch);
719*437bfbebSnyanmisaka task->session = session;
720*437bfbebSnyanmisaka task->batch = NULL;
721*437bfbebSnyanmisaka task->task_id = -1;
722*437bfbebSnyanmisaka task->slot_idx = i;
723*437bfbebSnyanmisaka
724*437bfbebSnyanmisaka list_add_tail(&task->link_session, &session->list_done);
725*437bfbebSnyanmisaka }
726*437bfbebSnyanmisaka
727*437bfbebSnyanmisaka list_add_tail(&session->list_server, &server->session_list);
728*437bfbebSnyanmisaka ctx->serv_ctx = session;
729*437bfbebSnyanmisaka
730*437bfbebSnyanmisaka if (srv->enable) {
731*437bfbebSnyanmisaka ctx->batch_io = 1;
732*437bfbebSnyanmisaka ctx->server = server->server_fd;
733*437bfbebSnyanmisaka } else {
734*437bfbebSnyanmisaka ctx->batch_io = 0;
735*437bfbebSnyanmisaka ctx->server = ctx->client;
736*437bfbebSnyanmisaka }
737*437bfbebSnyanmisaka
738*437bfbebSnyanmisaka server->batch_max_count++;
739*437bfbebSnyanmisaka server->session_count++;
740*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
741*437bfbebSnyanmisaka
742*437bfbebSnyanmisaka return rk_ok;
743*437bfbebSnyanmisaka }
744*437bfbebSnyanmisaka
server_detach(MppDevServer * srv,MppDevMppService * ctx)745*437bfbebSnyanmisaka static rk_s32 server_detach(MppDevServer *srv, MppDevMppService *ctx)
746*437bfbebSnyanmisaka {
747*437bfbebSnyanmisaka MppClientType client_type = (MppClientType)ctx->client_type;
748*437bfbebSnyanmisaka MppDevBatServ *server = bat_server_get(srv, client_type);
749*437bfbebSnyanmisaka MppDevSession *session = (MppDevSession *)ctx->serv_ctx;
750*437bfbebSnyanmisaka
751*437bfbebSnyanmisaka mpp_assert(server);
752*437bfbebSnyanmisaka
753*437bfbebSnyanmisaka mpp_mutex_lock(&srv->lock);
754*437bfbebSnyanmisaka if (!ctx->serv_ctx) {
755*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
756*437bfbebSnyanmisaka return rk_ok;
757*437bfbebSnyanmisaka }
758*437bfbebSnyanmisaka
759*437bfbebSnyanmisaka ctx->server = ctx->client;
760*437bfbebSnyanmisaka ctx->serv_ctx = NULL;
761*437bfbebSnyanmisaka ctx->batch_io = 0;
762*437bfbebSnyanmisaka
763*437bfbebSnyanmisaka mpp_assert(server);
764*437bfbebSnyanmisaka mpp_assert(session);
765*437bfbebSnyanmisaka mpp_assert(session->client == ctx->client);
766*437bfbebSnyanmisaka mpp_assert(session->task_wait == session->task_done);
767*437bfbebSnyanmisaka mpp_assert(list_empty(&session->list_wait));
768*437bfbebSnyanmisaka
769*437bfbebSnyanmisaka list_del_init(&session->list_server);
770*437bfbebSnyanmisaka
771*437bfbebSnyanmisaka mpp_mutex_cond_destroy(&session->cond_lock);
772*437bfbebSnyanmisaka
773*437bfbebSnyanmisaka mpp_mem_pool_put_f(srv->session_pool, session);
774*437bfbebSnyanmisaka server->batch_max_count++;
775*437bfbebSnyanmisaka server->session_count++;
776*437bfbebSnyanmisaka
777*437bfbebSnyanmisaka mpp_mutex_unlock(&srv->lock);
778*437bfbebSnyanmisaka
779*437bfbebSnyanmisaka return rk_ok;
780*437bfbebSnyanmisaka }
781*437bfbebSnyanmisaka
server_clear(MppDevServer * srv)782*437bfbebSnyanmisaka static void server_clear(MppDevServer *srv)
783*437bfbebSnyanmisaka {
784*437bfbebSnyanmisaka if (srv) {
785*437bfbebSnyanmisaka if (srv->session_pool) {
786*437bfbebSnyanmisaka mpp_mem_pool_deinit_f(srv->session_pool);
787*437bfbebSnyanmisaka srv->session_pool = NULL;
788*437bfbebSnyanmisaka }
789*437bfbebSnyanmisaka
790*437bfbebSnyanmisaka if (srv->batch_pool) {
791*437bfbebSnyanmisaka mpp_mem_pool_deinit_f(srv->batch_pool);
792*437bfbebSnyanmisaka srv->batch_pool = NULL;
793*437bfbebSnyanmisaka }
794*437bfbebSnyanmisaka
795*437bfbebSnyanmisaka srv->inited = 0;
796*437bfbebSnyanmisaka srv->enable = 0;
797*437bfbebSnyanmisaka
798*437bfbebSnyanmisaka mpp_free(srv);
799*437bfbebSnyanmisaka }
800*437bfbebSnyanmisaka }
801*437bfbebSnyanmisaka
mpp_server_init()802*437bfbebSnyanmisaka static void mpp_server_init()
803*437bfbebSnyanmisaka {
804*437bfbebSnyanmisaka MppDevServer *srv = srv_server;
805*437bfbebSnyanmisaka rk_s32 batch_task_size = 0;
806*437bfbebSnyanmisaka
807*437bfbebSnyanmisaka if (srv)
808*437bfbebSnyanmisaka return;
809*437bfbebSnyanmisaka
810*437bfbebSnyanmisaka srv = mpp_calloc(MppDevServer, 1);
811*437bfbebSnyanmisaka if (!srv) {
812*437bfbebSnyanmisaka mpp_err_f("failed to allocate mpp_server service\n");
813*437bfbebSnyanmisaka return;
814*437bfbebSnyanmisaka }
815*437bfbebSnyanmisaka
816*437bfbebSnyanmisaka srv_server = srv;
817*437bfbebSnyanmisaka
818*437bfbebSnyanmisaka srv->server_error = NULL;
819*437bfbebSnyanmisaka srv->server_name = NULL;
820*437bfbebSnyanmisaka srv->inited = 0;
821*437bfbebSnyanmisaka srv->enable = 1;
822*437bfbebSnyanmisaka srv->session_pool = NULL;
823*437bfbebSnyanmisaka srv->batch_pool = NULL;
824*437bfbebSnyanmisaka srv->max_task_in_batch = 0;
825*437bfbebSnyanmisaka srv->cmd_cap = NULL;
826*437bfbebSnyanmisaka
827*437bfbebSnyanmisaka mpp_env_get_u32("mpp_server_debug", &mpp_server_debug, 0);
828*437bfbebSnyanmisaka mpp_env_get_u32("mpp_server_enable", &srv->enable, 1);
829*437bfbebSnyanmisaka mpp_env_get_u32("mpp_server_batch_task", (rk_u32 *)&srv->max_task_in_batch,
830*437bfbebSnyanmisaka MAX_BATCH_TASK);
831*437bfbebSnyanmisaka
832*437bfbebSnyanmisaka mpp_assert(srv->max_task_in_batch >= 1 && srv->max_task_in_batch <= 32);
833*437bfbebSnyanmisaka batch_task_size = sizeof(MppDevBatTask) + srv->max_task_in_batch *
834*437bfbebSnyanmisaka (sizeof(MppReqV1) * (MAX_REQ_SEND_CNT + MAX_REQ_WAIT_CNT) +
835*437bfbebSnyanmisaka sizeof(MppDevBatCmd));
836*437bfbebSnyanmisaka
837*437bfbebSnyanmisaka srv->cmd_cap = mpp_get_mpp_service_cmd_cap();
838*437bfbebSnyanmisaka if (rk_ok != mpp_service_check_cmd_valid(MPP_CMD_SET_SESSION_FD, srv->cmd_cap)) {
839*437bfbebSnyanmisaka srv->server_error = "mpp_service cmd not support";
840*437bfbebSnyanmisaka return;
841*437bfbebSnyanmisaka }
842*437bfbebSnyanmisaka
843*437bfbebSnyanmisaka mpp_mutex_init(&srv->lock);
844*437bfbebSnyanmisaka memset(srv->bat_server, 0, sizeof(srv->bat_server));
845*437bfbebSnyanmisaka
846*437bfbebSnyanmisaka do {
847*437bfbebSnyanmisaka srv->server_name = mpp_get_mpp_service_name();
848*437bfbebSnyanmisaka if (!srv->server_name) {
849*437bfbebSnyanmisaka srv->server_error = "get service device failed";
850*437bfbebSnyanmisaka break;
851*437bfbebSnyanmisaka }
852*437bfbebSnyanmisaka
853*437bfbebSnyanmisaka srv->session_pool = mpp_mem_pool_init_f("server_session", sizeof(MppDevSession));
854*437bfbebSnyanmisaka if (!srv->session_pool) {
855*437bfbebSnyanmisaka srv->server_error = "create session pool failed";
856*437bfbebSnyanmisaka break;
857*437bfbebSnyanmisaka }
858*437bfbebSnyanmisaka
859*437bfbebSnyanmisaka srv->batch_pool = mpp_mem_pool_init_f("server_batch", batch_task_size);
860*437bfbebSnyanmisaka if (!srv->batch_pool) {
861*437bfbebSnyanmisaka srv->server_error = "create batch tack pool failed";
862*437bfbebSnyanmisaka break;
863*437bfbebSnyanmisaka }
864*437bfbebSnyanmisaka
865*437bfbebSnyanmisaka srv->inited = 1;
866*437bfbebSnyanmisaka } while (0);
867*437bfbebSnyanmisaka
868*437bfbebSnyanmisaka if (!srv->inited) {
869*437bfbebSnyanmisaka server_clear(srv);
870*437bfbebSnyanmisaka srv_server = NULL;
871*437bfbebSnyanmisaka }
872*437bfbebSnyanmisaka }
873*437bfbebSnyanmisaka
mpp_server_deinit()874*437bfbebSnyanmisaka static void mpp_server_deinit()
875*437bfbebSnyanmisaka {
876*437bfbebSnyanmisaka MppDevServer *srv = srv_server;
877*437bfbebSnyanmisaka
878*437bfbebSnyanmisaka srv_server = NULL;
879*437bfbebSnyanmisaka
880*437bfbebSnyanmisaka if (srv) {
881*437bfbebSnyanmisaka rk_s32 i;
882*437bfbebSnyanmisaka
883*437bfbebSnyanmisaka for (i = 0; i < VPU_CLIENT_BUTT; i++)
884*437bfbebSnyanmisaka bat_server_put(srv, (MppClientType)i);
885*437bfbebSnyanmisaka
886*437bfbebSnyanmisaka mpp_mutex_destroy(&srv->lock);
887*437bfbebSnyanmisaka server_clear(srv);
888*437bfbebSnyanmisaka }
889*437bfbebSnyanmisaka }
890*437bfbebSnyanmisaka
mpp_server_attach(MppDev ctx)891*437bfbebSnyanmisaka rk_s32 mpp_server_attach(MppDev ctx)
892*437bfbebSnyanmisaka {
893*437bfbebSnyanmisaka MppDevServer *srv = get_srv_server();
894*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
895*437bfbebSnyanmisaka
896*437bfbebSnyanmisaka if (srv && ctx) {
897*437bfbebSnyanmisaka MppDevMppService *dev = (MppDevMppService *)ctx;
898*437bfbebSnyanmisaka
899*437bfbebSnyanmisaka ret = server_attach(srv, dev);
900*437bfbebSnyanmisaka }
901*437bfbebSnyanmisaka
902*437bfbebSnyanmisaka return ret;
903*437bfbebSnyanmisaka }
904*437bfbebSnyanmisaka
mpp_server_detach(MppDev ctx)905*437bfbebSnyanmisaka rk_s32 mpp_server_detach(MppDev ctx)
906*437bfbebSnyanmisaka {
907*437bfbebSnyanmisaka MppDevServer *srv = get_srv_server();
908*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
909*437bfbebSnyanmisaka
910*437bfbebSnyanmisaka if (srv && ctx) {
911*437bfbebSnyanmisaka MppDevMppService *dev = (MppDevMppService *)ctx;
912*437bfbebSnyanmisaka
913*437bfbebSnyanmisaka ret = server_detach(srv, dev);
914*437bfbebSnyanmisaka }
915*437bfbebSnyanmisaka
916*437bfbebSnyanmisaka return ret;
917*437bfbebSnyanmisaka }
918*437bfbebSnyanmisaka
mpp_server_send_task(MppDev ctx)919*437bfbebSnyanmisaka rk_s32 mpp_server_send_task(MppDev ctx)
920*437bfbebSnyanmisaka {
921*437bfbebSnyanmisaka MppDevServer *srv = get_srv_server();
922*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
923*437bfbebSnyanmisaka
924*437bfbebSnyanmisaka if (srv && ctx)
925*437bfbebSnyanmisaka ret = send_task((MppDevMppService *)ctx);
926*437bfbebSnyanmisaka
927*437bfbebSnyanmisaka return ret;
928*437bfbebSnyanmisaka }
929*437bfbebSnyanmisaka
mpp_server_wait_task(MppDev ctx,rk_s64 timeout)930*437bfbebSnyanmisaka rk_s32 mpp_server_wait_task(MppDev ctx, rk_s64 timeout)
931*437bfbebSnyanmisaka {
932*437bfbebSnyanmisaka MppDevServer *srv = get_srv_server();
933*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
934*437bfbebSnyanmisaka
935*437bfbebSnyanmisaka if (srv && ctx)
936*437bfbebSnyanmisaka ret = wait_task((MppDevMppService *)ctx, timeout);
937*437bfbebSnyanmisaka
938*437bfbebSnyanmisaka return ret;
939*437bfbebSnyanmisaka }
940*437bfbebSnyanmisaka
941*437bfbebSnyanmisaka MPP_SINGLETON(MPP_SGLN_SERVER, mpp_server, mpp_server_init, mpp_server_deinit)
942