@@ -21,6 +21,13 @@ static const struct of_device_id mt8183_mdp_probe_infra[MDP_INFRA_MAX] = {
[MDP_INFRA_SCP] = { .compatible = "mediatek,mt8183-scp" }
};
+static const struct mdp_pipe_info mt8183_pipe_info[] = {
+ {MDP_PIPE_IMGI, 0},
+ {MDP_PIPE_RDMA0, 1},
+ {MDP_PIPE_WPEI, 2},
+ {MDP_PIPE_WPEI2, 3}
+};
+
static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = {
[MDP_COMP_RDMA0] = MUTEX_MOD_IDX_MDP_RDMA0,
[MDP_COMP_RSZ0] = MUTEX_MOD_IDX_MDP_RSZ0,
@@ -36,6 +36,18 @@ static bool is_output_disabled(const struct img_compparam *param, u32 count)
true;
}
+static int mdp_get_pipe_idx(const struct mtk_mdp_driver_data *data,
+ enum mdp_pipe_id pipe_id)
+{
+ int i;
+
+ for (i = 0; i < data->pipe_info_len; i++)
+ if (pipe_id == data->pipe_info[i].pipe_id)
+ return i;
+
+ return -ENODEV;
+}
+
static int mdp_path_subfrm_require(const struct mdp_path *path,
struct mdp_cmdq_cmd *cmd,
s32 *mutex_id, u32 count)
@@ -50,16 +62,20 @@ static int mdp_path_subfrm_require(const struct mdp_path *path,
/* Decide which mutex to use based on the current pipeline */
switch (path->comps[0].comp->public_id) {
case MDP_COMP_RDMA0:
- *mutex_id = MDP_PIPE_RDMA0;
+ index = mdp_get_pipe_idx(data, MDP_PIPE_RDMA0);
+ *mutex_id = data->pipe_info[index].mutex_id;
break;
case MDP_COMP_ISP_IMGI:
- *mutex_id = MDP_PIPE_IMGI;
+ index = mdp_get_pipe_idx(data, MDP_PIPE_IMGI);
+ *mutex_id = data->pipe_info[index].mutex_id;
break;
case MDP_COMP_WPEI:
- *mutex_id = MDP_PIPE_WPEI;
+ index = mdp_get_pipe_idx(data, MDP_PIPE_WPEI);
+ *mutex_id = data->pipe_info[index].mutex_id;
break;
case MDP_COMP_WPEI2:
- *mutex_id = MDP_PIPE_WPEI2;
+ index = mdp_get_pipe_idx(data, MDP_PIPE_WPEI2);
+ *mutex_id = data->pipe_info[index].mutex_id;
break;
default:
dev_err(dev, "Unknown pipeline and no mutex is assigned");
@@ -286,11 +302,13 @@ static void mdp_auto_release_work(struct work_struct *work)
{
struct mdp_cmdq_cmd *cmd;
struct mdp_dev *mdp;
+ int idx;
cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work);
mdp = cmd->mdp;
- mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+ idx = mdp_get_pipe_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+ mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[idx].mutex_id]);
mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
cmd->num_comps);
@@ -310,6 +328,7 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
struct cmdq_cb_data *data;
struct mdp_dev *mdp;
struct device *dev;
+ int idx;
if (!mssg) {
pr_info("%s:no callback data\n", __func__);
@@ -335,7 +354,8 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
INIT_WORK(&cmd->auto_release_work, mdp_auto_release_work);
if (!queue_work(mdp->clock_wq, &cmd->auto_release_work)) {
dev_err(dev, "%s:queue_work fail!\n", __func__);
- mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+ idx = mdp_get_pipe_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+ mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[idx].mutex_id]);
mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
cmd->num_comps);
@@ -387,7 +407,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
goto err_free_comps;
}
- ret = mtk_mutex_prepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+ i = mdp_get_pipe_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+ ret = mtk_mutex_prepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
if (ret) {
dev_err(dev, "Fail to enable mutex clk\n");
goto err_free_path;
@@ -453,7 +474,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
cmd->num_comps);
err_free_path:
- mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+ i = mdp_get_pipe_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+ mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
kfree(path);
err_free_comps:
kfree(comps);
@@ -24,6 +24,8 @@ static const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
.mdp_mutex_table_idx = mt8183_mutex_idx,
.comp_data = mt8183_mdp_comp_data,
.comp_data_len = ARRAY_SIZE(mt8183_mdp_comp_data),
+ .pipe_info = mt8183_pipe_info,
+ .pipe_info_len = ARRAY_SIZE(mt8183_pipe_info),
.format = mt8183_formats,
.format_len = ARRAY_SIZE(mt8183_formats),
.def_limit = &mt8183_mdp_def_limit,
@@ -165,7 +167,7 @@ static int mdp_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct mdp_dev *mdp;
struct platform_device *mm_pdev;
- int ret, i;
+ int ret, i, mutex_id;
mdp = kzalloc(sizeof(*mdp), GFP_KERNEL);
if (!mdp) {
@@ -188,9 +190,12 @@ static int mdp_probe(struct platform_device *pdev)
ret = -ENODEV;
goto err_destroy_device;
}
- for (i = 0; i < MDP_PIPE_MAX; i++) {
- mdp->mdp_mutex[i] = mtk_mutex_get(&mm_pdev->dev);
- if (!mdp->mdp_mutex[i]) {
+ for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) {
+ mutex_id = mdp->mdp_data->pipe_info[i].mutex_id;
+ if (mdp->mdp_mutex[mutex_id])
+ continue;
+ mdp->mdp_mutex[mutex_id] = mtk_mutex_get(&mm_pdev->dev);
+ if (!mdp->mdp_mutex[mutex_id]) {
ret = -ENODEV;
goto err_free_mutex;
}
@@ -271,7 +276,7 @@ static int mdp_probe(struct platform_device *pdev)
err_deinit_comp:
mdp_comp_destroy(mdp);
err_free_mutex:
- for (i = 0; i < MDP_PIPE_MAX; i++)
+ for (i = 0; i < mdp->mdp_data->pipe_info_len; i++)
mtk_mutex_put(mdp->mdp_mutex[i]);
err_destroy_device:
kfree(mdp);
@@ -57,6 +57,8 @@ struct mtk_mdp_driver_data {
const u32 *mdp_mutex_table_idx;
const struct mdp_comp_data *comp_data;
unsigned int comp_data_len;
+ const struct mdp_pipe_info *pipe_info;
+ unsigned int pipe_info_len;
const struct mdp_format *format;
unsigned int format_len;
const struct mdp_limit *def_limit;
@@ -91,6 +93,11 @@ struct mdp_dev {
atomic_t job_count;
};
+struct mdp_pipe_info {
+ enum mdp_pipe_id pipe_id;
+ u32 mutex_id;
+};
+
int mdp_vpu_get_locked(struct mdp_dev *mdp);
void mdp_vpu_put_locked(struct mdp_dev *mdp);
int mdp_vpu_register(struct mdp_dev *mdp);
In MDP3, a pipe is used to represent a data path which consisting of different components and MUTEX, as shown in the following diagram: +----------------------------+ | MUTEX [*1] | +----------------------------+ S ^ S ^ S ^ S ^ S ^ | | | | | | | | | | | | | | | | | | | | +--------------+ | | | | | | | | +-------------+ | +--------------+ | | | | | | +-------------+ | | | +------+ | | | | +------+ | | | | | +------+ | | +------+ | | | | | | | | | | | | | | | | | | | | | | | v E v E v E v E v E +-------+ +-----+ +-------+ +-----+ +-------+ B>--->| RDMA0 |>-->| PQ |>-->| RSZ0 |>-->| PQ |>-->| WROT0 |>-->B +-------+ +-----+ +-------+ +-----+ +-------+ [*1] MUTEX is SOF/EOF signal controller [*2] S = Start of frame (SOF) [*3] E = End of frame (EOF) [*4] B = frame buffer More pipes will be introduced in future chip for applications such as higher frame rate frequency, which should move the relevant information into the chip configuration header file. Signed-off-by: Moudy Ho <moudy.ho@mediatek.com> --- .../media/platform/mediatek/mdp3/mt8183_mdp.h | 7 ++++ .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 38 +++++++++++++++---- .../platform/mediatek/mdp3/mtk-mdp3-core.c | 15 +++++--- .../platform/mediatek/mdp3/mtk-mdp3-core.h | 7 ++++ 4 files changed, 54 insertions(+), 13 deletions(-)