[PATCH v12 2/4] soc: mediatek: mmsys: add support for ISP control

From: Moudy Ho
Date: Tue Mar 01 2022 - 05:03:16 EST


This patch adds 8183 ISP settings in MMSYS domain and interface.

Signed-off-by: Moudy Ho <moudy.ho@xxxxxxxxxxxx>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@xxxxxxxxxxxxx>
---
drivers/soc/mediatek/mt8183-mmsys.h | 26 ++++++
drivers/soc/mediatek/mtk-mmsys.c | 115 +++++++++++++++++++++++++
drivers/soc/mediatek/mtk-mmsys.h | 1 +
include/linux/soc/mediatek/mtk-mmsys.h | 30 +++++++
4 files changed, 172 insertions(+)

diff --git a/drivers/soc/mediatek/mt8183-mmsys.h b/drivers/soc/mediatek/mt8183-mmsys.h
index 9dee485807c9..179d5996c659 100644
--- a/drivers/soc/mediatek/mt8183-mmsys.h
+++ b/drivers/soc/mediatek/mt8183-mmsys.h
@@ -13,6 +13,18 @@
#define MT8183_DISP_RDMA0_SOUT_SEL_IN 0xf50
#define MT8183_DISP_RDMA1_SOUT_SEL_IN 0xf54

+#define MT8183_ISP_REG_MMSYS_SW0_RST_B 0x140
+#define MT8183_ISP_REG_MMSYS_SW1_RST_B 0x144
+#define MT8183_ISP_REG_MDP_ASYNC_CFG_WD 0x934
+#define MT8183_ISP_REG_MDP_ASYNC_IPU_CFG_WD 0x93C
+#define MT8183_ISP_REG_ISP_RELAY_CFG_WD 0x994
+#define MT8183_ISP_REG_IPU_RELAY_CFG_WD 0x9a0
+#define MT8183_ISP_BIT_MDP_DL_ASYNC_TX BIT(3)
+#define MT8183_ISP_BIT_MDP_DL_ASYNC_TX2 BIT(4)
+#define MT8183_ISP_BIT_MDP_DL_ASYNC_RX BIT(10)
+#define MT8183_ISP_BIT_MDP_DL_ASYNC_RX2 BIT(11)
+#define MT8183_ISP_BIT_NO_SOF_MODE BIT(31)
+
#define MT8183_OVL0_MOUT_EN_OVL0_2L BIT(4)
#define MT8183_OVL0_2L_MOUT_EN_DISP_PATH0 BIT(0)
#define MT8183_OVL1_2L_MOUT_EN_RDMA1 BIT(4)
@@ -57,5 +69,19 @@ static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
}
};

+static const unsigned int mmsys_mt8183_mdp_isp_ctrl_table[ISP_CTRL_MAX] = {
+ [ISP_REG_MMSYS_SW0_RST_B] = MT8183_ISP_REG_MMSYS_SW0_RST_B,
+ [ISP_REG_MMSYS_SW1_RST_B] = MT8183_ISP_REG_MMSYS_SW1_RST_B,
+ [ISP_REG_MDP_ASYNC_CFG_WD] = MT8183_ISP_REG_MDP_ASYNC_CFG_WD,
+ [ISP_REG_MDP_ASYNC_IPU_CFG_WD] = MT8183_ISP_REG_MDP_ASYNC_IPU_CFG_WD,
+ [ISP_REG_ISP_RELAY_CFG_WD] = MT8183_ISP_REG_ISP_RELAY_CFG_WD,
+ [ISP_REG_IPU_RELAY_CFG_WD] = MT8183_ISP_REG_IPU_RELAY_CFG_WD,
+ [ISP_BIT_MDP_DL_ASYNC_TX] = MT8183_ISP_BIT_MDP_DL_ASYNC_TX,
+ [ISP_BIT_MDP_DL_ASYNC_TX2] = MT8183_ISP_BIT_MDP_DL_ASYNC_TX2,
+ [ISP_BIT_MDP_DL_ASYNC_RX] = MT8183_ISP_BIT_MDP_DL_ASYNC_RX,
+ [ISP_BIT_MDP_DL_ASYNC_RX2] = MT8183_ISP_BIT_MDP_DL_ASYNC_RX2,
+ [ISP_BIT_NO_SOF_MODE] = MT8183_ISP_BIT_NO_SOF_MODE,
+};
+
#endif /* __SOC_MEDIATEK_MT8183_MMSYS_H */

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 04c0c7de395e..0e271d1a86e5 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -58,6 +58,7 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
.routes = mmsys_mt8183_routing_table,
.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
.has_gce_client_reg = true,
+ .mdp_isp_ctrl = mmsys_mt8183_mdp_isp_ctrl_table,
};

static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
@@ -136,6 +137,120 @@ void mtk_mmsys_write_reg_by_cmdq(struct device *dev,
}
EXPORT_SYMBOL_GPL(mtk_mmsys_write_reg_by_cmdq);

