Re: [PATCH v2 05/13] media: platform: mediatek: add isp_7x seninf unit
From: CK Hu (胡俊光) <hidden>
Date: 2025-07-10 06:39:51
Also in:
dri-devel, linux-devicetree, linux-media, linux-mediatek, lkml
On Mon, 2025-07-07 at 09:31 +0800, shangyao lin wrote:
From: "shangyao.lin" <redacted> Introduce support for the MediaTek sensor interface (seninf) in the SoC camera subsystem, focusing on CSI and stream control. The driver manages parameter control, metering, status tracking, and interrupt handling for the camera sensor interface hardware. It integrates with the MediaTek ISP CAMSYS, bridging camera sensors and the ISP system, and provides V4L2 framework support for dynamic stream configuration and virtual channel management. ---
[snip]
quoted hunk
diff --git a/drivers/media/platform/mediatek/isp/isp_7x/camsys/mtk_csi_phy_2_0/mtk_cam-seninf-hw_phy_2_0.c b/drivers/media/platform/mediatek/isp/isp_7x/camsys/mtk_csi_phy_2_0/mtk_cam-seninf-hw_phy_2_0.c new file mode 100755 index 000000000000..a3c926cc3cee --- /dev/null +++ b/drivers/media/platform/mediatek/isp/isp_7x/camsys/mtk_csi_phy_2_0/mtk_cam-seninf-hw_phy_2_0.c@@ -0,0 +1,1932 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2022 MediaTek Inc. + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/bitfield.h> +#include <linux/bitops.h> + +#include "../mtk_cam-seninf.h" +#include "../mtk_cam-seninf-hw.h" +#include "../mtk_cam-seninf-regs.h" +#include "mtk_cam-seninf-top-ctrl.h" +#include "mtk_cam-seninf-seninf1-mux.h" +#include "mtk_cam-seninf-seninf1.h" +#include "mtk_cam-seninf-seninf1-csi2.h" +#include "mtk_cam-seninf-tg1.h" +#include "mtk_cam-seninf-cammux.h" +#include "mtk_cam-seninf-mipi-rx-ana-cdphy-csi0a.h" +#include "mtk_cam-seninf-csi0-cphy.h" +#include "mtk_cam-seninf-csi0-dphy.h" +#include "../kd_imgsensor_define_v4l2.h" + +static struct mtk_cam_seninf_cfg _seninf_cfg = { + .mux_num = 8, + .seninf_num = 4, + .cam_mux_num = 11, + .pref_mux_num = 11, +}; + +struct mtk_cam_seninf_cfg *g_seninf_cfg = &_seninf_cfg; + +static inline u32 get_port_num(int port) +{ + if (port >= CSI_PORT_0A) + return FIELD_GET(CSI_PORT_A_MASK, port - CSI_PORT_0A); + else + return port; +} + +static inline void mtk_cam_seninf_set_di_ch_ctrl(void __iomem *pseninf, + unsigned int stream_id, + struct seninf_vc *vc) +{ + if (stream_id > SENINF_MAX_STREAM) + return; + + SENINF_BITS(pseninf, SENINF_CSI2_S0_DI_CTRL + (stream_id << 0x2), + RG_CSI2_DT_SEL, vc->dt); + SENINF_BITS(pseninf, SENINF_CSI2_S0_DI_CTRL + (stream_id << 0x2), + RG_CSI2_VC_SEL, 0); + SENINF_BITS(pseninf, SENINF_CSI2_S0_DI_CTRL + (stream_id << 0x2), + RG_CSI2_DT_INTERLEAVE_MODE, 1); + SENINF_BITS(pseninf, SENINF_CSI2_S0_DI_CTRL + (stream_id << 0x2), + RG_CSI2_VC_INTERLEAVE_EN, 1); + + switch (stream_id) { + case 0: + SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, + RG_CSI2_S0_GRP_EN, 1); + break; + case 1: + SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, + RG_CSI2_S1_GRP_EN, 1); + break; + case 2: + SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, + RG_CSI2_S2_GRP_EN, 1); + break; + case 3: + SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, + RG_CSI2_S3_GRP_EN, 1); + break; + case 4: + SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, + RG_CSI2_S4_GRP_EN, 1); + break; + case 5: + SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, + RG_CSI2_S5_GRP_EN, 1); + break; + case 6: + SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, + RG_CSI2_S6_GRP_EN, 1); + break; + case 7: + SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, + RG_CSI2_S7_GRP_EN, 1); + break; + default: + return; + }
#define RG_CSI2_SX_GRP_EN(x) BIT(x + 8) and this switch case could be reduced as SENINF_BITS(pseninf, SENINF_CSI2_CH0_CTRL, RG_CSI2_SX_GRP_EN(stream_id), 1);
+} +
[snip]
+
+int mtk_cam_seninf_set_top_mux_ctrl(struct seninf_ctx *ctx, int mux_idx,
+ int seninf_src)
+{
+ void __iomem *seninf = ctx->reg_if_top;
+
+ switch (mux_idx) {
+ case SENINF_MUX1:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_0,
+ RG_SENINF_MUX1_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX2:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_0,
+ RG_SENINF_MUX2_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX3:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_0,
+ RG_SENINF_MUX3_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX4:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_0,
+ RG_SENINF_MUX4_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX5:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_1,
+ RG_SENINF_MUX5_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX6:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_1,
+ RG_SENINF_MUX6_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX7:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_1,
+ RG_SENINF_MUX7_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX8:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_1,
+ RG_SENINF_MUX8_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX9:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_2,
+ RG_SENINF_MUX9_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX10:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_2,
+ RG_SENINF_MUX10_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX11:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_2,
+ RG_SENINF_MUX11_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX12:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_2,
+ RG_SENINF_MUX12_SRC_SEL, seninf_src);
+ break;
+ case SENINF_MUX13:
+ SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL_3,
+ RG_SENINF_MUX13_SRC_SEL, seninf_src);
+ break;
+ default:
+ dev_dbg(ctx->dev, "invalid mux_idx %d\n", mux_idx);
+ return -EINVAL;
+ }
+#define SENINF_TOP_MUX_CTRL(x) (0x10 + 4 * x) #define RG_SENINF_MUX_SRC_SEL(x) GENMASK((x % 4) * 4 + 3, (x % 4) * 4) And this switch case could be reduced as SENINF_BITS(seninf, SENINF_TOP_MUX_CTRL(mux_idx / 4), RG_SENINF_MUX_SRC_SEL(mux_idx), seninf_src); Regards, CK
+ return 0; +} +