summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/camss
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/camss')
-rw-r--r--drivers/media/platform/qcom/camss/Makefile1
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c102
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy.c1
-rw-r--r--drivers/media/platform/qcom/camss/camss-ispif.c8
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-4-1.c12
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-vbif.c31
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-vbif.h19
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.c17
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.h3
-rw-r--r--drivers/media/platform/qcom/camss/camss.c483
-rw-r--r--drivers/media/platform/qcom/camss/camss.h3
11 files changed, 675 insertions, 5 deletions
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 23960d02877d..5e349b491513 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -23,6 +23,7 @@ qcom-camss-objs += \
camss-vfe-680.o \
camss-vfe-gen3.o \
camss-vfe-gen1.o \
+ camss-vfe-vbif.o \
camss-vfe.o \
camss-video.o \
camss-format.o \
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
index a229ba04b158..619abbf60781 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -587,6 +587,102 @@ csiphy_lane_regs lane_regs_sm8550[] = {
{0x0C64, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
};
+/* GEN2 2.2.0 2PH 4 lane DPHY mode */
+static const struct
+csiphy_lane_regs lane_regs_sm8650[] = {
+ {0x0e94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0ea0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e90, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e98, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e94, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS},
+ {0x0e30, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e28, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e00, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e0c, 0xff, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e38, 0x1f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e2c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e34, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e1c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e14, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e3c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e04, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e20, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0e08, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0e10, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+
+ {0x0094, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x00a0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0090, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0098, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0094, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS},
+ {0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0000, 0x8e, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0038, 0xfe, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x002c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0034, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x001c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x003c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0004, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0008, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+
+ {0x0494, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x04a0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0490, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0498, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0494, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS},
+ {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0400, 0x8e, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0438, 0xfe, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x042c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0434, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x041c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x043c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0404, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0408, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+
+ {0x0894, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x08a0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0890, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0898, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0894, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS},
+ {0x0830, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x8e, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0838, 0xfe, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x082c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0834, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x081c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0814, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x083c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0804, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0820, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0808, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0810, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+
+ {0x0c94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0ca0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c90, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c98, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c94, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS},
+ {0x0c30, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c00, 0x8e, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c38, 0xfe, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c2c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c34, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c1c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c14, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c3c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c04, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c20, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0c08, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0c10, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+};
+
/* 4nm 2PH v 2.1.2 2p5Gbps 4 lane DPHY mode */
static const struct
csiphy_lane_regs lane_regs_x1e80100[] = {
@@ -914,6 +1010,7 @@ static bool csiphy_is_gen2(u32 version)
case CAMSS_8300:
case CAMSS_845:
case CAMSS_8550:
+ case CAMSS_8650:
case CAMSS_8775P:
case CAMSS_X1E80100:
ret = true;
@@ -1018,6 +1115,11 @@ static int csiphy_init(struct csiphy_device *csiphy)
regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8550);
regs->offset = 0x1000;
break;
+ case CAMSS_8650:
+ regs->lane_regs = &lane_regs_sm8650[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8650);
+ regs->offset = 0x1000;
+ break;
case CAMSS_8300:
case CAMSS_8775P:
regs->lane_regs = &lane_regs_sa8775p[0];
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 2de97f58f9ae..a734fb7dde0a 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -600,6 +600,7 @@ int msm_csiphy_subdev_init(struct camss *camss,
return PTR_ERR(csiphy->base);
if (camss->res->version == CAMSS_8x16 ||
+ camss->res->version == CAMSS_8x39 ||
camss->res->version == CAMSS_8x53 ||
camss->res->version == CAMSS_8x96) {
csiphy->base_clk_mux =
diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c
index 2dc585c6123d..aaf3caa42d33 100644
--- a/drivers/media/platform/qcom/camss/camss-ispif.c
+++ b/drivers/media/platform/qcom/camss/camss-ispif.c
@@ -1112,6 +1112,8 @@ int msm_ispif_subdev_init(struct camss *camss,
/* Number of ISPIF lines - same as number of CSID hardware modules */
if (camss->res->version == CAMSS_8x16)
ispif->line_num = 2;
+ else if (camss->res->version == CAMSS_8x39)
+ ispif->line_num = 3;
else if (camss->res->version == CAMSS_8x96 ||
camss->res->version == CAMSS_8x53 ||
camss->res->version == CAMSS_660)
@@ -1128,7 +1130,8 @@ int msm_ispif_subdev_init(struct camss *camss,
ispif->line[i].ispif = ispif;
ispif->line[i].id = i;
- if (camss->res->version == CAMSS_8x16) {
+ if (camss->res->version == CAMSS_8x16 ||
+ camss->res->version == CAMSS_8x39) {
ispif->line[i].formats = ispif_formats_8x16;
ispif->line[i].nformats =
ARRAY_SIZE(ispif_formats_8x16);
@@ -1162,7 +1165,8 @@ int msm_ispif_subdev_init(struct camss *camss,
ispif->irq = ret;
snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s",
dev_name(dev), MSM_ISPIF_NAME);
- if (camss->res->version == CAMSS_8x16)
+ if (camss->res->version == CAMSS_8x16 ||
+ camss->res->version == CAMSS_8x39)
ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16,
IRQF_TRIGGER_RISING, ispif->irq_name, ispif);
else if (camss->res->version == CAMSS_8x96 ||
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
index 901677293d97..9cf1ccdb2fe7 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
@@ -15,6 +15,7 @@
#include "camss.h"
#include "camss-vfe.h"
#include "camss-vfe-gen1.h"
+#include "camss-vfe-vbif.h"
#define VFE_0_HW_VERSION 0x000
@@ -733,6 +734,7 @@ static void vfe_set_qos(struct vfe_device *vfe)
{
u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG;
u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG;
+ int ret;
writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0);
writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1);
@@ -742,6 +744,16 @@ static void vfe_set_qos(struct vfe_device *vfe)
writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5);
writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6);
writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7);
+
+ /* SoC-specific VBIF settings */
+ if (vfe->res->has_vbif) {
+ ret = vfe_vbif_apply_settings(vfe);
+ if (ret < 0) {
+ dev_err_ratelimited(vfe->camss->dev,
+ "VFE: VBIF error %d\n",
+ ret);
+ }
+ }
}
static void vfe_set_ds(struct vfe_device *vfe)
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-vbif.c b/drivers/media/platform/qcom/camss/camss-vfe-vbif.c
new file mode 100644
index 000000000000..911f8da02f1f
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-vfe-vbif.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * camss-vfe-vbif.c
+ *
+ * Qualcomm MSM Camera Subsystem - VFE VBIF Module
+ *
+ * Copyright (c) 2025, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <linux/io.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+#include "camss-vfe-vbif.h"
+
+#define VBIF_FIXED_SORT_EN 0x30
+#define VBIF_FIXED_SORT_SEL0 0x34
+
+void vfe_vbif_write_reg(struct vfe_device *vfe, u32 reg, u32 val)
+{
+ writel_relaxed(val, vfe->vbif_base + reg);
+}
+
+int vfe_vbif_apply_settings(struct vfe_device *vfe)
+{
+ vfe_vbif_write_reg(vfe, VBIF_FIXED_SORT_EN, 0xfff);
+ vfe_vbif_write_reg(vfe, VBIF_FIXED_SORT_SEL0, 0x555000);
+
+ return 0;
+}
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-vbif.h b/drivers/media/platform/qcom/camss/camss-vfe-vbif.h
new file mode 100644
index 000000000000..502db629e961
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-vfe-vbif.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * camss-vfe-vbif.h
+ *
+ * Qualcomm MSM Camera Subsystem - VFE VBIF Module
+ *
+ * Copyright (c) 2025, The Linux Foundation. All rights reserved.
+ *
+ */
+#ifndef QC_MSM_CAMSS_VFE_VBIF_H
+#define QC_MSM_CAMSS_VFE_VBIF_H
+
+#include "camss-vfe.h"
+
+void vfe_vbif_write_reg(struct vfe_device *vfe, u32 reg, u32 val);
+
+int vfe_vbif_apply_settings(struct vfe_device *vfe);
+
+#endif /* QC_MSM_CAMSS_VFE_VBIF_H */
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index dff8d0a1e8c2..9c7ad8aa4058 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -290,6 +290,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
switch (vfe->camss->res->version) {
case CAMSS_8x16:
+ case CAMSS_8x39:
case CAMSS_8x53:
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
@@ -348,6 +349,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
case CAMSS_8300:
case CAMSS_845:
case CAMSS_8550:
+ case CAMSS_8650:
case CAMSS_8775P:
case CAMSS_X1E80100:
switch (sink_code) {
@@ -541,7 +543,7 @@ int vfe_enable_output_v2(struct vfe_line *line)
ops->vfe_wm_start(vfe, output->wm_idx[0], line);
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < CAMSS_INIT_BUF_COUNT; i++) {
output->buf[i] = vfe_buf_get_pending(output);
if (!output->buf[i])
break;
@@ -914,7 +916,8 @@ static int vfe_match_clock_names(struct vfe_device *vfe,
return (!strcmp(clock->name, vfe_name) ||
!strcmp(clock->name, vfe_lite_name) ||
!strcmp(clock->name, "vfe_lite") ||
- !strcmp(clock->name, "camnoc_axi"));
+ !strcmp(clock->name, "camnoc_axi") ||
+ !strcmp(clock->name, "camnoc_rt_axi"));
}
/*
@@ -1827,6 +1830,15 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
return PTR_ERR(vfe->base);
}
+ if (vfe->res->has_vbif) {
+ vfe->vbif_base = devm_platform_ioremap_resource_byname(pdev,
+ vfe->res->vbif_name);
+ if (IS_ERR(vfe->vbif_base)) {
+ dev_err(dev, "could not map vbif memory\n");
+ return PTR_ERR(vfe->vbif_base);
+ }
+ }
+
/* Interrupt */
ret = platform_get_irq_byname(pdev, res->interrupt[0]);
@@ -1995,6 +2007,7 @@ static int vfe_bpl_align(struct vfe_device *vfe)
case CAMSS_8300:
case CAMSS_845:
case CAMSS_8550:
+ case CAMSS_8650:
case CAMSS_8775P:
case CAMSS_X1E80100:
ret = 16;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 0300efdb1c46..ae9dad353a37 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -136,6 +136,8 @@ struct vfe_subdev_resources {
u8 line_num;
bool has_pd;
char *pd_name;
+ bool has_vbif;
+ char *vbif_name;
const struct vfe_hw_ops *hw_ops;
const struct camss_formats *formats_rdi;
const struct camss_formats *formats_pix;
@@ -145,6 +147,7 @@ struct vfe_device {
struct camss *camss;
u8 id;
void __iomem *base;
+ void __iomem *vbif_base;
u32 irq;
char irq_name[30];
struct camss_clock *clock;
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 2fbcd0e343aa..fcc2b2c3cba0 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -154,6 +154,149 @@ static const struct camss_subdev_resources vfe_res_8x16[] = {
}
};
+static const struct camss_subdev_resources csiphy_res_8x39[] = {
+ /* CSIPHY0 */
+ {
+ .regulators = { "vdda" },
+ .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
+ .clock_rate = { { 0 },
+ { 40000000, 80000000 },
+ { 0 },
+ { 100000000, 200000000 } },
+ .reg = { "csiphy0", "csiphy0_clk_mux" },
+ .interrupt = { "csiphy0" },
+ .csiphy = {
+ .id = 0,
+ .hw_ops = &csiphy_ops_2ph_1_0,
+ .formats = &csiphy_formats_8x16
+ }
+ },
+
+ /* CSIPHY1 */
+ {
+ .regulators = { "vdda" },
+ .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
+ .clock_rate = { { 0 },
+ { 40000000, 80000000 },
+ { 0 },
+ { 100000000, 200000000 } },
+ .reg = { "csiphy1", "csiphy1_clk_mux" },
+ .interrupt = { "csiphy1" },
+ .csiphy = {
+ .id = 1,
+ .hw_ops = &csiphy_ops_2ph_1_0,
+ .formats = &csiphy_formats_8x16
+ }
+ }
+};
+
+static const struct camss_subdev_resources csid_res_8x39[] = {
+ /* CSID0 */
+ {
+ .regulators = {},
+ .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
+ "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
+ .clock_rate = { { 0 },
+ { 40000000, 80000000 },
+ { 0 },
+ { 0 },
+ { 100000000, 200000000 },
+ { 0 },
+ { 0 },
+ { 0 } },
+ .reg = { "csid0" },
+ .interrupt = { "csid0" },
+ .csid = {
+ .hw_ops = &csid_ops_4_1,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_4_1
+ }
+ },
+
+ /* CSID1 */
+ {
+ .regulators = {},
+ .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
+ "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
+ .clock_rate = { { 0 },
+ { 40000000, 80000000 },
+ { 0 },
+ { 0 },
+ { 100000000, 200000000 },
+ { 0 },
+ { 0 },
+ { 0 } },
+ .reg = { "csid1" },
+ .interrupt = { "csid1" },
+ .csid = {
+ .hw_ops = &csid_ops_4_1,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_4_1
+ }
+ },
+
+ /* CSID2 */
+ {
+ .regulators = {},
+ .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
+ "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" },
+ .clock_rate = { { 0 },
+ { 40000000, 80000000 },
+ { 0 },
+ { 0 },
+ { 100000000, 200000000 },
+ { 0 },
+ { 0 },
+ { 0 } },
+ .reg = { "csid2" },
+ .interrupt = { "csid2" },
+ .csid = {
+ .hw_ops = &csid_ops_4_1,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .formats = &csid_formats_4_1
+ }
+ },
+};
+
+static const struct camss_subdev_resources ispif_res_8x39 = {
+ /* ISPIF */
+ .clock = { "top_ahb", "ispif_ahb", "ahb",
+ "csi0", "csi0_pix", "csi0_rdi",
+ "csi1", "csi1_pix", "csi1_rdi",
+ "csi2", "csi2_pix", "csi2_rdi" },
+ .clock_for_reset = { "vfe0", "csi_vfe0" },
+ .reg = { "ispif", "csi_clk_mux" },
+ .interrupt = { "ispif" },
+};
+
+static const struct camss_subdev_resources vfe_res_8x39[] = {
+ /* VFE0 */
+ {
+ .regulators = {},
+ .clock = { "top_ahb", "ispif_ahb", "vfe0", "csi_vfe0",
+ "vfe_ahb", "vfe_axi", "ahb" },
+ .clock_rate = { { 0 },
+ { 40000000, 80000000 },
+ { 50000000, 80000000, 100000000, 160000000,
+ 177780000, 200000000, 266670000, 320000000,
+ 400000000, 465000000, 480000000, 600000000 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe0" },
+ .interrupt = { "vfe0" },
+ .vfe = {
+ .line_num = 3,
+ .has_vbif = true,
+ .vbif_name = "vfe0_vbif",
+ .hw_ops = &vfe_ops_4_1,
+ .formats_rdi = &vfe_formats_rdi_8x16,
+ .formats_pix = &vfe_formats_pix_8x16
+ }
+ }
+};
+
static const struct camss_subdev_resources csid_res_8x53[] = {
/* CSID0 */
{
@@ -2617,6 +2760,317 @@ static const struct resources_icc icc_res_sm8550[] = {
},
};
+static const struct camss_subdev_resources csiphy_res_sm8650[] = {
+ /* CSIPHY0 */
+ {
+ .regulators = { "vdd-csiphy01-0p9", "vdd-csiphy01-1p2", },
+ .clock = { "csiphy0", "csiphy0_timer" },
+ .clock_rate = { { 400000000 },
+ { 400000000 } },
+ .reg = { "csiphy0" },
+ .interrupt = { "csiphy0" },
+ .csiphy = {
+ .id = 0,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ },
+ },
+ /* CSIPHY1 */
+ {
+ .regulators = { "vdd-csiphy01-0p9", "vdd-csiphy01-1p2", },
+ .clock = { "csiphy1", "csiphy1_timer" },
+ .clock_rate = { { 400000000 },
+ { 400000000 } },
+ .reg = { "csiphy1" },
+ .interrupt = { "csiphy1" },
+ .csiphy = {
+ .id = 1,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ },
+ },
+ /* CSIPHY2 */
+ {
+ .regulators = { "vdd-csiphy24-0p9", "vdd-csiphy24-1p2", },
+ .clock = { "csiphy2", "csiphy2_timer" },
+ .clock_rate = { { 400000000 },
+ { 400000000 } },
+ .reg = { "csiphy2" },
+ .interrupt = { "csiphy2" },
+ .csiphy = {
+ .id = 2,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ },
+ },
+ /* CSIPHY3 */
+ {
+ .regulators = { "vdd-csiphy35-0p9", "vdd-csiphy35-1p2", },
+ .clock = { "csiphy3", "csiphy3_timer" },
+ .clock_rate = { { 400000000 },
+ { 400000000 } },
+ .reg = { "csiphy3" },
+ .interrupt = { "csiphy3" },
+ .csiphy = {
+ .id = 3,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ },
+ },
+ /* CSIPHY4 */
+ {
+ .regulators = { "vdd-csiphy24-0p9", "vdd-csiphy24-1p2", },
+ .clock = { "csiphy4", "csiphy4_timer" },
+ .clock_rate = { { 400000000 },
+ { 400000000 } },
+ .reg = { "csiphy4" },
+ .interrupt = { "csiphy4" },
+ .csiphy = {
+ .id = 4,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ },
+ },
+ /* CSIPHY5 */
+ {
+ .regulators = { "vdd-csiphy35-0p9", "vdd-csiphy35-1p2", },
+ .clock = { "csiphy5", "csiphy5_timer" },
+ .clock_rate = { { 400000000 },
+ { 400000000 } },
+ .reg = { "csiphy5" },
+ .interrupt = { "csiphy5" },
+ .csiphy = {
+ .id = 5,
+ .hw_ops = &csiphy_ops_3ph_1_0,
+ .formats = &csiphy_formats_sdm845,
+ },
+ },
+};
+
+static const struct camss_subdev_resources csid_res_sm8650[] = {
+ /* CSID0 */
+ {
+ .regulators = { },
+ .clock = { "csid", "csiphy_rx" },
+ .clock_rate = { { 400000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid0" },
+ .interrupt = { "csid0" },
+ .csid = {
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_gen3,
+ .formats = &csid_formats_gen2,
+ },
+ },
+ /* CSID1 */
+ {
+ .regulators = { },
+ .clock = { "csid", "csiphy_rx" },
+ .clock_rate = { { 400000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid1" },
+ .interrupt = { "csid1" },
+ .csid = {
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_gen3,
+ .formats = &csid_formats_gen2,
+ },
+ },
+ /* CSID2 */
+ {
+ .regulators = { },
+ .clock = { "csid", "csiphy_rx" },
+ .clock_rate = { { 400000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid2" },
+ .interrupt = { "csid2" },
+ .csid = {
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_gen3,
+ .formats = &csid_formats_gen2,
+ },
+ },
+ /* CSID3 lite */
+ {
+ .regulators = { },
+ .clock = { "vfe_lite_ahb", "vfe_lite_csid", "vfe_lite_cphy_rx" },
+ .clock_rate = { { 0 },
+ { 400000000, 480000000 },
+ { 0 } },
+ .reg = { "csid_lite0" },
+ .interrupt = { "csid_lite0" },
+ .csid = {
+ .is_lite = true,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_gen3,
+ .formats = &csid_formats_gen2,
+ },
+ },
+ /* CSID4 lite */
+ {
+ .regulators = { },
+ .clock = { "vfe_lite_ahb", "vfe_lite_csid", "vfe_lite_cphy_rx" },
+ .clock_rate = { { 0 },
+ { 400000000, 480000000 },
+ { 0 } },
+ .reg = { "csid_lite1" },
+ .interrupt = { "csid_lite1" },
+ .csid = {
+ .is_lite = true,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_gen3,
+ .formats = &csid_formats_gen2,
+ },
+ },
+};
+
+static const struct camss_subdev_resources vfe_res_sm8650[] = {
+ /* VFE0 */
+ {
+ .regulators = { },
+ .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb",
+ "camnoc_axi", "vfe0_fast_ahb", "vfe0", "cpas_vfe0",
+ "qdss_debug_xo",
+ },
+ .clock_rate = { { 0 },
+ { 80000000 },
+ { 300000000, 400000000 },
+ { 300000000, 400000000 },
+ { 0 },
+ { 466000000, 594000000, 675000000, 785000000 },
+ { 0 },
+ { 0 },
+ },
+ .reg = { "vfe0" },
+ .interrupt = { "vfe0" },
+ .vfe = {
+ .line_num = 3,
+ .has_pd = true,
+ .pd_name = "ife0",
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ },
+ },
+ /* VFE1 */
+ {
+ .regulators = { },
+ .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb",
+ "camnoc_axi", "vfe1_fast_ahb", "vfe1", "cpas_vfe1",
+ "qdss_debug_xo",
+ },
+ .clock_rate = { { 0 },
+ { 80000000 },
+ { 300000000, 400000000 },
+ { 300000000, 400000000 },
+ { 0 },
+ { 466000000, 594000000, 675000000, 785000000 },
+ { 0 },
+ { 0 },
+ },
+ .reg = { "vfe1" },
+ .interrupt = { "vfe1" },
+ .vfe = {
+ .line_num = 3,
+ .has_pd = true,
+ .pd_name = "ife1",
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ },
+ },
+ /* VFE2 */
+ {
+ .regulators = { },
+ .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb",
+ "camnoc_axi", "vfe2_fast_ahb", "vfe2", "cpas_vfe2",
+ "qdss_debug_xo",
+ },
+ .clock_rate = { { 0 },
+ { 80000000 },
+ { 300000000, 400000000 },
+ { 300000000, 400000000 },
+ { 0 },
+ { 466000000, 594000000, 675000000, 785000000 },
+ { 0 },
+ { 0 },
+ },
+ .reg = { "vfe2" },
+ .interrupt = { "vfe2" },
+ .vfe = {
+ .line_num = 3,
+ .has_pd = true,
+ .pd_name = "ife2",
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ },
+ },
+ /* VFE3 lite */
+ {
+ .regulators = { },
+ .clock = { "gcc_axi_hf", "cpas_ahb", "camnoc_axi",
+ "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
+ "qdss_debug_xo",
+ },
+ .clock_rate = { { 0 },
+ { 80000000 },
+ { 300000000, 400000000 },
+ { 0 },
+ { 400000000, 480000000 },
+ { 0 },
+ { 0 },
+ },
+ .reg = { "vfe_lite0" },
+ .interrupt = { "vfe_lite0" },
+ .vfe = {
+ .line_num = 4,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ },
+ },
+ /* VFE4 lite */
+ {
+ .regulators = { },
+ .clock = { "gcc_axi_hf", "cpas_ahb", "camnoc_axi",
+ "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
+ "qdss_debug_xo",
+ },
+ .clock_rate = { { 0 },
+ { 80000000 },
+ { 300000000, 400000000 },
+ { 0 },
+ { 400000000, 480000000 },
+ { 0 },
+ { 0 },
+ },
+ .reg = { "vfe_lite1" },
+ .interrupt = { "vfe_lite1" },
+ .vfe = {
+ .line_num = 4,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_gen3,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ },
+ },
+};
+
+static const struct resources_icc icc_res_sm8650[] = {
+ {
+ .name = "ahb",
+ .icc_bw_tbl.avg = 38400,
+ .icc_bw_tbl.peak = 76800,
+ },
+ {
+ .name = "hf_mnoc",
+ .icc_bw_tbl.avg = 2097152,
+ .icc_bw_tbl.peak = 2097152,
+ },
+};
+
static const struct camss_subdev_resources csiphy_res_8300[] = {
/* CSIPHY0 */
{
@@ -4171,6 +4625,7 @@ static int camss_probe(struct platform_device *pdev)
return -ENOMEM;
if (camss->res->version == CAMSS_8x16 ||
+ camss->res->version == CAMSS_8x39 ||
camss->res->version == CAMSS_8x53 ||
camss->res->version == CAMSS_8x96) {
camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
@@ -4302,6 +4757,17 @@ static const struct camss_resources msm8916_resources = {
.vfe_num = ARRAY_SIZE(vfe_res_8x16),
};
+static const struct camss_resources msm8939_resources = {
+ .version = CAMSS_8x39,
+ .csiphy_res = csiphy_res_8x39,
+ .csid_res = csid_res_8x39,
+ .ispif_res = &ispif_res_8x39,
+ .vfe_res = vfe_res_8x39,
+ .csiphy_num = ARRAY_SIZE(csiphy_res_8x39),
+ .csid_num = ARRAY_SIZE(csid_res_8x39),
+ .vfe_num = ARRAY_SIZE(vfe_res_8x39),
+};
+
static const struct camss_resources msm8953_resources = {
.version = CAMSS_8x53,
.icc_res = icc_res_8x53,
@@ -4452,6 +4918,20 @@ static const struct camss_resources sm8550_resources = {
.vfe_num = ARRAY_SIZE(vfe_res_8550),
};
+static const struct camss_resources sm8650_resources = {
+ .version = CAMSS_8650,
+ .pd_name = "top",
+ .csiphy_res = csiphy_res_sm8650,
+ .csid_res = csid_res_sm8650,
+ .csid_wrapper_res = &csid_wrapper_res_sm8550,
+ .vfe_res = vfe_res_sm8650,
+ .icc_res = icc_res_sm8650,
+ .icc_path_num = ARRAY_SIZE(icc_res_sm8650),
+ .csiphy_num = ARRAY_SIZE(csiphy_res_sm8650),
+ .csid_num = ARRAY_SIZE(csid_res_sm8650),
+ .vfe_num = ARRAY_SIZE(vfe_res_sm8650),
+};
+
static const struct camss_resources x1e80100_resources = {
.version = CAMSS_X1E80100,
.pd_name = "top",
@@ -4468,6 +4948,7 @@ static const struct camss_resources x1e80100_resources = {
static const struct of_device_id camss_dt_match[] = {
{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
+ { .compatible = "qcom,msm8939-camss", .data = &msm8939_resources },
{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
{ .compatible = "qcom,qcm2290-camss", .data = &qcm2290_resources },
@@ -4480,6 +4961,7 @@ static const struct of_device_id camss_dt_match[] = {
{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
{ .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
{ .compatible = "qcom,sm8550-camss", .data = &sm8550_resources },
+ { .compatible = "qcom,sm8650-camss", .data = &sm8650_resources },
{ .compatible = "qcom,x1e80100-camss", .data = &x1e80100_resources },
{ }
};
@@ -4537,7 +5019,6 @@ static struct platform_driver qcom_camss_driver = {
module_platform_driver(qcom_camss_driver);
-MODULE_ALIAS("platform:qcom-camss");
MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver");
MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index a70fbc78ccc3..9d9a62640e25 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -41,6 +41,7 @@
(to_camss_index(ptr_module, index)->dev)
#define CAMSS_RES_MAX 17
+#define CAMSS_INIT_BUF_COUNT 2
struct camss_subdev_resources {
char *regulators[CAMSS_RES_MAX];
@@ -81,6 +82,7 @@ enum camss_version {
CAMSS_2290,
CAMSS_7280,
CAMSS_8x16,
+ CAMSS_8x39,
CAMSS_8x53,
CAMSS_8x96,
CAMSS_8250,
@@ -88,6 +90,7 @@ enum camss_version {
CAMSS_8300,
CAMSS_845,
CAMSS_8550,
+ CAMSS_8650,
CAMSS_8775P,
CAMSS_X1E80100,
};