+void mtk_mmsys_mdp_isp_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+ enum mtk_mdp_comp_id id)
+{
+ struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+ const unsigned int *isp_ctrl = mmsys->data->mdp_isp_ctrl;
+ u32 reg;
+
+ /* Direct link */
+ if (id == MDP_COMP_CAMIN) {
+ /* Reset MDP_DL_ASYNC_TX */
+ if (isp_ctrl[ISP_REG_MMSYS_SW0_RST_B]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_MMSYS_SW0_RST_B];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ 0x0,
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX]);
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX],
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX]);
+ }
+
+ /* Reset MDP_DL_ASYNC_RX */
+ if (isp_ctrl[ISP_REG_MMSYS_SW1_RST_B]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_MMSYS_SW1_RST_B];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ 0x0,
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX]);
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX],
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX]);
+ }
+
+ /* Enable sof mode */
+ if (isp_ctrl[ISP_REG_ISP_RELAY_CFG_WD]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_ISP_RELAY_CFG_WD];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ 0x0,
+ isp_ctrl[ISP_BIT_NO_SOF_MODE]);
+ }
+ }
+
+ if (id == MDP_COMP_CAMIN2) {
+ /* Reset MDP_DL_ASYNC2_TX */
+ if (isp_ctrl[ISP_REG_MMSYS_SW0_RST_B]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_MMSYS_SW0_RST_B];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ 0x0,
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX2]);
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX2],
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX2]);
+ }
+
+ /* Reset MDP_DL_ASYNC2_RX */
+ if (isp_ctrl[ISP_REG_MMSYS_SW1_RST_B]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_MMSYS_SW1_RST_B];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ 0x0,
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX2]);
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX2],
+ isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX2]);
+ }
+
+ /* Enable sof mode */
+ if (isp_ctrl[ISP_REG_IPU_RELAY_CFG_WD]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_IPU_RELAY_CFG_WD];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ 0x0,
+ isp_ctrl[ISP_BIT_NO_SOF_MODE]);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_isp_ctrl);
+
+void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+ enum mtk_mdp_comp_id id, u32 camin_w, u32 camin_h)
+{
+ struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+ const unsigned int *isp_ctrl = mmsys->data->mdp_isp_ctrl;
+ u32 reg;
+
+ /* Config for direct link */
+ if (id == MDP_COMP_CAMIN) {
+ if (isp_ctrl[ISP_REG_MDP_ASYNC_CFG_WD]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_MDP_ASYNC_CFG_WD];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ (camin_h << 16) + camin_w,
+ 0x3FFF3FFF);
+ }
+
+ if (isp_ctrl[ISP_REG_ISP_RELAY_CFG_WD]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_ISP_RELAY_CFG_WD];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ (camin_h << 16) + camin_w,
+ 0x3FFF3FFF);
+ }
+ }
+ if (id == MDP_COMP_CAMIN2) {
+ if (isp_ctrl[ISP_REG_MDP_ASYNC_IPU_CFG_WD]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_MDP_ASYNC_IPU_CFG_WD];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ (camin_h << 16) + camin_w,
+ 0x3FFF3FFF);
+ }
+ if (isp_ctrl[ISP_REG_IPU_RELAY_CFG_WD]) {
+ reg = mmsys->addr + isp_ctrl[ISP_REG_IPU_RELAY_CFG_WD];
+ cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+ (camin_h << 16) + camin_w,
+ 0x3FFF3FFF);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_camin_ctrl);
+
static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
bool assert)
{
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 9fce400507d2..ad8b92389b54 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -93,6 +93,7 @@ struct mtk_mmsys_driver_data {
const struct mtk_mmsys_routes *routes;
const unsigned int num_routes;
bool has_gce_client_reg;
+ const unsigned int *mdp_isp_ctrl;
};

/*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 7f8ecc98d023..45e77d1cd6c1 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -91,6 +91,29 @@ enum mtk_mdp_comp_id {
MDP_MAX_COMP_COUNT /* ALWAYS keep at the end */
};

+enum mtk_mdp_pipe_id {
+ MDP_PIPE_RDMA0,
+ MDP_PIPE_IMGI,
+ MDP_PIPE_WPEI,
+ MDP_PIPE_WPEI2,
+ MDP_PIPE_MAX
+};
+
+enum mtk_isp_ctrl {
+ ISP_REG_MMSYS_SW0_RST_B,
+ ISP_REG_MMSYS_SW1_RST_B,
+ ISP_REG_MDP_ASYNC_CFG_WD,
+ ISP_REG_MDP_ASYNC_IPU_CFG_WD,
+ ISP_REG_ISP_RELAY_CFG_WD,
+ ISP_REG_IPU_RELAY_CFG_WD,
+ ISP_BIT_MDP_DL_ASYNC_TX,
+ ISP_BIT_MDP_DL_ASYNC_TX2,
+ ISP_BIT_MDP_DL_ASYNC_RX,
+ ISP_BIT_MDP_DL_ASYNC_RX2,
+ ISP_BIT_NO_SOF_MODE,
+ ISP_CTRL_MAX
+};
+
void mtk_mmsys_ddp_connect(struct device *dev,
enum mtk_ddp_comp_id cur,
enum mtk_ddp_comp_id next);
@@ -103,4 +126,11 @@ void mtk_mmsys_write_reg_by_cmdq(struct device *dev,
struct mmsys_cmdq_cmd *cmd,
u32 alias_id, u32 value, u32 mask);

+void mtk_mmsys_mdp_isp_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+ enum mtk_mdp_comp_id id);
+
+void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+ enum mtk_mdp_comp_id id,
+ u32 camin_w, u32 camin_h);
+
#endif /* __MTK_MMSYS_H */
--
2.18.0