]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
media: qcom: camss: tpg: Add TPG support for multiple targets
authorWenmeng Liu <wenmeng.liu@oss.qualcomm.com>
Tue, 17 Mar 2026 10:05:47 +0000 (18:05 +0800)
committerBryan O'Donoghue <bod@kernel.org>
Fri, 8 May 2026 23:22:58 +0000 (00:22 +0100)
Add support for TPG found on LeMans, Monaco, Hamoa.

Signed-off-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # Dell Inpsiron14p
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
drivers/media/platform/qcom/camss/Makefile
drivers/media/platform/qcom/camss/camss-csid-680.c
drivers/media/platform/qcom/camss/camss-csid-gen3.c
drivers/media/platform/qcom/camss/camss-tpg-gen1.c [new file with mode: 0644]
drivers/media/platform/qcom/camss/camss.c

index d747aa7db3c12ad27d986e0b2b85a44870f89ad3..27898b3cc7d3c8f275567f81f0952e2a0e18f189 100644 (file)
@@ -16,6 +16,7 @@ qcom-camss-objs += \
                camss-format.o \
                camss-ispif.o \
                camss-tpg.o \
+               camss-tpg-gen1.o \
                camss-vfe.o \
                camss-vfe-4-1.o \
                camss-vfe-4-7.o \
index 3ad3a174bcfb8c0d319930d0010df92308cb5ae4..2e4547455d229227ba7cc339a13271fb28e103a5 100644 (file)
 #define                CSI2_RX_CFG0_PHY_NUM_SEL                        20
 #define                CSI2_RX_CFG0_PHY_SEL_BASE_IDX                   1
 #define                CSI2_RX_CFG0_PHY_TYPE_SEL                       24
+#define                CSI2_RX_CFG0_TPG_MUX_EN                         BIT(27)
+#define                CSI2_RX_CFG0_TPG_MUX_SEL                        GENMASK(29, 28)
 
 #define CSID_CSI2_RX_CFG1                                      0x204
 #define                CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN           BIT(0)
@@ -185,10 +187,20 @@ static void __csid_configure_rx(struct csid_device *csid,
                                struct csid_phy_config *phy, int vc)
 {
        u32 val;
+       struct camss *camss;
 
+       camss = csid->camss;
        val = (phy->lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES;
        val |= phy->lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL;
-       val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX) << CSI2_RX_CFG0_PHY_NUM_SEL;
+
+       if (camss->tpg && csid->tpg_linked &&
+           camss->tpg[phy->csiphy_id].testgen.mode != TPG_PAYLOAD_MODE_DISABLED) {
+               val |= FIELD_PREP(CSI2_RX_CFG0_TPG_MUX_SEL, phy->csiphy_id + 1);
+               val |= CSI2_RX_CFG0_TPG_MUX_EN;
+       } else {
+               val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX)
+                       << CSI2_RX_CFG0_PHY_NUM_SEL;
+       }
 
        writel(val, csid->base + CSID_CSI2_RX_CFG0);
 
index bd059243790edeb045080905eb76fef3b12caae1..222765fe7914da3bcba9ab9edd15332ba9ccb990 100644 (file)
@@ -66,6 +66,8 @@
 #define                CSI2_RX_CFG0_VC_MODE            3
 #define                CSI2_RX_CFG0_DL0_INPUT_SEL      4
 #define                CSI2_RX_CFG0_PHY_NUM_SEL        20
+#define                CSI2_RX_CFG0_TPG_MUX_EN         BIT(27)
+#define                CSI2_RX_CFG0_TPG_MUX_SEL        GENMASK(29, 28)
 
 #define CSID_CSI2_RX_CFG1              0x204
 #define                CSI2_RX_CFG1_ECC_CORRECTION_EN  BIT(0)
@@ -109,10 +111,20 @@ static void __csid_configure_rx(struct csid_device *csid,
                                struct csid_phy_config *phy, int vc)
 {
        int val;
+       struct camss *camss;
 
+       camss = csid->camss;
        val = (phy->lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES;
        val |= phy->lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL;
-       val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX) << CSI2_RX_CFG0_PHY_NUM_SEL;
+
+       if (camss->tpg && csid->tpg_linked &&
+           camss->tpg[phy->csiphy_id].testgen.mode != TPG_PAYLOAD_MODE_DISABLED) {
+               val |= FIELD_PREP(CSI2_RX_CFG0_TPG_MUX_SEL, phy->csiphy_id + 1);
+               val |= CSI2_RX_CFG0_TPG_MUX_EN;
+       } else {
+               val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX)
+                       << CSI2_RX_CFG0_PHY_NUM_SEL;
+       }
 
        writel(val, csid->base + CSID_CSI2_RX_CFG0);
 
