Commit 09e694f1 authored by Moudy Ho's avatar Moudy Ho Committed by Hans Verkuil

media: platform: mtk-mdp3: decompose hardware-related information in shared memory

The communication between the MDP3 kernel driver and SCP is to
pass a shared memory through the cooperation of "mtk-mdp3-vpu.c" and
remoteproc driver.
The data structure of this shared memory is defined in "mtk-img-ipi.h",
as shown below:

vpu->work_addr -> +-----------------------------------------+
                  |                                         |
                  | To SCP : Input frame parameters         |
                  |          (struct img_ipi_frameparam)    |
                  |                                         |
     vpu->pool -> +-----------------------------------------+
                  |                                         |
                  | From SCP : Output component config pool |
                  |            (struct img_config)          |
                  |                                         |
                  |           *struct img_config 1          |
                  |                    |                    |
                  |                    |                    |
                  |                    v                    |
                  |           *struct img_config N          |
                  |            (N = MDP_CONFIG_POOL_SIZE)   |
                  +-----------------------------------------+

One output component configuration contains the components
currently used by the pipeline, and has the register settings
that each component needs to set.

Since the quantity, type and function of components on each chip
will vary, the effect is that the size of the "struct img_config"
and its substructures will be different on each chip.
In addition, all chips will have to update their SCP firmware for
every change if the output component config structure is defined
and shared by a common header.

