kernel_samsung_a34x-permissive/drivers/gpu/drm/mediatek/mtk_drm_helper.c

202 lines
6 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/of_graph.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_of.h>
#include <linux/device.h>
#include "mtk_drm_helper.h"
#include "mtk_log.h"
static struct mtk_drm_helper help_info[] = {
{MTK_DRM_OPT_STAGE, 0, "MTK_DRM_OPT_STAGE"}, /* must enable */
{MTK_DRM_OPT_USE_CMDQ, 0, "MTK_DRM_OPT_USE_CMDQ"}, /* must enable */
{MTK_DRM_OPT_USE_M4U, 0, "MTK_DRM_OPT_USE_M4U"}, /* must enable */
/* low power option start */
{MTK_DRM_OPT_SODI_SUPPORT, 0, "MTK_DRM_OPT_SODI_SUPPORT"},
{MTK_DRM_OPT_IDLE_MGR, 0, "MTK_DRM_OPT_IDLE_MGR"},
{MTK_DRM_OPT_IDLEMGR_SWTCH_DECOUPLE, 0,
"MTK_DRM_OPT_IDLEMGR_SWTCH_DECOUPLE"},
{MTK_DRM_OPT_IDLEMGR_BY_REPAINT, 0, "MTK_DRM_OPT_IDLEMGR_BY_REPAINT"},
{MTK_DRM_OPT_IDLEMGR_ENTER_ULPS, 0, "MTK_DRM_OPT_IDLEMGR_ENTER_ULPS"},
{MTK_DRM_OPT_IDLEMGR_KEEP_LP11, 0, "MTK_DRM_OPT_IDLEMGR_KEEP_LP11"},
{MTK_DRM_OPT_DYNAMIC_RDMA_GOLDEN_SETTING, 0,
"MTK_DRM_OPT_DYNAMIC_RDMA_GOLDEN_SETTING"},
{MTK_DRM_OPT_IDLEMGR_DISABLE_ROUTINE_IRQ, 0,
"MTK_DRM_OPT_IDLEMGR_DISABLE_ROUTINE_IRQ"},
{MTK_DRM_OPT_MET_LOG, 0, "MTK_DRM_OPT_MET_LOG"},
/* low power option end */
{MTK_DRM_OPT_USE_PQ, 0, "MTK_DRM_OPT_USE_PQ"},
{MTK_DRM_OPT_ESD_CHECK_RECOVERY, 1, "MTK_DRM_OPT_ESD_CHECK_RECOVERY"},
{MTK_DRM_OPT_ESD_CHECK_SWITCH, 0, "MTK_DRM_OPT_ESD_CHECK_SWITCH"},
{MTK_DRM_OPT_PRESENT_FENCE, 1, "MTK_DRM_OPT_PRESENT_FENCE"},
{MTK_DRM_OPT_RDMA_UNDERFLOW_AEE, 0, "MTK_DRM_OPT_RDMA_UNDERFLOW_AEE"},
{MTK_DRM_OPT_DSI_UNDERRUN_AEE, 0, "MTK_DRM_OPT_DSI_UNDERRUN_AEE"},
{MTK_DRM_OPT_HRT, 1, "MTK_DRM_OPT_HRT"},
/* HRT_MODE, 0 -> legacy PMQOS, 1 -> HRT BW */
{MTK_DRM_OPT_HRT_MODE, 0, "MTK_DRM_OPT_HRT_MODE"},
{MTK_DRM_OPT_DELAYED_TRIGGER, 0, "MTK_DRM_OPT_DELAYED_TRIGGER"},
{MTK_DRM_OPT_OVL_EXT_LAYER, 0, "MTK_DRM_OPT_OVL_EXT_LAYER"},
{MTK_DRM_OPT_AOD, 0, "MTK_DRM_OPT_AOD"},
{MTK_DRM_OPT_RPO, 0, "MTK_DRM_OPT_RPO"},
{MTK_DRM_OPT_DUAL_PIPE, 0, "MTK_DRM_OPT_DUAL_PIPE"},
{MTK_DRM_OPT_DC_BY_HRT, 0, "MTK_DRM_OPT_DC_BY_HRT"},
{MTK_DRM_OPT_OVL_WCG, 1, "MTK_DRM_OPT_OVL_WCG"},
{MTK_DRM_OPT_OVL_SBCH, 0, "MTK_DRM_OPT_OVL_SBCH"},
{MTK_DRM_OPT_COMMIT_NO_WAIT_VBLANK, 0,
"MTK_DRM_OPT_COMMIT_NO_WAIT_VBLANK"},
{MTK_DRM_OPT_MET, 0, "MTK_DRM_OPT_MET"},
{MTK_DRM_OPT_REG_PARSER_RAW_DUMP, 0, "MTK_DRM_OPT_REG_PARSER_RAW_DUMP"},
{MTK_DRM_OPT_VP_PQ, 0, "MTK_DRM_OPT_VP_PQ"},
{MTK_DRM_OPT_GAME_PQ, 0, "MTK_DRM_OPT_GAME_PQ"},
{MTK_DRM_OPT_MMPATH, 0, "MTK_DRM_OPT_MMPATH"},
{MTK_DRM_OPT_HBM, 0, "MTK_DRM_OPT_HBM"},
{MTK_DRM_OPT_LAYER_REC, 0, "MTK_DRM_OPT_LAYER_REC"},
{MTK_DRM_OPT_CLEAR_LAYER, 0, "MTK_DRM_OPT_CLEAR_LAYER"},
{MTK_DRM_OPT_VDS_PATH_SWITCH, 0, "MTK_DRM_OPT_VDS_PATH_SWITCH"},
{MTK_DRM_OPT_LFR, 0, "MTK_DRM_OPT_LFR"},
{MTK_DRM_OPT_SF_PF, 0, "MTK_DRM_OPT_SF_PF"},
{MTK_DRM_OPT_PRIM_DUAL_PIPE, 0, "MTK_DRM_OPT_PRIM_DUAL_PIPE"},
{MTK_DRM_OPT_DYN_MIPI_CHANGE, 0, "MTK_DRM_OPT_DYN_MIPI_CHANGE"},
{MTK_DRM_OPT_PQ_34_COLOR_MATRIX, 0, "MTK_DRM_OPT_PQ_34_COLOR_MATRIX"},
};
static const char *mtk_drm_helper_opt_spy(struct mtk_drm_helper *helper_opt,
enum MTK_DRM_HELPER_OPT option)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(help_info); i++) {
if (helper_opt[i].opt == option)
return helper_opt[i].desc;
}
return "unknown option!!";
}
enum MTK_DRM_HELPER_OPT
mtk_drm_helper_name_to_opt(struct mtk_drm_helper *helper_opt, const char *name)
{
int i;
for (i = 0; i < MTK_DRM_OPT_NUM; i++) {
const char *opt_name = mtk_drm_helper_opt_spy(helper_opt, i);
if (strcmp(name, opt_name) == 0)
return i;
}
DDPINFO("%s: unknown name: %s\n", __func__, name);
return MTK_DRM_OPT_NUM;
}
int mtk_drm_helper_set_opt(struct mtk_drm_helper *helper_opt,
enum MTK_DRM_HELPER_OPT option, int value)
{
unsigned int i;
if (option >= MTK_DRM_OPT_NUM) {
DDPINFO("wrong option: %d\n", option);
return -EINVAL;
}
for (i = 0; i < ARRAY_SIZE(help_info); i++) {
if (helper_opt[i].opt == option && helper_opt[i].val != value) {
DDPMSG("Set Option %d(%s) from (%d) to (%d)\n", option,
mtk_drm_helper_opt_spy(helper_opt, option),
mtk_drm_helper_get_opt(helper_opt, option),
value);
helper_opt[i].val = value;
}
}
return 0;
}
int mtk_drm_helper_set_opt_by_name(struct mtk_drm_helper *helper_opt,
const char *name, int value)
{
enum MTK_DRM_HELPER_OPT opt;
opt = mtk_drm_helper_name_to_opt(helper_opt, name);
if (opt >= MTK_DRM_OPT_NUM)
return -1;
return mtk_drm_helper_set_opt(helper_opt, opt, value);
}
int mtk_drm_helper_get_opt(struct mtk_drm_helper *helper_opt,
enum MTK_DRM_HELPER_OPT option)
{
int ret = 0;
int i;
if (option >= MTK_DRM_OPT_NUM) {
DDPINFO("%s: option invalid %d\n", __func__, option);
return -1;
}
for (i = 0; i < ARRAY_SIZE(help_info); i++) {
if (helper_opt[i].opt == option)
return helper_opt[i].val;
}
return ret;
}
void mtk_drm_helper_init(struct device *dev, struct mtk_drm_helper **helper_opt)
{
int i, value, index, ret;
struct mtk_drm_helper *tmp_opt;
tmp_opt = kmalloc(sizeof(help_info), GFP_KERNEL);
if (!tmp_opt) {
DDPPR_ERR("helper info creation failed\n");
return;
}
memcpy(tmp_opt, help_info, sizeof(help_info));
for (i = 0; i < MTK_DRM_OPT_NUM; i++) {
index = of_property_match_string(dev->of_node, "helper-name",
help_info[i].desc);
if (index < 0)
value = 0;
else {
ret = of_property_read_u32_index(
dev->of_node, "helper-value", index, &value);
if (ret < 0)
value = 0;
}
tmp_opt[i].val = value;
DDPINFO("%s %d\n", tmp_opt[i].desc, tmp_opt[i].val);
}
*helper_opt = tmp_opt;
}
int mtk_drm_helper_get_opt_list(struct mtk_drm_helper *helper_opt,
char *stringbuf, int buf_len)
{
int len = 0;
int i = 0;
for (i = 0; i < ARRAY_SIZE(help_info); i++) {
if (stringbuf != NULL && buf_len > 0)
len += scnprintf(stringbuf + len, buf_len - len,
"Option: [%d][%s] Value: [%d]\n", i,
mtk_drm_helper_opt_spy(helper_opt, i),
mtk_drm_helper_get_opt(helper_opt, i));
}
return len;
}