unplugged-kernel/drivers/gpu/drm/mediatek/mtk_drm_ddp_addon.c

688 lines
20 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include "mtk_drm_ddp_addon.h"
#include "mtk_drm_drv.h"
#include "mtk_rect.h"
#include "mtk_dump.h"
#include "mtk_drm_ddp_comp.h"
#include "mtk_drm_crtc.h"
static const int disp_rsz_path[] = {
DDP_COMPONENT_RSZ0,
};
static const int disp_rsz_path_v2[] = {
DDP_COMPONENT_OVL0_2L_VIRTUAL0,
DDP_COMPONENT_RSZ0,
};
static const int disp_rsz_path_v3[] = {
DDP_COMPONENT_OVL1_2L_VIRTUAL0,
DDP_COMPONENT_RSZ1,
};
static const int dmdp_pq_with_rdma_path[] = {
DDP_COMPONENT_DMDP_RDMA0, DDP_COMPONENT_DMDP_HDR0,
DDP_COMPONENT_DMDP_AAL0, DDP_COMPONENT_DMDP_RSZ0,
DDP_COMPONENT_DMDP_TDSHP0,
};
static const int disp_wdma0_path[] = {
DDP_COMPONENT_WDMA0,
};
static const int disp_wdma1_path[] = {
DDP_COMPONENT_WDMA1,
};
static const struct mtk_addon_path_data addon_module_path[ADDON_MODULE_NUM] = {
[DISP_RSZ] = {
.path = disp_rsz_path,
.path_len = ARRAY_SIZE(disp_rsz_path),
},
[DISP_RSZ_v2] = {
.path = disp_rsz_path_v2,
.path_len = ARRAY_SIZE(disp_rsz_path_v2),
},
[DISP_RSZ_v3] = {
.path = disp_rsz_path_v3,
.path_len = ARRAY_SIZE(disp_rsz_path_v3),
},
[DMDP_PQ_WITH_RDMA] = {
.path = dmdp_pq_with_rdma_path,
.path_len = ARRAY_SIZE(dmdp_pq_with_rdma_path),
},
[DISP_WDMA0] = {
.path = disp_wdma0_path,
.path_len = ARRAY_SIZE(disp_wdma0_path),
},
[DISP_WDMA1] = {
.path = disp_wdma1_path,
.path_len = ARRAY_SIZE(disp_wdma1_path),
},
};
const struct mtk_addon_path_data *
mtk_addon_module_get_path(enum addon_module module)
{
return &addon_module_path[module];
}
const struct mtk_addon_scenario_data *
mtk_addon_get_scenario_data(const char *source, struct drm_crtc *crtc,
enum addon_scenario scn)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
if (scn < NONE || scn >= ADDON_SCN_NR)
goto err;
if (mtk_crtc->path_data && mtk_crtc->path_data->addon_data)
return &mtk_crtc->path_data->addon_data[scn];
err:
DDPPR_ERR("[%s] crtc%d cannot get addon data scn[%u]\n", source,
drm_crtc_index(crtc), scn);
return NULL;
}
const struct mtk_addon_scenario_data *
mtk_addon_get_scenario_data_dual(const char *source, struct drm_crtc *crtc,
enum addon_scenario scn)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
if ((scn < NONE) || (scn > TRIPLE_DISP)) {
DDPPR_ERR("[%s] crtc%d scn is wrong\n", source,
drm_crtc_index(crtc));
return NULL;
}
if (mtk_crtc->path_data && mtk_crtc->path_data->addon_data_dual)
return &mtk_crtc->path_data->addon_data_dual[scn];
DDPPR_ERR("[%s] crtc%d cannot get addon data\n", source,
drm_crtc_index(crtc));
return NULL;
}
bool mtk_addon_scenario_support(struct drm_crtc *crtc, enum addon_scenario scn)
{
const struct mtk_addon_scenario_data *data =
mtk_addon_get_scenario_data(__func__, crtc, scn);
if (data && (data->module_num > 0 || scn == NONE))
return true;
return false;
}
static void mtk_addon_path_start(struct drm_crtc *crtc,
const struct mtk_addon_path_data *path_data,
struct cmdq_pkt *cmdq_handle)
{
int i;
struct mtk_ddp_comp *add_comp = NULL;
struct mtk_drm_private *priv = crtc->dev->dev_private;
for (i = 0; i < path_data->path_len; i++) {
if (mtk_ddp_comp_get_type(path_data->path[i])
== MTK_DISP_VIRTUAL)
continue;
add_comp = priv->ddp_comp[path_data->path[i]];
mtk_ddp_comp_start(add_comp, cmdq_handle);
}
}
static void mtk_addon_path_stop(struct drm_crtc *crtc,
const struct mtk_addon_path_data *path_data,
struct cmdq_pkt *cmdq_handle)
{
int i;
struct mtk_ddp_comp *add_comp = NULL;
struct mtk_drm_private *priv = crtc->dev->dev_private;
for (i = 0; i < path_data->path_len; i++) {
if (mtk_ddp_comp_get_type(path_data->path[i])
== MTK_DISP_VIRTUAL)
continue;
add_comp = priv->ddp_comp[path_data->path[i]];
mtk_ddp_comp_stop(add_comp, cmdq_handle);
}
}
static void
mtk_addon_path_connect_and_add_mutex(struct drm_crtc *crtc,
unsigned int ddp_mode,
const struct mtk_addon_module_data *module,
struct cmdq_pkt *cmdq_handle)
{
int i;
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
int mutex_id =
mtk_crtc_get_mutex_id(crtc, ddp_mode, module->attach_comp);
const struct mtk_addon_path_data *path_data =
mtk_addon_module_get_path(module->module);
if (mutex_id < 0) {
DDPPR_ERR("invalid mutex id:%d\n", mutex_id);
return;
}
for (i = 0; i < path_data->path_len - 1; i++) {
mtk_ddp_add_comp_to_path_with_cmdq(mtk_crtc, path_data->path[i],
path_data->path[i + 1],
cmdq_handle);
mtk_disp_mutex_add_comp_with_cmdq(
mtk_crtc, path_data->path[i],
mtk_crtc_is_frame_trigger_mode(crtc), cmdq_handle,
mutex_id);
}
mtk_disp_mutex_add_comp_with_cmdq(
mtk_crtc, path_data->path[path_data->path_len - 1],
mtk_crtc_is_frame_trigger_mode(crtc), cmdq_handle, mutex_id);
}
static void mtk_addon_path_disconnect_and_remove_mutex(
struct drm_crtc *crtc, unsigned int ddp_mode,
const struct mtk_addon_module_data *module,
struct cmdq_pkt *cmdq_handle)
{
int i;
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
int mutex_id =
mtk_crtc_get_mutex_id(crtc, ddp_mode, module->attach_comp);
const struct mtk_addon_path_data *path_data =
mtk_addon_module_get_path(module->module);
if (mutex_id < 0) {
DDPPR_ERR("invalid mutex id:%d\n", mutex_id);
return;
}
for (i = 0; i < path_data->path_len - 1; i++) {
mtk_ddp_remove_comp_from_path_with_cmdq(
mtk_crtc, path_data->path[i], path_data->path[i + 1],
cmdq_handle);
mtk_disp_mutex_remove_comp_with_cmdq(
mtk_crtc, path_data->path[i], cmdq_handle, mutex_id);
}
mtk_disp_mutex_remove_comp_with_cmdq(
mtk_crtc, path_data->path[path_data->path_len - 1], cmdq_handle,
mutex_id);
}
void mtk_addon_connect_between(struct drm_crtc *crtc, unsigned int ddp_mode,
const struct mtk_addon_module_data *module_data,
union mtk_addon_config *addon_config,
struct cmdq_pkt *cmdq_handle)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private;
struct mtk_ddp_comp *comp = NULL;
enum mtk_ddp_comp_id attach_comp_id, next_attach_comp_id, prev_comp_id,
cur_comp_id, next_comp_id;
const struct mtk_addon_path_data *path_data =
mtk_addon_module_get_path(module_data->module);
int i, j;
unsigned int addon_idx;
attach_comp_id =
mtk_crtc_find_comp(crtc, ddp_mode, module_data->attach_comp);
if (module_data->attach_comp < 0) {
DDPPR_ERR("Invalid attach_comp value\n");
return;
}
if (attach_comp_id == -1) {
comp = priv->ddp_comp[module_data->attach_comp];
DDPPR_ERR("Attach module:%s is not in path mode %d\n",
mtk_dump_comp_str(comp), ddp_mode);
return;
}
next_attach_comp_id = mtk_crtc_find_next_comp(crtc, ddp_mode,
module_data->attach_comp);
if (module_data->attach_comp < 0) {
DDPPR_ERR("Invalid attach_comp value\n");
return;
}
if (next_attach_comp_id == -1) {
comp = priv->ddp_comp[module_data->attach_comp];
DDPPR_ERR("Attach module:%s has not a next comp in path mode\n",
mtk_dump_comp_str(comp));
return;
}
/* 1. remove original path*/
mtk_crtc_disconnect_path_between_component(
crtc, ddp_mode, attach_comp_id, next_attach_comp_id,
cmdq_handle);
/* 2. connect subpath and add mutex*/
mtk_addon_path_connect_and_add_mutex(crtc, ddp_mode, module_data,
cmdq_handle);
/* 3. add subpath to main path */
mtk_ddp_add_comp_to_path_with_cmdq(mtk_crtc, attach_comp_id,
path_data->path[0], cmdq_handle);
mtk_ddp_add_comp_to_path_with_cmdq(
mtk_crtc, path_data->path[path_data->path_len - 1],
next_attach_comp_id, cmdq_handle);
/* 4. config module */
/* config attach comp */
comp = priv->ddp_comp[attach_comp_id];
prev_comp_id = mtk_crtc_find_prev_comp(crtc, ddp_mode, attach_comp_id);
cur_comp_id = comp->id;
next_comp_id = path_data->path[0];
for (i = 0; i < path_data->path_len; i++)
if (mtk_ddp_comp_get_type(path_data->path[i]) !=
MTK_DISP_VIRTUAL) {
next_comp_id = path_data->path[i];
break;
}
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
/* config subpath comp without last comp*/
addon_idx = i;
for (i = addon_idx; i < path_data->path_len; i++) {
if (mtk_ddp_comp_get_type(path_data->path[i]) ==
MTK_DISP_VIRTUAL)
continue;
addon_idx = i;
comp = priv->ddp_comp[path_data->path[i]];
prev_comp_id = cur_comp_id;
cur_comp_id = comp->id;
comp->mtk_crtc = mtk_crtc;
for (j = i + 1; j < path_data->path_len; j++)
if (mtk_ddp_comp_get_type(path_data->path[j]) !=
MTK_DISP_VIRTUAL) {
next_comp_id = path_data->path[j];
mtk_ddp_comp_addon_config(
comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
break;
}
}
/* config subpath last comp */
comp = priv->ddp_comp[path_data->path[addon_idx]];
prev_comp_id = cur_comp_id;
cur_comp_id = comp->id;
next_comp_id = next_attach_comp_id;
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
/* config next attach comp */
comp = priv->ddp_comp[next_attach_comp_id];
prev_comp_id = cur_comp_id;
cur_comp_id = comp->id;
next_comp_id =
mtk_crtc_find_next_comp(crtc, ddp_mode, next_attach_comp_id);
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
/* 5. start addon module */
mtk_addon_path_start(crtc, path_data, cmdq_handle);
}
void mtk_addon_disconnect_between(
struct drm_crtc *crtc, unsigned int ddp_mode,
const struct mtk_addon_module_data *module_data,
union mtk_addon_config *addon_config, struct cmdq_pkt *cmdq_handle)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private;
struct mtk_ddp_comp *comp = NULL;
enum mtk_ddp_comp_id attach_comp_id, next_attach_comp_id, prev_comp_id,
next_comp_id;
const struct mtk_addon_path_data *path_data =
mtk_addon_module_get_path(module_data->module);
attach_comp_id =
mtk_crtc_find_comp(crtc, ddp_mode, module_data->attach_comp);
if (module_data->attach_comp < 0) {
DDPPR_ERR("Invalid attach_comp value\n");
return;
}
if (attach_comp_id == -1) {
comp = priv->ddp_comp[module_data->attach_comp];
DDPPR_ERR("Attach module:%s is not in path mode %d\n",
mtk_dump_comp_str(comp), ddp_mode);
return;
}
next_attach_comp_id = mtk_crtc_find_next_comp(crtc, ddp_mode,
module_data->attach_comp);
if (module_data->attach_comp < 0) {
DDPPR_ERR("Invalid attach_comp value\n");
return;
}
if (next_attach_comp_id == -1) {
comp = priv->ddp_comp[module_data->attach_comp];
DDPPR_ERR(
"Attach module:%s has not a next comp in path mode %d\n",
mtk_dump_comp_str(comp), ddp_mode);
return;
}
/* 1. stop addon module*/
mtk_addon_path_stop(crtc, path_data, cmdq_handle);
/* 2. remove subpath from main path */
mtk_ddp_remove_comp_from_path_with_cmdq(
mtk_crtc, attach_comp_id, path_data->path[0], cmdq_handle);
mtk_ddp_remove_comp_from_path_with_cmdq(
mtk_crtc, path_data->path[path_data->path_len - 1],
next_attach_comp_id, cmdq_handle);
/* 3. disconnect subpath and remove mutex */
mtk_addon_path_disconnect_and_remove_mutex(crtc, ddp_mode, module_data,
cmdq_handle);
/* 4. connect original path*/
mtk_crtc_connect_path_between_component(crtc, ddp_mode, attach_comp_id,
next_attach_comp_id,
cmdq_handle);
/* 5. config module*/
/* config attach comp */
comp = priv->ddp_comp[attach_comp_id];
prev_comp_id = mtk_crtc_find_prev_comp(crtc, ddp_mode, attach_comp_id);
next_comp_id = next_attach_comp_id;
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
comp = priv->ddp_comp[next_attach_comp_id];
prev_comp_id = attach_comp_id;
next_comp_id =
mtk_crtc_find_next_comp(crtc, ddp_mode, next_attach_comp_id);
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
}
void mtk_addon_connect_before(struct drm_crtc *crtc, unsigned int ddp_mode,
const struct mtk_addon_module_data *module_data,
union mtk_addon_config *addon_config,
struct cmdq_pkt *cmdq_handle)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private;
struct mtk_ddp_comp *comp = NULL;
enum mtk_ddp_comp_id next_attach_comp_id, prev_comp_id, cur_comp_id,
next_comp_id;
const struct mtk_addon_path_data *path_data =
mtk_addon_module_get_path(module_data->module);
int i, j;
unsigned int addon_idx;
next_attach_comp_id =
mtk_crtc_find_comp(crtc, ddp_mode, module_data->attach_comp);
if (module_data->attach_comp < 0) {
DDPPR_ERR("Invalid attach_comp value\n");
return;
}
if (next_attach_comp_id == -1) {
comp = priv->ddp_comp[module_data->attach_comp];
DDPPR_ERR("Attach module:%s is not in path mode %d\n",
mtk_dump_comp_str(comp), ddp_mode);
return;
}
/* 1. connect subpath and add mutex*/
mtk_addon_path_connect_and_add_mutex(crtc, ddp_mode, module_data,
cmdq_handle);
/* 2. add subpath to main path */
mtk_ddp_add_comp_to_path_with_cmdq(
mtk_crtc, path_data->path[path_data->path_len - 1],
next_attach_comp_id, cmdq_handle);
/* 3. config module */
/* config subpath comp without last comp*/
addon_idx = 0;
cur_comp_id = -1;
for (i = 0; i < path_data->path_len; i++) {
if (mtk_ddp_comp_get_type(path_data->path[i]) ==
MTK_DISP_VIRTUAL)
continue;
addon_idx = i;
comp = priv->ddp_comp[path_data->path[i]];
prev_comp_id = cur_comp_id;
cur_comp_id = comp->id;
for (j = i + 1; j < path_data->path_len; j++)
if (mtk_ddp_comp_get_type(path_data->path[j]) !=
MTK_DISP_VIRTUAL) {
next_comp_id = path_data->path[j];
mtk_ddp_comp_addon_config(
comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
break;
}
}
/* config subpath last comp */
comp = priv->ddp_comp[path_data->path[addon_idx]];
prev_comp_id = cur_comp_id;
cur_comp_id = comp->id;
next_comp_id = next_attach_comp_id;
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
/* config attach comp */
comp = priv->ddp_comp[next_attach_comp_id];
prev_comp_id = cur_comp_id;
cur_comp_id = comp->id;
next_comp_id =
mtk_crtc_find_next_comp(crtc, ddp_mode, next_attach_comp_id);
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
/* 4. start addon module */
mtk_addon_path_start(crtc, path_data, cmdq_handle);
}
void mtk_addon_disconnect_before(
struct drm_crtc *crtc, unsigned int ddp_mode,
const struct mtk_addon_module_data *module_data,
union mtk_addon_config *addon_config, struct cmdq_pkt *cmdq_handle)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private;
struct mtk_ddp_comp *comp = NULL;
enum mtk_ddp_comp_id prev_comp_id, next_comp_id, next_attach_comp_id;
const struct mtk_addon_path_data *path_data =
mtk_addon_module_get_path(module_data->module);
next_attach_comp_id =
mtk_crtc_find_comp(crtc, ddp_mode, module_data->attach_comp);
if (module_data->attach_comp < 0) {
DDPPR_ERR("Invalid attach_comp value\n");
return;
}
if (next_attach_comp_id == -1) {
comp = priv->ddp_comp[module_data->attach_comp];
DDPPR_ERR("Attach module:%s is not in path mode %d\n",
mtk_dump_comp_str(comp), ddp_mode);
return;
}
/* 1. stop addon module*/
mtk_addon_path_stop(crtc, path_data, cmdq_handle);
/* 2. remove subpath from main path */
mtk_ddp_remove_comp_from_path_with_cmdq(
mtk_crtc, path_data->path[path_data->path_len - 1],
next_attach_comp_id, cmdq_handle);
/* 3. disconnect subpath and remove mutex */
mtk_addon_path_disconnect_and_remove_mutex(crtc, ddp_mode, module_data,
cmdq_handle);
/* 4. config module */
/* config attach comp */
comp = priv->ddp_comp[next_attach_comp_id];
prev_comp_id =
mtk_crtc_find_prev_comp(crtc, ddp_mode, next_attach_comp_id);
next_comp_id =
mtk_crtc_find_next_comp(crtc, ddp_mode, next_attach_comp_id);
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
}
void mtk_addon_connect_after(struct drm_crtc *crtc, unsigned int ddp_mode,
const struct mtk_addon_module_data *module_data,
union mtk_addon_config *addon_config,
struct cmdq_pkt *cmdq_handle)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private;
struct mtk_ddp_comp *comp = NULL;
enum mtk_ddp_comp_id prev_attach_comp_id, prev_comp_id, cur_comp_id,
next_comp_id;
const struct mtk_addon_path_data *path_data =
mtk_addon_module_get_path(module_data->module);
int i, j;
unsigned int addon_idx;
prev_attach_comp_id =
mtk_crtc_find_comp(crtc, ddp_mode, module_data->attach_comp);
if (prev_attach_comp_id < 0) {
comp = priv->ddp_comp[module_data->attach_comp];
DDPMSG("[ERR]Attach module:%s is not in path mode %d\n",
mtk_dump_comp_str(comp), ddp_mode);
return;
}
/* 0. attach subpath to crtc*/
/* some comp need crtc info in addon_config or irq */
mtk_crtc_attach_addon_path_comp(crtc, module_data, true);
/* 1. connect subpath and add mutex*/
mtk_addon_path_connect_and_add_mutex(crtc, ddp_mode, module_data,
cmdq_handle);
/* 2. add subpath to main path */
mtk_ddp_add_comp_to_path_with_cmdq(
mtk_crtc, prev_attach_comp_id, path_data->path[0],
cmdq_handle);
/* 3. config module */
/* config attach comp */
comp = priv->ddp_comp[prev_attach_comp_id];
prev_comp_id = mtk_crtc_find_prev_comp(crtc, ddp_mode,
prev_attach_comp_id);
cur_comp_id = comp->id;
next_comp_id = -1;
for (i = 0; i < path_data->path_len; i++)
if (mtk_ddp_comp_get_type(path_data->path[i]) !=
MTK_DISP_VIRTUAL) {
next_comp_id = path_data->path[i];
break;
}
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
/* config subpath comp without last comp*/
addon_idx = i;
for (; i < path_data->path_len; i++) {
if (mtk_ddp_comp_get_type(path_data->path[i]) ==
MTK_DISP_VIRTUAL)
continue;
addon_idx = i;
comp = priv->ddp_comp[path_data->path[i]];
for (j = i + 1; j < path_data->path_len; j++)
if (mtk_ddp_comp_get_type(path_data->path[j]) !=
MTK_DISP_VIRTUAL) {
prev_comp_id = cur_comp_id;
cur_comp_id = comp->id;
next_comp_id = path_data->path[j];
mtk_ddp_comp_addon_config(
comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
break;
}
}
/* config subpath last comp */
comp = priv->ddp_comp[path_data->path[addon_idx]];
prev_comp_id = cur_comp_id;
cur_comp_id = comp->id;
next_comp_id = -1;
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
/* 4. start addon module */
mtk_addon_path_start(crtc, path_data, cmdq_handle);
}
void mtk_addon_disconnect_after(
struct drm_crtc *crtc, unsigned int ddp_mode,
const struct mtk_addon_module_data *module_data,
union mtk_addon_config *addon_config, struct cmdq_pkt *cmdq_handle)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private;
struct mtk_ddp_comp *comp = NULL;
enum mtk_ddp_comp_id prev_attach_comp_id, prev_comp_id, next_comp_id;
const struct mtk_addon_path_data *path_data =
mtk_addon_module_get_path(module_data->module);
prev_attach_comp_id =
mtk_crtc_find_comp(crtc, ddp_mode, module_data->attach_comp);
if (prev_attach_comp_id == -1) {
comp = priv->ddp_comp[(module_data->attach_comp > 0) ?
module_data->attach_comp : 0];
DDPMSG("[ERR]Attach module:%s is not in path mode %d\n",
mtk_dump_comp_str(comp), ddp_mode);
return;
}
/* 0. attach subpath to crtc*/
/* some comp need crtc info in stop*/
mtk_crtc_attach_addon_path_comp(crtc, module_data, true);
/* 1. stop addon module*/
mtk_addon_path_stop(crtc, path_data, cmdq_handle);
/* 2. remove subpath from main path */
mtk_ddp_remove_comp_from_path_with_cmdq(
mtk_crtc, prev_attach_comp_id, path_data->path[0],
cmdq_handle);
/* 3. disconnect subpath and remove mutex */
mtk_addon_path_disconnect_and_remove_mutex(crtc, ddp_mode, module_data,
cmdq_handle);
/* 4. config module */
/* config attach comp */
comp = priv->ddp_comp[prev_attach_comp_id];
prev_comp_id =
mtk_crtc_find_prev_comp(crtc, ddp_mode, prev_attach_comp_id);
next_comp_id =
mtk_crtc_find_next_comp(crtc, ddp_mode, prev_attach_comp_id);
mtk_ddp_comp_addon_config(comp, prev_comp_id, next_comp_id,
addon_config, cmdq_handle);
}