688 lines
20 KiB
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);
|
|
}
|