Therefore, all functions that operate on "struct img_config" and
its substructures must be separated by chips and so are the
relevant definations.
Signed-off-by: default avatarMoudy Ho <moudy.ho@mediatek.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent da1a8a4f
......@@ -4,6 +4,7 @@
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#include "mtk-img-ipi.h"
#include "mtk-mdp3-cfg.h"
#include "mtk-mdp3-core.h"
#include "mtk-mdp3-comp.h"
......@@ -408,6 +409,7 @@ static const struct mdp_pipe_info mt8183_pipe_info[] = {
};
const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
.mdp_plat_id = MT8183,
.mdp_probe_infra = mt8183_mdp_probe_infra,
.mdp_cfg = &mt8183_plat_cfg,
.mdp_mutex_table_idx = mt8183_mutex_idx,
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2023 MediaTek Inc.
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#ifndef __MDP_SM_MT8183_H__
#define __MDP_SM_MT8183_H__
#include "mtk-mdp3-type.h"
/*
* ISP-MDP generic output information
* MD5 of the target SCP blob:
* 6da52bdcf4bf76a0983b313e1d4745d6
*/
#define IMG_MAX_SUBFRAMES_8183 14
struct img_comp_frame_8183 {
u32 output_disable:1;
u32 bypass:1;
u16 in_width;
u16 in_height;
u16 out_width;
u16 out_height;
struct img_crop crop;
u16 in_total_width;
u16 out_total_width;
} __packed;
struct img_comp_subfrm_8183 {
u32 tile_disable:1;
struct img_region in;
struct img_region out;
struct img_offset luma;
struct img_offset chroma;
s16 out_vertical; /* Output vertical index */
s16 out_horizontal; /* Output horizontal index */
} __packed;
struct mdp_rdma_subfrm_8183 {
u32 offset[IMG_MAX_PLANES];
u32 offset_0_p;
u32 src;
u32 clip;
u32 clip_ofst;
} __packed;
struct mdp_rdma_data_8183 {
u32 src_ctrl;
u32 control;
u32 iova[IMG_MAX_PLANES];
u32 iova_end[IMG_MAX_PLANES];
u32 mf_bkgd;
u32 mf_bkgd_in_pxl;
u32 sf_bkgd;
u32 ufo_dec_y;
u32 ufo_dec_c;
u32 transform;
struct mdp_rdma_subfrm_8183 subfrms[IMG_MAX_SUBFRAMES_8183];
} __packed;
struct mdp_rsz_subfrm_8183 {
u32 control2;
u32 src;
u32 clip;
} __packed;
struct mdp_rsz_data_8183 {
u32 coeff_step_x;
u32 coeff_step_y;
u32 control1;
u32 control2;
struct mdp_rsz_subfrm_8183 subfrms[IMG_MAX_SUBFRAMES_8183];
} __packed;
struct mdp_wrot_subfrm_8183 {
u32 offset[IMG_MAX_PLANES];
u32 src;
u32 clip;
u32 clip_ofst;
u32 main_buf;
} __packed;
struct mdp_wrot_data_8183 {
u32 iova[IMG_MAX_PLANES];
u32 control;
u32 stride[IMG_MAX_PLANES];
u32 mat_ctrl;
u32 fifo_test;
u32 filter;
struct mdp_wrot_subfrm_8183 subfrms[IMG_MAX_SUBFRAMES_8183];
} __packed;
struct mdp_wdma_subfrm_8183 {
u32 offset[IMG_MAX_PLANES];
u32 src;
u32 clip;
u32 clip_ofst;
} __packed;
struct mdp_wdma_data_8183 {
u32 wdma_cfg;
u32 iova[IMG_MAX_PLANES];
u32 w_in_byte;
u32 uv_stride;
struct mdp_wdma_subfrm_8183 subfrms[IMG_MAX_SUBFRAMES_8183];
} __packed;
struct isp_data_8183 {
u64 dl_flags; /* 1 << (enum mdp_comp_type) */
u32 smxi_iova[4];
u32 cq_idx;
u32 cq_iova;
u32 tpipe_iova[IMG_MAX_SUBFRAMES_8183];
} __packed;
struct img_compparam_8183 {
u16 type; /* enum mdp_comp_id */
u16 id; /* engine alias_id */
u32 input;
u32 outputs[IMG_MAX_HW_OUTPUTS];
u32 num_outputs;
struct img_comp_frame_8183 frame;
struct img_comp_subfrm_8183 subfrms[IMG_MAX_SUBFRAMES_8183];
u32 num_subfrms;
union {
struct mdp_rdma_data_8183 rdma;
struct mdp_rsz_data_8183 rsz;
struct mdp_wrot_data_8183 wrot;
struct mdp_wdma_data_8183 wdma;
struct isp_data_8183 isp;
};
} __packed;
struct img_config_8183 {
struct img_compparam_8183 components[IMG_MAX_COMPONENTS];
u32 num_components;
struct img_mmsys_ctrl ctrls[IMG_MAX_SUBFRAMES_8183];
u32 num_subfrms;
} __packed;
#endif /* __MDP_SM_MT8183_H__ */
......@@ -8,13 +8,11 @@
#ifndef __MTK_IMG_IPI_H__
#define __MTK_IMG_IPI_H__
#include <linux/err.h>
#include "mdp_sm_mt8183.h"
#include "mtk-mdp3-type.h"
/*
* ISP-MDP generic input information
* MD5 of the target SCP blob:
* 6da52bdcf4bf76a0983b313e1d4745d6
*/
/* ISP-MDP generic input information */
#define IMG_IPI_INIT 1
#define IMG_IPI_DEINIT 2
......@@ -115,132 +113,37 @@ struct img_frameparam {
struct img_ipi_frameparam frameparam;
} __packed;
/* ISP-MDP generic output information */
/* Platform config indicator */
#define MT8183 8183
struct img_comp_frame {
u32 output_disable;
u32 bypass;
u32 in_width;
u32 in_height;
u32 out_width;
u32 out_height;
struct img_crop crop;
u32 in_total_width;
u32 out_total_width;
} __packed;
#define CFG_CHECK(plat, p_id) ((plat) == (p_id))
struct img_comp_subfrm {
u32 tile_disable;
struct img_region in;
struct img_region out;
struct img_offset luma;
struct img_offset chroma;
s32 out_vertical; /* Output vertical index */
s32 out_horizontal; /* Output horizontal index */
} __packed;
#define _CFG_OFST(plat, cfg, ofst) ((void *)(&((cfg)->config_##plat) + (ofst)))
#define CFG_OFST(plat, cfg, ofst) \
(IS_ERR_OR_NULL(cfg) ? NULL : _CFG_OFST(plat, cfg, ofst))
#define IMG_MAX_SUBFRAMES 14
#define _CFG_ADDR(plat, cfg, mem) (&((cfg)->config_##plat.mem))
#define CFG_ADDR(plat, cfg, mem) \
(IS_ERR_OR_NULL(cfg) ? NULL : _CFG_ADDR(plat, cfg, mem))
struct mdp_rdma_subfrm {
u32 offset[IMG_MAX_PLANES];
u32 offset_0_p;
u32 src;
u32 clip;
u32 clip_ofst;
} __packed;
#define _CFG_GET(plat, cfg, mem) ((cfg)->config_##plat.mem)
#define CFG_GET(plat, cfg, mem) \
(IS_ERR_OR_NULL(cfg) ? 0 : _CFG_GET(plat, cfg, mem))
struct mdp_rdma_data {
u32 src_ctrl;
u32 control;
u32 iova[IMG_MAX_PLANES];
u32 iova_end[IMG_MAX_PLANES];
u32 mf_bkgd;
u32 mf_bkgd_in_pxl;
u32 sf_bkgd;
u32 ufo_dec_y;
u32 ufo_dec_c;
u32 transform;
struct mdp_rdma_subfrm subfrms[IMG_MAX_SUBFRAMES];
} __packed;
#define _CFG_COMP(plat, comp, mem) ((comp)->comp_##plat.mem)
#define CFG_COMP(plat, comp, mem) \
(IS_ERR_OR_NULL(comp) ? 0 : _CFG_COMP(plat, comp, mem))
struct mdp_rsz_subfrm {
u32 control2;
u32 src;
u32 clip;
} __packed;
struct mdp_rsz_data {
u32 coeff_step_x;
u32 coeff_step_y;
u32 control1;
u32 control2;
struct mdp_rsz_subfrm subfrms[IMG_MAX_SUBFRAMES];
} __packed;
struct mdp_wrot_subfrm {
u32 offset[IMG_MAX_PLANES];
u32 src;
u32 clip;
u32 clip_ofst;
u32 main_buf;
} __packed;
struct mdp_wrot_data {
u32 iova[IMG_MAX_PLANES];
u32 control;
u32 stride[IMG_MAX_PLANES];
u32 mat_ctrl;
u32 fifo_test;
u32 filter;
struct mdp_wrot_subfrm subfrms[IMG_MAX_SUBFRAMES];
} __packed;
struct mdp_wdma_subfrm {
u32 offset[IMG_MAX_PLANES];
u32 src;
u32 clip;
u32 clip_ofst;
} __packed;
struct mdp_wdma_data {
u32 wdma_cfg;
u32 iova[IMG_MAX_PLANES];
u32 w_in_byte;
u32 uv_stride;
struct mdp_wdma_subfrm subfrms[IMG_MAX_SUBFRAMES];
} __packed;
struct isp_data {
u64 dl_flags; /* 1 << (enum mdp_comp_type) */
u32 smxi_iova[4];
u32 cq_idx;
u32 cq_iova;
u32 tpipe_iova[IMG_MAX_SUBFRAMES];
struct img_config {
union {
struct img_config_8183 config_8183;
};
} __packed;
struct img_compparam {
u32 type; /* enum mdp_comp_id */
u32 id; /* engine alias_id */
u32 input;
u32 outputs[IMG_MAX_HW_OUTPUTS];
u32 num_outputs;
struct img_comp_frame frame;
struct img_comp_subfrm subfrms[IMG_MAX_SUBFRAMES];
u32 num_subfrms;
union {
struct mdp_rdma_data rdma;
struct mdp_rsz_data rsz;
struct mdp_wrot_data wrot;
struct mdp_wdma_data wdma;
struct isp_data isp;
struct img_compparam_8183 comp_8183;
};
} __packed;
struct img_config {
struct img_compparam components[IMG_MAX_COMPONENTS];
u32 num_components;
struct img_mmsys_ctrl ctrls[IMG_MAX_SUBFRAMES];
u32 num_subfrms;
} __packed;
#endif /* __MTK_IMG_IPI_H__ */
......@@ -10,6 +10,7 @@
#include "mtk-mdp3-comp.h"
#include "mtk-mdp3-core.h"
#include "mtk-mdp3-m2m.h"
#include "mtk-img-ipi.h"
#define MDP_PATH_MAX_COMPS IMG_MAX_COMPONENTS
......@@ -28,24 +29,35 @@ struct mdp_path {
#define call_op(ctx, op, ...) \
(has_op(ctx, op) ? (ctx)->comp->ops->op(ctx, ##__VA_ARGS__) : 0)
static bool is_output_disabled(const struct img_compparam *param, u32 count)
static bool is_output_disabled(int p_id, const struct img_compparam *param, u32 count)
{
return (count < param->num_subfrms) ?
(param->frame.output_disable ||
param->subfrms[count].tile_disable) :
true;
u32 num = 0;
bool dis_output = false;
bool dis_tile = false;
if (CFG_CHECK(MT8183, p_id)) {
num = CFG_COMP(MT8183, param, num_subfrms);
dis_output = CFG_COMP(MT8183, param, frame.output_disable);
dis_tile = CFG_COMP(MT8183, param, frame.output_disable);
}
return (count < num) ? (dis_output || dis_tile) : true;
}
static int mdp_path_subfrm_require(const struct mdp_path *path,
struct mdp_cmdq_cmd *cmd,
s32 *mutex_id, u32 count)
{
const struct img_config *config = path->config;
const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
const struct mdp_comp_ctx *ctx;
const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data;
struct device *dev = &path->mdp_dev->pdev->dev;
struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
int id, index;
u32 num_comp = 0;
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
/* Decide which mutex to use based on the current pipeline */
switch (path->comps[0].comp->public_id) {
......@@ -68,9 +80,9 @@ static int mdp_path_subfrm_require(const struct mdp_path *path,
*mutex_id = data->pipe_info[index].mutex_id;
/* Set mutex mod */
for (index = 0; index < config->num_components; index++) {
for (index = 0; index < num_comp; index++) {
ctx = &path->comps[index];
if (is_output_disabled(ctx->param, count))
if (is_output_disabled(p_id, ctx->param, count))
continue;
id = ctx->comp->public_id;
mtk_mutex_write_mod(mutex[*mutex_id],
......@@ -87,11 +99,12 @@ static int mdp_path_subfrm_run(const struct mdp_path *path,
struct mdp_cmdq_cmd *cmd,
s32 *mutex_id, u32 count)
{
const struct img_config *config = path->config;
const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
const struct mdp_comp_ctx *ctx;
struct device *dev = &path->mdp_dev->pdev->dev;
struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
int index;
u32 num_comp = 0;
s32 event;
if (-1 == *mutex_id) {
......@@ -99,11 +112,14 @@ static int mdp_path_subfrm_run(const struct mdp_path *path,
return -EINVAL;
}
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
/* Wait WROT SRAM shared to DISP RDMA */
/* Clear SOF event for each engine */
for (index = 0; index < config->num_components; index++) {
for (index = 0; index < num_comp; index++) {
ctx = &path->comps[index];
if (is_output_disabled(ctx->param, count))
if (is_output_disabled(p_id, ctx->param, count))
continue;
event = ctx->comp->gce_event[MDP_GCE_EVENT_SOF];
if (event != MDP_GCE_NO_EVENT)
......@@ -114,9 +130,9 @@ static int mdp_path_subfrm_run(const struct mdp_path *path,
mtk_mutex_enable_by_cmdq(mutex[*mutex_id], (void *)&cmd->pkt);
/* Wait SOF events and clear mutex modules (optional) */
for (index = 0; index < config->num_components; index++) {
for (index = 0; index < num_comp; index++) {
ctx = &path->comps[index];
if (is_output_disabled(ctx->param, count))
if (is_output_disabled(p_id, ctx->param, count))
continue;
event = ctx->comp->gce_event[MDP_GCE_EVENT_SOF];
if (event != MDP_GCE_NO_EVENT)
......@@ -128,16 +144,22 @@ static int mdp_path_subfrm_run(const struct mdp_path *path,
static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path)
{
const struct img_config *config = path->config;
const int p_id = mdp->mdp_data->mdp_plat_id;
void *param = NULL;
int index, ret;
u32 num_comp = 0;
if (config->num_components < 1)
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
if (num_comp < 1)
return -EINVAL;
for (index = 0; index < config->num_components; index++) {
for (index = 0; index < num_comp; index++) {
if (CFG_CHECK(MT8183, p_id))
param = (void *)CFG_ADDR(MT8183, path->config, components[index]);
ret = mdp_comp_ctx_config(mdp, &path->comps[index],
&config->components[index],
path->param);
param, path->param);
if (ret)
return ret;
}
......@@ -148,12 +170,19 @@ static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path)
static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
struct mdp_path *path, u32 count)
{
const struct img_config *config = path->config;
const struct img_mmsys_ctrl *ctrl = &config->ctrls[count];
const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
const struct img_mmsys_ctrl *ctrl = NULL;
const struct img_mux *set;
struct mdp_comp_ctx *ctx;
s32 mutex_id;
int index, ret;
u32 num_comp = 0;
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
if (CFG_CHECK(MT8183, p_id))
ctrl = CFG_ADDR(MT8183, path->config, ctrls[count]);
/* Acquire components */
ret = mdp_path_subfrm_require(path, cmd, &mutex_id, count);
......@@ -166,9 +195,9 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
set->value, 0xFFFFFFFF);
}
/* Config sub-frame information */
for (index = (config->num_components - 1); index >= 0; index--) {
for (index = (num_comp - 1); index >= 0; index--) {
ctx = &path->comps[index];
if (is_output_disabled(ctx->param, count))
if (is_output_disabled(p_id, ctx->param, count))
continue;
ret = call_op(ctx, config_subfrm, cmd, count);
if (ret)
......@@ -179,16 +208,16 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
if (ret)
return ret;
/* Wait components done */
for (index = 0; index < config->num_components; index++) {
for (index = 0; index < num_comp; index++) {
ctx = &path->comps[index];
if (is_output_disabled(ctx->param, count))
if (is_output_disabled(p_id, ctx->param, count))
continue;
ret = call_op(ctx, wait_comp_event, cmd);
if (ret)
return ret;
}
/* Advance to the next sub-frame */
for (index = 0; index < config->num_components; index++) {
for (index = 0; index < num_comp; index++) {
ctx = &path->comps[index];
ret = call_op(ctx, advance_subfrm, cmd, count);
if (ret)
......@@ -207,23 +236,35 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
struct mdp_path *path)
{
const struct img_config *config = path->config;
const int p_id = mdp->mdp_data->mdp_plat_id;
struct mdp_comp_ctx *ctx;
int index, count, ret;
u32 num_comp = 0;
u32 num_sub = 0;
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
if (CFG_CHECK(MT8183, p_id))
num_sub = CFG_GET(MT8183, path->config, num_subfrms);
/* Config path frame */
/* Reset components */
for (index = 0; index < config->num_components; index++) {
for (index = 0; index < num_comp; index++) {
ctx = &path->comps[index];
ret = call_op(ctx, init_comp, cmd);
if (ret)
return ret;
}
/* Config frame mode */
for (index = 0; index < config->num_components; index++) {
const struct v4l2_rect *compose =
path->composes[ctx->param->outputs[0]];
for (index = 0; index < num_comp; index++) {
const struct v4l2_rect *compose;
u32 out = 0;
if (CFG_CHECK(MT8183, p_id))
out = CFG_COMP(MT8183, ctx->param, outputs[0]);
compose = path->composes[out];
ctx = &path->comps[index];
ret = call_op(ctx, config_frame, cmd, compose);
if (ret)
......@@ -231,13 +272,13 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
}
/* Config path sub-frames */
for (count = 0; count < config->num_subfrms; count++) {
for (count = 0; count < num_sub; count++) {
ret = mdp_path_config_subfrm(cmd, path, count);
if (ret)
return ret;
}
/* Post processing information */
for (index = 0; index < config->num_components; index++) {
for (index = 0; index < num_comp; index++) {
ctx = &path->comps[index];
ret = call_op(ctx, post_process, cmd);
if (ret)
......@@ -361,7 +402,9 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
struct mdp_cmdq_cmd *cmd = NULL;
struct mdp_comp *comps = NULL;
struct device *dev = &mdp->pdev->dev;
const int p_id = mdp->mdp_data->mdp_plat_id;
int i, ret;
u32 num_comp = 0;
atomic_inc(&mdp->job_count);
if (atomic_read(&mdp->suspended)) {
......@@ -379,8 +422,13 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
if (ret)
goto err_free_cmd;
comps = kcalloc(param->config->num_components, sizeof(*comps),
GFP_KERNEL);
if (CFG_CHECK(MT8183, p_id)) {
num_comp = CFG_GET(MT8183, param->config, num_components);
} else {
ret = -EINVAL;
goto err_destroy_pkt;
}
comps = kcalloc(num_comp, sizeof(*comps), GFP_KERNEL);
if (!comps) {
ret = -ENOMEM;
goto err_destroy_pkt;
......@@ -412,7 +460,6 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
path->composes[i] = param->composes[i] ?
param->composes[i] : &path->bounds[i];
}
ret = mdp_path_ctx_init(mdp, path);
if (ret) {
dev_err(dev, "mdp_path_ctx_init error\n");
......@@ -426,7 +473,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
}
cmdq_pkt_finalize(&cmd->pkt);
for (i = 0; i < param->config->num_components; i++)
for (i = 0; i < num_comp; i++)
memcpy(&comps[i], path->comps[i].comp,
sizeof(struct mdp_comp));
......@@ -435,7 +482,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
cmd->user_cmdq_cb = param->cmdq_cb;
cmd->user_cb_data = param->cb_data;
cmd->comps = comps;
cmd->num_comps = param->config->num_components;
cmd->num_comps = num_comp;
cmd->mdp_ctx = param->mdp_ctx;
ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps);
......
......@@ -51,6 +51,7 @@ enum mdp_pipe_id {
};
struct mtk_mdp_driver_data {
const int mdp_plat_id;
const struct of_device_id *mdp_probe_infra;
const struct mdp_platform_config *mdp_cfg;
const u32 *mdp_mutex_table_idx;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment