kernel-brax3-ubuntu-touch/drivers/media/platform/mtk-isp/imgsys/mtk_imgsys-cmdq.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

353 lines
8.9 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018 MediaTek Inc.
*
* Author: Daniel Huang <daniel.huang@mediatek.com>
*
*/
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/soc/mediatek/mtk-cmdq-ext.h>
//#include <linux/pm_opp.h>
//#include <linux/pm_runtime.h>
//#include <linux/regulator/consumer.h>
#include "mtk_imgsys-cmdq.h"
#include "mtk_imgsys-cmdq-ext.h"
//#include "mtk_imgsys-trace.h"
//#include "mtk-interconnect.h"
#include "platforms/isp71/mtk_imgsys-cmdq-plat_def.h"
#include "platforms/isp7s/mtk_imgsys-cmdq-plat_def.h"
static struct mtk_imgcmdq_dev *imgsys_cmdq_dev;
int imgsys_cmdq_ftrace_en;
module_param(imgsys_cmdq_ftrace_en, int, 0644);
int imgsys_cmdq_ts_en;
module_param(imgsys_cmdq_ts_en, int, 0644);
int imgsys_wpe_bwlog_en;
module_param(imgsys_wpe_bwlog_en, int, 0644);
int imgsys_cmdq_ts_dbg_en;
module_param(imgsys_cmdq_ts_dbg_en, int, 0644);
int imgsys_dvfs_dbg_en;
module_param(imgsys_dvfs_dbg_en, int, 0644);
int imgsys_qos_dbg_en;
module_param(imgsys_qos_dbg_en, int, 0644);
int imgsys_qos_update_freq;
module_param(imgsys_qos_update_freq, int, 0644);
int imgsys_qos_blank_int;
module_param(imgsys_qos_blank_int, int, 0644);
int imgsys_qos_factor;
module_param(imgsys_qos_factor, int, 0644);
int imgsys_quick_onoff_en;
module_param(imgsys_quick_onoff_en, int, 0644);
int imgsys_fence_dbg_en;
module_param(imgsys_fence_dbg_en, int, 0644);
int imgsys_fine_grain_dvfs_en;
module_param(imgsys_fine_grain_dvfs_en, int, 0644);
/*#####*/
bool imgsys_cmdq_ts_enable(void)
{
return imgsys_cmdq_ts_en;
}
u32 imgsys_wpe_bwlog_enable(void)
{
return imgsys_wpe_bwlog_en;
}
bool imgsys_cmdq_ts_dbg_enable(void)
{
return imgsys_cmdq_ts_dbg_en;
}
bool imgsys_dvfs_dbg_enable(void)
{
return imgsys_dvfs_dbg_en;
}
bool imgsys_qos_dbg_enable(void)
{
return imgsys_qos_dbg_en;
}
bool imgsys_cmdq_ftrace_enabled(void)
{
return imgsys_cmdq_ftrace_en;
}
bool imgsys_quick_onoff_enable(void)
{
return imgsys_quick_onoff_en;
}
EXPORT_SYMBOL(imgsys_quick_onoff_enable);
/*#####*/
static int mtk_imgsys_power_ctrl_ccu(struct mtk_imgsys_dev *imgsys_dev, int on_off)
{
int ret = 0;
if (on_off) {
if (imgsys_dev->rproc_ccu_handle == NULL) {
dev_info(imgsys_dev->dev, "CCU handle is NULL\n");
ret = -EINVAL;
goto out;
}
#if IS_ENABLED(CONFIG_MTK_CCU_DEBUG)
ret = rproc_bootx(imgsys_dev->rproc_ccu_handle, RPROC_UID_IMG);
#else
ret = rproc_boot(imgsys_dev->rproc_ccu_handle);
#endif
if (ret)
dev_info(imgsys_dev->dev, "boot ccu rproc fail\n");
} else {
if (imgsys_dev->rproc_ccu_handle)
#if IS_ENABLED(CONFIG_MTK_CCU_DEBUG)
rproc_shutdownx(imgsys_dev->rproc_ccu_handle, RPROC_UID_IMG);
#else
rproc_shutdown(imgsys_dev->rproc_ccu_handle);
#endif
else
ret = -EINVAL;
}
out:
return ret;
}
static void module_uninit(struct kref *kref)
{
struct mtk_imgsys_dev *imgsys_dev;
int i;
struct mtk_imgsys_dvfs *dvfs_info;
imgsys_dev = container_of(kref, struct mtk_imgsys_dev, init_kref);
dvfs_info = &imgsys_dev->dvfs_info;
for (i = 0; i < (imgsys_dev->num_mods); i++)
if (imgsys_dev->modules[i].uninit)
imgsys_dev->modules[i].uninit(imgsys_dev);
if (IS_ERR_OR_NULL(dvfs_info->reg) || !regulator_is_enabled(dvfs_info->reg))
dev_dbg(dvfs_info->dev,
"%s: [ERROR] reg is null or disabled\n", __func__);
else
regulator_disable(dvfs_info->reg);
mtk_imgsys_power_ctrl_ccu(imgsys_dev, 0);
if (IS_ERR_OR_NULL(dvfs_info->mmdvfs_clk))
dev_dbg(dvfs_info->dev,
"%s: [ERROR] mmdvfs_clk is null\n", __func__);
else {
mtk_mmdvfs_enable_ccu(false, CCU_PWR_USR_IMG);
mtk_mmdvfs_enable_vcp(false, VCP_PWR_USR_IMG);
}
}
void mtk_imgsys_mod_put(struct mtk_imgsys_dev *imgsys_dev)
{
struct kref *kref;
kref = &imgsys_dev->init_kref;
kref_put(kref, module_uninit);
}
void mtk_imgsys_mod_get(struct mtk_imgsys_dev *imgsys_dev)
{
struct kref *kref;
kref = &imgsys_dev->init_kref;
kref_get(kref);
}
/*####*/
void imgsys_cmdq_init(struct mtk_imgsys_dev *imgsys_dev, const int nr_imgsys_dev)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->cmdq_init(imgsys_dev, nr_imgsys_dev);
}
EXPORT_SYMBOL(imgsys_cmdq_init);
void imgsys_cmdq_release(struct mtk_imgsys_dev *imgsys_dev)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->cmdq_release(imgsys_dev);
}
EXPORT_SYMBOL(imgsys_cmdq_release);
void imgsys_cmdq_streamon(struct mtk_imgsys_dev *imgsys_dev)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->cmdq_streamon(imgsys_dev);
}
EXPORT_SYMBOL(imgsys_cmdq_streamon);
void imgsys_cmdq_streamoff(struct mtk_imgsys_dev *imgsys_dev)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->cmdq_streamoff(imgsys_dev);
}
EXPORT_SYMBOL(imgsys_cmdq_streamoff);
int imgsys_cmdq_sendtask(struct mtk_imgsys_dev *imgsys_dev,
struct swfrm_info_t *frm_info,
void (*cmdq_cb)(struct cmdq_cb_data data,
uint32_t subfidx, bool isLastTaskInReq),
void (*cmdq_err_cb)(struct cmdq_cb_data data,
uint32_t fail_subfidx, bool isHWhang, uint32_t hangEvent))
{
int ret = 0;
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
ret = cmdq_dev->cust_data->cmdq_sendtask(imgsys_dev, frm_info, cmdq_cb, cmdq_err_cb);
return ret;
}
EXPORT_SYMBOL(imgsys_cmdq_sendtask);
void imgsys_cmdq_clearevent(struct mtk_imgsys_dev *imgsys_dev, int event_id)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->cmdq_clearevent(event_id);
}
EXPORT_SYMBOL(imgsys_cmdq_clearevent);
#if DVFS_QOS_READY
void mtk_imgsys_mmdvfs_init(struct mtk_imgsys_dev *imgsys_dev)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->mmdvfs_init(imgsys_dev);
}
EXPORT_SYMBOL(mtk_imgsys_mmdvfs_init);
void mtk_imgsys_mmdvfs_uninit(struct mtk_imgsys_dev *imgsys_dev)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->mmdvfs_uninit(imgsys_dev);
}
EXPORT_SYMBOL(mtk_imgsys_mmdvfs_uninit);
void mtk_imgsys_mmqos_init(struct mtk_imgsys_dev *imgsys_dev)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->mmqos_init(imgsys_dev);
}
EXPORT_SYMBOL(mtk_imgsys_mmqos_init);
void mtk_imgsys_mmqos_uninit(struct mtk_imgsys_dev *imgsys_dev)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->mmqos_init(imgsys_dev);
}
EXPORT_SYMBOL(mtk_imgsys_mmqos_uninit);
void mtk_imgsys_power_ctrl(struct mtk_imgsys_dev *imgsys_dev, bool isPowerOn)
{
struct mtk_imgcmdq_dev *cmdq_dev = platform_get_drvdata(imgsys_dev->imgcmdq_pdev);
cmdq_dev->cust_data->power_ctrl(imgsys_dev, isPowerOn);
}
EXPORT_SYMBOL(mtk_imgsys_power_ctrl);
#endif
//#########
struct platform_device *mtk_imgsys_cmdq_get_plat_dev(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *cmdq_node;
struct platform_device *cmdq_pdev;
dev_dbg(&pdev->dev, "- E. imgsys cmdq get platform device.\n");
cmdq_node = of_parse_phandle(dev->of_node, "mediatek,imgsys_cmdq", 0);
if (cmdq_node == NULL) {
dev_info(&pdev->dev, "%s can't get imgsys cmdq node.\n", __func__);
return NULL;
}
cmdq_pdev = of_find_device_by_node(cmdq_node);
if (WARN_ON(cmdq_pdev == NULL) == true) {
dev_info(&pdev->dev, "%s imgsys cmdq pdev failed.\n", __func__);
of_node_put(cmdq_node);
return NULL;
}
return cmdq_pdev;
}
EXPORT_SYMBOL(mtk_imgsys_cmdq_get_plat_dev);
static int mtk_imgsys_cmdq_probe(struct platform_device *pdev)
{
struct mtk_imgcmdq_dev *cmdq_dev;
dev_info(&pdev->dev, "- E. imgsys cmdq driver probe\n");
cmdq_dev = devm_kzalloc(&pdev->dev, sizeof(struct mtk_imgcmdq_dev), GFP_KERNEL);
if (cmdq_dev == NULL)
return -ENOMEM;
imgsys_cmdq_dev = cmdq_dev;
cmdq_dev->dev = &pdev->dev;
cmdq_dev->cust_data = of_device_get_match_data(&pdev->dev);
platform_set_drvdata(pdev, cmdq_dev);
dev_set_drvdata(&pdev->dev, cmdq_dev);
dev_dbg(&pdev->dev, "- X. imgsys cmdq driver probe success\n");
return 0;
}
static int mtk_imgsys_cmdq_remove(struct platform_device *pdev)
{
dev_dbg(&pdev->dev, "- E. imgsys cmdq driver remove\n");
devm_kfree(&pdev->dev, imgsys_cmdq_dev);
dev_dbg(&pdev->dev, "- X. imgsys cmdq driver remove success\n");
return 0;
}
static const struct of_device_id mtk_imgsys_cmdq_of_match[] = {
{.compatible = "mediatek,imgsys-cmdq-71", .data = (void *)&imgsys_cmdq_data_71},
{.compatible = "mediatek,imgsys-cmdq-7s", .data = (void *)&imgsys_cmdq_data_7s},
{}
};
MODULE_DEVICE_TABLE(of, mtk_imgsys_cmdq_of_match);
static struct platform_driver mtk_imgsys_cmdq_driver = {
.probe = mtk_imgsys_cmdq_probe,
.remove = mtk_imgsys_cmdq_remove,
.driver = {
.name = "camera-imgsys-cmdq",
.owner = THIS_MODULE,
.of_match_table = mtk_imgsys_cmdq_of_match,
},
};
module_platform_driver(mtk_imgsys_cmdq_driver);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Mediatek imgsys cmdq driver");