diff --git a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
new file mode 100644 (file)
index 0000000..d29de5f
--- /dev/null
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * Qualcomm MSM Camera Subsystem - TPG (Test Pattern Generator) Module
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include "camss-tpg.h"
+#include "camss.h"
+
+/* TPG global registers */
+#define TPG_HW_VERSION         0x0
+# define HW_VERSION_STEPPING           GENMASK(15, 0)
+# define HW_VERSION_REVISION           GENMASK(27, 16)
+# define HW_VERSION_GENERATION         GENMASK(31, 28)
+
+#define TPG_HW_VER(gen, rev, step) \
+       (((u32)(gen) << 28) | ((u32)(rev) << 16) | (u32)(step))
+
+#define TPG_HW_VER_2_0_0                TPG_HW_VER(2, 0, 0)
+#define TPG_HW_VER_2_1_0                TPG_HW_VER(2, 1, 0)
+
+#define TPG_HW_STATUS          0x4
+
+#define TPG_CTRL               0x64
+# define TPG_CTRL_TEST_EN              BIT(0)
+# define TPG_CTRL_PHY_SEL              BIT(3)
+# define TPG_CTRL_NUM_ACTIVE_LANES     GENMASK(5, 4)
+# define TPG_CTRL_VC_DT_PATTERN_ID     GENMASK(8, 6)
+# define TPG_CTRL_OVERLAP_SHDR_EN      BIT(10)
+# define TPG_CTRL_NUM_ACTIVE_VC                GENMASK(31, 30)
+
+#define TPG_CLEAR              0x1F4
+
+/* TPG VC-based registers */
+#define TPG_VC_n_GAIN_CFG(n)           (0x60 + (n) * 0x60)
+
+#define TPG_VC_n_CFG0(n)       (0x68 + (n) * 0x60)
+# define TPG_VC_n_CFG0_VC_NUM                  GENMASK(4, 0)
+# define TPG_VC_n_CFG0_NUM_ACTIVE_DT           GENMASK(9, 8)
+# define TPG_VC_n_CFG0_NUM_BATCH               GENMASK(15, 12)
+# define TPG_VC_n_CFG0_NUM_FRAMES              GENMASK(31, 16)
+
+#define TPG_VC_n_LSFR_SEED(n)  (0x6C + (n) * 0x60)
+#define TPG_VC_n_HBI_CFG(n)    (0x70 + (n) * 0x60)
+#define TPG_VC_n_VBI_CFG(n)    (0x74 + (n) * 0x60)
+
+#define TPG_VC_n_COLOR_BARS_CFG(n)             (0x78 + (n) * 0x60)
+# define TPG_VC_n_COLOR_BARS_CFG_PIX_PATTERN           GENMASK(2, 0)
+# define TPG_VC_n_COLOR_BARS_CFG_QCFA_EN               BIT(3)
+# define TPG_VC_n_COLOR_BARS_CFG_SPLIT_EN              BIT(4)
+# define TPG_VC_n_COLOR_BARS_CFG_NOISE_EN              BIT(5)
+# define TPG_VC_n_COLOR_BARS_CFG_ROTATE_PERIOD         GENMASK(13, 8)
+# define TPG_VC_n_COLOR_BARS_CFG_XCFA_EN               BIT(16)
+# define TPG_VC_n_COLOR_BARS_CFG_SIZE_X                        GENMASK(26, 24)
+# define TPG_VC_n_COLOR_BARS_CFG_SIZE_Y                        GENMASK(30, 28)
+
+/* TPG DT-based registers */
+#define TPG_VC_m_DT_n_CFG_0(m, n)              (0x7C + (m) * 0x60 + (n) * 0xC)
+# define TPG_VC_m_DT_n_CFG_0_FRAME_HEIGHT      GENMASK(15, 0)
+# define TPG_VC_m_DT_n_CFG_0_FRAME_WIDTH       GENMASK(31, 16)
+
+#define TPG_VC_m_DT_n_CFG_1(m, n)              (0x80 + (m) * 0x60 + (n) * 0xC)
+# define TPG_VC_m_DT_n_CFG_1_DATA_TYPE         GENMASK(5, 0)
+# define TPG_VC_m_DT_n_CFG_1_ECC_XOR_MASK      GENMASK(13, 8)
+# define TPG_VC_m_DT_n_CFG_1_CRC_XOR_MASK      GENMASK(31, 16)
+
+#define TPG_VC_m_DT_n_CFG_2(m, n)              (0x84 + (m) * 0x60 + (n) * 0xC)
+# define TPG_VC_m_DT_n_CFG_2_PAYLOAD_MODE              GENMASK(3, 0)
+/* v2.0.0: USER[19:4], ENC[23:20] */
+# define TPG_V2_0_0_VC_m_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD             GENMASK(19, 4)
+# define TPG_V2_0_0_VC_m_DT_n_CFG_2_ENCODE_FORMAT                      GENMASK(23, 20)
+/* v2.1.0: USER[27:4], ENC[31:28] */
+# define TPG_V2_1_0_VC_m_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD     GENMASK(27, 4)
+# define TPG_V2_1_0_VC_m_DT_n_CFG_2_ENCODE_FORMAT                      GENMASK(31, 28)
+
+#define TPG_HBI_PCT_DEFAULT                    545     /* 545% */
+#define TPG_VBI_PCT_DEFAULT                    10      /* 10% */
+#define PERCENT_BASE                           100
+
+/* Default user-specified payload for TPG test generator.
+ * Keep consistent with CSID TPG default: 0xBE.
+ */
+#define TPG_USER_SPECIFIED_PAYLOAD_DEFAULT     0xBE
+#define TPG_LFSR_SEED_DEFAULT                  0x12345678
+#define TPG_COLOR_BARS_CFG_STANDARD \
+       FIELD_PREP(TPG_VC_n_COLOR_BARS_CFG_ROTATE_PERIOD, 0xA)
+
+static const char * const testgen_payload_modes[] = {
+       [TPG_PAYLOAD_MODE_DISABLED]             = "Disabled",
+       [TPG_PAYLOAD_MODE_INCREMENTING]         = "Incrementing",
+       [TPG_PAYLOAD_MODE_ALTERNATING_55_AA]    = "Alternating 0x55/0xAA",
+       [TPG_PAYLOAD_MODE_RANDOM]               = "Pseudo-random Data",
+       [TPG_PAYLOAD_MODE_USER_SPECIFIED]       = "User Specified",
+       [TPG_PAYLOAD_MODE_COLOR_BARS]           = "Color bars",
+};
+
+static int tpg_stream_on(struct tpg_device *tpg)
+{
+       struct tpg_testgen_config *tg = &tpg->testgen;
+       struct v4l2_mbus_framefmt *input_format;
+       const struct tpg_format_info *format;
+       u8 payload_mode = (tg->mode > TPG_PAYLOAD_MODE_DISABLED) ?
+                          tg->mode - 1 : 0;
+       u8 lane_cnt = tpg->res->lane_cnt;
+       u8 vc, dt, last_vc = 0;
+       u32 val;
+
+       for (vc = 0; vc <= MSM_TPG_ACTIVE_VC; vc++) {
+               last_vc = vc;
+
+               input_format = &tpg->fmt;
+               format = tpg_get_fmt_entry(tpg->res->formats->formats,
+                                          tpg->res->formats->nformats,
+                                          input_format->code);
+               if (IS_ERR(format))
+                       return -EINVAL;
+
+               /* VC configuration */
+               val = FIELD_PREP(TPG_VC_n_CFG0_NUM_ACTIVE_DT, MSM_TPG_ACTIVE_DT) |
+                     FIELD_PREP(TPG_VC_n_CFG0_NUM_FRAMES, 0);
+               writel(val, tpg->base + TPG_VC_n_CFG0(vc));
+
+               writel(TPG_LFSR_SEED_DEFAULT, tpg->base + TPG_VC_n_LSFR_SEED(vc));
+
+               val = DIV_ROUND_UP(input_format->width * format->bpp * TPG_HBI_PCT_DEFAULT,
+                                  BITS_PER_BYTE * lane_cnt * PERCENT_BASE);
+               writel(val, tpg->base + TPG_VC_n_HBI_CFG(vc));
+
+               val = input_format->height * TPG_VBI_PCT_DEFAULT / PERCENT_BASE;
+               writel(val, tpg->base + TPG_VC_n_VBI_CFG(vc));
+
+               writel(TPG_COLOR_BARS_CFG_STANDARD, tpg->base + TPG_VC_n_COLOR_BARS_CFG(vc));
+
+               /* DT configuration */
+               for (dt = 0; dt <= MSM_TPG_ACTIVE_DT; dt++) {
+                       val = FIELD_PREP(TPG_VC_m_DT_n_CFG_0_FRAME_HEIGHT,
+                                        input_format->height & 0xffff) |
+                             FIELD_PREP(TPG_VC_m_DT_n_CFG_0_FRAME_WIDTH,
+                                        input_format->width & 0xffff);
+                       writel(val, tpg->base + TPG_VC_m_DT_n_CFG_0(vc, dt));
+
+                       val = FIELD_PREP(TPG_VC_m_DT_n_CFG_1_DATA_TYPE, format->data_type);
+                       writel(val, tpg->base + TPG_VC_m_DT_n_CFG_1(vc, dt));
+
+                       if (tpg->hw_version == TPG_HW_VER_2_0_0) {
+                               val = FIELD_PREP(TPG_VC_m_DT_n_CFG_2_PAYLOAD_MODE, payload_mode) |
+                                     FIELD_PREP(TPG_V2_0_0_VC_m_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD,
+                                                TPG_USER_SPECIFIED_PAYLOAD_DEFAULT) |
+                                     FIELD_PREP(TPG_V2_0_0_VC_m_DT_n_CFG_2_ENCODE_FORMAT,
+                                                format->encode_format);
+                       } else if (tpg->hw_version >= TPG_HW_VER_2_1_0) {
+                               val = FIELD_PREP(TPG_VC_m_DT_n_CFG_2_PAYLOAD_MODE, payload_mode) |
+                                     FIELD_PREP(TPG_V2_1_0_VC_m_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD,
+                                                TPG_USER_SPECIFIED_PAYLOAD_DEFAULT) |
+                                     FIELD_PREP(TPG_V2_1_0_VC_m_DT_n_CFG_2_ENCODE_FORMAT,
+                                                format->encode_format);
+                       }
+                       writel(val, tpg->base + TPG_VC_m_DT_n_CFG_2(vc, dt));
+               }
+       }
+
+       /* Global TPG control */
+       val = FIELD_PREP(TPG_CTRL_TEST_EN, 1) |
+             FIELD_PREP(TPG_CTRL_NUM_ACTIVE_LANES, lane_cnt - 1) |
+             FIELD_PREP(TPG_CTRL_NUM_ACTIVE_VC, last_vc);
+       writel(val, tpg->base + TPG_CTRL);
+
+       return 0;
+}
+
+static int tpg_reset(struct tpg_device *tpg)
+{
+       writel(0, tpg->base + TPG_CTRL);
+       writel(1, tpg->base + TPG_CLEAR);
+
+       return 0;
+}
+
+static void tpg_stream_off(struct tpg_device *tpg)
+{
+       tpg_reset(tpg);
+}
+
+static int tpg_configure_stream(struct tpg_device *tpg, u8 enable)
+{
+       if (enable)
+               return tpg_stream_on(tpg);
+
+       tpg_stream_off(tpg);
+
+       return 0;
+}
+
+static int tpg_configure_testgen_pattern(struct tpg_device *tpg, s32 val)
+{
+       if (val >= 0 && val <= TPG_PAYLOAD_MODE_COLOR_BARS)
+               tpg->testgen.mode = val;
+
+       return 0;
+}
+
+static u32 tpg_hw_version(struct tpg_device *tpg)
+{
+       u32 hw_version = readl(tpg->base + TPG_HW_VERSION);
+
+       tpg->hw_version = hw_version;
+       dev_dbg(tpg->camss->dev, "tpg HW Version = %u.%u.%u\n",
+               (u32)FIELD_GET(HW_VERSION_GENERATION, hw_version),
+               (u32)FIELD_GET(HW_VERSION_REVISION, hw_version),
+               (u32)FIELD_GET(HW_VERSION_STEPPING, hw_version));
+
+       return hw_version;
+}
+
+static void tpg_subdev_init(struct tpg_device *tpg)
+{
+       tpg->testgen.modes = testgen_payload_modes;
+       tpg->testgen.nmodes = TPG_PAYLOAD_MODE_NUM_SUPPORTED_GEN1;
+}
+
+const struct tpg_hw_ops tpg_ops_gen1 = {
+       .configure_stream = tpg_configure_stream,
+       .configure_testgen_pattern = tpg_configure_testgen_pattern,
+       .hw_version = tpg_hw_version,
+       .reset = tpg_reset,
+       .subdev_init = tpg_subdev_init,
+};
index bd351ceadda751ed399e9b35f9cb272b3078b19e..2123f6388e3d7eafe669efd6b033e22d8eb5cf79 100644 (file)
@@ -3806,6 +3806,54 @@ static const struct camss_subdev_resources csiphy_res_8775p[] = {
        },
 };
 
