GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / media / platform / mediatek / mdp3 / mtk-mdp3-cmdq.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022 MediaTek Inc.
4  * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
5  */
6
7 #include <linux/mailbox_controller.h>
8 #include <linux/platform_device.h>
9 #include "mtk-mdp3-cmdq.h"
10 #include "mtk-mdp3-comp.h"
11 #include "mtk-mdp3-core.h"
12 #include "mtk-mdp3-m2m.h"
13 #include "mtk-img-ipi.h"
14
15 #define MDP_PATH_MAX_COMPS      IMG_MAX_COMPONENTS
16
17 struct mdp_path {
18         struct mdp_dev          *mdp_dev;
19         struct mdp_comp_ctx     comps[MDP_PATH_MAX_COMPS];
20         u32                     num_comps;
21         const struct img_config *config;
22         const struct img_ipi_frameparam *param;
23         const struct v4l2_rect  *composes[IMG_MAX_HW_OUTPUTS];
24         struct v4l2_rect        bounds[IMG_MAX_HW_OUTPUTS];
25 };
26
27 #define has_op(ctx, op) \
28         ((ctx)->comp->ops && (ctx)->comp->ops->op)
29  #define call_op(ctx, op, ...) \
30         (has_op(ctx, op) ? (ctx)->comp->ops->op(ctx, ##__VA_ARGS__) : 0)
31
32 static bool is_output_disabled(int p_id, const struct img_compparam *param, u32 count)
33 {
34         u32 num = 0;
35         bool dis_output = false;
36         bool dis_tile = false;
37
38         if (CFG_CHECK(MT8183, p_id)) {
39                 num = CFG_COMP(MT8183, param, num_subfrms);
40                 dis_output = CFG_COMP(MT8183, param, frame.output_disable);
41                 dis_tile = CFG_COMP(MT8183, param, frame.output_disable);
42         }
43
44         return (count < num) ? (dis_output || dis_tile) : true;
45 }
46
47 static int mdp_path_subfrm_require(const struct mdp_path *path,
48                                    struct mdp_cmdq_cmd *cmd,
49                                    s32 *mutex_id, u32 count)
50 {
51         const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
52         const struct mdp_comp_ctx *ctx;
53         const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data;
54         struct device *dev = &path->mdp_dev->pdev->dev;
55         struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
56         int id, index;
57         u32 num_comp = 0;
58
59         if (CFG_CHECK(MT8183, p_id))
60                 num_comp = CFG_GET(MT8183, path->config, num_components);
61
62         /* Decide which mutex to use based on the current pipeline */
63         switch (path->comps[0].comp->public_id) {
64         case MDP_COMP_RDMA0:
65                 index = MDP_PIPE_RDMA0;
66                 break;
67         case MDP_COMP_ISP_IMGI:
68                 index = MDP_PIPE_IMGI;
69                 break;
70         case MDP_COMP_WPEI:
71                 index = MDP_PIPE_WPEI;
72                 break;
73         case MDP_COMP_WPEI2:
74                 index = MDP_PIPE_WPEI2;
75                 break;
76         default:
77                 dev_err(dev, "Unknown pipeline and no mutex is assigned");
78                 return -EINVAL;
79         }
80         *mutex_id = data->pipe_info[index].mutex_id;
81
82         /* Set mutex mod */
83         for (index = 0; index < num_comp; index++) {
84                 ctx = &path->comps[index];
85                 if (is_output_disabled(p_id, ctx->param, count))
86                         continue;
87                 id = ctx->comp->public_id;
88                 mtk_mutex_write_mod(mutex[*mutex_id],
89                                     data->mdp_mutex_table_idx[id], false);
90         }
91
92         mtk_mutex_write_sof(mutex[*mutex_id],
93                             MUTEX_SOF_IDX_SINGLE_MODE);
94
95         return 0;
96 }
97
98 static int mdp_path_subfrm_run(const struct mdp_path *path,
99                                struct mdp_cmdq_cmd *cmd,
100                                s32 *mutex_id, u32 count)
101 {
102         const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
103         const struct mdp_comp_ctx *ctx;
104         struct device *dev = &path->mdp_dev->pdev->dev;
105         struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
106         int index;
107         u32 num_comp = 0;
108         s32 event;
109
110         if (-1 == *mutex_id) {
111                 dev_err(dev, "Incorrect mutex id");
112                 return -EINVAL;
113         }
114
115         if (CFG_CHECK(MT8183, p_id))
116                 num_comp = CFG_GET(MT8183, path->config, num_components);
117
118         /* Wait WROT SRAM shared to DISP RDMA */
119         /* Clear SOF event for each engine */
120         for (index = 0; index < num_comp; index++) {
121                 ctx = &path->comps[index];
122                 if (is_output_disabled(p_id, ctx->param, count))
123                         continue;
124                 event = ctx->comp->gce_event[MDP_GCE_EVENT_SOF];
125                 if (event != MDP_GCE_NO_EVENT)
126                         MM_REG_CLEAR(cmd, event);
127         }
128
129         /* Enable the mutex */
130         mtk_mutex_enable_by_cmdq(mutex[*mutex_id], (void *)&cmd->pkt);
131
132         /* Wait SOF events and clear mutex modules (optional) */
133         for (index = 0; index < num_comp; index++) {
134                 ctx = &path->comps[index];
135                 if (is_output_disabled(p_id, ctx->param, count))
136                         continue;
137                 event = ctx->comp->gce_event[MDP_GCE_EVENT_SOF];
138                 if (event != MDP_GCE_NO_EVENT)
139                         MM_REG_WAIT(cmd, event);
140         }
141
142         return 0;
143 }
144
145 static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path)
146 {
147         const int p_id = mdp->mdp_data->mdp_plat_id;
148         void *param = NULL;
149         int index, ret;
150         u32 num_comp = 0;
151
152         if (CFG_CHECK(MT8183, p_id))
153                 num_comp = CFG_GET(MT8183, path->config, num_components);
154
155         if (num_comp < 1)
156                 return -EINVAL;
157
158         for (index = 0; index < num_comp; index++) {
159                 if (CFG_CHECK(MT8183, p_id))
160                         param = (void *)CFG_ADDR(MT8183, path->config, components[index]);
161                 ret = mdp_comp_ctx_config(mdp, &path->comps[index],
162                                           param, path->param);
163                 if (ret)
164                         return ret;
165         }
166
167         return 0;
168 }
169
170 static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
171                                   struct mdp_path *path, u32 count)
172 {
173         const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
174         const struct img_mmsys_ctrl *ctrl = NULL;
175         const struct img_mux *set;
176         struct mdp_comp_ctx *ctx;
177         s32 mutex_id;
178         int index, ret;
179         u32 num_comp = 0;
180
181         if (CFG_CHECK(MT8183, p_id))
182                 num_comp = CFG_GET(MT8183, path->config, num_components);
183
184         if (CFG_CHECK(MT8183, p_id))
185                 ctrl = CFG_ADDR(MT8183, path->config, ctrls[count]);
186
187         /* Acquire components */
188         ret = mdp_path_subfrm_require(path, cmd, &mutex_id, count);
189         if (ret)
190                 return ret;
191         /* Enable mux settings */
192         for (index = 0; index < ctrl->num_sets; index++) {
193                 set = &ctrl->sets[index];
194                 cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
195                                     set->value, 0xFFFFFFFF);
196         }
197         /* Config sub-frame information */
198         for (index = (num_comp - 1); index >= 0; index--) {
199                 ctx = &path->comps[index];
200                 if (is_output_disabled(p_id, ctx->param, count))
201                         continue;
202                 ret = call_op(ctx, config_subfrm, cmd, count);
203                 if (ret)
204                         return ret;
205         }
206         /* Run components */
207         ret = mdp_path_subfrm_run(path, cmd, &mutex_id, count);
208         if (ret)
209                 return ret;
210         /* Wait components done */
211         for (index = 0; index < num_comp; index++) {
212                 ctx = &path->comps[index];
213                 if (is_output_disabled(p_id, ctx->param, count))
214                         continue;
215                 ret = call_op(ctx, wait_comp_event, cmd);
216                 if (ret)
217                         return ret;
218         }
219         /* Advance to the next sub-frame */
220         for (index = 0; index < num_comp; index++) {
221                 ctx = &path->comps[index];
222                 ret = call_op(ctx, advance_subfrm, cmd, count);
223                 if (ret)
224                         return ret;
225         }
226         /* Disable mux settings */
227         for (index = 0; index < ctrl->num_sets; index++) {
228                 set = &ctrl->sets[index];
229                 cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
230                                     0, 0xFFFFFFFF);
231         }
232
233         return 0;
234 }
235
236 static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
237                            struct mdp_path *path)
238 {
239         const int p_id = mdp->mdp_data->mdp_plat_id;
240         struct mdp_comp_ctx *ctx;
241         int index, count, ret;
242         u32 num_comp = 0;
243         u32 num_sub = 0;
244
245         if (CFG_CHECK(MT8183, p_id))
246                 num_comp = CFG_GET(MT8183, path->config, num_components);
247
248         if (CFG_CHECK(MT8183, p_id))
249                 num_sub = CFG_GET(MT8183, path->config, num_subfrms);
250
251         /* Config path frame */
252         /* Reset components */
253         for (index = 0; index < num_comp; index++) {
254                 ctx = &path->comps[index];
255                 ret = call_op(ctx, init_comp, cmd);
256                 if (ret)
257                         return ret;
258         }
259         /* Config frame mode */
260         for (index = 0; index < num_comp; index++) {
261                 const struct v4l2_rect *compose;
262                 u32 out = 0;
263
264                 ctx = &path->comps[index];
265                 if (CFG_CHECK(MT8183, p_id))
266                         out = CFG_COMP(MT8183, ctx->param, outputs[0]);
267
268                 compose = path->composes[out];
269                 ret = call_op(ctx, config_frame, cmd, compose);
270                 if (ret)
271                         return ret;
272         }
273
274         /* Config path sub-frames */
275         for (count = 0; count < num_sub; count++) {
276                 ret = mdp_path_config_subfrm(cmd, path, count);
277                 if (ret)
278                         return ret;
279         }
280         /* Post processing information */
281         for (index = 0; index < num_comp; index++) {
282                 ctx = &path->comps[index];
283                 ret = call_op(ctx, post_process, cmd);
284                 if (ret)
285                         return ret;
286         }
287         return 0;
288 }
289
290 static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
291                                size_t size)
292 {
293         struct device *dev;
294         dma_addr_t dma_addr;
295
296         pkt->va_base = kzalloc(size, GFP_KERNEL);
297         if (!pkt->va_base)
298                 return -ENOMEM;
299
300         pkt->buf_size = size;
301         pkt->cl = (void *)client;
302
303         dev = client->chan->mbox->dev;
304         dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
305                                   DMA_TO_DEVICE);
306         if (dma_mapping_error(dev, dma_addr)) {
307                 dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
308                 kfree(pkt->va_base);
309                 return -ENOMEM;
310         }
311
312         pkt->pa_base = dma_addr;
313
314         return 0;
315 }
316
317 static void mdp_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
318 {
319         struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
320
321         dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
322                          DMA_TO_DEVICE);
323         kfree(pkt->va_base);
324         pkt->va_base = NULL;
325 }
326
327 static void mdp_auto_release_work(struct work_struct *work)
328 {
329         struct mdp_cmdq_cmd *cmd;
330         struct mdp_dev *mdp;
331         int id;
332
333         cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work);
334         mdp = cmd->mdp;
335
336         id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id;
337         mtk_mutex_unprepare(mdp->mdp_mutex[id]);
338         mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
339                             cmd->num_comps);
340
341         atomic_dec(&mdp->job_count);
342         wake_up(&mdp->callback_wq);
343
344         mdp_cmdq_pkt_destroy(&cmd->pkt);
345         kfree(cmd->comps);
346         cmd->comps = NULL;
347         kfree(cmd);
348         cmd = NULL;
349 }
350
351 static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
352 {
353         struct mdp_cmdq_cmd *cmd;
354         struct cmdq_cb_data *data;
355         struct mdp_dev *mdp;
356         struct device *dev;
357         int id;
358
359         if (!mssg) {
360                 pr_info("%s:no callback data\n", __func__);
361                 return;
362         }
363
364         data = (struct cmdq_cb_data *)mssg;
365         cmd = container_of(data->pkt, struct mdp_cmdq_cmd, pkt);
366         mdp = cmd->mdp;
367         dev = &mdp->pdev->dev;
368
369         if (cmd->mdp_ctx)
370                 mdp_m2m_job_finish(cmd->mdp_ctx);
371
372         if (cmd->user_cmdq_cb) {
373                 struct cmdq_cb_data user_cb_data;
374
375                 user_cb_data.sta = data->sta;
376                 user_cb_data.pkt = data->pkt;
377                 cmd->user_cmdq_cb(user_cb_data);
378         }
379
380         INIT_WORK(&cmd->auto_release_work, mdp_auto_release_work);
381         if (!queue_work(mdp->clock_wq, &cmd->auto_release_work)) {
382                 dev_err(dev, "%s:queue_work fail!\n", __func__);
383                 id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id;
384                 mtk_mutex_unprepare(mdp->mdp_mutex[id]);
385                 mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
386                                     cmd->num_comps);
387
388                 atomic_dec(&mdp->job_count);
389                 wake_up(&mdp->callback_wq);
390
391                 mdp_cmdq_pkt_destroy(&cmd->pkt);
392                 kfree(cmd->comps);
393                 cmd->comps = NULL;
394                 kfree(cmd);
395                 cmd = NULL;
396         }
397 }
398
399 int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
400 {
401         struct mdp_path *path = NULL;
402         struct mdp_cmdq_cmd *cmd = NULL;
403         struct mdp_comp *comps = NULL;
404         struct device *dev = &mdp->pdev->dev;
405         const int p_id = mdp->mdp_data->mdp_plat_id;
406         int i, ret;
407         u32 num_comp = 0;
408
409         atomic_inc(&mdp->job_count);
410         if (atomic_read(&mdp->suspended)) {
411                 atomic_dec(&mdp->job_count);
412                 return -ECANCELED;
413         }
414
415         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
416         if (!cmd) {
417                 ret = -ENOMEM;
418                 goto err_cancel_job;
419         }
420
421         ret = mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K);
422         if (ret)
423                 goto err_free_cmd;
424
425         if (CFG_CHECK(MT8183, p_id)) {
426                 num_comp = CFG_GET(MT8183, param->config, num_components);
427         } else {
428                 ret = -EINVAL;
429                 goto err_destroy_pkt;
430         }
431         comps = kcalloc(num_comp, sizeof(*comps), GFP_KERNEL);
432         if (!comps) {
433                 ret = -ENOMEM;
434                 goto err_destroy_pkt;
435         }
436
437         path = kzalloc(sizeof(*path), GFP_KERNEL);
438         if (!path) {
439                 ret = -ENOMEM;
440                 goto err_free_comps;
441         }
442
443         i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id;
444         ret = mtk_mutex_prepare(mdp->mdp_mutex[i]);
445         if (ret) {
446                 dev_err(dev, "Fail to enable mutex clk\n");
447                 goto err_free_path;
448         }
449
450         path->mdp_dev = mdp;
451         path->config = param->config;
452         path->param = param->param;
453         for (i = 0; i < param->param->num_outputs; i++) {
454                 path->bounds[i].left = 0;
455                 path->bounds[i].top = 0;
456                 path->bounds[i].width =
457                         param->param->outputs[i].buffer.format.width;
458                 path->bounds[i].height =
459                         param->param->outputs[i].buffer.format.height;
460                 path->composes[i] = param->composes[i] ?
461                         param->composes[i] : &path->bounds[i];
462         }
463         ret = mdp_path_ctx_init(mdp, path);
464         if (ret) {
465                 dev_err(dev, "mdp_path_ctx_init error\n");
466                 goto err_free_path;
467         }
468
469         ret = mdp_path_config(mdp, cmd, path);
470         if (ret) {
471                 dev_err(dev, "mdp_path_config error\n");
472                 goto err_free_path;
473         }
474         cmdq_pkt_finalize(&cmd->pkt);
475
476         for (i = 0; i < num_comp; i++)
477                 memcpy(&comps[i], path->comps[i].comp,
478                        sizeof(struct mdp_comp));
479
480         mdp->cmdq_clt->client.rx_callback = mdp_handle_cmdq_callback;
481         cmd->mdp = mdp;
482         cmd->user_cmdq_cb = param->cmdq_cb;
483         cmd->user_cb_data = param->cb_data;
484         cmd->comps = comps;
485         cmd->num_comps = num_comp;
486         cmd->mdp_ctx = param->mdp_ctx;
487
488         ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps);
489         if (ret)
490                 goto err_free_path;
491
492         dma_sync_single_for_device(mdp->cmdq_clt->chan->mbox->dev,
493                                    cmd->pkt.pa_base, cmd->pkt.cmd_buf_size,
494                                    DMA_TO_DEVICE);
495         ret = mbox_send_message(mdp->cmdq_clt->chan, &cmd->pkt);
496         if (ret < 0) {
497                 dev_err(dev, "mbox send message fail %d!\n", ret);
498                 goto err_clock_off;
499         }
500         mbox_client_txdone(mdp->cmdq_clt->chan, 0);
501
502         kfree(path);
503         return 0;
504
505 err_clock_off:
506         mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
507                             cmd->num_comps);
508 err_free_path:
509         i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id;
510         mtk_mutex_unprepare(mdp->mdp_mutex[i]);
511         kfree(path);
512 err_free_comps:
513         kfree(comps);
514 err_destroy_pkt:
515         mdp_cmdq_pkt_destroy(&cmd->pkt);
516 err_free_cmd:
517         kfree(cmd);
518 err_cancel_job:
519         atomic_dec(&mdp->job_count);
520
521         return ret;
522 }
523 EXPORT_SYMBOL_GPL(mdp_cmdq_send);