+static const struct camss_subdev_resources tpg_res_8775p[] = {
+       /* TPG0 */
+       {
+               .regulators = {},
+               .clock = { "cpas_ahb", "csiphy_rx" },
+               .clock_rate = {
+                       { 0 },
+                       { 400000000 },
+               },
+               .reg = { "tpg0" },
+               .tpg = {
+                       .lane_cnt = 4,
+                       .formats = &tpg_formats_gen1,
+                       .hw_ops = &tpg_ops_gen1
+               }
+       },
+       /* TPG1 */
+       {
+               .regulators = {},
+               .clock = { "cpas_ahb", "csiphy_rx" },
+               .clock_rate = {
+                       { 0 },
+                       { 400000000 },
+               },
+               .reg = { "tpg1" },
+               .tpg = {
+                       .lane_cnt = 4,
+                       .formats = &tpg_formats_gen1,
+                       .hw_ops = &tpg_ops_gen1
+               }
+       },
+       /* TPG2 */
+       {
+               .regulators = {},
+               .clock = { "cpas_ahb", "csiphy_rx" },
+               .clock_rate = {
+                       { 0 },
+                       { 400000000 },
+               },
+               .reg = { "tpg2" },
+               .tpg = {
+                       .lane_cnt = 4,
+                       .formats = &tpg_formats_gen1,
+                       .hw_ops = &tpg_ops_gen1
+               }
+       },
+};
+
 static const struct camss_subdev_resources csid_res_8775p[] = {
        /* CSID0 */
        {
@@ -4210,6 +4258,54 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = {
        },
 };
 
+static const struct camss_subdev_resources tpg_res_x1e80100[] = {
+       /* TPG0 */
+       {
+               .regulators = {},
+               .clock = { "cpas_ahb", "csid_csiphy_rx" },
+               .clock_rate = {
+                       { 0 },
+                       { 400000000 },
+               },
+               .reg = { "csitpg0" },
+               .tpg = {
+                       .lane_cnt = 4,
+                       .formats = &tpg_formats_gen1,
+                       .hw_ops = &tpg_ops_gen1
+               }
+       },
+       /* TPG1 */
+       {
+               .regulators = {},
+               .clock = { "cpas_ahb", "csid_csiphy_rx" },
+               .clock_rate = {
+                       { 0 },
+                       { 400000000 },
+               },
+               .reg = { "csitpg1" },
+               .tpg = {
+                       .lane_cnt = 4,
+                       .formats = &tpg_formats_gen1,
+                       .hw_ops = &tpg_ops_gen1
+               }
+       },
+       /* TPG2 */
+       {
+               .regulators = {},
+               .clock = { "cpas_ahb", "csid_csiphy_rx" },
+               .clock_rate = {
+                       { 0 },
+                       { 400000000 },
+               },
+               .reg = { "csitpg2" },
+               .tpg = {
+                       .lane_cnt = 4,
+                       .formats = &tpg_formats_gen1,
+                       .hw_ops = &tpg_ops_gen1
+               }
+       },
+};
+
 static const struct camss_subdev_resources csid_res_x1e80100[] = {
        /* CSID0 */
        {
@@ -4323,7 +4419,7 @@ static const struct camss_subdev_resources vfe_res_x1e80100[] = {
                .clock = {"camnoc_rt_axi", "camnoc_nrt_axi", "cpas_ahb",
                          "cpas_fast_ahb", "cpas_vfe0", "vfe0_fast_ahb",
                          "vfe0" },
-               .clock_rate = { { 0 },
+               .clock_rate = { { 400000000 },
                                { 0 },
                                { 0 },
                                { 0 },
@@ -4347,7 +4443,7 @@ static const struct camss_subdev_resources vfe_res_x1e80100[] = {
                .clock = { "camnoc_rt_axi", "camnoc_nrt_axi", "cpas_ahb",
                           "cpas_fast_ahb", "cpas_vfe1", "vfe1_fast_ahb",
                           "vfe1"  },
-               .clock_rate = { { 0 },
+               .clock_rate = { { 400000000 },
                                { 0 },
                                { 0 },
                                { 0 },
@@ -4371,7 +4467,7 @@ static const struct camss_subdev_resources vfe_res_x1e80100[] = {
                .clock = { "camnoc_rt_axi", "camnoc_nrt_axi", "cpas_ahb",
                           "vfe_lite_ahb", "cpas_vfe_lite", "vfe_lite",
                           "vfe_lite_csid" },
-               .clock_rate = { { 0 },
+               .clock_rate = { { 400000000 },
                                { 0 },
                                { 0 },
                                { 0 },
@@ -4394,7 +4490,7 @@ static const struct camss_subdev_resources vfe_res_x1e80100[] = {
                .clock = { "camnoc_rt_axi", "camnoc_nrt_axi", "cpas_ahb",
                           "vfe_lite_ahb", "cpas_vfe_lite", "vfe_lite",
                           "vfe_lite_csid" },
-               .clock_rate = { { 0 },
+               .clock_rate = { { 400000000 },
                                { 0 },
                                { 0 },
                                { 0 },
@@ -5277,6 +5373,13 @@ static int camss_probe(struct platform_device *pdev)
        if (!camss->csiphy)
                return -ENOMEM;
 
+       if (camss->res->tpg_num > 0) {
+               camss->tpg = devm_kcalloc(dev, camss->res->tpg_num,
+                                         sizeof(*camss->tpg), GFP_KERNEL);
+               if (!camss->tpg)
+                       return -ENOMEM;
+       }
+
        camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid),
                                   GFP_KERNEL);
        if (!camss->csid)
@@ -5466,11 +5569,13 @@ static const struct camss_resources qcs8300_resources = {
        .version = CAMSS_8300,
        .pd_name = "top",
        .csiphy_res = csiphy_res_8300,
+       .tpg_res = tpg_res_8775p,
        .csid_res = csid_res_8775p,
        .csid_wrapper_res = &csid_wrapper_res_sm8550,
        .vfe_res = vfe_res_8775p,
        .icc_res = icc_res_qcs8300,
        .csiphy_num = ARRAY_SIZE(csiphy_res_8300),
+       .tpg_num = ARRAY_SIZE(tpg_res_8775p),
        .csid_num = ARRAY_SIZE(csid_res_8775p),
        .vfe_num = ARRAY_SIZE(vfe_res_8775p),
        .icc_path_num = ARRAY_SIZE(icc_res_qcs8300),
@@ -5480,11 +5585,13 @@ static const struct camss_resources sa8775p_resources = {
        .version = CAMSS_8775P,
        .pd_name = "top",
        .csiphy_res = csiphy_res_8775p,
+       .tpg_res = tpg_res_8775p,
        .csid_res = csid_res_8775p,
        .csid_wrapper_res = &csid_wrapper_res_sm8550,
        .vfe_res = vfe_res_8775p,
        .icc_res = icc_res_sa8775p,
        .csiphy_num = ARRAY_SIZE(csiphy_res_8775p),
+       .tpg_num = ARRAY_SIZE(tpg_res_8775p),
        .csid_num = ARRAY_SIZE(csid_res_8775p),
        .vfe_num = ARRAY_SIZE(vfe_res_8775p),
        .icc_path_num = ARRAY_SIZE(icc_res_sa8775p),
@@ -5620,12 +5727,14 @@ static const struct camss_resources x1e80100_resources = {
        .version = CAMSS_X1E80100,
        .pd_name = "top",
        .csiphy_res = csiphy_res_x1e80100,
+       .tpg_res = tpg_res_x1e80100,
        .csid_res = csid_res_x1e80100,
        .vfe_res = vfe_res_x1e80100,
        .csid_wrapper_res = &csid_wrapper_res_x1e80100,
        .icc_res = icc_res_x1e80100,
        .icc_path_num = ARRAY_SIZE(icc_res_x1e80100),
        .csiphy_num = ARRAY_SIZE(csiphy_res_x1e80100),
+       .tpg_num = ARRAY_SIZE(tpg_res_x1e80100),
        .csid_num = ARRAY_SIZE(csid_res_x1e80100),
        .vfe_num = ARRAY_SIZE(vfe_res_x1e80100),
 };